blob: 88484327fee801bb456397d8a94e6aaa75fd0125 [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
107/* ---------------------------------------------------------------------------
108 * Math utilities.
109 */
110
111/* k = i+j overflows iff k differs in sign from both inputs,
112 * iff k^i has sign bit set and k^j has sign bit set,
113 * iff (k^i)&(k^j) has sign bit set.
114 */
115#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000117
118/* Compute Python divmod(x, y), returning the quotient and storing the
119 * remainder into *r. The quotient is the floor of x/y, and that's
120 * the real point of this. C will probably truncate instead (C99
121 * requires truncation; C89 left it implementation-defined).
122 * Simplification: we *require* that y > 0 here. That's appropriate
123 * for all the uses made of it. This simplifies the code and makes
124 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
125 * overflow case).
126 */
127static int
128divmod(int x, int y, int *r)
129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 assert(y > 0);
133 quo = x / y;
134 *r = x - quo * y;
135 if (*r < 0) {
136 --quo;
137 *r += y;
138 }
139 assert(0 <= *r && *r < y);
140 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000141}
142
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000143/* Nearest integer to m / n for integers m and n. Half-integer results
144 * are rounded to even.
145 */
146static PyObject *
147divide_nearest(PyObject *m, PyObject *n)
148{
149 PyObject *result;
150 PyObject *temp;
151
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000152 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000153 if (temp == NULL)
154 return NULL;
155 result = PyTuple_GET_ITEM(temp, 0);
156 Py_INCREF(result);
157 Py_DECREF(temp);
158
159 return result;
160}
161
Tim Peters2a799bf2002-12-16 20:18:38 +0000162/* ---------------------------------------------------------------------------
163 * General calendrical helper functions
164 */
165
166/* For each month ordinal in 1..12, the number of days in that month,
167 * and the number of days before that month in the same year. These
168 * are correct for non-leap years only.
169 */
170static int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 0, /* unused; this vector uses 1-based indexing */
172 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000173};
174
175static int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 0, /* unused; this vector uses 1-based indexing */
177 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000178};
179
180/* year -> 1 if leap year, else 0. */
181static int
182is_leap(int year)
183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 /* Cast year to unsigned. The result is the same either way, but
185 * C can generate faster code for unsigned mod than for signed
186 * mod (especially for % 4 -- a good compiler should just grab
187 * the last 2 bits when the LHS is unsigned).
188 */
189 const unsigned int ayear = (unsigned int)year;
190 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000191}
192
193/* year, month -> number of days in that month in that year */
194static int
195days_in_month(int year, int month)
196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 assert(month >= 1);
198 assert(month <= 12);
199 if (month == 2 && is_leap(year))
200 return 29;
201 else
202 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000203}
204
205/* year, month -> number of days in year preceeding first day of month */
206static int
207days_before_month(int year, int month)
208{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 assert(month >= 1);
212 assert(month <= 12);
213 days = _days_before_month[month];
214 if (month > 2 && is_leap(year))
215 ++days;
216 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000217}
218
219/* year -> number of days before January 1st of year. Remember that we
220 * start with year 1, so days_before_year(1) == 0.
221 */
222static int
223days_before_year(int year)
224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 int y = year - 1;
226 /* This is incorrect if year <= 0; we really want the floor
227 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000228 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000230 assert (year >= 1);
231 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000232}
233
234/* Number of days in 4, 100, and 400 year cycles. That these have
235 * the correct values is asserted in the module init function.
236 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237#define DI4Y 1461 /* days_before_year(5); days in 4 years */
238#define DI100Y 36524 /* days_before_year(101); days in 100 years */
239#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000240
241/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
242static void
243ord_to_ymd(int ordinal, int *year, int *month, int *day)
244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
248 * leap years repeats exactly every 400 years. The basic strategy is
249 * to find the closest 400-year boundary at or before ordinal, then
250 * work with the offset from that boundary to ordinal. Life is much
251 * clearer if we subtract 1 from ordinal first -- then the values
252 * of ordinal at 400-year boundaries are exactly those divisible
253 * by DI400Y:
254 *
255 * D M Y n n-1
256 * -- --- ---- ---------- ----------------
257 * 31 Dec -400 -DI400Y -DI400Y -1
258 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
259 * ...
260 * 30 Dec 000 -1 -2
261 * 31 Dec 000 0 -1
262 * 1 Jan 001 1 0 400-year boundary
263 * 2 Jan 001 2 1
264 * 3 Jan 001 3 2
265 * ...
266 * 31 Dec 400 DI400Y DI400Y -1
267 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
268 */
269 assert(ordinal >= 1);
270 --ordinal;
271 n400 = ordinal / DI400Y;
272 n = ordinal % DI400Y;
273 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 /* Now n is the (non-negative) offset, in days, from January 1 of
276 * year, to the desired date. Now compute how many 100-year cycles
277 * precede n.
278 * Note that it's possible for n100 to equal 4! In that case 4 full
279 * 100-year cycles precede the desired day, which implies the
280 * desired day is December 31 at the end of a 400-year cycle.
281 */
282 n100 = n / DI100Y;
283 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 /* Now compute how many 4-year cycles precede it. */
286 n4 = n / DI4Y;
287 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 /* And now how many single years. Again n1 can be 4, and again
290 * meaning that the desired day is December 31 at the end of the
291 * 4-year cycle.
292 */
293 n1 = n / 365;
294 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 *year += n100 * 100 + n4 * 4 + n1;
297 if (n1 == 4 || n100 == 4) {
298 assert(n == 0);
299 *year -= 1;
300 *month = 12;
301 *day = 31;
302 return;
303 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 /* Now the year is correct, and n is the offset from January 1. We
306 * find the month via an estimate that's either exact or one too
307 * large.
308 */
309 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
310 assert(leapyear == is_leap(*year));
311 *month = (n + 50) >> 5;
312 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
313 if (preceding > n) {
314 /* estimate is too large */
315 *month -= 1;
316 preceding -= days_in_month(*year, *month);
317 }
318 n -= preceding;
319 assert(0 <= n);
320 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000323}
324
325/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
326static int
327ymd_to_ord(int year, int month, int day)
328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000330}
331
332/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
333static int
334weekday(int year, int month, int day)
335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000337}
338
339/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
340 * first calendar week containing a Thursday.
341 */
342static int
343iso_week1_monday(int year)
344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
346 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
347 int first_weekday = (first_day + 6) % 7;
348 /* ordinal of closest Monday at or before 1/1 */
349 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
352 week1_monday += 7;
353 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000354}
355
356/* ---------------------------------------------------------------------------
357 * Range checkers.
358 */
359
360/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
361 * If not, raise OverflowError and return -1.
362 */
363static int
364check_delta_day_range(int days)
365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
367 return 0;
368 PyErr_Format(PyExc_OverflowError,
369 "days=%d; must have magnitude <= %d",
370 days, MAX_DELTA_DAYS);
371 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000372}
373
374/* Check that date arguments are in range. Return 0 if they are. If they
375 * aren't, raise ValueError and return -1.
376 */
377static int
378check_date_args(int year, int month, int day)
379{
380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (year < MINYEAR || year > MAXYEAR) {
382 PyErr_SetString(PyExc_ValueError,
383 "year is out of range");
384 return -1;
385 }
386 if (month < 1 || month > 12) {
387 PyErr_SetString(PyExc_ValueError,
388 "month must be in 1..12");
389 return -1;
390 }
391 if (day < 1 || day > days_in_month(year, month)) {
392 PyErr_SetString(PyExc_ValueError,
393 "day is out of range for month");
394 return -1;
395 }
396 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000397}
398
399/* Check that time arguments are in range. Return 0 if they are. If they
400 * aren't, raise ValueError and return -1.
401 */
402static int
403check_time_args(int h, int m, int s, int us)
404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 if (h < 0 || h > 23) {
406 PyErr_SetString(PyExc_ValueError,
407 "hour must be in 0..23");
408 return -1;
409 }
410 if (m < 0 || m > 59) {
411 PyErr_SetString(PyExc_ValueError,
412 "minute must be in 0..59");
413 return -1;
414 }
415 if (s < 0 || s > 59) {
416 PyErr_SetString(PyExc_ValueError,
417 "second must be in 0..59");
418 return -1;
419 }
420 if (us < 0 || us > 999999) {
421 PyErr_SetString(PyExc_ValueError,
422 "microsecond must be in 0..999999");
423 return -1;
424 }
425 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000426}
427
428/* ---------------------------------------------------------------------------
429 * Normalization utilities.
430 */
431
432/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
433 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
434 * at least factor, enough of *lo is converted into "hi" units so that
435 * 0 <= *lo < factor. The input values must be such that int overflow
436 * is impossible.
437 */
438static void
439normalize_pair(int *hi, int *lo, int factor)
440{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 assert(factor > 0);
442 assert(lo != hi);
443 if (*lo < 0 || *lo >= factor) {
444 const int num_hi = divmod(*lo, factor, lo);
445 const int new_hi = *hi + num_hi;
446 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
447 *hi = new_hi;
448 }
449 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000450}
451
452/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 * 0 <= *s < 24*3600
454 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000455 * The input values must be such that the internals don't overflow.
456 * The way this routine is used, we don't get close.
457 */
458static void
459normalize_d_s_us(int *d, int *s, int *us)
460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 if (*us < 0 || *us >= 1000000) {
462 normalize_pair(s, us, 1000000);
463 /* |s| can't be bigger than about
464 * |original s| + |original us|/1000000 now.
465 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 }
468 if (*s < 0 || *s >= 24*3600) {
469 normalize_pair(d, s, 24*3600);
470 /* |d| can't be bigger than about
471 * |original d| +
472 * (|original s| + |original us|/1000000) / (24*3600) now.
473 */
474 }
475 assert(0 <= *s && *s < 24*3600);
476 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000477}
478
479/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 * 1 <= *m <= 12
481 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000482 * The input values must be such that the internals don't overflow.
483 * The way this routine is used, we don't get close.
484 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000485static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000486normalize_y_m_d(int *y, int *m, int *d)
487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000489
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000490 /* In actual use, m is always the month component extracted from a
491 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 /* Now only day can be out of bounds (year may also be out of bounds
497 * for a datetime object, but we don't care about that here).
498 * If day is out of bounds, what to do is arguable, but at least the
499 * method here is principled and explainable.
500 */
501 dim = days_in_month(*y, *m);
502 if (*d < 1 || *d > dim) {
503 /* Move day-1 days from the first of the month. First try to
504 * get off cheap if we're only one day out of range
505 * (adjustments for timezone alone can't be worse than that).
506 */
507 if (*d == 0) {
508 --*m;
509 if (*m > 0)
510 *d = days_in_month(*y, *m);
511 else {
512 --*y;
513 *m = 12;
514 *d = 31;
515 }
516 }
517 else if (*d == dim + 1) {
518 /* move forward a day */
519 ++*m;
520 *d = 1;
521 if (*m > 12) {
522 *m = 1;
523 ++*y;
524 }
525 }
526 else {
527 int ordinal = ymd_to_ord(*y, *m, 1) +
528 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000529 if (ordinal < 1 || ordinal > MAXORDINAL) {
530 goto error;
531 } else {
532 ord_to_ymd(ordinal, y, m, d);
533 return 0;
534 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 }
536 }
537 assert(*m > 0);
538 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000539 if (MINYEAR <= *y && *y <= MAXYEAR)
540 return 0;
541 error:
542 PyErr_SetString(PyExc_OverflowError,
543 "date value out of range");
544 return -1;
545
Tim Peters2a799bf2002-12-16 20:18:38 +0000546}
547
548/* Fiddle out-of-bounds months and days so that the result makes some kind
549 * of sense. The parameters are both inputs and outputs. Returns < 0 on
550 * failure, where failure means the adjusted year is out of bounds.
551 */
552static int
553normalize_date(int *year, int *month, int *day)
554{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000555 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000556}
557
558/* Force all the datetime fields into range. The parameters are both
559 * inputs and outputs. Returns < 0 on error.
560 */
561static int
562normalize_datetime(int *year, int *month, int *day,
563 int *hour, int *minute, int *second,
564 int *microsecond)
565{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 normalize_pair(second, microsecond, 1000000);
567 normalize_pair(minute, second, 60);
568 normalize_pair(hour, minute, 60);
569 normalize_pair(day, hour, 24);
570 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000571}
572
573/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000574 * Basic object allocation: tp_alloc implementations. These allocate
575 * Python objects of the right size and type, and do the Python object-
576 * initialization bit. If there's not enough memory, they return NULL after
577 * setting MemoryError. All data members remain uninitialized trash.
578 *
579 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000580 * member is needed. This is ugly, imprecise, and possibly insecure.
581 * tp_basicsize for the time and datetime types is set to the size of the
582 * struct that has room for the tzinfo member, so subclasses in Python will
583 * allocate enough space for a tzinfo member whether or not one is actually
584 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
585 * part is that PyType_GenericAlloc() (which subclasses in Python end up
586 * using) just happens today to effectively ignore the nitems argument
587 * when tp_itemsize is 0, which it is for these type objects. If that
588 * changes, perhaps the callers of tp_alloc slots in this file should
589 * be changed to force a 0 nitems argument unless the type being allocated
590 * is a base type implemented in this file (so that tp_alloc is time_alloc
591 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000592 */
593
594static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000595time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000596{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 self = (PyObject *)
600 PyObject_MALLOC(aware ?
601 sizeof(PyDateTime_Time) :
602 sizeof(_PyDateTime_BaseTime));
603 if (self == NULL)
604 return (PyObject *)PyErr_NoMemory();
605 PyObject_INIT(self, type);
606 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000607}
608
609static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000610datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 self = (PyObject *)
615 PyObject_MALLOC(aware ?
616 sizeof(PyDateTime_DateTime) :
617 sizeof(_PyDateTime_BaseDateTime));
618 if (self == NULL)
619 return (PyObject *)PyErr_NoMemory();
620 PyObject_INIT(self, type);
621 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000622}
623
624/* ---------------------------------------------------------------------------
625 * Helpers for setting object fields. These work on pointers to the
626 * appropriate base class.
627 */
628
629/* For date and datetime. */
630static void
631set_date_fields(PyDateTime_Date *self, int y, int m, int d)
632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 self->hashcode = -1;
634 SET_YEAR(self, y);
635 SET_MONTH(self, m);
636 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000637}
638
639/* ---------------------------------------------------------------------------
640 * Create various objects, mostly without range checking.
641 */
642
643/* Create a date instance with no range checking. */
644static PyObject *
645new_date_ex(int year, int month, int day, PyTypeObject *type)
646{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
650 if (self != NULL)
651 set_date_fields(self, year, month, day);
652 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000653}
654
655#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000657
658/* Create a datetime instance with no range checking. */
659static PyObject *
660new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000662{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 PyDateTime_DateTime *self;
664 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
667 if (self != NULL) {
668 self->hastzinfo = aware;
669 set_date_fields((PyDateTime_Date *)self, year, month, day);
670 DATE_SET_HOUR(self, hour);
671 DATE_SET_MINUTE(self, minute);
672 DATE_SET_SECOND(self, second);
673 DATE_SET_MICROSECOND(self, usecond);
674 if (aware) {
675 Py_INCREF(tzinfo);
676 self->tzinfo = tzinfo;
677 }
678 }
679 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000680}
681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
683 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
684 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000685
686/* Create a time instance with no range checking. */
687static PyObject *
688new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000690{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 PyDateTime_Time *self;
692 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
695 if (self != NULL) {
696 self->hastzinfo = aware;
697 self->hashcode = -1;
698 TIME_SET_HOUR(self, hour);
699 TIME_SET_MINUTE(self, minute);
700 TIME_SET_SECOND(self, second);
701 TIME_SET_MICROSECOND(self, usecond);
702 if (aware) {
703 Py_INCREF(tzinfo);
704 self->tzinfo = tzinfo;
705 }
706 }
707 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000708}
709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710#define new_time(hh, mm, ss, us, tzinfo) \
711 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000712
713/* Create a timedelta instance. Normalize the members iff normalize is
714 * true. Passing false is a speed optimization, if you know for sure
715 * that seconds and microseconds are already in their proper ranges. In any
716 * case, raises OverflowError and returns NULL if the normalized days is out
717 * of range).
718 */
719static PyObject *
720new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000722{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 if (normalize)
726 normalize_d_s_us(&days, &seconds, &microseconds);
727 assert(0 <= seconds && seconds < 24*3600);
728 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 if (check_delta_day_range(days) < 0)
731 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
734 if (self != NULL) {
735 self->hashcode = -1;
736 SET_TD_DAYS(self, days);
737 SET_TD_SECONDS(self, seconds);
738 SET_TD_MICROSECONDS(self, microseconds);
739 }
740 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000741}
742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743#define new_delta(d, s, us, normalize) \
744 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000745
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000746
747typedef struct
748{
749 PyObject_HEAD
750 PyObject *offset;
751 PyObject *name;
752} PyDateTime_TimeZone;
753
Victor Stinner6ced7c42011-03-21 18:15:42 +0100754/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000755static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -0400756/* The interned Epoch datetime instance */
757static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000758
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000759/* Create new timezone instance checking offset range. This
760 function does not check the name argument. Caller must assure
761 that offset is a timedelta instance and name is either NULL
762 or a unicode object. */
763static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000764create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000765{
766 PyDateTime_TimeZone *self;
767 PyTypeObject *type = &PyDateTime_TimeZoneType;
768
769 assert(offset != NULL);
770 assert(PyDelta_Check(offset));
771 assert(name == NULL || PyUnicode_Check(name));
772
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000773 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
774 if (self == NULL) {
775 return NULL;
776 }
777 Py_INCREF(offset);
778 self->offset = offset;
779 Py_XINCREF(name);
780 self->name = name;
781 return (PyObject *)self;
782}
783
784static int delta_bool(PyDateTime_Delta *self);
785
786static PyObject *
787new_timezone(PyObject *offset, PyObject *name)
788{
789 assert(offset != NULL);
790 assert(PyDelta_Check(offset));
791 assert(name == NULL || PyUnicode_Check(name));
792
793 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
794 Py_INCREF(PyDateTime_TimeZone_UTC);
795 return PyDateTime_TimeZone_UTC;
796 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000797 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
798 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400799 " representing a whole number of minutes,"
800 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000801 return NULL;
802 }
803 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
804 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
805 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
806 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400807 " timedelta(hours=24),"
808 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000809 return NULL;
810 }
811
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000812 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000813}
814
Tim Petersb0c854d2003-05-17 15:57:00 +0000815/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000816 * tzinfo helpers.
817 */
818
Tim Peters855fe882002-12-22 03:43:39 +0000819/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
820 * raise TypeError and return -1.
821 */
822static int
823check_tzinfo_subclass(PyObject *p)
824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825 if (p == Py_None || PyTZInfo_Check(p))
826 return 0;
827 PyErr_Format(PyExc_TypeError,
828 "tzinfo argument must be None or of a tzinfo subclass, "
829 "not type '%s'",
830 Py_TYPE(p)->tp_name);
831 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000832}
833
Tim Peters2a799bf2002-12-16 20:18:38 +0000834/* If self has a tzinfo member, return a BORROWED reference to it. Else
835 * return NULL, which is NOT AN ERROR. There are no error returns here,
836 * and the caller must not decref the result.
837 */
838static PyObject *
839get_tzinfo_member(PyObject *self)
840{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 if (PyDateTime_Check(self) && HASTZINFO(self))
844 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
845 else if (PyTime_Check(self) && HASTZINFO(self))
846 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000849}
850
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000851/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
852 * be an instance of the tzinfo class. If the method returns None, this
853 * returns None. If the method doesn't return None or timedelta, TypeError is
854 * raised and this returns NULL. If it returns a timedelta and the value is
855 * out of range or isn't a whole number of minutes, ValueError is raised and
856 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000857 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000858static PyObject *
859call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000860{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000861 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000864 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000866
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000867 if (tzinfo == Py_None)
868 Py_RETURN_NONE;
869 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
870 if (offset == Py_None || offset == NULL)
871 return offset;
872 if (PyDelta_Check(offset)) {
873 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
874 Py_DECREF(offset);
875 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
876 " representing a whole number of minutes");
877 return NULL;
878 }
879 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
880 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
881 Py_DECREF(offset);
882 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
883 " strictly between -timedelta(hours=24) and"
884 " timedelta(hours=24).");
885 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 }
887 }
888 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000889 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 PyErr_Format(PyExc_TypeError,
891 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000892 "timedelta, not '%.200s'",
893 name, Py_TYPE(offset)->tp_name);
894 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000896
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000897 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000898}
899
900/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
901 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
902 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000903 * doesn't return None or timedelta, TypeError is raised and this returns -1.
904 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
905 * # of minutes), ValueError is raised and this returns -1. Else *none is
906 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000907 */
Tim Peters855fe882002-12-22 03:43:39 +0000908static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000909call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
910{
911 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000912}
913
Tim Peters2a799bf2002-12-16 20:18:38 +0000914/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
915 * result. tzinfo must be an instance of the tzinfo class. If dst()
916 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000917 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000918 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000919 * ValueError is raised and this returns -1. Else *none is set to 0 and
920 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000921 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000922static PyObject *
923call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000924{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000925 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000926}
927
Tim Petersbad8ff02002-12-30 20:52:32 +0000928/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000929 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000930 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000931 * returns NULL. If the result is a string, we ensure it is a Unicode
932 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000933 */
934static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000935call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000936{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200938 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 assert(tzinfo != NULL);
941 assert(check_tzinfo_subclass(tzinfo) >= 0);
942 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000945 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000946
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200947 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000948
949 if (result == NULL || result == Py_None)
950 return result;
951
952 if (!PyUnicode_Check(result)) {
953 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
954 "return None or a string, not '%s'",
955 Py_TYPE(result)->tp_name);
956 Py_DECREF(result);
957 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000959
960 return result;
Tim Peters00237032002-12-27 02:21:51 +0000961}
962
Tim Peters2a799bf2002-12-16 20:18:38 +0000963/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
964 * stuff
965 * ", tzinfo=" + repr(tzinfo)
966 * before the closing ")".
967 */
968static PyObject *
969append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
970{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 assert(PyUnicode_Check(repr));
974 assert(tzinfo);
975 if (tzinfo == Py_None)
976 return repr;
977 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200978 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
979 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 Py_DECREF(repr);
981 if (temp == NULL)
982 return NULL;
983 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
984 Py_DECREF(temp);
985 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +0000986}
987
988/* ---------------------------------------------------------------------------
989 * String format helpers.
990 */
991
992static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +0000993format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 static const char *DayNames[] = {
996 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
997 };
998 static const char *MonthNames[] = {
999 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1000 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1001 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1006 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1007 GET_DAY(date), hours, minutes, seconds,
1008 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001009}
1010
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001011static PyObject *delta_negative(PyDateTime_Delta *self);
1012
Tim Peters2a799bf2002-12-16 20:18:38 +00001013/* Add an hours & minutes UTC offset string to buf. buf has no more than
1014 * buflen bytes remaining. The UTC offset is gotten by calling
1015 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1016 * *buf, and that's all. Else the returned value is checked for sanity (an
1017 * integer in range), and if that's OK it's converted to an hours & minutes
1018 * string of the form
1019 * sign HH sep MM
1020 * Returns 0 if everything is OK. If the return value from utcoffset() is
1021 * bogus, an appropriate exception is set and -1 is returned.
1022 */
1023static int
Tim Peters328fff72002-12-20 01:31:27 +00001024format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001026{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001027 PyObject *offset;
1028 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001032
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001033 offset = call_utcoffset(tzinfo, tzinfoarg);
1034 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001036 if (offset == Py_None) {
1037 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 *buf = '\0';
1039 return 0;
1040 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001041 /* Offset is normalized, so it is negative if days < 0 */
1042 if (GET_TD_DAYS(offset) < 0) {
1043 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001045 offset = delta_negative((PyDateTime_Delta *)offset);
1046 Py_DECREF(temp);
1047 if (offset == NULL)
1048 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001050 else {
1051 sign = '+';
1052 }
1053 /* Offset is not negative here. */
1054 seconds = GET_TD_SECONDS(offset);
1055 Py_DECREF(offset);
1056 minutes = divmod(seconds, 60, &seconds);
1057 hours = divmod(minutes, 60, &minutes);
1058 assert(seconds == 0);
1059 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001063}
1064
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001065static PyObject *
1066make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 PyObject *temp;
1069 PyObject *tzinfo = get_tzinfo_member(object);
1070 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001071 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 if (Zreplacement == NULL)
1074 return NULL;
1075 if (tzinfo == Py_None || tzinfo == NULL)
1076 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 assert(tzinfoarg != NULL);
1079 temp = call_tzname(tzinfo, tzinfoarg);
1080 if (temp == NULL)
1081 goto Error;
1082 if (temp == Py_None) {
1083 Py_DECREF(temp);
1084 return Zreplacement;
1085 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 assert(PyUnicode_Check(temp));
1088 /* Since the tzname is getting stuffed into the
1089 * format, we have to double any % signs so that
1090 * strftime doesn't treat them as format codes.
1091 */
1092 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001093 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 Py_DECREF(temp);
1095 if (Zreplacement == NULL)
1096 return NULL;
1097 if (!PyUnicode_Check(Zreplacement)) {
1098 PyErr_SetString(PyExc_TypeError,
1099 "tzname.replace() did not return a string");
1100 goto Error;
1101 }
1102 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001103
1104 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 Py_DECREF(Zreplacement);
1106 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001107}
1108
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001109static PyObject *
1110make_freplacement(PyObject *object)
1111{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 char freplacement[64];
1113 if (PyTime_Check(object))
1114 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1115 else if (PyDateTime_Check(object))
1116 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1117 else
1118 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001121}
1122
Tim Peters2a799bf2002-12-16 20:18:38 +00001123/* I sure don't want to reproduce the strftime code from the time module,
1124 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001125 * giving special meanings to the %z, %Z and %f format codes via a
1126 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001127 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1128 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001129 */
1130static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001131wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1137 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1138 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 const char *pin; /* pointer to next char in input format */
1141 Py_ssize_t flen; /* length of input format */
1142 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 PyObject *newfmt = NULL; /* py string, the output format */
1145 char *pnew; /* pointer to available byte in output format */
1146 size_t totalnew; /* number bytes total in output format buffer,
1147 exclusive of trailing \0 */
1148 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 const char *ptoappend; /* ptr to string to append to output buffer */
1151 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 assert(object && format && timetuple);
1154 assert(PyUnicode_Check(format));
1155 /* Convert the input format to a C string and size */
1156 pin = _PyUnicode_AsStringAndSize(format, &flen);
1157 if (!pin)
1158 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 /* Scan the input format, looking for %z/%Z/%f escapes, building
1161 * a new format. Since computing the replacements for those codes
1162 * is expensive, don't unless they're actually used.
1163 */
1164 if (flen > INT_MAX - 1) {
1165 PyErr_NoMemory();
1166 goto Done;
1167 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 totalnew = flen + 1; /* realistic if no %z/%Z */
1170 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1171 if (newfmt == NULL) goto Done;
1172 pnew = PyBytes_AsString(newfmt);
1173 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 while ((ch = *pin++) != '\0') {
1176 if (ch != '%') {
1177 ptoappend = pin - 1;
1178 ntoappend = 1;
1179 }
1180 else if ((ch = *pin++) == '\0') {
1181 /* There's a lone trailing %; doesn't make sense. */
1182 PyErr_SetString(PyExc_ValueError, "strftime format "
1183 "ends with raw %");
1184 goto Done;
1185 }
1186 /* A % has been seen and ch is the character after it. */
1187 else if (ch == 'z') {
1188 if (zreplacement == NULL) {
1189 /* format utcoffset */
1190 char buf[100];
1191 PyObject *tzinfo = get_tzinfo_member(object);
1192 zreplacement = PyBytes_FromStringAndSize("", 0);
1193 if (zreplacement == NULL) goto Done;
1194 if (tzinfo != Py_None && tzinfo != NULL) {
1195 assert(tzinfoarg != NULL);
1196 if (format_utcoffset(buf,
1197 sizeof(buf),
1198 "",
1199 tzinfo,
1200 tzinfoarg) < 0)
1201 goto Done;
1202 Py_DECREF(zreplacement);
1203 zreplacement =
1204 PyBytes_FromStringAndSize(buf,
1205 strlen(buf));
1206 if (zreplacement == NULL)
1207 goto Done;
1208 }
1209 }
1210 assert(zreplacement != NULL);
1211 ptoappend = PyBytes_AS_STRING(zreplacement);
1212 ntoappend = PyBytes_GET_SIZE(zreplacement);
1213 }
1214 else if (ch == 'Z') {
1215 /* format tzname */
1216 if (Zreplacement == NULL) {
1217 Zreplacement = make_Zreplacement(object,
1218 tzinfoarg);
1219 if (Zreplacement == NULL)
1220 goto Done;
1221 }
1222 assert(Zreplacement != NULL);
1223 assert(PyUnicode_Check(Zreplacement));
1224 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1225 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001226 if (ptoappend == NULL)
1227 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 }
1229 else if (ch == 'f') {
1230 /* format microseconds */
1231 if (freplacement == NULL) {
1232 freplacement = make_freplacement(object);
1233 if (freplacement == NULL)
1234 goto Done;
1235 }
1236 assert(freplacement != NULL);
1237 assert(PyBytes_Check(freplacement));
1238 ptoappend = PyBytes_AS_STRING(freplacement);
1239 ntoappend = PyBytes_GET_SIZE(freplacement);
1240 }
1241 else {
1242 /* percent followed by neither z nor Z */
1243 ptoappend = pin - 2;
1244 ntoappend = 2;
1245 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 /* Append the ntoappend chars starting at ptoappend to
1248 * the new format.
1249 */
1250 if (ntoappend == 0)
1251 continue;
1252 assert(ptoappend != NULL);
1253 assert(ntoappend > 0);
1254 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001255 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 PyErr_NoMemory();
1257 goto Done;
1258 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001259 totalnew <<= 1;
1260 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 pnew = PyBytes_AsString(newfmt) + usednew;
1263 }
1264 memcpy(pnew, ptoappend, ntoappend);
1265 pnew += ntoappend;
1266 usednew += ntoappend;
1267 assert(usednew <= totalnew);
1268 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1271 goto Done;
1272 {
1273 PyObject *format;
1274 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 if (time == NULL)
1277 goto Done;
1278 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1279 if (format != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001280 _Py_IDENTIFIER(strftime);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001281
1282 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1283 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 Py_DECREF(format);
1285 }
1286 Py_DECREF(time);
1287 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001288 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 Py_XDECREF(freplacement);
1290 Py_XDECREF(zreplacement);
1291 Py_XDECREF(Zreplacement);
1292 Py_XDECREF(newfmt);
1293 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001294}
1295
Tim Peters2a799bf2002-12-16 20:18:38 +00001296/* ---------------------------------------------------------------------------
1297 * Wrap functions from the time module. These aren't directly available
1298 * from C. Perhaps they should be.
1299 */
1300
1301/* Call time.time() and return its result (a Python float). */
1302static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001303time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 PyObject *result = NULL;
1306 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001309 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001310
1311 result = _PyObject_CallMethodId(time, &PyId_time, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 Py_DECREF(time);
1313 }
1314 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001315}
1316
1317/* Build a time.struct_time. The weekday and day number are automatically
1318 * computed from the y,m,d args.
1319 */
1320static PyObject *
1321build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 PyObject *time;
1324 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 time = PyImport_ImportModuleNoBlock("time");
1327 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001328 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001329
1330 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1331 "((iiiiiiiii))",
1332 y, m, d,
1333 hh, mm, ss,
1334 weekday(y, m, d),
1335 days_before_month(y, m) + d,
1336 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 Py_DECREF(time);
1338 }
1339 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001340}
1341
1342/* ---------------------------------------------------------------------------
1343 * Miscellaneous helpers.
1344 */
1345
Mark Dickinsone94c6792009-02-02 20:36:42 +00001346/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001347 * The comparisons here all most naturally compute a cmp()-like result.
1348 * This little helper turns that into a bool result for rich comparisons.
1349 */
1350static PyObject *
1351diff_to_bool(int diff, int op)
1352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 PyObject *result;
1354 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 switch (op) {
1357 case Py_EQ: istrue = diff == 0; break;
1358 case Py_NE: istrue = diff != 0; break;
1359 case Py_LE: istrue = diff <= 0; break;
1360 case Py_GE: istrue = diff >= 0; break;
1361 case Py_LT: istrue = diff < 0; break;
1362 case Py_GT: istrue = diff > 0; break;
1363 default:
1364 assert(! "op unknown");
1365 istrue = 0; /* To shut up compiler */
1366 }
1367 result = istrue ? Py_True : Py_False;
1368 Py_INCREF(result);
1369 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001370}
1371
Tim Peters07534a62003-02-07 22:50:28 +00001372/* Raises a "can't compare" TypeError and returns NULL. */
1373static PyObject *
1374cmperror(PyObject *a, PyObject *b)
1375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 PyErr_Format(PyExc_TypeError,
1377 "can't compare %s to %s",
1378 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1379 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001380}
1381
Tim Peters2a799bf2002-12-16 20:18:38 +00001382/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001383 * Cached Python objects; these are set by the module init function.
1384 */
1385
1386/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001387static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388static PyObject *us_per_ms = NULL; /* 1000 */
1389static PyObject *us_per_second = NULL; /* 1000000 */
1390static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001391static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1392static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1393static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001394static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1395
Tim Peters2a799bf2002-12-16 20:18:38 +00001396/* ---------------------------------------------------------------------------
1397 * Class implementations.
1398 */
1399
1400/*
1401 * PyDateTime_Delta implementation.
1402 */
1403
1404/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001406 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001407 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1408 * due to ubiquitous overflow possibilities.
1409 */
1410static PyObject *
1411delta_to_microseconds(PyDateTime_Delta *self)
1412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 PyObject *x1 = NULL;
1414 PyObject *x2 = NULL;
1415 PyObject *x3 = NULL;
1416 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1419 if (x1 == NULL)
1420 goto Done;
1421 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1422 if (x2 == NULL)
1423 goto Done;
1424 Py_DECREF(x1);
1425 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 /* x2 has days in seconds */
1428 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1429 if (x1 == NULL)
1430 goto Done;
1431 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1432 if (x3 == NULL)
1433 goto Done;
1434 Py_DECREF(x1);
1435 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001436 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 /* x3 has days+seconds in seconds */
1439 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1440 if (x1 == NULL)
1441 goto Done;
1442 Py_DECREF(x3);
1443 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 /* x1 has days+seconds in us */
1446 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1447 if (x2 == NULL)
1448 goto Done;
1449 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001450
1451Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 Py_XDECREF(x1);
1453 Py_XDECREF(x2);
1454 Py_XDECREF(x3);
1455 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001456}
1457
Serhiy Storchaka95949422013-08-27 19:40:23 +03001458/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001459 */
1460static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001461microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 int us;
1464 int s;
1465 int d;
1466 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 PyObject *tuple = NULL;
1469 PyObject *num = NULL;
1470 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 tuple = PyNumber_Divmod(pyus, us_per_second);
1473 if (tuple == NULL)
1474 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 num = PyTuple_GetItem(tuple, 1); /* us */
1477 if (num == NULL)
1478 goto Done;
1479 temp = PyLong_AsLong(num);
1480 num = NULL;
1481 if (temp == -1 && PyErr_Occurred())
1482 goto Done;
1483 assert(0 <= temp && temp < 1000000);
1484 us = (int)temp;
1485 if (us < 0) {
1486 /* The divisor was positive, so this must be an error. */
1487 assert(PyErr_Occurred());
1488 goto Done;
1489 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1492 if (num == NULL)
1493 goto Done;
1494 Py_INCREF(num);
1495 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 tuple = PyNumber_Divmod(num, seconds_per_day);
1498 if (tuple == NULL)
1499 goto Done;
1500 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 num = PyTuple_GetItem(tuple, 1); /* seconds */
1503 if (num == NULL)
1504 goto Done;
1505 temp = PyLong_AsLong(num);
1506 num = NULL;
1507 if (temp == -1 && PyErr_Occurred())
1508 goto Done;
1509 assert(0 <= temp && temp < 24*3600);
1510 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 if (s < 0) {
1513 /* The divisor was positive, so this must be an error. */
1514 assert(PyErr_Occurred());
1515 goto Done;
1516 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1519 if (num == NULL)
1520 goto Done;
1521 Py_INCREF(num);
1522 temp = PyLong_AsLong(num);
1523 if (temp == -1 && PyErr_Occurred())
1524 goto Done;
1525 d = (int)temp;
1526 if ((long)d != temp) {
1527 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1528 "large to fit in a C int");
1529 goto Done;
1530 }
1531 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001532
1533Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 Py_XDECREF(tuple);
1535 Py_XDECREF(num);
1536 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001537}
1538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539#define microseconds_to_delta(pymicros) \
1540 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001541
Tim Peters2a799bf2002-12-16 20:18:38 +00001542static PyObject *
1543multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 PyObject *pyus_in;
1546 PyObject *pyus_out;
1547 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 pyus_in = delta_to_microseconds(delta);
1550 if (pyus_in == NULL)
1551 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1554 Py_DECREF(pyus_in);
1555 if (pyus_out == NULL)
1556 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 result = microseconds_to_delta(pyus_out);
1559 Py_DECREF(pyus_out);
1560 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001561}
1562
1563static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001564multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1565{
1566 PyObject *result = NULL;
1567 PyObject *pyus_in = NULL, *temp, *pyus_out;
1568 PyObject *ratio = NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001569 _Py_IDENTIFIER(as_integer_ratio);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001570
1571 pyus_in = delta_to_microseconds(delta);
1572 if (pyus_in == NULL)
1573 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001574 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001575 if (ratio == NULL)
1576 goto error;
1577 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1578 Py_DECREF(pyus_in);
1579 pyus_in = NULL;
1580 if (temp == NULL)
1581 goto error;
1582 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1583 Py_DECREF(temp);
1584 if (pyus_out == NULL)
1585 goto error;
1586 result = microseconds_to_delta(pyus_out);
1587 Py_DECREF(pyus_out);
1588 error:
1589 Py_XDECREF(pyus_in);
1590 Py_XDECREF(ratio);
1591
1592 return result;
1593}
1594
1595static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001596divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 PyObject *pyus_in;
1599 PyObject *pyus_out;
1600 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 pyus_in = delta_to_microseconds(delta);
1603 if (pyus_in == NULL)
1604 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1607 Py_DECREF(pyus_in);
1608 if (pyus_out == NULL)
1609 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 result = microseconds_to_delta(pyus_out);
1612 Py_DECREF(pyus_out);
1613 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001614}
1615
1616static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001617divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 PyObject *pyus_left;
1620 PyObject *pyus_right;
1621 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 pyus_left = delta_to_microseconds(left);
1624 if (pyus_left == NULL)
1625 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 pyus_right = delta_to_microseconds(right);
1628 if (pyus_right == NULL) {
1629 Py_DECREF(pyus_left);
1630 return NULL;
1631 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1634 Py_DECREF(pyus_left);
1635 Py_DECREF(pyus_right);
1636 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001637}
1638
1639static PyObject *
1640truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 PyObject *pyus_left;
1643 PyObject *pyus_right;
1644 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 pyus_left = delta_to_microseconds(left);
1647 if (pyus_left == NULL)
1648 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 pyus_right = delta_to_microseconds(right);
1651 if (pyus_right == NULL) {
1652 Py_DECREF(pyus_left);
1653 return NULL;
1654 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1657 Py_DECREF(pyus_left);
1658 Py_DECREF(pyus_right);
1659 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001660}
1661
1662static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001663truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1664{
1665 PyObject *result = NULL;
1666 PyObject *pyus_in = NULL, *temp, *pyus_out;
1667 PyObject *ratio = NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001668 _Py_IDENTIFIER(as_integer_ratio);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001669
1670 pyus_in = delta_to_microseconds(delta);
1671 if (pyus_in == NULL)
1672 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001673 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001674 if (ratio == NULL)
1675 goto error;
1676 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1677 Py_DECREF(pyus_in);
1678 pyus_in = NULL;
1679 if (temp == NULL)
1680 goto error;
1681 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1682 Py_DECREF(temp);
1683 if (pyus_out == NULL)
1684 goto error;
1685 result = microseconds_to_delta(pyus_out);
1686 Py_DECREF(pyus_out);
1687 error:
1688 Py_XDECREF(pyus_in);
1689 Py_XDECREF(ratio);
1690
1691 return result;
1692}
1693
1694static PyObject *
1695truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1696{
1697 PyObject *result;
1698 PyObject *pyus_in, *pyus_out;
1699 pyus_in = delta_to_microseconds(delta);
1700 if (pyus_in == NULL)
1701 return NULL;
1702 pyus_out = divide_nearest(pyus_in, i);
1703 Py_DECREF(pyus_in);
1704 if (pyus_out == NULL)
1705 return NULL;
1706 result = microseconds_to_delta(pyus_out);
1707 Py_DECREF(pyus_out);
1708
1709 return result;
1710}
1711
1712static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001713delta_add(PyObject *left, PyObject *right)
1714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1718 /* delta + delta */
1719 /* The C-level additions can't overflow because of the
1720 * invariant bounds.
1721 */
1722 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1723 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1724 int microseconds = GET_TD_MICROSECONDS(left) +
1725 GET_TD_MICROSECONDS(right);
1726 result = new_delta(days, seconds, microseconds, 1);
1727 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 if (result == Py_NotImplemented)
1730 Py_INCREF(result);
1731 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001732}
1733
1734static PyObject *
1735delta_negative(PyDateTime_Delta *self)
1736{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 return new_delta(-GET_TD_DAYS(self),
1738 -GET_TD_SECONDS(self),
1739 -GET_TD_MICROSECONDS(self),
1740 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001741}
1742
1743static PyObject *
1744delta_positive(PyDateTime_Delta *self)
1745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 /* Could optimize this (by returning self) if this isn't a
1747 * subclass -- but who uses unary + ? Approximately nobody.
1748 */
1749 return new_delta(GET_TD_DAYS(self),
1750 GET_TD_SECONDS(self),
1751 GET_TD_MICROSECONDS(self),
1752 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001753}
1754
1755static PyObject *
1756delta_abs(PyDateTime_Delta *self)
1757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 assert(GET_TD_MICROSECONDS(self) >= 0);
1761 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 if (GET_TD_DAYS(self) < 0)
1764 result = delta_negative(self);
1765 else
1766 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001769}
1770
1771static PyObject *
1772delta_subtract(PyObject *left, PyObject *right)
1773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1777 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001778 /* The C-level additions can't overflow because of the
1779 * invariant bounds.
1780 */
1781 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1782 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1783 int microseconds = GET_TD_MICROSECONDS(left) -
1784 GET_TD_MICROSECONDS(right);
1785 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 if (result == Py_NotImplemented)
1789 Py_INCREF(result);
1790 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001791}
1792
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001793static int
1794delta_cmp(PyObject *self, PyObject *other)
1795{
1796 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1797 if (diff == 0) {
1798 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1799 if (diff == 0)
1800 diff = GET_TD_MICROSECONDS(self) -
1801 GET_TD_MICROSECONDS(other);
1802 }
1803 return diff;
1804}
1805
Tim Peters2a799bf2002-12-16 20:18:38 +00001806static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001807delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001810 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 return diff_to_bool(diff, op);
1812 }
1813 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001814 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001816}
1817
1818static PyObject *delta_getstate(PyDateTime_Delta *self);
1819
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001820static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001821delta_hash(PyDateTime_Delta *self)
1822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 if (self->hashcode == -1) {
1824 PyObject *temp = delta_getstate(self);
1825 if (temp != NULL) {
1826 self->hashcode = PyObject_Hash(temp);
1827 Py_DECREF(temp);
1828 }
1829 }
1830 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001831}
1832
1833static PyObject *
1834delta_multiply(PyObject *left, PyObject *right)
1835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 if (PyDelta_Check(left)) {
1839 /* delta * ??? */
1840 if (PyLong_Check(right))
1841 result = multiply_int_timedelta(right,
1842 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001843 else if (PyFloat_Check(right))
1844 result = multiply_float_timedelta(right,
1845 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 }
1847 else if (PyLong_Check(left))
1848 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001849 (PyDateTime_Delta *) right);
1850 else if (PyFloat_Check(left))
1851 result = multiply_float_timedelta(left,
1852 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 if (result == Py_NotImplemented)
1855 Py_INCREF(result);
1856 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001857}
1858
1859static PyObject *
1860delta_divide(PyObject *left, PyObject *right)
1861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 if (PyDelta_Check(left)) {
1865 /* delta * ??? */
1866 if (PyLong_Check(right))
1867 result = divide_timedelta_int(
1868 (PyDateTime_Delta *)left,
1869 right);
1870 else if (PyDelta_Check(right))
1871 result = divide_timedelta_timedelta(
1872 (PyDateTime_Delta *)left,
1873 (PyDateTime_Delta *)right);
1874 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 if (result == Py_NotImplemented)
1877 Py_INCREF(result);
1878 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001879}
1880
Mark Dickinson7c186e22010-04-20 22:32:49 +00001881static PyObject *
1882delta_truedivide(PyObject *left, PyObject *right)
1883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (PyDelta_Check(left)) {
1887 if (PyDelta_Check(right))
1888 result = truedivide_timedelta_timedelta(
1889 (PyDateTime_Delta *)left,
1890 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001891 else if (PyFloat_Check(right))
1892 result = truedivide_timedelta_float(
1893 (PyDateTime_Delta *)left, right);
1894 else if (PyLong_Check(right))
1895 result = truedivide_timedelta_int(
1896 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 if (result == Py_NotImplemented)
1900 Py_INCREF(result);
1901 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001902}
1903
1904static PyObject *
1905delta_remainder(PyObject *left, PyObject *right)
1906{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 PyObject *pyus_left;
1908 PyObject *pyus_right;
1909 PyObject *pyus_remainder;
1910 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001911
Brian Curtindfc80e32011-08-10 20:28:54 -05001912 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1913 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1916 if (pyus_left == NULL)
1917 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1920 if (pyus_right == NULL) {
1921 Py_DECREF(pyus_left);
1922 return NULL;
1923 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1926 Py_DECREF(pyus_left);
1927 Py_DECREF(pyus_right);
1928 if (pyus_remainder == NULL)
1929 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 remainder = microseconds_to_delta(pyus_remainder);
1932 Py_DECREF(pyus_remainder);
1933 if (remainder == NULL)
1934 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001937}
1938
1939static PyObject *
1940delta_divmod(PyObject *left, PyObject *right)
1941{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 PyObject *pyus_left;
1943 PyObject *pyus_right;
1944 PyObject *divmod;
1945 PyObject *delta;
1946 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001947
Brian Curtindfc80e32011-08-10 20:28:54 -05001948 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1949 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1952 if (pyus_left == NULL)
1953 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1956 if (pyus_right == NULL) {
1957 Py_DECREF(pyus_left);
1958 return NULL;
1959 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1962 Py_DECREF(pyus_left);
1963 Py_DECREF(pyus_right);
1964 if (divmod == NULL)
1965 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 assert(PyTuple_Size(divmod) == 2);
1968 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1969 if (delta == NULL) {
1970 Py_DECREF(divmod);
1971 return NULL;
1972 }
1973 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1974 Py_DECREF(delta);
1975 Py_DECREF(divmod);
1976 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001977}
1978
Tim Peters2a799bf2002-12-16 20:18:38 +00001979/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1980 * timedelta constructor. sofar is the # of microseconds accounted for
1981 * so far, and there are factor microseconds per current unit, the number
1982 * of which is given by num. num * factor is added to sofar in a
1983 * numerically careful way, and that's the result. Any fractional
1984 * microseconds left over (this can happen if num is a float type) are
1985 * added into *leftover.
1986 * Note that there are many ways this can give an error (NULL) return.
1987 */
1988static PyObject *
1989accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1990 double *leftover)
1991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 PyObject *prod;
1993 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00001994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 if (PyLong_Check(num)) {
1998 prod = PyNumber_Multiply(num, factor);
1999 if (prod == NULL)
2000 return NULL;
2001 sum = PyNumber_Add(sofar, prod);
2002 Py_DECREF(prod);
2003 return sum;
2004 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 if (PyFloat_Check(num)) {
2007 double dnum;
2008 double fracpart;
2009 double intpart;
2010 PyObject *x;
2011 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 /* The Plan: decompose num into an integer part and a
2014 * fractional part, num = intpart + fracpart.
2015 * Then num * factor ==
2016 * intpart * factor + fracpart * factor
2017 * and the LHS can be computed exactly in long arithmetic.
2018 * The RHS is again broken into an int part and frac part.
2019 * and the frac part is added into *leftover.
2020 */
2021 dnum = PyFloat_AsDouble(num);
2022 if (dnum == -1.0 && PyErr_Occurred())
2023 return NULL;
2024 fracpart = modf(dnum, &intpart);
2025 x = PyLong_FromDouble(intpart);
2026 if (x == NULL)
2027 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 prod = PyNumber_Multiply(x, factor);
2030 Py_DECREF(x);
2031 if (prod == NULL)
2032 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 sum = PyNumber_Add(sofar, prod);
2035 Py_DECREF(prod);
2036 if (sum == NULL)
2037 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 if (fracpart == 0.0)
2040 return sum;
2041 /* So far we've lost no information. Dealing with the
2042 * fractional part requires float arithmetic, and may
2043 * lose a little info.
2044 */
2045 assert(PyLong_Check(factor));
2046 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 dnum *= fracpart;
2049 fracpart = modf(dnum, &intpart);
2050 x = PyLong_FromDouble(intpart);
2051 if (x == NULL) {
2052 Py_DECREF(sum);
2053 return NULL;
2054 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 y = PyNumber_Add(sum, x);
2057 Py_DECREF(sum);
2058 Py_DECREF(x);
2059 *leftover += fracpart;
2060 return y;
2061 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 PyErr_Format(PyExc_TypeError,
2064 "unsupported type for timedelta %s component: %s",
2065 tag, Py_TYPE(num)->tp_name);
2066 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002067}
2068
2069static PyObject *
2070delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002072 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 /* Argument objects. */
2075 PyObject *day = NULL;
2076 PyObject *second = NULL;
2077 PyObject *us = NULL;
2078 PyObject *ms = NULL;
2079 PyObject *minute = NULL;
2080 PyObject *hour = NULL;
2081 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 PyObject *x = NULL; /* running sum of microseconds */
2084 PyObject *y = NULL; /* temp sum of microseconds */
2085 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 static char *keywords[] = {
2088 "days", "seconds", "microseconds", "milliseconds",
2089 "minutes", "hours", "weeks", NULL
2090 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002092 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2093 keywords,
2094 &day, &second, &us,
2095 &ms, &minute, &hour, &week) == 0)
2096 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 x = PyLong_FromLong(0);
2099 if (x == NULL)
2100 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102#define CLEANUP \
2103 Py_DECREF(x); \
2104 x = y; \
2105 if (x == NULL) \
2106 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002109 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 CLEANUP;
2111 }
2112 if (ms) {
2113 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2114 CLEANUP;
2115 }
2116 if (second) {
2117 y = accum("seconds", x, second, us_per_second, &leftover_us);
2118 CLEANUP;
2119 }
2120 if (minute) {
2121 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2122 CLEANUP;
2123 }
2124 if (hour) {
2125 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2126 CLEANUP;
2127 }
2128 if (day) {
2129 y = accum("days", x, day, us_per_day, &leftover_us);
2130 CLEANUP;
2131 }
2132 if (week) {
2133 y = accum("weeks", x, week, us_per_week, &leftover_us);
2134 CLEANUP;
2135 }
2136 if (leftover_us) {
2137 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002138 double whole_us = round(leftover_us);
2139 int x_is_odd;
2140 PyObject *temp;
2141
2142 whole_us = round(leftover_us);
2143 if (fabs(whole_us - leftover_us) == 0.5) {
2144 /* We're exactly halfway between two integers. In order
2145 * to do round-half-to-even, we must determine whether x
2146 * is odd. Note that x is odd when it's last bit is 1. The
2147 * code below uses bitwise and operation to check the last
2148 * bit. */
2149 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2150 if (temp == NULL) {
2151 Py_DECREF(x);
2152 goto Done;
2153 }
2154 x_is_odd = PyObject_IsTrue(temp);
2155 Py_DECREF(temp);
2156 if (x_is_odd == -1) {
2157 Py_DECREF(x);
2158 goto Done;
2159 }
2160 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2161 }
2162
Victor Stinner36a5a062013-08-28 01:53:39 +02002163 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 if (temp == NULL) {
2166 Py_DECREF(x);
2167 goto Done;
2168 }
2169 y = PyNumber_Add(x, temp);
2170 Py_DECREF(temp);
2171 CLEANUP;
2172 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 self = microseconds_to_delta_ex(x, type);
2175 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002176Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002178
2179#undef CLEANUP
2180}
2181
2182static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002183delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 return (GET_TD_DAYS(self) != 0
2186 || GET_TD_SECONDS(self) != 0
2187 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002188}
2189
2190static PyObject *
2191delta_repr(PyDateTime_Delta *self)
2192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 if (GET_TD_MICROSECONDS(self) != 0)
2194 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2195 Py_TYPE(self)->tp_name,
2196 GET_TD_DAYS(self),
2197 GET_TD_SECONDS(self),
2198 GET_TD_MICROSECONDS(self));
2199 if (GET_TD_SECONDS(self) != 0)
2200 return PyUnicode_FromFormat("%s(%d, %d)",
2201 Py_TYPE(self)->tp_name,
2202 GET_TD_DAYS(self),
2203 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002205 return PyUnicode_FromFormat("%s(%d)",
2206 Py_TYPE(self)->tp_name,
2207 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002208}
2209
2210static PyObject *
2211delta_str(PyDateTime_Delta *self)
2212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 int us = GET_TD_MICROSECONDS(self);
2214 int seconds = GET_TD_SECONDS(self);
2215 int minutes = divmod(seconds, 60, &seconds);
2216 int hours = divmod(minutes, 60, &minutes);
2217 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219 if (days) {
2220 if (us)
2221 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2222 days, (days == 1 || days == -1) ? "" : "s",
2223 hours, minutes, seconds, us);
2224 else
2225 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2226 days, (days == 1 || days == -1) ? "" : "s",
2227 hours, minutes, seconds);
2228 } else {
2229 if (us)
2230 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2231 hours, minutes, seconds, us);
2232 else
2233 return PyUnicode_FromFormat("%d:%02d:%02d",
2234 hours, minutes, seconds);
2235 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002236
Tim Peters2a799bf2002-12-16 20:18:38 +00002237}
2238
Tim Peters371935f2003-02-01 01:52:50 +00002239/* Pickle support, a simple use of __reduce__. */
2240
Tim Petersb57f8f02003-02-01 02:54:15 +00002241/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002242static PyObject *
2243delta_getstate(PyDateTime_Delta *self)
2244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 return Py_BuildValue("iii", GET_TD_DAYS(self),
2246 GET_TD_SECONDS(self),
2247 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002248}
2249
Tim Peters2a799bf2002-12-16 20:18:38 +00002250static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002251delta_total_seconds(PyObject *self)
2252{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 PyObject *total_seconds;
2254 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2257 if (total_microseconds == NULL)
2258 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002259
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002260 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002264}
2265
2266static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002267delta_reduce(PyDateTime_Delta* self)
2268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002269 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002270}
2271
2272#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2273
2274static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 {"days", T_INT, OFFSET(days), READONLY,
2277 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 {"seconds", T_INT, OFFSET(seconds), READONLY,
2280 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2283 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2284 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002285};
2286
2287static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2289 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2292 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002295};
2296
2297static char delta_doc[] =
2298PyDoc_STR("Difference between two datetime values.");
2299
2300static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002301 delta_add, /* nb_add */
2302 delta_subtract, /* nb_subtract */
2303 delta_multiply, /* nb_multiply */
2304 delta_remainder, /* nb_remainder */
2305 delta_divmod, /* nb_divmod */
2306 0, /* nb_power */
2307 (unaryfunc)delta_negative, /* nb_negative */
2308 (unaryfunc)delta_positive, /* nb_positive */
2309 (unaryfunc)delta_abs, /* nb_absolute */
2310 (inquiry)delta_bool, /* nb_bool */
2311 0, /*nb_invert*/
2312 0, /*nb_lshift*/
2313 0, /*nb_rshift*/
2314 0, /*nb_and*/
2315 0, /*nb_xor*/
2316 0, /*nb_or*/
2317 0, /*nb_int*/
2318 0, /*nb_reserved*/
2319 0, /*nb_float*/
2320 0, /*nb_inplace_add*/
2321 0, /*nb_inplace_subtract*/
2322 0, /*nb_inplace_multiply*/
2323 0, /*nb_inplace_remainder*/
2324 0, /*nb_inplace_power*/
2325 0, /*nb_inplace_lshift*/
2326 0, /*nb_inplace_rshift*/
2327 0, /*nb_inplace_and*/
2328 0, /*nb_inplace_xor*/
2329 0, /*nb_inplace_or*/
2330 delta_divide, /* nb_floor_divide */
2331 delta_truedivide, /* nb_true_divide */
2332 0, /* nb_inplace_floor_divide */
2333 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002334};
2335
2336static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 PyVarObject_HEAD_INIT(NULL, 0)
2338 "datetime.timedelta", /* tp_name */
2339 sizeof(PyDateTime_Delta), /* tp_basicsize */
2340 0, /* tp_itemsize */
2341 0, /* tp_dealloc */
2342 0, /* tp_print */
2343 0, /* tp_getattr */
2344 0, /* tp_setattr */
2345 0, /* tp_reserved */
2346 (reprfunc)delta_repr, /* tp_repr */
2347 &delta_as_number, /* tp_as_number */
2348 0, /* tp_as_sequence */
2349 0, /* tp_as_mapping */
2350 (hashfunc)delta_hash, /* tp_hash */
2351 0, /* tp_call */
2352 (reprfunc)delta_str, /* tp_str */
2353 PyObject_GenericGetAttr, /* tp_getattro */
2354 0, /* tp_setattro */
2355 0, /* tp_as_buffer */
2356 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2357 delta_doc, /* tp_doc */
2358 0, /* tp_traverse */
2359 0, /* tp_clear */
2360 delta_richcompare, /* tp_richcompare */
2361 0, /* tp_weaklistoffset */
2362 0, /* tp_iter */
2363 0, /* tp_iternext */
2364 delta_methods, /* tp_methods */
2365 delta_members, /* tp_members */
2366 0, /* tp_getset */
2367 0, /* tp_base */
2368 0, /* tp_dict */
2369 0, /* tp_descr_get */
2370 0, /* tp_descr_set */
2371 0, /* tp_dictoffset */
2372 0, /* tp_init */
2373 0, /* tp_alloc */
2374 delta_new, /* tp_new */
2375 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002376};
2377
2378/*
2379 * PyDateTime_Date implementation.
2380 */
2381
2382/* Accessor properties. */
2383
2384static PyObject *
2385date_year(PyDateTime_Date *self, void *unused)
2386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002388}
2389
2390static PyObject *
2391date_month(PyDateTime_Date *self, void *unused)
2392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002394}
2395
2396static PyObject *
2397date_day(PyDateTime_Date *self, void *unused)
2398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002400}
2401
2402static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 {"year", (getter)date_year},
2404 {"month", (getter)date_month},
2405 {"day", (getter)date_day},
2406 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002407};
2408
2409/* Constructors. */
2410
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002411static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002412
Tim Peters2a799bf2002-12-16 20:18:38 +00002413static PyObject *
2414date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 PyObject *self = NULL;
2417 PyObject *state;
2418 int year;
2419 int month;
2420 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 /* Check for invocation from pickle with __getstate__ state */
2423 if (PyTuple_GET_SIZE(args) == 1 &&
2424 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2425 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2426 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2427 {
2428 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002430 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2431 if (me != NULL) {
2432 char *pdata = PyBytes_AS_STRING(state);
2433 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2434 me->hashcode = -1;
2435 }
2436 return (PyObject *)me;
2437 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2440 &year, &month, &day)) {
2441 if (check_date_args(year, month, day) < 0)
2442 return NULL;
2443 self = new_date_ex(year, month, day, type);
2444 }
2445 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002446}
2447
2448/* Return new date from localtime(t). */
2449static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002450date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 struct tm *tm;
2453 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002454
Victor Stinner5d272cc2012-03-13 13:35:55 +01002455 if (_PyTime_ObjectToTime_t(obj, &t) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002456 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002458 tm = localtime(&t);
Victor Stinner21f58932012-03-14 00:15:40 +01002459 if (tm == NULL) {
2460 /* unconvertible time */
2461#ifdef EINVAL
2462 if (errno == 0)
2463 errno = EINVAL;
2464#endif
2465 PyErr_SetFromErrno(PyExc_OSError);
2466 return NULL;
2467 }
2468
2469 return PyObject_CallFunction(cls, "iii",
2470 tm->tm_year + 1900,
2471 tm->tm_mon + 1,
2472 tm->tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002473}
2474
2475/* Return new date from current time.
2476 * We say this is equivalent to fromtimestamp(time.time()), and the
2477 * only way to be sure of that is to *call* time.time(). That's not
2478 * generally the same as calling C's time.
2479 */
2480static PyObject *
2481date_today(PyObject *cls, PyObject *dummy)
2482{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 PyObject *time;
2484 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002485 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 time = time_time();
2488 if (time == NULL)
2489 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002491 /* Note well: today() is a class method, so this may not call
2492 * date.fromtimestamp. For example, it may call
2493 * datetime.fromtimestamp. That's why we need all the accuracy
2494 * time.time() delivers; if someone were gonzo about optimization,
2495 * date.today() could get away with plain C time().
2496 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002497 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 Py_DECREF(time);
2499 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002500}
2501
2502/* Return new date from given timestamp (Python timestamp -- a double). */
2503static PyObject *
2504date_fromtimestamp(PyObject *cls, PyObject *args)
2505{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002506 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002507 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002508
Victor Stinner5d272cc2012-03-13 13:35:55 +01002509 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2510 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002512}
2513
2514/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2515 * the ordinal is out of range.
2516 */
2517static PyObject *
2518date_fromordinal(PyObject *cls, PyObject *args)
2519{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 PyObject *result = NULL;
2521 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2524 int year;
2525 int month;
2526 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 if (ordinal < 1)
2529 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2530 ">= 1");
2531 else {
2532 ord_to_ymd(ordinal, &year, &month, &day);
2533 result = PyObject_CallFunction(cls, "iii",
2534 year, month, day);
2535 }
2536 }
2537 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002538}
2539
2540/*
2541 * Date arithmetic.
2542 */
2543
2544/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2545 * instead.
2546 */
2547static PyObject *
2548add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2549{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002550 PyObject *result = NULL;
2551 int year = GET_YEAR(date);
2552 int month = GET_MONTH(date);
2553 int deltadays = GET_TD_DAYS(delta);
2554 /* C-level overflow is impossible because |deltadays| < 1e9. */
2555 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002557 if (normalize_date(&year, &month, &day) >= 0)
2558 result = new_date(year, month, day);
2559 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002560}
2561
2562static PyObject *
2563date_add(PyObject *left, PyObject *right)
2564{
Brian Curtindfc80e32011-08-10 20:28:54 -05002565 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2566 Py_RETURN_NOTIMPLEMENTED;
2567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002568 if (PyDate_Check(left)) {
2569 /* date + ??? */
2570 if (PyDelta_Check(right))
2571 /* date + delta */
2572 return add_date_timedelta((PyDateTime_Date *) left,
2573 (PyDateTime_Delta *) right,
2574 0);
2575 }
2576 else {
2577 /* ??? + date
2578 * 'right' must be one of us, or we wouldn't have been called
2579 */
2580 if (PyDelta_Check(left))
2581 /* delta + date */
2582 return add_date_timedelta((PyDateTime_Date *) right,
2583 (PyDateTime_Delta *) left,
2584 0);
2585 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002586 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002587}
2588
2589static PyObject *
2590date_subtract(PyObject *left, PyObject *right)
2591{
Brian Curtindfc80e32011-08-10 20:28:54 -05002592 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2593 Py_RETURN_NOTIMPLEMENTED;
2594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002595 if (PyDate_Check(left)) {
2596 if (PyDate_Check(right)) {
2597 /* date - date */
2598 int left_ord = ymd_to_ord(GET_YEAR(left),
2599 GET_MONTH(left),
2600 GET_DAY(left));
2601 int right_ord = ymd_to_ord(GET_YEAR(right),
2602 GET_MONTH(right),
2603 GET_DAY(right));
2604 return new_delta(left_ord - right_ord, 0, 0, 0);
2605 }
2606 if (PyDelta_Check(right)) {
2607 /* date - delta */
2608 return add_date_timedelta((PyDateTime_Date *) left,
2609 (PyDateTime_Delta *) right,
2610 1);
2611 }
2612 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002613 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002614}
2615
2616
2617/* Various ways to turn a date into a string. */
2618
2619static PyObject *
2620date_repr(PyDateTime_Date *self)
2621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2623 Py_TYPE(self)->tp_name,
2624 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002625}
2626
2627static PyObject *
2628date_isoformat(PyDateTime_Date *self)
2629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 return PyUnicode_FromFormat("%04d-%02d-%02d",
2631 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002632}
2633
Tim Peterse2df5ff2003-05-02 18:39:55 +00002634/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002635static PyObject *
2636date_str(PyDateTime_Date *self)
2637{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002638 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002639
2640 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002641}
2642
2643
2644static PyObject *
2645date_ctime(PyDateTime_Date *self)
2646{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002647 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002648}
2649
2650static PyObject *
2651date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2652{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 /* This method can be inherited, and needs to call the
2654 * timetuple() method appropriate to self's class.
2655 */
2656 PyObject *result;
2657 PyObject *tuple;
2658 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002659 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002660 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2663 &format))
2664 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002665
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002666 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002667 if (tuple == NULL)
2668 return NULL;
2669 result = wrap_strftime((PyObject *)self, format, tuple,
2670 (PyObject *)self);
2671 Py_DECREF(tuple);
2672 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002673}
2674
Eric Smith1ba31142007-09-11 18:06:02 +00002675static PyObject *
2676date_format(PyDateTime_Date *self, PyObject *args)
2677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002678 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002679 _Py_IDENTIFIER(strftime);
Eric Smith1ba31142007-09-11 18:06:02 +00002680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002681 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2682 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002684 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002685 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002686 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002687
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002688 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002689}
2690
Tim Peters2a799bf2002-12-16 20:18:38 +00002691/* ISO methods. */
2692
2693static PyObject *
2694date_isoweekday(PyDateTime_Date *self)
2695{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002696 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002698 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002699}
2700
2701static PyObject *
2702date_isocalendar(PyDateTime_Date *self)
2703{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002704 int year = GET_YEAR(self);
2705 int week1_monday = iso_week1_monday(year);
2706 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2707 int week;
2708 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002710 week = divmod(today - week1_monday, 7, &day);
2711 if (week < 0) {
2712 --year;
2713 week1_monday = iso_week1_monday(year);
2714 week = divmod(today - week1_monday, 7, &day);
2715 }
2716 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2717 ++year;
2718 week = 0;
2719 }
2720 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002721}
2722
2723/* Miscellaneous methods. */
2724
Tim Peters2a799bf2002-12-16 20:18:38 +00002725static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002726date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002728 if (PyDate_Check(other)) {
2729 int diff = memcmp(((PyDateTime_Date *)self)->data,
2730 ((PyDateTime_Date *)other)->data,
2731 _PyDateTime_DATE_DATASIZE);
2732 return diff_to_bool(diff, op);
2733 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002734 else
2735 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002736}
2737
2738static PyObject *
2739date_timetuple(PyDateTime_Date *self)
2740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002741 return build_struct_time(GET_YEAR(self),
2742 GET_MONTH(self),
2743 GET_DAY(self),
2744 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002745}
2746
Tim Peters12bf3392002-12-24 05:41:27 +00002747static PyObject *
2748date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002750 PyObject *clone;
2751 PyObject *tuple;
2752 int year = GET_YEAR(self);
2753 int month = GET_MONTH(self);
2754 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002756 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2757 &year, &month, &day))
2758 return NULL;
2759 tuple = Py_BuildValue("iii", year, month, day);
2760 if (tuple == NULL)
2761 return NULL;
2762 clone = date_new(Py_TYPE(self), tuple, NULL);
2763 Py_DECREF(tuple);
2764 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002765}
2766
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002767static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002768generic_hash(unsigned char *data, int len)
2769{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002770 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002771}
2772
2773
2774static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002775
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002776static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002777date_hash(PyDateTime_Date *self)
2778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002779 if (self->hashcode == -1)
2780 self->hashcode = generic_hash(
2781 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002783 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002784}
2785
2786static PyObject *
2787date_toordinal(PyDateTime_Date *self)
2788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002789 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2790 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002791}
2792
2793static PyObject *
2794date_weekday(PyDateTime_Date *self)
2795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002798 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002799}
2800
Tim Peters371935f2003-02-01 01:52:50 +00002801/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002802
Tim Petersb57f8f02003-02-01 02:54:15 +00002803/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002804static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002805date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002806{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002807 PyObject* field;
2808 field = PyBytes_FromStringAndSize((char*)self->data,
2809 _PyDateTime_DATE_DATASIZE);
2810 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002811}
2812
2813static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002814date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002815{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002816 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002817}
2818
2819static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002821 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002822
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002823 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2824 METH_CLASS,
2825 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2826 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002828 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2829 METH_CLASS,
2830 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2831 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002833 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2834 PyDoc_STR("Current date or datetime: same as "
2835 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002839 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2840 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002842 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2843 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2846 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002848 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2849 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2852 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2853 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002855 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2856 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002858 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2859 PyDoc_STR("Return the day of the week represented by the date.\n"
2860 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2863 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2864 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002866 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2867 PyDoc_STR("Return the day of the week represented by the date.\n"
2868 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002870 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2871 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002873 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2874 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002876 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002877};
2878
2879static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002880PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002881
2882static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002883 date_add, /* nb_add */
2884 date_subtract, /* nb_subtract */
2885 0, /* nb_multiply */
2886 0, /* nb_remainder */
2887 0, /* nb_divmod */
2888 0, /* nb_power */
2889 0, /* nb_negative */
2890 0, /* nb_positive */
2891 0, /* nb_absolute */
2892 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002893};
2894
2895static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002896 PyVarObject_HEAD_INIT(NULL, 0)
2897 "datetime.date", /* tp_name */
2898 sizeof(PyDateTime_Date), /* tp_basicsize */
2899 0, /* tp_itemsize */
2900 0, /* tp_dealloc */
2901 0, /* tp_print */
2902 0, /* tp_getattr */
2903 0, /* tp_setattr */
2904 0, /* tp_reserved */
2905 (reprfunc)date_repr, /* tp_repr */
2906 &date_as_number, /* tp_as_number */
2907 0, /* tp_as_sequence */
2908 0, /* tp_as_mapping */
2909 (hashfunc)date_hash, /* tp_hash */
2910 0, /* tp_call */
2911 (reprfunc)date_str, /* tp_str */
2912 PyObject_GenericGetAttr, /* tp_getattro */
2913 0, /* tp_setattro */
2914 0, /* tp_as_buffer */
2915 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2916 date_doc, /* tp_doc */
2917 0, /* tp_traverse */
2918 0, /* tp_clear */
2919 date_richcompare, /* tp_richcompare */
2920 0, /* tp_weaklistoffset */
2921 0, /* tp_iter */
2922 0, /* tp_iternext */
2923 date_methods, /* tp_methods */
2924 0, /* tp_members */
2925 date_getset, /* tp_getset */
2926 0, /* tp_base */
2927 0, /* tp_dict */
2928 0, /* tp_descr_get */
2929 0, /* tp_descr_set */
2930 0, /* tp_dictoffset */
2931 0, /* tp_init */
2932 0, /* tp_alloc */
2933 date_new, /* tp_new */
2934 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002935};
2936
2937/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002938 * PyDateTime_TZInfo implementation.
2939 */
2940
2941/* This is a pure abstract base class, so doesn't do anything beyond
2942 * raising NotImplemented exceptions. Real tzinfo classes need
2943 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002944 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002945 * be subclasses of this tzinfo class, which is easy and quick to check).
2946 *
2947 * Note: For reasons having to do with pickling of subclasses, we have
2948 * to allow tzinfo objects to be instantiated. This wasn't an issue
2949 * in the Python implementation (__init__() could raise NotImplementedError
2950 * there without ill effect), but doing so in the C implementation hit a
2951 * brick wall.
2952 */
2953
2954static PyObject *
2955tzinfo_nogo(const char* methodname)
2956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002957 PyErr_Format(PyExc_NotImplementedError,
2958 "a tzinfo subclass must implement %s()",
2959 methodname);
2960 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002961}
2962
2963/* Methods. A subclass must implement these. */
2964
Tim Peters52dcce22003-01-23 16:36:11 +00002965static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002966tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002968 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002969}
2970
Tim Peters52dcce22003-01-23 16:36:11 +00002971static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002972tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002974 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002975}
2976
Tim Peters52dcce22003-01-23 16:36:11 +00002977static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002978tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002980 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002981}
2982
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002983
2984static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2985 PyDateTime_Delta *delta,
2986 int factor);
2987static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2988static PyObject *datetime_dst(PyObject *self, PyObject *);
2989
Tim Peters52dcce22003-01-23 16:36:11 +00002990static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002991tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002992{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002993 PyObject *result = NULL;
2994 PyObject *off = NULL, *dst = NULL;
2995 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002996
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002997 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002998 PyErr_SetString(PyExc_TypeError,
2999 "fromutc: argument must be a datetime");
3000 return NULL;
3001 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003002 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003003 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3004 "is not self");
3005 return NULL;
3006 }
Tim Peters52dcce22003-01-23 16:36:11 +00003007
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003008 off = datetime_utcoffset(dt, NULL);
3009 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003010 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003011 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003012 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3013 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003014 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 }
Tim Peters52dcce22003-01-23 16:36:11 +00003016
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003017 dst = datetime_dst(dt, NULL);
3018 if (dst == NULL)
3019 goto Fail;
3020 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003021 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3022 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003023 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003024 }
Tim Peters52dcce22003-01-23 16:36:11 +00003025
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003026 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3027 if (delta == NULL)
3028 goto Fail;
3029 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003030 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003031 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003032
3033 Py_DECREF(dst);
3034 dst = call_dst(GET_DT_TZINFO(dt), result);
3035 if (dst == NULL)
3036 goto Fail;
3037 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003039 if (delta_bool(delta) != 0) {
3040 PyObject *temp = result;
3041 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3042 (PyDateTime_Delta *)dst, 1);
3043 Py_DECREF(temp);
3044 if (result == NULL)
3045 goto Fail;
3046 }
3047 Py_DECREF(delta);
3048 Py_DECREF(dst);
3049 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003050 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003051
3052Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003053 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3054 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003056 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003057Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003058 Py_XDECREF(off);
3059 Py_XDECREF(dst);
3060 Py_XDECREF(delta);
3061 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003063}
3064
Tim Peters2a799bf2002-12-16 20:18:38 +00003065/*
3066 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003067 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003068 */
3069
Guido van Rossum177e41a2003-01-30 22:06:23 +00003070static PyObject *
3071tzinfo_reduce(PyObject *self)
3072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003073 PyObject *args, *state, *tmp;
3074 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003075 _Py_IDENTIFIER(__getinitargs__);
3076 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003078 tmp = PyTuple_New(0);
3079 if (tmp == NULL)
3080 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003081
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003082 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 if (getinitargs != NULL) {
3084 args = PyObject_CallObject(getinitargs, tmp);
3085 Py_DECREF(getinitargs);
3086 if (args == NULL) {
3087 Py_DECREF(tmp);
3088 return NULL;
3089 }
3090 }
3091 else {
3092 PyErr_Clear();
3093 args = tmp;
3094 Py_INCREF(args);
3095 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003096
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003097 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003098 if (getstate != NULL) {
3099 state = PyObject_CallObject(getstate, tmp);
3100 Py_DECREF(getstate);
3101 if (state == NULL) {
3102 Py_DECREF(args);
3103 Py_DECREF(tmp);
3104 return NULL;
3105 }
3106 }
3107 else {
3108 PyObject **dictptr;
3109 PyErr_Clear();
3110 state = Py_None;
3111 dictptr = _PyObject_GetDictPtr(self);
3112 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3113 state = *dictptr;
3114 Py_INCREF(state);
3115 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003117 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003119 if (state == Py_None) {
3120 Py_DECREF(state);
3121 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3122 }
3123 else
3124 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003125}
Tim Peters2a799bf2002-12-16 20:18:38 +00003126
3127static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003129 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3130 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003132 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003133 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3134 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003136 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3137 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003140 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003142 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3143 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003145 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003146};
3147
3148static char tzinfo_doc[] =
3149PyDoc_STR("Abstract base class for time zone info objects.");
3150
Neal Norwitz227b5332006-03-22 09:28:35 +00003151static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003152 PyVarObject_HEAD_INIT(NULL, 0)
3153 "datetime.tzinfo", /* tp_name */
3154 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3155 0, /* tp_itemsize */
3156 0, /* tp_dealloc */
3157 0, /* tp_print */
3158 0, /* tp_getattr */
3159 0, /* tp_setattr */
3160 0, /* tp_reserved */
3161 0, /* tp_repr */
3162 0, /* tp_as_number */
3163 0, /* tp_as_sequence */
3164 0, /* tp_as_mapping */
3165 0, /* tp_hash */
3166 0, /* tp_call */
3167 0, /* tp_str */
3168 PyObject_GenericGetAttr, /* tp_getattro */
3169 0, /* tp_setattro */
3170 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003171 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 tzinfo_doc, /* tp_doc */
3173 0, /* tp_traverse */
3174 0, /* tp_clear */
3175 0, /* tp_richcompare */
3176 0, /* tp_weaklistoffset */
3177 0, /* tp_iter */
3178 0, /* tp_iternext */
3179 tzinfo_methods, /* tp_methods */
3180 0, /* tp_members */
3181 0, /* tp_getset */
3182 0, /* tp_base */
3183 0, /* tp_dict */
3184 0, /* tp_descr_get */
3185 0, /* tp_descr_set */
3186 0, /* tp_dictoffset */
3187 0, /* tp_init */
3188 0, /* tp_alloc */
3189 PyType_GenericNew, /* tp_new */
3190 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003191};
3192
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003193static char *timezone_kws[] = {"offset", "name", NULL};
3194
3195static PyObject *
3196timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3197{
3198 PyObject *offset;
3199 PyObject *name = NULL;
3200 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3201 &PyDateTime_DeltaType, &offset,
3202 &PyUnicode_Type, &name))
3203 return new_timezone(offset, name);
3204
3205 return NULL;
3206}
3207
3208static void
3209timezone_dealloc(PyDateTime_TimeZone *self)
3210{
3211 Py_CLEAR(self->offset);
3212 Py_CLEAR(self->name);
3213 Py_TYPE(self)->tp_free((PyObject *)self);
3214}
3215
3216static PyObject *
3217timezone_richcompare(PyDateTime_TimeZone *self,
3218 PyDateTime_TimeZone *other, int op)
3219{
Brian Curtindfc80e32011-08-10 20:28:54 -05003220 if (op != Py_EQ && op != Py_NE)
3221 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003222 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
3223 if (op == Py_EQ)
3224 Py_RETURN_FALSE;
3225 else
3226 Py_RETURN_TRUE;
3227 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003228 return delta_richcompare(self->offset, other->offset, op);
3229}
3230
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003231static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003232timezone_hash(PyDateTime_TimeZone *self)
3233{
3234 return delta_hash((PyDateTime_Delta *)self->offset);
3235}
3236
3237/* Check argument type passed to tzname, utcoffset, or dst methods.
3238 Returns 0 for good argument. Returns -1 and sets exception info
3239 otherwise.
3240 */
3241static int
3242_timezone_check_argument(PyObject *dt, const char *meth)
3243{
3244 if (dt == Py_None || PyDateTime_Check(dt))
3245 return 0;
3246 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3247 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3248 return -1;
3249}
3250
3251static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003252timezone_repr(PyDateTime_TimeZone *self)
3253{
3254 /* Note that although timezone is not subclassable, it is convenient
3255 to use Py_TYPE(self)->tp_name here. */
3256 const char *type_name = Py_TYPE(self)->tp_name;
3257
3258 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3259 return PyUnicode_FromFormat("%s.utc", type_name);
3260
3261 if (self->name == NULL)
3262 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3263
3264 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3265 self->name);
3266}
3267
3268
3269static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003270timezone_str(PyDateTime_TimeZone *self)
3271{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003272 int hours, minutes, seconds;
3273 PyObject *offset;
3274 char sign;
3275
3276 if (self->name != NULL) {
3277 Py_INCREF(self->name);
3278 return self->name;
3279 }
3280 /* Offset is normalized, so it is negative if days < 0 */
3281 if (GET_TD_DAYS(self->offset) < 0) {
3282 sign = '-';
3283 offset = delta_negative((PyDateTime_Delta *)self->offset);
3284 if (offset == NULL)
3285 return NULL;
3286 }
3287 else {
3288 sign = '+';
3289 offset = self->offset;
3290 Py_INCREF(offset);
3291 }
3292 /* Offset is not negative here. */
3293 seconds = GET_TD_SECONDS(offset);
3294 Py_DECREF(offset);
3295 minutes = divmod(seconds, 60, &seconds);
3296 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003297 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003298 assert(seconds == 0);
3299 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003300}
3301
3302static PyObject *
3303timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3304{
3305 if (_timezone_check_argument(dt, "tzname") == -1)
3306 return NULL;
3307
3308 return timezone_str(self);
3309}
3310
3311static PyObject *
3312timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3313{
3314 if (_timezone_check_argument(dt, "utcoffset") == -1)
3315 return NULL;
3316
3317 Py_INCREF(self->offset);
3318 return self->offset;
3319}
3320
3321static PyObject *
3322timezone_dst(PyObject *self, PyObject *dt)
3323{
3324 if (_timezone_check_argument(dt, "dst") == -1)
3325 return NULL;
3326
3327 Py_RETURN_NONE;
3328}
3329
3330static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003331timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3332{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003333 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003334 PyErr_SetString(PyExc_TypeError,
3335 "fromutc: argument must be a datetime");
3336 return NULL;
3337 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003338 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003339 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3340 "is not self");
3341 return NULL;
3342 }
3343
3344 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3345}
3346
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003347static PyObject *
3348timezone_getinitargs(PyDateTime_TimeZone *self)
3349{
3350 if (self->name == NULL)
3351 return Py_BuildValue("(O)", self->offset);
3352 return Py_BuildValue("(OO)", self->offset, self->name);
3353}
3354
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003355static PyMethodDef timezone_methods[] = {
3356 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3357 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003358 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003359
3360 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003361 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003362
3363 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003364 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003365
3366 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3367 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3368
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003369 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3370 PyDoc_STR("pickle support")},
3371
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003372 {NULL, NULL}
3373};
3374
3375static char timezone_doc[] =
3376PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3377
3378static PyTypeObject PyDateTime_TimeZoneType = {
3379 PyVarObject_HEAD_INIT(NULL, 0)
3380 "datetime.timezone", /* tp_name */
3381 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3382 0, /* tp_itemsize */
3383 (destructor)timezone_dealloc, /* tp_dealloc */
3384 0, /* tp_print */
3385 0, /* tp_getattr */
3386 0, /* tp_setattr */
3387 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003388 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003389 0, /* tp_as_number */
3390 0, /* tp_as_sequence */
3391 0, /* tp_as_mapping */
3392 (hashfunc)timezone_hash, /* tp_hash */
3393 0, /* tp_call */
3394 (reprfunc)timezone_str, /* tp_str */
3395 0, /* tp_getattro */
3396 0, /* tp_setattro */
3397 0, /* tp_as_buffer */
3398 Py_TPFLAGS_DEFAULT, /* tp_flags */
3399 timezone_doc, /* tp_doc */
3400 0, /* tp_traverse */
3401 0, /* tp_clear */
3402 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3403 0, /* tp_weaklistoffset */
3404 0, /* tp_iter */
3405 0, /* tp_iternext */
3406 timezone_methods, /* tp_methods */
3407 0, /* tp_members */
3408 0, /* tp_getset */
3409 &PyDateTime_TZInfoType, /* tp_base */
3410 0, /* tp_dict */
3411 0, /* tp_descr_get */
3412 0, /* tp_descr_set */
3413 0, /* tp_dictoffset */
3414 0, /* tp_init */
3415 0, /* tp_alloc */
3416 timezone_new, /* tp_new */
3417};
3418
Tim Peters2a799bf2002-12-16 20:18:38 +00003419/*
Tim Peters37f39822003-01-10 03:49:02 +00003420 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003421 */
3422
Tim Peters37f39822003-01-10 03:49:02 +00003423/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003424 */
3425
3426static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003427time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003429 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003430}
3431
Tim Peters37f39822003-01-10 03:49:02 +00003432static PyObject *
3433time_minute(PyDateTime_Time *self, void *unused)
3434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003435 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003436}
3437
3438/* The name time_second conflicted with some platform header file. */
3439static PyObject *
3440py_time_second(PyDateTime_Time *self, void *unused)
3441{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003442 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003443}
3444
3445static PyObject *
3446time_microsecond(PyDateTime_Time *self, void *unused)
3447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003448 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003449}
3450
3451static PyObject *
3452time_tzinfo(PyDateTime_Time *self, void *unused)
3453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003454 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3455 Py_INCREF(result);
3456 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003457}
3458
3459static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003460 {"hour", (getter)time_hour},
3461 {"minute", (getter)time_minute},
3462 {"second", (getter)py_time_second},
3463 {"microsecond", (getter)time_microsecond},
3464 {"tzinfo", (getter)time_tzinfo},
3465 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003466};
3467
3468/*
3469 * Constructors.
3470 */
3471
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003472static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003473 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003474
Tim Peters2a799bf2002-12-16 20:18:38 +00003475static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003476time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003478 PyObject *self = NULL;
3479 PyObject *state;
3480 int hour = 0;
3481 int minute = 0;
3482 int second = 0;
3483 int usecond = 0;
3484 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003486 /* Check for invocation from pickle with __getstate__ state */
3487 if (PyTuple_GET_SIZE(args) >= 1 &&
3488 PyTuple_GET_SIZE(args) <= 2 &&
3489 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3490 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3491 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3492 {
3493 PyDateTime_Time *me;
3494 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003496 if (PyTuple_GET_SIZE(args) == 2) {
3497 tzinfo = PyTuple_GET_ITEM(args, 1);
3498 if (check_tzinfo_subclass(tzinfo) < 0) {
3499 PyErr_SetString(PyExc_TypeError, "bad "
3500 "tzinfo state arg");
3501 return NULL;
3502 }
3503 }
3504 aware = (char)(tzinfo != Py_None);
3505 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3506 if (me != NULL) {
3507 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003509 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3510 me->hashcode = -1;
3511 me->hastzinfo = aware;
3512 if (aware) {
3513 Py_INCREF(tzinfo);
3514 me->tzinfo = tzinfo;
3515 }
3516 }
3517 return (PyObject *)me;
3518 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003520 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3521 &hour, &minute, &second, &usecond,
3522 &tzinfo)) {
3523 if (check_time_args(hour, minute, second, usecond) < 0)
3524 return NULL;
3525 if (check_tzinfo_subclass(tzinfo) < 0)
3526 return NULL;
3527 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3528 type);
3529 }
3530 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003531}
3532
3533/*
3534 * Destructor.
3535 */
3536
3537static void
Tim Peters37f39822003-01-10 03:49:02 +00003538time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003540 if (HASTZINFO(self)) {
3541 Py_XDECREF(self->tzinfo);
3542 }
3543 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003544}
3545
3546/*
Tim Peters855fe882002-12-22 03:43:39 +00003547 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003548 */
3549
Tim Peters2a799bf2002-12-16 20:18:38 +00003550/* These are all METH_NOARGS, so don't need to check the arglist. */
3551static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003552time_utcoffset(PyObject *self, PyObject *unused) {
3553 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003554}
3555
3556static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003557time_dst(PyObject *self, PyObject *unused) {
3558 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003559}
3560
3561static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003562time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003563 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003564}
3565
3566/*
Tim Peters37f39822003-01-10 03:49:02 +00003567 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003568 */
3569
3570static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003571time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003573 const char *type_name = Py_TYPE(self)->tp_name;
3574 int h = TIME_GET_HOUR(self);
3575 int m = TIME_GET_MINUTE(self);
3576 int s = TIME_GET_SECOND(self);
3577 int us = TIME_GET_MICROSECOND(self);
3578 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003580 if (us)
3581 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3582 type_name, h, m, s, us);
3583 else if (s)
3584 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3585 type_name, h, m, s);
3586 else
3587 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3588 if (result != NULL && HASTZINFO(self))
3589 result = append_keyword_tzinfo(result, self->tzinfo);
3590 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003591}
3592
Tim Peters37f39822003-01-10 03:49:02 +00003593static PyObject *
3594time_str(PyDateTime_Time *self)
3595{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003596 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003597
3598 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003599}
Tim Peters2a799bf2002-12-16 20:18:38 +00003600
3601static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003602time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003603{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003604 char buf[100];
3605 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003606 int us = TIME_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003608 if (us)
3609 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3610 TIME_GET_HOUR(self),
3611 TIME_GET_MINUTE(self),
3612 TIME_GET_SECOND(self),
3613 us);
3614 else
3615 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3616 TIME_GET_HOUR(self),
3617 TIME_GET_MINUTE(self),
3618 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003619
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003620 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003621 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003623 /* We need to append the UTC offset. */
3624 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3625 Py_None) < 0) {
3626 Py_DECREF(result);
3627 return NULL;
3628 }
3629 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3630 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003631}
3632
Tim Peters37f39822003-01-10 03:49:02 +00003633static PyObject *
3634time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3635{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003636 PyObject *result;
3637 PyObject *tuple;
3638 PyObject *format;
3639 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003641 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3642 &format))
3643 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003645 /* Python's strftime does insane things with the year part of the
3646 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003647 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003648 */
3649 tuple = Py_BuildValue("iiiiiiiii",
3650 1900, 1, 1, /* year, month, day */
3651 TIME_GET_HOUR(self),
3652 TIME_GET_MINUTE(self),
3653 TIME_GET_SECOND(self),
3654 0, 1, -1); /* weekday, daynum, dst */
3655 if (tuple == NULL)
3656 return NULL;
3657 assert(PyTuple_Size(tuple) == 9);
3658 result = wrap_strftime((PyObject *)self, format, tuple,
3659 Py_None);
3660 Py_DECREF(tuple);
3661 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003662}
Tim Peters2a799bf2002-12-16 20:18:38 +00003663
3664/*
3665 * Miscellaneous methods.
3666 */
3667
Tim Peters37f39822003-01-10 03:49:02 +00003668static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003669time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003670{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003671 PyObject *result = NULL;
3672 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003673 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003674
Brian Curtindfc80e32011-08-10 20:28:54 -05003675 if (! PyTime_Check(other))
3676 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003677
3678 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003679 diff = memcmp(((PyDateTime_Time *)self)->data,
3680 ((PyDateTime_Time *)other)->data,
3681 _PyDateTime_TIME_DATASIZE);
3682 return diff_to_bool(diff, op);
3683 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003684 offset1 = time_utcoffset(self, NULL);
3685 if (offset1 == NULL)
3686 return NULL;
3687 offset2 = time_utcoffset(other, NULL);
3688 if (offset2 == NULL)
3689 goto done;
3690 /* If they're both naive, or both aware and have the same offsets,
3691 * we get off cheap. Note that if they're both naive, offset1 ==
3692 * offset2 == Py_None at this point.
3693 */
3694 if ((offset1 == offset2) ||
3695 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3696 delta_cmp(offset1, offset2) == 0)) {
3697 diff = memcmp(((PyDateTime_Time *)self)->data,
3698 ((PyDateTime_Time *)other)->data,
3699 _PyDateTime_TIME_DATASIZE);
3700 result = diff_to_bool(diff, op);
3701 }
3702 /* The hard case: both aware with different UTC offsets */
3703 else if (offset1 != Py_None && offset2 != Py_None) {
3704 int offsecs1, offsecs2;
3705 assert(offset1 != offset2); /* else last "if" handled it */
3706 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3707 TIME_GET_MINUTE(self) * 60 +
3708 TIME_GET_SECOND(self) -
3709 GET_TD_DAYS(offset1) * 86400 -
3710 GET_TD_SECONDS(offset1);
3711 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3712 TIME_GET_MINUTE(other) * 60 +
3713 TIME_GET_SECOND(other) -
3714 GET_TD_DAYS(offset2) * 86400 -
3715 GET_TD_SECONDS(offset2);
3716 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003717 if (diff == 0)
3718 diff = TIME_GET_MICROSECOND(self) -
3719 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003720 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003721 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003722 else if (op == Py_EQ) {
3723 result = Py_False;
3724 Py_INCREF(result);
3725 }
3726 else if (op == Py_NE) {
3727 result = Py_True;
3728 Py_INCREF(result);
3729 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003730 else {
3731 PyErr_SetString(PyExc_TypeError,
3732 "can't compare offset-naive and "
3733 "offset-aware times");
3734 }
3735 done:
3736 Py_DECREF(offset1);
3737 Py_XDECREF(offset2);
3738 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003739}
3740
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003741static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003742time_hash(PyDateTime_Time *self)
3743{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003744 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003745 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003746
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003747 offset = time_utcoffset((PyObject *)self, NULL);
3748
3749 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003750 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003752 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003753 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003754 self->hashcode = generic_hash(
3755 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003756 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003757 PyObject *temp1, *temp2;
3758 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003759 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003760 seconds = TIME_GET_HOUR(self) * 3600 +
3761 TIME_GET_MINUTE(self) * 60 +
3762 TIME_GET_SECOND(self);
3763 microseconds = TIME_GET_MICROSECOND(self);
3764 temp1 = new_delta(0, seconds, microseconds, 1);
3765 if (temp1 == NULL) {
3766 Py_DECREF(offset);
3767 return -1;
3768 }
3769 temp2 = delta_subtract(temp1, offset);
3770 Py_DECREF(temp1);
3771 if (temp2 == NULL) {
3772 Py_DECREF(offset);
3773 return -1;
3774 }
3775 self->hashcode = PyObject_Hash(temp2);
3776 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003777 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003778 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003779 }
3780 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003781}
Tim Peters2a799bf2002-12-16 20:18:38 +00003782
Tim Peters12bf3392002-12-24 05:41:27 +00003783static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003784time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003786 PyObject *clone;
3787 PyObject *tuple;
3788 int hh = TIME_GET_HOUR(self);
3789 int mm = TIME_GET_MINUTE(self);
3790 int ss = TIME_GET_SECOND(self);
3791 int us = TIME_GET_MICROSECOND(self);
3792 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003794 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3795 time_kws,
3796 &hh, &mm, &ss, &us, &tzinfo))
3797 return NULL;
3798 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3799 if (tuple == NULL)
3800 return NULL;
3801 clone = time_new(Py_TYPE(self), tuple, NULL);
3802 Py_DECREF(tuple);
3803 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003804}
3805
Tim Peters2a799bf2002-12-16 20:18:38 +00003806static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003807time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003808{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003809 PyObject *offset, *tzinfo;
3810 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003812 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3813 /* Since utcoffset is in whole minutes, nothing can
3814 * alter the conclusion that this is nonzero.
3815 */
3816 return 1;
3817 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003818 tzinfo = GET_TIME_TZINFO(self);
3819 if (tzinfo != Py_None) {
3820 offset = call_utcoffset(tzinfo, Py_None);
3821 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003822 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003823 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3824 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003825 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003826 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003827}
3828
Tim Peters371935f2003-02-01 01:52:50 +00003829/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003830
Tim Peters33e0f382003-01-10 02:05:14 +00003831/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003832 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3833 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003834 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003835 */
3836static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003837time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003838{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003839 PyObject *basestate;
3840 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003842 basestate = PyBytes_FromStringAndSize((char *)self->data,
3843 _PyDateTime_TIME_DATASIZE);
3844 if (basestate != NULL) {
3845 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3846 result = PyTuple_Pack(1, basestate);
3847 else
3848 result = PyTuple_Pack(2, basestate, self->tzinfo);
3849 Py_DECREF(basestate);
3850 }
3851 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003852}
3853
3854static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003855time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003857 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003858}
3859
Tim Peters37f39822003-01-10 03:49:02 +00003860static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003862 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3863 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3864 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003866 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3867 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003869 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3870 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003872 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3873 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003875 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3876 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003878 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3879 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003881 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3882 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003884 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3885 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003887 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003888};
3889
Tim Peters37f39822003-01-10 03:49:02 +00003890static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003891PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3892\n\
3893All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03003894a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003895
Tim Peters37f39822003-01-10 03:49:02 +00003896static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003897 0, /* nb_add */
3898 0, /* nb_subtract */
3899 0, /* nb_multiply */
3900 0, /* nb_remainder */
3901 0, /* nb_divmod */
3902 0, /* nb_power */
3903 0, /* nb_negative */
3904 0, /* nb_positive */
3905 0, /* nb_absolute */
3906 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003907};
3908
Neal Norwitz227b5332006-03-22 09:28:35 +00003909static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003910 PyVarObject_HEAD_INIT(NULL, 0)
3911 "datetime.time", /* tp_name */
3912 sizeof(PyDateTime_Time), /* tp_basicsize */
3913 0, /* tp_itemsize */
3914 (destructor)time_dealloc, /* tp_dealloc */
3915 0, /* tp_print */
3916 0, /* tp_getattr */
3917 0, /* tp_setattr */
3918 0, /* tp_reserved */
3919 (reprfunc)time_repr, /* tp_repr */
3920 &time_as_number, /* tp_as_number */
3921 0, /* tp_as_sequence */
3922 0, /* tp_as_mapping */
3923 (hashfunc)time_hash, /* tp_hash */
3924 0, /* tp_call */
3925 (reprfunc)time_str, /* tp_str */
3926 PyObject_GenericGetAttr, /* tp_getattro */
3927 0, /* tp_setattro */
3928 0, /* tp_as_buffer */
3929 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3930 time_doc, /* tp_doc */
3931 0, /* tp_traverse */
3932 0, /* tp_clear */
3933 time_richcompare, /* tp_richcompare */
3934 0, /* tp_weaklistoffset */
3935 0, /* tp_iter */
3936 0, /* tp_iternext */
3937 time_methods, /* tp_methods */
3938 0, /* tp_members */
3939 time_getset, /* tp_getset */
3940 0, /* tp_base */
3941 0, /* tp_dict */
3942 0, /* tp_descr_get */
3943 0, /* tp_descr_set */
3944 0, /* tp_dictoffset */
3945 0, /* tp_init */
3946 time_alloc, /* tp_alloc */
3947 time_new, /* tp_new */
3948 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003949};
3950
3951/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003952 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003953 */
3954
Tim Petersa9bc1682003-01-11 03:39:11 +00003955/* Accessor properties. Properties for day, month, and year are inherited
3956 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003957 */
3958
3959static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003960datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003962 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003963}
3964
Tim Petersa9bc1682003-01-11 03:39:11 +00003965static PyObject *
3966datetime_minute(PyDateTime_DateTime *self, void *unused)
3967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003968 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003969}
3970
3971static PyObject *
3972datetime_second(PyDateTime_DateTime *self, void *unused)
3973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003974 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003975}
3976
3977static PyObject *
3978datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003981}
3982
3983static PyObject *
3984datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3985{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003986 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3987 Py_INCREF(result);
3988 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003989}
3990
3991static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003992 {"hour", (getter)datetime_hour},
3993 {"minute", (getter)datetime_minute},
3994 {"second", (getter)datetime_second},
3995 {"microsecond", (getter)datetime_microsecond},
3996 {"tzinfo", (getter)datetime_tzinfo},
3997 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003998};
3999
4000/*
4001 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004002 */
4003
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004004static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004005 "year", "month", "day", "hour", "minute", "second",
4006 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004007};
4008
Tim Peters2a799bf2002-12-16 20:18:38 +00004009static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004010datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004011{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004012 PyObject *self = NULL;
4013 PyObject *state;
4014 int year;
4015 int month;
4016 int day;
4017 int hour = 0;
4018 int minute = 0;
4019 int second = 0;
4020 int usecond = 0;
4021 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004023 /* Check for invocation from pickle with __getstate__ state */
4024 if (PyTuple_GET_SIZE(args) >= 1 &&
4025 PyTuple_GET_SIZE(args) <= 2 &&
4026 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4027 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4028 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4029 {
4030 PyDateTime_DateTime *me;
4031 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004033 if (PyTuple_GET_SIZE(args) == 2) {
4034 tzinfo = PyTuple_GET_ITEM(args, 1);
4035 if (check_tzinfo_subclass(tzinfo) < 0) {
4036 PyErr_SetString(PyExc_TypeError, "bad "
4037 "tzinfo state arg");
4038 return NULL;
4039 }
4040 }
4041 aware = (char)(tzinfo != Py_None);
4042 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4043 if (me != NULL) {
4044 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004046 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4047 me->hashcode = -1;
4048 me->hastzinfo = aware;
4049 if (aware) {
4050 Py_INCREF(tzinfo);
4051 me->tzinfo = tzinfo;
4052 }
4053 }
4054 return (PyObject *)me;
4055 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004057 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4058 &year, &month, &day, &hour, &minute,
4059 &second, &usecond, &tzinfo)) {
4060 if (check_date_args(year, month, day) < 0)
4061 return NULL;
4062 if (check_time_args(hour, minute, second, usecond) < 0)
4063 return NULL;
4064 if (check_tzinfo_subclass(tzinfo) < 0)
4065 return NULL;
4066 self = new_datetime_ex(year, month, day,
4067 hour, minute, second, usecond,
4068 tzinfo, type);
4069 }
4070 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004071}
4072
Tim Petersa9bc1682003-01-11 03:39:11 +00004073/* TM_FUNC is the shared type of localtime() and gmtime(). */
4074typedef struct tm *(*TM_FUNC)(const time_t *timer);
4075
4076/* Internal helper.
4077 * Build datetime from a time_t and a distinct count of microseconds.
4078 * Pass localtime or gmtime for f, to control the interpretation of timet.
4079 */
4080static PyObject *
4081datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004082 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004084 struct tm *tm;
Tim Petersa9bc1682003-01-11 03:39:11 +00004085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004086 tm = f(&timet);
Victor Stinner21f58932012-03-14 00:15:40 +01004087 if (tm == NULL) {
4088#ifdef EINVAL
4089 if (errno == 0)
4090 errno = EINVAL;
4091#endif
4092 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004093 }
Victor Stinner21f58932012-03-14 00:15:40 +01004094
4095 /* The platform localtime/gmtime may insert leap seconds,
4096 * indicated by tm->tm_sec > 59. We don't care about them,
4097 * except to the extent that passing them on to the datetime
4098 * constructor would raise ValueError for a reason that
4099 * made no sense to the user.
4100 */
4101 if (tm->tm_sec > 59)
4102 tm->tm_sec = 59;
4103 return PyObject_CallFunction(cls, "iiiiiiiO",
4104 tm->tm_year + 1900,
4105 tm->tm_mon + 1,
4106 tm->tm_mday,
4107 tm->tm_hour,
4108 tm->tm_min,
4109 tm->tm_sec,
4110 us,
4111 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004112}
4113
4114/* Internal helper.
4115 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4116 * to control the interpretation of the timestamp. Since a double doesn't
4117 * have enough bits to cover a datetime's full range of precision, it's
4118 * better to call datetime_from_timet_and_us provided you have a way
4119 * to get that much precision (e.g., C time() isn't good enough).
4120 */
4121static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004122datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004123 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004125 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004126 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004127
Victor Stinner5d272cc2012-03-13 13:35:55 +01004128 if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004129 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004130 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004131}
4132
4133/* Internal helper.
4134 * Build most accurate possible datetime for current time. Pass localtime or
4135 * gmtime for f as appropriate.
4136 */
4137static PyObject *
4138datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4139{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004140 _PyTime_timeval t;
4141 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004142 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4143 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004144}
4145
Larry Hastings31826802013-10-19 00:09:25 -07004146/*[clinic]
4147module datetime
4148
4149@classmethod
4150datetime.now
4151
4152 tz: object = None
4153 Timezone object.
4154
4155Returns new datetime object representing current time local to tz.
4156
4157If no tz is specified, uses local timezone.
4158[clinic]*/
4159
4160PyDoc_STRVAR(datetime_now__doc__,
4161"Returns new datetime object representing current time local to tz.\n"
4162"\n"
4163"datetime.now(tz=None)\n"
4164" tz\n"
4165" Timezone object.\n"
4166"\n"
4167"If no tz is specified, uses local timezone.");
4168
4169#define DATETIME_NOW_METHODDEF \
4170 {"now", (PyCFunction)datetime_now, METH_VARARGS|METH_KEYWORDS|METH_CLASS, datetime_now__doc__},
4171
Tim Peters2a799bf2002-12-16 20:18:38 +00004172static PyObject *
Larry Hastings31826802013-10-19 00:09:25 -07004173datetime_now_impl(PyObject *cls, PyObject *tz);
4174
4175static PyObject *
4176datetime_now(PyObject *cls, PyObject *args, PyObject *kwargs)
4177{
4178 PyObject *return_value = NULL;
4179 static char *_keywords[] = {"tz", NULL};
4180 PyObject *tz = Py_None;
4181
4182 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4183 "|O:now", _keywords,
4184 &tz))
4185 goto exit;
4186 return_value = datetime_now_impl(cls, tz);
4187
4188exit:
4189 return return_value;
4190}
4191
4192static PyObject *
4193datetime_now_impl(PyObject *cls, PyObject *tz)
4194/*[clinic checksum: 328b54387f4c2f8cb534997e1bd55f8cb38c4992]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004196 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004197
Larry Hastings31826802013-10-19 00:09:25 -07004198 /* Return best possible local time -- this isn't constrained by the
4199 * precision of a timestamp.
4200 */
4201 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004202 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004204 self = datetime_best_possible(cls,
Larry Hastings31826802013-10-19 00:09:25 -07004205 tz == Py_None ? localtime : gmtime,
4206 tz);
4207 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004208 /* Convert UTC to tzinfo's zone. */
4209 PyObject *temp = self;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004210 _Py_IDENTIFIER(fromutc);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004211
Larry Hastings31826802013-10-19 00:09:25 -07004212 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004213 Py_DECREF(temp);
4214 }
4215 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004216}
4217
Tim Petersa9bc1682003-01-11 03:39:11 +00004218/* Return best possible UTC time -- this isn't constrained by the
4219 * precision of a timestamp.
4220 */
4221static PyObject *
4222datetime_utcnow(PyObject *cls, PyObject *dummy)
4223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004224 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004225}
4226
Tim Peters2a799bf2002-12-16 20:18:38 +00004227/* Return new local datetime from timestamp (Python timestamp -- a double). */
4228static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004229datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004231 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004232 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004233 PyObject *tzinfo = Py_None;
4234 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004235
Victor Stinner5d272cc2012-03-13 13:35:55 +01004236 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004237 keywords, &timestamp, &tzinfo))
4238 return NULL;
4239 if (check_tzinfo_subclass(tzinfo) < 0)
4240 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004242 self = datetime_from_timestamp(cls,
4243 tzinfo == Py_None ? localtime : gmtime,
4244 timestamp,
4245 tzinfo);
4246 if (self != NULL && tzinfo != Py_None) {
4247 /* Convert UTC to tzinfo's zone. */
4248 PyObject *temp = self;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004249 _Py_IDENTIFIER(fromutc);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004250
4251 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004252 Py_DECREF(temp);
4253 }
4254 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004255}
4256
Tim Petersa9bc1682003-01-11 03:39:11 +00004257/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4258static PyObject *
4259datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4260{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004261 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004262 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004263
Victor Stinner5d272cc2012-03-13 13:35:55 +01004264 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004265 result = datetime_from_timestamp(cls, gmtime, timestamp,
4266 Py_None);
4267 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004268}
4269
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004270/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004271static PyObject *
4272datetime_strptime(PyObject *cls, PyObject *args)
4273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004274 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004275 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004276 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004277
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004278 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004279 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004280
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004281 if (module == NULL) {
4282 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004283 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004284 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004285 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004286 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4287 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004288}
4289
Tim Petersa9bc1682003-01-11 03:39:11 +00004290/* Return new datetime from date/datetime and time arguments. */
4291static PyObject *
4292datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004294 static char *keywords[] = {"date", "time", NULL};
4295 PyObject *date;
4296 PyObject *time;
4297 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004299 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4300 &PyDateTime_DateType, &date,
4301 &PyDateTime_TimeType, &time)) {
4302 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004304 if (HASTZINFO(time))
4305 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4306 result = PyObject_CallFunction(cls, "iiiiiiiO",
4307 GET_YEAR(date),
4308 GET_MONTH(date),
4309 GET_DAY(date),
4310 TIME_GET_HOUR(time),
4311 TIME_GET_MINUTE(time),
4312 TIME_GET_SECOND(time),
4313 TIME_GET_MICROSECOND(time),
4314 tzinfo);
4315 }
4316 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004317}
Tim Peters2a799bf2002-12-16 20:18:38 +00004318
4319/*
4320 * Destructor.
4321 */
4322
4323static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004324datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004326 if (HASTZINFO(self)) {
4327 Py_XDECREF(self->tzinfo);
4328 }
4329 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004330}
4331
4332/*
4333 * Indirect access to tzinfo methods.
4334 */
4335
Tim Peters2a799bf2002-12-16 20:18:38 +00004336/* These are all METH_NOARGS, so don't need to check the arglist. */
4337static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004338datetime_utcoffset(PyObject *self, PyObject *unused) {
4339 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004340}
4341
4342static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004343datetime_dst(PyObject *self, PyObject *unused) {
4344 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004345}
4346
4347static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004348datetime_tzname(PyObject *self, PyObject *unused) {
4349 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004350}
4351
4352/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004353 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004354 */
4355
Tim Petersa9bc1682003-01-11 03:39:11 +00004356/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4357 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004358 */
4359static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004360add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004361 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004363 /* Note that the C-level additions can't overflow, because of
4364 * invariant bounds on the member values.
4365 */
4366 int year = GET_YEAR(date);
4367 int month = GET_MONTH(date);
4368 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4369 int hour = DATE_GET_HOUR(date);
4370 int minute = DATE_GET_MINUTE(date);
4371 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4372 int microsecond = DATE_GET_MICROSECOND(date) +
4373 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004375 assert(factor == 1 || factor == -1);
4376 if (normalize_datetime(&year, &month, &day,
4377 &hour, &minute, &second, &microsecond) < 0)
4378 return NULL;
4379 else
4380 return new_datetime(year, month, day,
4381 hour, minute, second, microsecond,
4382 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004383}
4384
4385static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004386datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004388 if (PyDateTime_Check(left)) {
4389 /* datetime + ??? */
4390 if (PyDelta_Check(right))
4391 /* datetime + delta */
4392 return add_datetime_timedelta(
4393 (PyDateTime_DateTime *)left,
4394 (PyDateTime_Delta *)right,
4395 1);
4396 }
4397 else if (PyDelta_Check(left)) {
4398 /* delta + datetime */
4399 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4400 (PyDateTime_Delta *) left,
4401 1);
4402 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004403 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004404}
4405
4406static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004407datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004409 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 if (PyDateTime_Check(left)) {
4412 /* datetime - ??? */
4413 if (PyDateTime_Check(right)) {
4414 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004415 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004416 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004417
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004418 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4419 offset2 = offset1 = Py_None;
4420 Py_INCREF(offset1);
4421 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004422 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004423 else {
4424 offset1 = datetime_utcoffset(left, NULL);
4425 if (offset1 == NULL)
4426 return NULL;
4427 offset2 = datetime_utcoffset(right, NULL);
4428 if (offset2 == NULL) {
4429 Py_DECREF(offset1);
4430 return NULL;
4431 }
4432 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4433 PyErr_SetString(PyExc_TypeError,
4434 "can't subtract offset-naive and "
4435 "offset-aware datetimes");
4436 Py_DECREF(offset1);
4437 Py_DECREF(offset2);
4438 return NULL;
4439 }
4440 }
4441 if ((offset1 != offset2) &&
4442 delta_cmp(offset1, offset2) != 0) {
4443 offdiff = delta_subtract(offset1, offset2);
4444 if (offdiff == NULL) {
4445 Py_DECREF(offset1);
4446 Py_DECREF(offset2);
4447 return NULL;
4448 }
4449 }
4450 Py_DECREF(offset1);
4451 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004452 delta_d = ymd_to_ord(GET_YEAR(left),
4453 GET_MONTH(left),
4454 GET_DAY(left)) -
4455 ymd_to_ord(GET_YEAR(right),
4456 GET_MONTH(right),
4457 GET_DAY(right));
4458 /* These can't overflow, since the values are
4459 * normalized. At most this gives the number of
4460 * seconds in one day.
4461 */
4462 delta_s = (DATE_GET_HOUR(left) -
4463 DATE_GET_HOUR(right)) * 3600 +
4464 (DATE_GET_MINUTE(left) -
4465 DATE_GET_MINUTE(right)) * 60 +
4466 (DATE_GET_SECOND(left) -
4467 DATE_GET_SECOND(right));
4468 delta_us = DATE_GET_MICROSECOND(left) -
4469 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004470 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004471 if (offdiff != NULL) {
4472 PyObject *temp = result;
4473 result = delta_subtract(result, offdiff);
4474 Py_DECREF(temp);
4475 Py_DECREF(offdiff);
4476 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004477 }
4478 else if (PyDelta_Check(right)) {
4479 /* datetime - delta */
4480 result = add_datetime_timedelta(
4481 (PyDateTime_DateTime *)left,
4482 (PyDateTime_Delta *)right,
4483 -1);
4484 }
4485 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004487 if (result == Py_NotImplemented)
4488 Py_INCREF(result);
4489 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004490}
4491
4492/* Various ways to turn a datetime into a string. */
4493
4494static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004495datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004496{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004497 const char *type_name = Py_TYPE(self)->tp_name;
4498 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004500 if (DATE_GET_MICROSECOND(self)) {
4501 baserepr = PyUnicode_FromFormat(
4502 "%s(%d, %d, %d, %d, %d, %d, %d)",
4503 type_name,
4504 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4505 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4506 DATE_GET_SECOND(self),
4507 DATE_GET_MICROSECOND(self));
4508 }
4509 else if (DATE_GET_SECOND(self)) {
4510 baserepr = PyUnicode_FromFormat(
4511 "%s(%d, %d, %d, %d, %d, %d)",
4512 type_name,
4513 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4514 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4515 DATE_GET_SECOND(self));
4516 }
4517 else {
4518 baserepr = PyUnicode_FromFormat(
4519 "%s(%d, %d, %d, %d, %d)",
4520 type_name,
4521 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4522 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4523 }
4524 if (baserepr == NULL || ! HASTZINFO(self))
4525 return baserepr;
4526 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004527}
4528
Tim Petersa9bc1682003-01-11 03:39:11 +00004529static PyObject *
4530datetime_str(PyDateTime_DateTime *self)
4531{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004532 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004533
4534 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004535}
Tim Peters2a799bf2002-12-16 20:18:38 +00004536
4537static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004538datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004540 int sep = 'T';
4541 static char *keywords[] = {"sep", NULL};
4542 char buffer[100];
4543 PyObject *result;
4544 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004546 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4547 return NULL;
4548 if (us)
4549 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4550 GET_YEAR(self), GET_MONTH(self),
4551 GET_DAY(self), (int)sep,
4552 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4553 DATE_GET_SECOND(self), us);
4554 else
4555 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4556 GET_YEAR(self), GET_MONTH(self),
4557 GET_DAY(self), (int)sep,
4558 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4559 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004561 if (!result || !HASTZINFO(self))
4562 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004564 /* We need to append the UTC offset. */
4565 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4566 (PyObject *)self) < 0) {
4567 Py_DECREF(result);
4568 return NULL;
4569 }
4570 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4571 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004572}
4573
Tim Petersa9bc1682003-01-11 03:39:11 +00004574static PyObject *
4575datetime_ctime(PyDateTime_DateTime *self)
4576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004577 return format_ctime((PyDateTime_Date *)self,
4578 DATE_GET_HOUR(self),
4579 DATE_GET_MINUTE(self),
4580 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004581}
4582
Tim Peters2a799bf2002-12-16 20:18:38 +00004583/* Miscellaneous methods. */
4584
Tim Petersa9bc1682003-01-11 03:39:11 +00004585static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004586datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004587{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004588 PyObject *result = NULL;
4589 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004590 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004592 if (! PyDateTime_Check(other)) {
4593 if (PyDate_Check(other)) {
4594 /* Prevent invocation of date_richcompare. We want to
4595 return NotImplemented here to give the other object
4596 a chance. But since DateTime is a subclass of
4597 Date, if the other object is a Date, it would
4598 compute an ordering based on the date part alone,
4599 and we don't want that. So force unequal or
4600 uncomparable here in that case. */
4601 if (op == Py_EQ)
4602 Py_RETURN_FALSE;
4603 if (op == Py_NE)
4604 Py_RETURN_TRUE;
4605 return cmperror(self, other);
4606 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004607 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004608 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004609
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004610 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004611 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4612 ((PyDateTime_DateTime *)other)->data,
4613 _PyDateTime_DATETIME_DATASIZE);
4614 return diff_to_bool(diff, op);
4615 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004616 offset1 = datetime_utcoffset(self, NULL);
4617 if (offset1 == NULL)
4618 return NULL;
4619 offset2 = datetime_utcoffset(other, NULL);
4620 if (offset2 == NULL)
4621 goto done;
4622 /* If they're both naive, or both aware and have the same offsets,
4623 * we get off cheap. Note that if they're both naive, offset1 ==
4624 * offset2 == Py_None at this point.
4625 */
4626 if ((offset1 == offset2) ||
4627 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4628 delta_cmp(offset1, offset2) == 0)) {
4629 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4630 ((PyDateTime_DateTime *)other)->data,
4631 _PyDateTime_DATETIME_DATASIZE);
4632 result = diff_to_bool(diff, op);
4633 }
4634 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004635 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004636
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004637 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004638 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4639 other);
4640 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004641 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004642 diff = GET_TD_DAYS(delta);
4643 if (diff == 0)
4644 diff = GET_TD_SECONDS(delta) |
4645 GET_TD_MICROSECONDS(delta);
4646 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004647 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004648 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004649 else if (op == Py_EQ) {
4650 result = Py_False;
4651 Py_INCREF(result);
4652 }
4653 else if (op == Py_NE) {
4654 result = Py_True;
4655 Py_INCREF(result);
4656 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004657 else {
4658 PyErr_SetString(PyExc_TypeError,
4659 "can't compare offset-naive and "
4660 "offset-aware datetimes");
4661 }
4662 done:
4663 Py_DECREF(offset1);
4664 Py_XDECREF(offset2);
4665 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004666}
4667
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004668static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004669datetime_hash(PyDateTime_DateTime *self)
4670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004671 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004672 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004673
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004674 offset = datetime_utcoffset((PyObject *)self, NULL);
4675
4676 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004677 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004679 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004680 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 self->hashcode = generic_hash(
4682 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004684 PyObject *temp1, *temp2;
4685 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004687 assert(HASTZINFO(self));
4688 days = ymd_to_ord(GET_YEAR(self),
4689 GET_MONTH(self),
4690 GET_DAY(self));
4691 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004692 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004693 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004694 temp1 = new_delta(days, seconds,
4695 DATE_GET_MICROSECOND(self),
4696 1);
4697 if (temp1 == NULL) {
4698 Py_DECREF(offset);
4699 return -1;
4700 }
4701 temp2 = delta_subtract(temp1, offset);
4702 Py_DECREF(temp1);
4703 if (temp2 == NULL) {
4704 Py_DECREF(offset);
4705 return -1;
4706 }
4707 self->hashcode = PyObject_Hash(temp2);
4708 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004709 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004710 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004711 }
4712 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004713}
Tim Peters2a799bf2002-12-16 20:18:38 +00004714
4715static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004716datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004717{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004718 PyObject *clone;
4719 PyObject *tuple;
4720 int y = GET_YEAR(self);
4721 int m = GET_MONTH(self);
4722 int d = GET_DAY(self);
4723 int hh = DATE_GET_HOUR(self);
4724 int mm = DATE_GET_MINUTE(self);
4725 int ss = DATE_GET_SECOND(self);
4726 int us = DATE_GET_MICROSECOND(self);
4727 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004729 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4730 datetime_kws,
4731 &y, &m, &d, &hh, &mm, &ss, &us,
4732 &tzinfo))
4733 return NULL;
4734 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4735 if (tuple == NULL)
4736 return NULL;
4737 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4738 Py_DECREF(tuple);
4739 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004740}
4741
4742static PyObject *
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004743local_timezone(PyDateTime_DateTime *utc_time)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004744{
4745 PyObject *result = NULL;
4746 struct tm *timep;
4747 time_t timestamp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004748 PyObject *delta;
4749 PyObject *one_second;
4750 PyObject *seconds;
4751 PyObject *nameo = NULL;
4752 const char *zone = NULL;
4753
4754 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
4755 if (delta == NULL)
4756 return NULL;
4757 one_second = new_delta(0, 1, 0, 0);
4758 if (one_second == NULL)
4759 goto error;
4760 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
4761 (PyDateTime_Delta *)one_second);
4762 Py_DECREF(one_second);
4763 if (seconds == NULL)
4764 goto error;
4765 Py_DECREF(delta);
4766 timestamp = PyLong_AsLong(seconds);
4767 Py_DECREF(seconds);
4768 if (timestamp == -1 && PyErr_Occurred())
4769 return NULL;
4770 timep = localtime(&timestamp);
4771#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004772 zone = timep->tm_zone;
4773 delta = new_delta(0, timep->tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004774#else /* HAVE_STRUCT_TM_TM_ZONE */
4775 {
4776 PyObject *local_time;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004777 local_time = new_datetime(timep->tm_year + 1900, timep->tm_mon + 1,
4778 timep->tm_mday, timep->tm_hour, timep->tm_min,
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004779 timep->tm_sec, DATE_GET_MICROSECOND(utc_time),
4780 utc_time->tzinfo);
4781 if (local_time == NULL)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004782 goto error;
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004783 delta = datetime_subtract(local_time, (PyObject*)utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004784 /* XXX: before relying on tzname, we should compare delta
4785 to the offset implied by timezone/altzone */
4786 if (daylight && timep->tm_isdst >= 0)
4787 zone = tzname[timep->tm_isdst % 2];
4788 else
4789 zone = tzname[0];
4790 Py_DECREF(local_time);
4791 }
4792#endif /* HAVE_STRUCT_TM_TM_ZONE */
4793 if (zone != NULL) {
4794 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
4795 if (nameo == NULL)
4796 goto error;
4797 }
4798 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02004799 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004800 error:
4801 Py_DECREF(delta);
4802 return result;
4803}
4804
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004805static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00004806datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004807{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004808 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004809 PyObject *offset;
4810 PyObject *temp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004811 PyObject *tzinfo = Py_None;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004812 _Py_IDENTIFIER(fromutc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004813 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004814
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004815 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
4816 &tzinfo))
4817 return NULL;
4818
4819 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004820 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004822 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4823 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004824
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004825 /* Conversion to self's own time zone is a NOP. */
4826 if (self->tzinfo == tzinfo) {
4827 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004828 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004829 }
Tim Peters521fc152002-12-31 17:36:56 +00004830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004831 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004832 offset = datetime_utcoffset((PyObject *)self, NULL);
4833 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004834 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004835 if (offset == Py_None) {
4836 Py_DECREF(offset);
4837 NeedAware:
4838 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4839 "a naive datetime");
4840 return NULL;
4841 }
Tim Petersf3615152003-01-01 21:51:37 +00004842
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004843 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004844 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4845 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004846 Py_DECREF(offset);
4847 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004848 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004850 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004851 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004852 if (tzinfo == Py_None) {
4853 tzinfo = local_timezone(result);
4854 if (tzinfo == NULL) {
4855 Py_DECREF(result);
4856 return NULL;
4857 }
4858 }
4859 else
4860 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004861 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004862 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004863
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004864 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004865 result = (PyDateTime_DateTime *)
4866 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004867 Py_DECREF(temp);
4868
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004869 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004870}
4871
4872static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004873datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004875 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004877 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004878 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004879
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004880 dst = call_dst(self->tzinfo, (PyObject *)self);
4881 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004883
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004884 if (dst != Py_None)
4885 dstflag = delta_bool((PyDateTime_Delta *)dst);
4886 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004887 }
4888 return build_struct_time(GET_YEAR(self),
4889 GET_MONTH(self),
4890 GET_DAY(self),
4891 DATE_GET_HOUR(self),
4892 DATE_GET_MINUTE(self),
4893 DATE_GET_SECOND(self),
4894 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004895}
4896
4897static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04004898datetime_timestamp(PyDateTime_DateTime *self)
4899{
4900 PyObject *result;
4901
4902 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4903 PyObject *delta;
4904 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
4905 if (delta == NULL)
4906 return NULL;
4907 result = delta_total_seconds(delta);
4908 Py_DECREF(delta);
4909 }
4910 else {
4911 struct tm time;
4912 time_t timestamp;
4913 memset((void *) &time, '\0', sizeof(struct tm));
4914 time.tm_year = GET_YEAR(self) - 1900;
4915 time.tm_mon = GET_MONTH(self) - 1;
4916 time.tm_mday = GET_DAY(self);
4917 time.tm_hour = DATE_GET_HOUR(self);
4918 time.tm_min = DATE_GET_MINUTE(self);
4919 time.tm_sec = DATE_GET_SECOND(self);
4920 time.tm_wday = -1;
4921 time.tm_isdst = -1;
4922 timestamp = mktime(&time);
Victor Stinner93037492013-06-25 22:54:35 +02004923 if (timestamp == (time_t)(-1)
4924#ifndef _AIX
4925 /* Return value of -1 does not necessarily mean an error,
4926 * but tm_wday cannot remain set to -1 if mktime succeeded. */
4927 && time.tm_wday == -1
4928#else
4929 /* on AIX, tm_wday is always sets, even on error */
4930#endif
4931 )
4932 {
Alexander Belopolskya4415142012-06-08 12:33:09 -04004933 PyErr_SetString(PyExc_OverflowError,
4934 "timestamp out of range");
4935 return NULL;
4936 }
4937 result = PyFloat_FromDouble(timestamp + DATE_GET_MICROSECOND(self) / 1e6);
4938 }
4939 return result;
4940}
4941
4942static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004943datetime_getdate(PyDateTime_DateTime *self)
4944{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004945 return new_date(GET_YEAR(self),
4946 GET_MONTH(self),
4947 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004948}
4949
4950static PyObject *
4951datetime_gettime(PyDateTime_DateTime *self)
4952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004953 return new_time(DATE_GET_HOUR(self),
4954 DATE_GET_MINUTE(self),
4955 DATE_GET_SECOND(self),
4956 DATE_GET_MICROSECOND(self),
4957 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004958}
4959
4960static PyObject *
4961datetime_gettimetz(PyDateTime_DateTime *self)
4962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004963 return new_time(DATE_GET_HOUR(self),
4964 DATE_GET_MINUTE(self),
4965 DATE_GET_SECOND(self),
4966 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004967 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004968}
4969
4970static PyObject *
4971datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004972{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004973 int y, m, d, hh, mm, ss;
4974 PyObject *tzinfo;
4975 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004976
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004977 tzinfo = GET_DT_TZINFO(self);
4978 if (tzinfo == Py_None) {
4979 utcself = self;
4980 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004981 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004982 else {
4983 PyObject *offset;
4984 offset = call_utcoffset(tzinfo, (PyObject *)self);
4985 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004986 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004987 if (offset == Py_None) {
4988 Py_DECREF(offset);
4989 utcself = self;
4990 Py_INCREF(utcself);
4991 }
4992 else {
4993 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4994 (PyDateTime_Delta *)offset, -1);
4995 Py_DECREF(offset);
4996 if (utcself == NULL)
4997 return NULL;
4998 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004999 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005000 y = GET_YEAR(utcself);
5001 m = GET_MONTH(utcself);
5002 d = GET_DAY(utcself);
5003 hh = DATE_GET_HOUR(utcself);
5004 mm = DATE_GET_MINUTE(utcself);
5005 ss = DATE_GET_SECOND(utcself);
5006
5007 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005008 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005009}
5010
Tim Peters371935f2003-02-01 01:52:50 +00005011/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005012
Tim Petersa9bc1682003-01-11 03:39:11 +00005013/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005014 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5015 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005016 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005017 */
5018static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005019datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005021 PyObject *basestate;
5022 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005024 basestate = PyBytes_FromStringAndSize((char *)self->data,
5025 _PyDateTime_DATETIME_DATASIZE);
5026 if (basestate != NULL) {
5027 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5028 result = PyTuple_Pack(1, basestate);
5029 else
5030 result = PyTuple_Pack(2, basestate, self->tzinfo);
5031 Py_DECREF(basestate);
5032 }
5033 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005034}
5035
5036static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00005037datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00005038{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005039 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00005040}
5041
Tim Petersa9bc1682003-01-11 03:39:11 +00005042static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005044 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005045
Larry Hastings31826802013-10-19 00:09:25 -07005046 DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005048 {"utcnow", (PyCFunction)datetime_utcnow,
5049 METH_NOARGS | METH_CLASS,
5050 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005052 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5053 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5054 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005056 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5057 METH_VARARGS | METH_CLASS,
5058 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
5059 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005061 {"strptime", (PyCFunction)datetime_strptime,
5062 METH_VARARGS | METH_CLASS,
5063 PyDoc_STR("string, format -> new datetime parsed from a string "
5064 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005066 {"combine", (PyCFunction)datetime_combine,
5067 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5068 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005070 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005072 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5073 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005075 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5076 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005078 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5079 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005081 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5082 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005084 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5085 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005086
Alexander Belopolskya4415142012-06-08 12:33:09 -04005087 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5088 PyDoc_STR("Return POSIX timestamp as float.")},
5089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005090 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5091 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005093 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5094 PyDoc_STR("[sep] -> string in ISO 8601 format, "
5095 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
5096 "sep is used to separate the year from the time, and "
5097 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005099 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5100 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005102 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5103 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005105 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5106 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005108 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5109 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005111 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5112 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005114 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5115 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005117 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005118};
5119
Tim Petersa9bc1682003-01-11 03:39:11 +00005120static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005121PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5122\n\
5123The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005124instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005125
Tim Petersa9bc1682003-01-11 03:39:11 +00005126static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005127 datetime_add, /* nb_add */
5128 datetime_subtract, /* nb_subtract */
5129 0, /* nb_multiply */
5130 0, /* nb_remainder */
5131 0, /* nb_divmod */
5132 0, /* nb_power */
5133 0, /* nb_negative */
5134 0, /* nb_positive */
5135 0, /* nb_absolute */
5136 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005137};
5138
Neal Norwitz227b5332006-03-22 09:28:35 +00005139static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005140 PyVarObject_HEAD_INIT(NULL, 0)
5141 "datetime.datetime", /* tp_name */
5142 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5143 0, /* tp_itemsize */
5144 (destructor)datetime_dealloc, /* tp_dealloc */
5145 0, /* tp_print */
5146 0, /* tp_getattr */
5147 0, /* tp_setattr */
5148 0, /* tp_reserved */
5149 (reprfunc)datetime_repr, /* tp_repr */
5150 &datetime_as_number, /* tp_as_number */
5151 0, /* tp_as_sequence */
5152 0, /* tp_as_mapping */
5153 (hashfunc)datetime_hash, /* tp_hash */
5154 0, /* tp_call */
5155 (reprfunc)datetime_str, /* tp_str */
5156 PyObject_GenericGetAttr, /* tp_getattro */
5157 0, /* tp_setattro */
5158 0, /* tp_as_buffer */
5159 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5160 datetime_doc, /* tp_doc */
5161 0, /* tp_traverse */
5162 0, /* tp_clear */
5163 datetime_richcompare, /* tp_richcompare */
5164 0, /* tp_weaklistoffset */
5165 0, /* tp_iter */
5166 0, /* tp_iternext */
5167 datetime_methods, /* tp_methods */
5168 0, /* tp_members */
5169 datetime_getset, /* tp_getset */
5170 &PyDateTime_DateType, /* tp_base */
5171 0, /* tp_dict */
5172 0, /* tp_descr_get */
5173 0, /* tp_descr_set */
5174 0, /* tp_dictoffset */
5175 0, /* tp_init */
5176 datetime_alloc, /* tp_alloc */
5177 datetime_new, /* tp_new */
5178 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005179};
5180
5181/* ---------------------------------------------------------------------------
5182 * Module methods and initialization.
5183 */
5184
5185static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005186 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005187};
5188
Tim Peters9ddf40b2004-06-20 22:41:32 +00005189/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5190 * datetime.h.
5191 */
5192static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005193 &PyDateTime_DateType,
5194 &PyDateTime_DateTimeType,
5195 &PyDateTime_TimeType,
5196 &PyDateTime_DeltaType,
5197 &PyDateTime_TZInfoType,
5198 new_date_ex,
5199 new_datetime_ex,
5200 new_time_ex,
5201 new_delta_ex,
5202 datetime_fromtimestamp,
5203 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005204};
5205
5206
Martin v. Löwis1a214512008-06-11 05:26:20 +00005207
5208static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005209 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005210 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005211 "Fast implementation of the datetime type.",
5212 -1,
5213 module_methods,
5214 NULL,
5215 NULL,
5216 NULL,
5217 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005218};
5219
Tim Peters2a799bf2002-12-16 20:18:38 +00005220PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005221PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005223 PyObject *m; /* a module object */
5224 PyObject *d; /* its dict */
5225 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005226 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005228 m = PyModule_Create(&datetimemodule);
5229 if (m == NULL)
5230 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005232 if (PyType_Ready(&PyDateTime_DateType) < 0)
5233 return NULL;
5234 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5235 return NULL;
5236 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5237 return NULL;
5238 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5239 return NULL;
5240 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5241 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005242 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5243 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005245 /* timedelta values */
5246 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005248 x = new_delta(0, 0, 1, 0);
5249 if (x == NULL || PyDict_SetItemString(d, "resolution", 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, 0, 0, 0);
5254 if (x == NULL || PyDict_SetItemString(d, "min", 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 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5259 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5260 return NULL;
5261 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005263 /* date values */
5264 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005266 x = new_date(1, 1, 1);
5267 if (x == NULL || PyDict_SetItemString(d, "min", 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_date(MAXYEAR, 12, 31);
5272 if (x == NULL || PyDict_SetItemString(d, "max", 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 x = new_delta(1, 0, 0, 0);
5277 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5278 return NULL;
5279 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005281 /* time values */
5282 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005284 x = new_time(0, 0, 0, 0, Py_None);
5285 if (x == NULL || PyDict_SetItemString(d, "min", 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_time(23, 59, 59, 999999, Py_None);
5290 if (x == NULL || PyDict_SetItemString(d, "max", 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 x = new_delta(0, 0, 1, 0);
5295 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5296 return NULL;
5297 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005299 /* datetime values */
5300 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005302 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5303 if (x == NULL || PyDict_SetItemString(d, "min", 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_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5308 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5309 return NULL;
5310 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005312 x = new_delta(0, 0, 1, 0);
5313 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5314 return NULL;
5315 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005316
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005317 /* timezone values */
5318 d = PyDateTime_TimeZoneType.tp_dict;
5319
5320 delta = new_delta(0, 0, 0, 0);
5321 if (delta == NULL)
5322 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005323 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005324 Py_DECREF(delta);
5325 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5326 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005327 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005328
5329 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5330 if (delta == NULL)
5331 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005332 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005333 Py_DECREF(delta);
5334 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5335 return NULL;
5336 Py_DECREF(x);
5337
5338 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5339 if (delta == NULL)
5340 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005341 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005342 Py_DECREF(delta);
5343 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5344 return NULL;
5345 Py_DECREF(x);
5346
Alexander Belopolskya4415142012-06-08 12:33:09 -04005347 /* Epoch */
5348 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
5349 PyDateTime_TimeZone_UTC);
5350 if (PyDateTime_Epoch == NULL)
5351 return NULL;
5352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005353 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005354 PyModule_AddIntMacro(m, MINYEAR);
5355 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005357 Py_INCREF(&PyDateTime_DateType);
5358 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005360 Py_INCREF(&PyDateTime_DateTimeType);
5361 PyModule_AddObject(m, "datetime",
5362 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005364 Py_INCREF(&PyDateTime_TimeType);
5365 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005367 Py_INCREF(&PyDateTime_DeltaType);
5368 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005370 Py_INCREF(&PyDateTime_TZInfoType);
5371 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005372
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005373 Py_INCREF(&PyDateTime_TimeZoneType);
5374 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005376 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5377 if (x == NULL)
5378 return NULL;
5379 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005381 /* A 4-year cycle has an extra leap day over what we'd get from
5382 * pasting together 4 single years.
5383 */
5384 assert(DI4Y == 4 * 365 + 1);
5385 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005387 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5388 * get from pasting together 4 100-year cycles.
5389 */
5390 assert(DI400Y == 4 * DI100Y + 1);
5391 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005393 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5394 * pasting together 25 4-year cycles.
5395 */
5396 assert(DI100Y == 25 * DI4Y - 1);
5397 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005398
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005399 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005400 us_per_ms = PyLong_FromLong(1000);
5401 us_per_second = PyLong_FromLong(1000000);
5402 us_per_minute = PyLong_FromLong(60000000);
5403 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005404 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005405 us_per_minute == NULL || seconds_per_day == NULL)
5406 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005408 /* The rest are too big for 32-bit ints, but even
5409 * us_per_week fits in 40 bits, so doubles should be exact.
5410 */
5411 us_per_hour = PyLong_FromDouble(3600000000.0);
5412 us_per_day = PyLong_FromDouble(86400000000.0);
5413 us_per_week = PyLong_FromDouble(604800000000.0);
5414 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5415 return NULL;
5416 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005417}
Tim Petersf3615152003-01-01 21:51:37 +00005418
5419/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005420Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005421 x.n = x stripped of its timezone -- its naive time.
5422 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005423 return None
Tim Petersf3615152003-01-01 21:51:37 +00005424 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005425 return None
Tim Petersf3615152003-01-01 21:51:37 +00005426 x.s = x's standard offset, x.o - x.d
5427
5428Now some derived rules, where k is a duration (timedelta).
5429
54301. x.o = x.s + x.d
5431 This follows from the definition of x.s.
5432
Tim Petersc5dc4da2003-01-02 17:55:03 +000054332. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005434 This is actually a requirement, an assumption we need to make about
5435 sane tzinfo classes.
5436
54373. The naive UTC time corresponding to x is x.n - x.o.
5438 This is again a requirement for a sane tzinfo class.
5439
54404. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005441 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005442
Tim Petersc5dc4da2003-01-02 17:55:03 +000054435. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005444 Again follows from how arithmetic is defined.
5445
Tim Peters8bb5ad22003-01-24 02:44:45 +00005446Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005447(meaning that the various tzinfo methods exist, and don't blow up or return
5448None when called).
5449
Tim Petersa9bc1682003-01-11 03:39:11 +00005450The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005451x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005452
5453By #3, we want
5454
Tim Peters8bb5ad22003-01-24 02:44:45 +00005455 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005456
5457The algorithm starts by attaching tz to x.n, and calling that y. So
5458x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5459becomes true; in effect, we want to solve [2] for k:
5460
Tim Peters8bb5ad22003-01-24 02:44:45 +00005461 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005462
5463By #1, this is the same as
5464
Tim Peters8bb5ad22003-01-24 02:44:45 +00005465 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005466
5467By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5468Substituting that into [3],
5469
Tim Peters8bb5ad22003-01-24 02:44:45 +00005470 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5471 k - (y+k).s - (y+k).d = 0; rearranging,
5472 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5473 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005474
Tim Peters8bb5ad22003-01-24 02:44:45 +00005475On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5476approximate k by ignoring the (y+k).d term at first. Note that k can't be
5477very large, since all offset-returning methods return a duration of magnitude
5478less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5479be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005480
5481In any case, the new value is
5482
Tim Peters8bb5ad22003-01-24 02:44:45 +00005483 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005484
Tim Peters8bb5ad22003-01-24 02:44:45 +00005485It's helpful to step back at look at [4] from a higher level: it's simply
5486mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005487
5488At this point, if
5489
Tim Peters8bb5ad22003-01-24 02:44:45 +00005490 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005491
5492we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005493at the start of daylight time. Picture US Eastern for concreteness. The wall
5494time 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 +00005495sense then. The docs ask that an Eastern tzinfo class consider such a time to
5496be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5497on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005498the only spelling that makes sense on the local wall clock.
5499
Tim Petersc5dc4da2003-01-02 17:55:03 +00005500In fact, if [5] holds at this point, we do have the standard-time spelling,
5501but that takes a bit of proof. We first prove a stronger result. What's the
5502difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005503
Tim Peters8bb5ad22003-01-24 02:44:45 +00005504 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005505
Tim Petersc5dc4da2003-01-02 17:55:03 +00005506Now
5507 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005508 (y + y.s).n = by #5
5509 y.n + y.s = since y.n = x.n
5510 x.n + y.s = since z and y are have the same tzinfo member,
5511 y.s = z.s by #2
5512 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005513
Tim Petersc5dc4da2003-01-02 17:55:03 +00005514Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005515
Tim Petersc5dc4da2003-01-02 17:55:03 +00005516 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005517 x.n - ((x.n + z.s) - z.o) = expanding
5518 x.n - x.n - z.s + z.o = cancelling
5519 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005520 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005521
Tim Petersc5dc4da2003-01-02 17:55:03 +00005522So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005523
Tim Petersc5dc4da2003-01-02 17:55:03 +00005524If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005525spelling we wanted in the endcase described above. We're done. Contrarily,
5526if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005527
Tim Petersc5dc4da2003-01-02 17:55:03 +00005528If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5529add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005530local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005531
Tim Petersc5dc4da2003-01-02 17:55:03 +00005532Let
Tim Petersf3615152003-01-01 21:51:37 +00005533
Tim Peters4fede1a2003-01-04 00:26:59 +00005534 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005535
Tim Peters4fede1a2003-01-04 00:26:59 +00005536and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005537
Tim Peters8bb5ad22003-01-24 02:44:45 +00005538 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005539
Tim Peters8bb5ad22003-01-24 02:44:45 +00005540If so, we're done. If not, the tzinfo class is insane, according to the
5541assumptions we've made. This also requires a bit of proof. As before, let's
5542compute the difference between the LHS and RHS of [8] (and skipping some of
5543the justifications for the kinds of substitutions we've done several times
5544already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005545
Tim Peters8bb5ad22003-01-24 02:44:45 +00005546 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005547 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5548 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5549 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5550 - z.n + z.n - z.o + z'.o = cancel z.n
5551 - z.o + z'.o = #1 twice
5552 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5553 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005554
5555So 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 +00005556we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5557return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005558
Tim Peters8bb5ad22003-01-24 02:44:45 +00005559How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5560a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5561would have to change the result dst() returns: we start in DST, and moving
5562a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005563
Tim Peters8bb5ad22003-01-24 02:44:45 +00005564There isn't a sane case where this can happen. The closest it gets is at
5565the end of DST, where there's an hour in UTC with no spelling in a hybrid
5566tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5567that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5568UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5569time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5570clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5571standard time. Since that's what the local clock *does*, we want to map both
5572UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005573in local time, but so it goes -- it's the way the local clock works.
5574
Tim Peters8bb5ad22003-01-24 02:44:45 +00005575When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5576so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5577z' = 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 +00005578(correctly) concludes that z' is not UTC-equivalent to x.
5579
5580Because we know z.d said z was in daylight time (else [5] would have held and
5581we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005582and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005583return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5584but the reasoning doesn't depend on the example -- it depends on there being
5585two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005586z' must be in standard time, and is the spelling we want in this case.
5587
5588Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5589concerned (because it takes z' as being in standard time rather than the
5590daylight time we intend here), but returning it gives the real-life "local
5591clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5592tz.
5593
5594When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5595the 1:MM standard time spelling we want.
5596
5597So how can this break? One of the assumptions must be violated. Two
5598possibilities:
5599
56001) [2] effectively says that y.s is invariant across all y belong to a given
5601 time zone. This isn't true if, for political reasons or continental drift,
5602 a region decides to change its base offset from UTC.
5603
56042) There may be versions of "double daylight" time where the tail end of
5605 the analysis gives up a step too early. I haven't thought about that
5606 enough to say.
5607
5608In any case, it's clear that the default fromutc() is strong enough to handle
5609"almost all" time zones: so long as the standard offset is invariant, it
5610doesn't matter if daylight time transition points change from year to year, or
5611if daylight time is skipped in some years; it doesn't matter how large or
5612small dst() may get within its bounds; and it doesn't even matter if some
5613perverse time zone returns a negative dst()). So a breaking case must be
5614pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005615--------------------------------------------------------------------------- */