blob: 8c473516327f67f5d114de0a80ebeac60a987bf9 [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"
6#include "modsupport.h"
7#include "structmember.h"
8
9#include <time.h>
10
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000011#include "_time.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000012
13/* Differentiate between building the core module and building extension
14 * modules.
15 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000016#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000017#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000018#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000019#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000020#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000021
22/* We require that C int be at least 32 bits, and use int virtually
23 * everywhere. In just a few cases we use a temp long, where a Python
24 * API returns a C long. In such cases, we have to ensure that the
25 * final result fits in a C int (this can be an issue on 64-bit boxes).
26 */
27#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000028# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000029#endif
30
31#define MINYEAR 1
32#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000033#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000034
35/* Nine decimal digits is easy to communicate, and leaves enough room
36 * so that two delta days can be added w/o fear of overflowing a signed
37 * 32-bit int, and with plenty of room left over to absorb any possible
38 * carries from adding seconds.
39 */
40#define MAX_DELTA_DAYS 999999999
41
42/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043#define GET_YEAR PyDateTime_GET_YEAR
44#define GET_MONTH PyDateTime_GET_MONTH
45#define GET_DAY PyDateTime_GET_DAY
46#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
47#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
48#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
49#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000050
51/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
53 ((o)->data[1] = ((v) & 0x00ff)))
54#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
55#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000056
57/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
59#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
60#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
61#define DATE_SET_MICROSECOND(o, v) \
62 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
63 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
64 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000065
66/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
68#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
69#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
70#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
71#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
72#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
73#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
74#define TIME_SET_MICROSECOND(o, v) \
75 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
76 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
77 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000078
79/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
81#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
82#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084#define SET_TD_DAYS(o, v) ((o)->days = (v))
85#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000086#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
87
Tim Petersa032d2e2003-01-11 00:15:54 +000088/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
89 * p->hastzinfo.
90 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +000091#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
92#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
93 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
94#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
95 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +000096/* M is a char or int claiming to be a valid month. The macro is equivalent
97 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +000099 */
100#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
101
Tim Peters2a799bf2002-12-16 20:18:38 +0000102/* Forward declarations. */
103static PyTypeObject PyDateTime_DateType;
104static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000105static PyTypeObject PyDateTime_DeltaType;
106static PyTypeObject PyDateTime_TimeType;
107static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000108static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000109
110/* ---------------------------------------------------------------------------
111 * Math utilities.
112 */
113
114/* k = i+j overflows iff k differs in sign from both inputs,
115 * iff k^i has sign bit set and k^j has sign bit set,
116 * iff (k^i)&(k^j) has sign bit set.
117 */
118#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000120
121/* Compute Python divmod(x, y), returning the quotient and storing the
122 * remainder into *r. The quotient is the floor of x/y, and that's
123 * the real point of this. C will probably truncate instead (C99
124 * requires truncation; C89 left it implementation-defined).
125 * Simplification: we *require* that y > 0 here. That's appropriate
126 * for all the uses made of it. This simplifies the code and makes
127 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
128 * overflow case).
129 */
130static int
131divmod(int x, int y, int *r)
132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 assert(y > 0);
136 quo = x / y;
137 *r = x - quo * y;
138 if (*r < 0) {
139 --quo;
140 *r += y;
141 }
142 assert(0 <= *r && *r < y);
143 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000144}
145
Tim Peters5d644dd2003-01-02 16:32:54 +0000146/* Round a double to the nearest long. |x| must be small enough to fit
147 * in a C long; this is not checked.
148 */
149static long
150round_to_long(double x)
151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 if (x >= 0.0)
153 x = floor(x + 0.5);
154 else
155 x = ceil(x - 0.5);
156 return (long)x;
Tim Peters5d644dd2003-01-02 16:32:54 +0000157}
158
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000159/* Nearest integer to m / n for integers m and n. Half-integer results
160 * are rounded to even.
161 */
162static PyObject *
163divide_nearest(PyObject *m, PyObject *n)
164{
165 PyObject *result;
166 PyObject *temp;
167
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000168 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000169 if (temp == NULL)
170 return NULL;
171 result = PyTuple_GET_ITEM(temp, 0);
172 Py_INCREF(result);
173 Py_DECREF(temp);
174
175 return result;
176}
177
Tim Peters2a799bf2002-12-16 20:18:38 +0000178/* ---------------------------------------------------------------------------
179 * General calendrical helper functions
180 */
181
182/* For each month ordinal in 1..12, the number of days in that month,
183 * and the number of days before that month in the same year. These
184 * are correct for non-leap years only.
185 */
186static int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 0, /* unused; this vector uses 1-based indexing */
188 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000189};
190
191static int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 0, /* unused; this vector uses 1-based indexing */
193 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000194};
195
196/* year -> 1 if leap year, else 0. */
197static int
198is_leap(int year)
199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 /* Cast year to unsigned. The result is the same either way, but
201 * C can generate faster code for unsigned mod than for signed
202 * mod (especially for % 4 -- a good compiler should just grab
203 * the last 2 bits when the LHS is unsigned).
204 */
205 const unsigned int ayear = (unsigned int)year;
206 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000207}
208
209/* year, month -> number of days in that month in that year */
210static int
211days_in_month(int year, int month)
212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 assert(month >= 1);
214 assert(month <= 12);
215 if (month == 2 && is_leap(year))
216 return 29;
217 else
218 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000219}
220
221/* year, month -> number of days in year preceeding first day of month */
222static int
223days_before_month(int year, int month)
224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 assert(month >= 1);
228 assert(month <= 12);
229 days = _days_before_month[month];
230 if (month > 2 && is_leap(year))
231 ++days;
232 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000233}
234
235/* year -> number of days before January 1st of year. Remember that we
236 * start with year 1, so days_before_year(1) == 0.
237 */
238static int
239days_before_year(int year)
240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 int y = year - 1;
242 /* This is incorrect if year <= 0; we really want the floor
243 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000244 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000246 assert (year >= 1);
247 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000248}
249
250/* Number of days in 4, 100, and 400 year cycles. That these have
251 * the correct values is asserted in the module init function.
252 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253#define DI4Y 1461 /* days_before_year(5); days in 4 years */
254#define DI100Y 36524 /* days_before_year(101); days in 100 years */
255#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000256
257/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
258static void
259ord_to_ymd(int ordinal, int *year, int *month, int *day)
260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
264 * leap years repeats exactly every 400 years. The basic strategy is
265 * to find the closest 400-year boundary at or before ordinal, then
266 * work with the offset from that boundary to ordinal. Life is much
267 * clearer if we subtract 1 from ordinal first -- then the values
268 * of ordinal at 400-year boundaries are exactly those divisible
269 * by DI400Y:
270 *
271 * D M Y n n-1
272 * -- --- ---- ---------- ----------------
273 * 31 Dec -400 -DI400Y -DI400Y -1
274 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
275 * ...
276 * 30 Dec 000 -1 -2
277 * 31 Dec 000 0 -1
278 * 1 Jan 001 1 0 400-year boundary
279 * 2 Jan 001 2 1
280 * 3 Jan 001 3 2
281 * ...
282 * 31 Dec 400 DI400Y DI400Y -1
283 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
284 */
285 assert(ordinal >= 1);
286 --ordinal;
287 n400 = ordinal / DI400Y;
288 n = ordinal % DI400Y;
289 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 /* Now n is the (non-negative) offset, in days, from January 1 of
292 * year, to the desired date. Now compute how many 100-year cycles
293 * precede n.
294 * Note that it's possible for n100 to equal 4! In that case 4 full
295 * 100-year cycles precede the desired day, which implies the
296 * desired day is December 31 at the end of a 400-year cycle.
297 */
298 n100 = n / DI100Y;
299 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 /* Now compute how many 4-year cycles precede it. */
302 n4 = n / DI4Y;
303 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 /* And now how many single years. Again n1 can be 4, and again
306 * meaning that the desired day is December 31 at the end of the
307 * 4-year cycle.
308 */
309 n1 = n / 365;
310 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 *year += n100 * 100 + n4 * 4 + n1;
313 if (n1 == 4 || n100 == 4) {
314 assert(n == 0);
315 *year -= 1;
316 *month = 12;
317 *day = 31;
318 return;
319 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 /* Now the year is correct, and n is the offset from January 1. We
322 * find the month via an estimate that's either exact or one too
323 * large.
324 */
325 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
326 assert(leapyear == is_leap(*year));
327 *month = (n + 50) >> 5;
328 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
329 if (preceding > n) {
330 /* estimate is too large */
331 *month -= 1;
332 preceding -= days_in_month(*year, *month);
333 }
334 n -= preceding;
335 assert(0 <= n);
336 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000339}
340
341/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
342static int
343ymd_to_ord(int year, int month, int day)
344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000346}
347
348/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
349static int
350weekday(int year, int month, int day)
351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000353}
354
355/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
356 * first calendar week containing a Thursday.
357 */
358static int
359iso_week1_monday(int year)
360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
362 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
363 int first_weekday = (first_day + 6) % 7;
364 /* ordinal of closest Monday at or before 1/1 */
365 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
368 week1_monday += 7;
369 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000370}
371
372/* ---------------------------------------------------------------------------
373 * Range checkers.
374 */
375
376/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
377 * If not, raise OverflowError and return -1.
378 */
379static int
380check_delta_day_range(int days)
381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
383 return 0;
384 PyErr_Format(PyExc_OverflowError,
385 "days=%d; must have magnitude <= %d",
386 days, MAX_DELTA_DAYS);
387 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000388}
389
390/* Check that date arguments are in range. Return 0 if they are. If they
391 * aren't, raise ValueError and return -1.
392 */
393static int
394check_date_args(int year, int month, int day)
395{
396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 if (year < MINYEAR || year > MAXYEAR) {
398 PyErr_SetString(PyExc_ValueError,
399 "year is out of range");
400 return -1;
401 }
402 if (month < 1 || month > 12) {
403 PyErr_SetString(PyExc_ValueError,
404 "month must be in 1..12");
405 return -1;
406 }
407 if (day < 1 || day > days_in_month(year, month)) {
408 PyErr_SetString(PyExc_ValueError,
409 "day is out of range for month");
410 return -1;
411 }
412 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000413}
414
415/* Check that time arguments are in range. Return 0 if they are. If they
416 * aren't, raise ValueError and return -1.
417 */
418static int
419check_time_args(int h, int m, int s, int us)
420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 if (h < 0 || h > 23) {
422 PyErr_SetString(PyExc_ValueError,
423 "hour must be in 0..23");
424 return -1;
425 }
426 if (m < 0 || m > 59) {
427 PyErr_SetString(PyExc_ValueError,
428 "minute must be in 0..59");
429 return -1;
430 }
431 if (s < 0 || s > 59) {
432 PyErr_SetString(PyExc_ValueError,
433 "second must be in 0..59");
434 return -1;
435 }
436 if (us < 0 || us > 999999) {
437 PyErr_SetString(PyExc_ValueError,
438 "microsecond must be in 0..999999");
439 return -1;
440 }
441 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000442}
443
444/* ---------------------------------------------------------------------------
445 * Normalization utilities.
446 */
447
448/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
449 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
450 * at least factor, enough of *lo is converted into "hi" units so that
451 * 0 <= *lo < factor. The input values must be such that int overflow
452 * is impossible.
453 */
454static void
455normalize_pair(int *hi, int *lo, int factor)
456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 assert(factor > 0);
458 assert(lo != hi);
459 if (*lo < 0 || *lo >= factor) {
460 const int num_hi = divmod(*lo, factor, lo);
461 const int new_hi = *hi + num_hi;
462 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
463 *hi = new_hi;
464 }
465 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000466}
467
468/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 * 0 <= *s < 24*3600
470 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000471 * The input values must be such that the internals don't overflow.
472 * The way this routine is used, we don't get close.
473 */
474static void
475normalize_d_s_us(int *d, int *s, int *us)
476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 if (*us < 0 || *us >= 1000000) {
478 normalize_pair(s, us, 1000000);
479 /* |s| can't be bigger than about
480 * |original s| + |original us|/1000000 now.
481 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 }
484 if (*s < 0 || *s >= 24*3600) {
485 normalize_pair(d, s, 24*3600);
486 /* |d| can't be bigger than about
487 * |original d| +
488 * (|original s| + |original us|/1000000) / (24*3600) now.
489 */
490 }
491 assert(0 <= *s && *s < 24*3600);
492 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000493}
494
495/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 * 1 <= *m <= 12
497 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000498 * The input values must be such that the internals don't overflow.
499 * The way this routine is used, we don't get close.
500 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000501static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000502normalize_y_m_d(int *y, int *m, int *d)
503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000505
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000506 /* In actual use, m is always the month component extracted from a
507 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 /* Now only day can be out of bounds (year may also be out of bounds
513 * for a datetime object, but we don't care about that here).
514 * If day is out of bounds, what to do is arguable, but at least the
515 * method here is principled and explainable.
516 */
517 dim = days_in_month(*y, *m);
518 if (*d < 1 || *d > dim) {
519 /* Move day-1 days from the first of the month. First try to
520 * get off cheap if we're only one day out of range
521 * (adjustments for timezone alone can't be worse than that).
522 */
523 if (*d == 0) {
524 --*m;
525 if (*m > 0)
526 *d = days_in_month(*y, *m);
527 else {
528 --*y;
529 *m = 12;
530 *d = 31;
531 }
532 }
533 else if (*d == dim + 1) {
534 /* move forward a day */
535 ++*m;
536 *d = 1;
537 if (*m > 12) {
538 *m = 1;
539 ++*y;
540 }
541 }
542 else {
543 int ordinal = ymd_to_ord(*y, *m, 1) +
544 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000545 if (ordinal < 1 || ordinal > MAXORDINAL) {
546 goto error;
547 } else {
548 ord_to_ymd(ordinal, y, m, d);
549 return 0;
550 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 }
552 }
553 assert(*m > 0);
554 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000555 if (MINYEAR <= *y && *y <= MAXYEAR)
556 return 0;
557 error:
558 PyErr_SetString(PyExc_OverflowError,
559 "date value out of range");
560 return -1;
561
Tim Peters2a799bf2002-12-16 20:18:38 +0000562}
563
564/* Fiddle out-of-bounds months and days so that the result makes some kind
565 * of sense. The parameters are both inputs and outputs. Returns < 0 on
566 * failure, where failure means the adjusted year is out of bounds.
567 */
568static int
569normalize_date(int *year, int *month, int *day)
570{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000571 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000572}
573
574/* Force all the datetime fields into range. The parameters are both
575 * inputs and outputs. Returns < 0 on error.
576 */
577static int
578normalize_datetime(int *year, int *month, int *day,
579 int *hour, int *minute, int *second,
580 int *microsecond)
581{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 normalize_pair(second, microsecond, 1000000);
583 normalize_pair(minute, second, 60);
584 normalize_pair(hour, minute, 60);
585 normalize_pair(day, hour, 24);
586 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000587}
588
589/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000590 * Basic object allocation: tp_alloc implementations. These allocate
591 * Python objects of the right size and type, and do the Python object-
592 * initialization bit. If there's not enough memory, they return NULL after
593 * setting MemoryError. All data members remain uninitialized trash.
594 *
595 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000596 * member is needed. This is ugly, imprecise, and possibly insecure.
597 * tp_basicsize for the time and datetime types is set to the size of the
598 * struct that has room for the tzinfo member, so subclasses in Python will
599 * allocate enough space for a tzinfo member whether or not one is actually
600 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
601 * part is that PyType_GenericAlloc() (which subclasses in Python end up
602 * using) just happens today to effectively ignore the nitems argument
603 * when tp_itemsize is 0, which it is for these type objects. If that
604 * changes, perhaps the callers of tp_alloc slots in this file should
605 * be changed to force a 0 nitems argument unless the type being allocated
606 * is a base type implemented in this file (so that tp_alloc is time_alloc
607 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000608 */
609
610static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000611time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 self = (PyObject *)
616 PyObject_MALLOC(aware ?
617 sizeof(PyDateTime_Time) :
618 sizeof(_PyDateTime_BaseTime));
619 if (self == NULL)
620 return (PyObject *)PyErr_NoMemory();
621 PyObject_INIT(self, type);
622 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000623}
624
625static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000626datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 self = (PyObject *)
631 PyObject_MALLOC(aware ?
632 sizeof(PyDateTime_DateTime) :
633 sizeof(_PyDateTime_BaseDateTime));
634 if (self == NULL)
635 return (PyObject *)PyErr_NoMemory();
636 PyObject_INIT(self, type);
637 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000638}
639
640/* ---------------------------------------------------------------------------
641 * Helpers for setting object fields. These work on pointers to the
642 * appropriate base class.
643 */
644
645/* For date and datetime. */
646static void
647set_date_fields(PyDateTime_Date *self, int y, int m, int d)
648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 self->hashcode = -1;
650 SET_YEAR(self, y);
651 SET_MONTH(self, m);
652 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000653}
654
655/* ---------------------------------------------------------------------------
656 * Create various objects, mostly without range checking.
657 */
658
659/* Create a date instance with no range checking. */
660static PyObject *
661new_date_ex(int year, int month, int day, PyTypeObject *type)
662{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
666 if (self != NULL)
667 set_date_fields(self, year, month, day);
668 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000669}
670
671#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000673
674/* Create a datetime instance with no range checking. */
675static PyObject *
676new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000678{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 PyDateTime_DateTime *self;
680 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
683 if (self != NULL) {
684 self->hastzinfo = aware;
685 set_date_fields((PyDateTime_Date *)self, year, month, day);
686 DATE_SET_HOUR(self, hour);
687 DATE_SET_MINUTE(self, minute);
688 DATE_SET_SECOND(self, second);
689 DATE_SET_MICROSECOND(self, usecond);
690 if (aware) {
691 Py_INCREF(tzinfo);
692 self->tzinfo = tzinfo;
693 }
694 }
695 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000696}
697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
699 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
700 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000701
702/* Create a time instance with no range checking. */
703static PyObject *
704new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000706{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 PyDateTime_Time *self;
708 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
711 if (self != NULL) {
712 self->hastzinfo = aware;
713 self->hashcode = -1;
714 TIME_SET_HOUR(self, hour);
715 TIME_SET_MINUTE(self, minute);
716 TIME_SET_SECOND(self, second);
717 TIME_SET_MICROSECOND(self, usecond);
718 if (aware) {
719 Py_INCREF(tzinfo);
720 self->tzinfo = tzinfo;
721 }
722 }
723 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000724}
725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726#define new_time(hh, mm, ss, us, tzinfo) \
727 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000728
729/* Create a timedelta instance. Normalize the members iff normalize is
730 * true. Passing false is a speed optimization, if you know for sure
731 * that seconds and microseconds are already in their proper ranges. In any
732 * case, raises OverflowError and returns NULL if the normalized days is out
733 * of range).
734 */
735static PyObject *
736new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000738{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 if (normalize)
742 normalize_d_s_us(&days, &seconds, &microseconds);
743 assert(0 <= seconds && seconds < 24*3600);
744 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 if (check_delta_day_range(days) < 0)
747 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
750 if (self != NULL) {
751 self->hashcode = -1;
752 SET_TD_DAYS(self, days);
753 SET_TD_SECONDS(self, seconds);
754 SET_TD_MICROSECONDS(self, microseconds);
755 }
756 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000757}
758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759#define new_delta(d, s, us, normalize) \
760 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000761
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000762
763typedef struct
764{
765 PyObject_HEAD
766 PyObject *offset;
767 PyObject *name;
768} PyDateTime_TimeZone;
769
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000770PyObject *PyDateTime_TimeZone_UTC;
771
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000772/* Create new timezone instance checking offset range. This
773 function does not check the name argument. Caller must assure
774 that offset is a timedelta instance and name is either NULL
775 or a unicode object. */
776static PyObject *
777new_timezone(PyObject *offset, PyObject *name)
778{
779 PyDateTime_TimeZone *self;
780 PyTypeObject *type = &PyDateTime_TimeZoneType;
781
782 assert(offset != NULL);
783 assert(PyDelta_Check(offset));
784 assert(name == NULL || PyUnicode_Check(name));
785
786 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
787 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
788 " representing a whole number of minutes");
789 return NULL;
790 }
791 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
792 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
793 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
794 " strictly between -timedelta(hours=24) and"
795 " timedelta(hours=24).");
796 return NULL;
797 }
798
799 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
800 if (self == NULL) {
801 return NULL;
802 }
803 Py_INCREF(offset);
804 self->offset = offset;
805 Py_XINCREF(name);
806 self->name = name;
807 return (PyObject *)self;
808}
809
Tim Petersb0c854d2003-05-17 15:57:00 +0000810/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000811 * tzinfo helpers.
812 */
813
Tim Peters855fe882002-12-22 03:43:39 +0000814/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
815 * raise TypeError and return -1.
816 */
817static int
818check_tzinfo_subclass(PyObject *p)
819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 if (p == Py_None || PyTZInfo_Check(p))
821 return 0;
822 PyErr_Format(PyExc_TypeError,
823 "tzinfo argument must be None or of a tzinfo subclass, "
824 "not type '%s'",
825 Py_TYPE(p)->tp_name);
826 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000827}
828
Tim Peters2a799bf2002-12-16 20:18:38 +0000829/* If self has a tzinfo member, return a BORROWED reference to it. Else
830 * return NULL, which is NOT AN ERROR. There are no error returns here,
831 * and the caller must not decref the result.
832 */
833static PyObject *
834get_tzinfo_member(PyObject *self)
835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 if (PyDateTime_Check(self) && HASTZINFO(self))
839 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
840 else if (PyTime_Check(self) && HASTZINFO(self))
841 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000844}
845
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000846/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
847 * be an instance of the tzinfo class. If the method returns None, this
848 * returns None. If the method doesn't return None or timedelta, TypeError is
849 * raised and this returns NULL. If it returns a timedelta and the value is
850 * out of range or isn't a whole number of minutes, ValueError is raised and
851 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000852 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000853static PyObject *
854call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000855{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000856 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000859 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000861
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000862 if (tzinfo == Py_None)
863 Py_RETURN_NONE;
864 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
865 if (offset == Py_None || offset == NULL)
866 return offset;
867 if (PyDelta_Check(offset)) {
868 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
869 Py_DECREF(offset);
870 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
871 " representing a whole number of minutes");
872 return NULL;
873 }
874 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
875 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
876 Py_DECREF(offset);
877 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
878 " strictly between -timedelta(hours=24) and"
879 " timedelta(hours=24).");
880 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 }
882 }
883 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000884 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000885 PyErr_Format(PyExc_TypeError,
886 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000887 "timedelta, not '%.200s'",
888 name, Py_TYPE(offset)->tp_name);
889 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000891
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000892 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000893}
894
895/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
896 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
897 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000898 * doesn't return None or timedelta, TypeError is raised and this returns -1.
899 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
900 * # of minutes), ValueError is raised and this returns -1. Else *none is
901 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000902 */
Tim Peters855fe882002-12-22 03:43:39 +0000903static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000904call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
905{
906 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000907}
908
Tim Peters2a799bf2002-12-16 20:18:38 +0000909/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
910 * result. tzinfo must be an instance of the tzinfo class. If dst()
911 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000912 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000913 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000914 * ValueError is raised and this returns -1. Else *none is set to 0 and
915 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000916 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000917static PyObject *
918call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000919{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000920 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000921}
922
Tim Petersbad8ff02002-12-30 20:52:32 +0000923/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000924 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000925 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000926 * returns NULL. If the result is a string, we ensure it is a Unicode
927 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000928 */
929static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000930call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 assert(tzinfo != NULL);
935 assert(check_tzinfo_subclass(tzinfo) >= 0);
936 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000939 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000940
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000941 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
942
943 if (result == NULL || result == Py_None)
944 return result;
945
946 if (!PyUnicode_Check(result)) {
947 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
948 "return None or a string, not '%s'",
949 Py_TYPE(result)->tp_name);
950 Py_DECREF(result);
951 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000953
954 return result;
Tim Peters00237032002-12-27 02:21:51 +0000955}
956
Tim Peters2a799bf2002-12-16 20:18:38 +0000957/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
958 * stuff
959 * ", tzinfo=" + repr(tzinfo)
960 * before the closing ")".
961 */
962static PyObject *
963append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
964{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 assert(PyUnicode_Check(repr));
968 assert(tzinfo);
969 if (tzinfo == Py_None)
970 return repr;
971 /* Get rid of the trailing ')'. */
972 assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
973 temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
974 PyUnicode_GET_SIZE(repr) - 1);
975 Py_DECREF(repr);
976 if (temp == NULL)
977 return NULL;
978 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
979 Py_DECREF(temp);
980 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +0000981}
982
983/* ---------------------------------------------------------------------------
984 * String format helpers.
985 */
986
987static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +0000988format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 static const char *DayNames[] = {
991 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
992 };
993 static const char *MonthNames[] = {
994 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
995 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
996 };
Tim Peters2a799bf2002-12-16 20:18:38 +0000997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +0000999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1001 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1002 GET_DAY(date), hours, minutes, seconds,
1003 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001004}
1005
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001006static PyObject *delta_negative(PyDateTime_Delta *self);
1007
Tim Peters2a799bf2002-12-16 20:18:38 +00001008/* Add an hours & minutes UTC offset string to buf. buf has no more than
1009 * buflen bytes remaining. The UTC offset is gotten by calling
1010 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1011 * *buf, and that's all. Else the returned value is checked for sanity (an
1012 * integer in range), and if that's OK it's converted to an hours & minutes
1013 * string of the form
1014 * sign HH sep MM
1015 * Returns 0 if everything is OK. If the return value from utcoffset() is
1016 * bogus, an appropriate exception is set and -1 is returned.
1017 */
1018static int
Tim Peters328fff72002-12-20 01:31:27 +00001019format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001021{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001022 PyObject *offset;
1023 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001027
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001028 offset = call_utcoffset(tzinfo, tzinfoarg);
1029 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001031 if (offset == Py_None) {
1032 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 *buf = '\0';
1034 return 0;
1035 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001036 /* Offset is normalized, so it is negative if days < 0 */
1037 if (GET_TD_DAYS(offset) < 0) {
1038 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001040 offset = delta_negative((PyDateTime_Delta *)offset);
1041 Py_DECREF(temp);
1042 if (offset == NULL)
1043 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001045 else {
1046 sign = '+';
1047 }
1048 /* Offset is not negative here. */
1049 seconds = GET_TD_SECONDS(offset);
1050 Py_DECREF(offset);
1051 minutes = divmod(seconds, 60, &seconds);
1052 hours = divmod(minutes, 60, &minutes);
1053 assert(seconds == 0);
1054 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001058}
1059
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001060static PyObject *
1061make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1062{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 PyObject *temp;
1064 PyObject *tzinfo = get_tzinfo_member(object);
1065 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1066 if (Zreplacement == NULL)
1067 return NULL;
1068 if (tzinfo == Py_None || tzinfo == NULL)
1069 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 assert(tzinfoarg != NULL);
1072 temp = call_tzname(tzinfo, tzinfoarg);
1073 if (temp == NULL)
1074 goto Error;
1075 if (temp == Py_None) {
1076 Py_DECREF(temp);
1077 return Zreplacement;
1078 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 assert(PyUnicode_Check(temp));
1081 /* Since the tzname is getting stuffed into the
1082 * format, we have to double any % signs so that
1083 * strftime doesn't treat them as format codes.
1084 */
1085 Py_DECREF(Zreplacement);
1086 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1087 Py_DECREF(temp);
1088 if (Zreplacement == NULL)
1089 return NULL;
1090 if (!PyUnicode_Check(Zreplacement)) {
1091 PyErr_SetString(PyExc_TypeError,
1092 "tzname.replace() did not return a string");
1093 goto Error;
1094 }
1095 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001096
1097 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 Py_DECREF(Zreplacement);
1099 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001100}
1101
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001102static PyObject *
1103make_freplacement(PyObject *object)
1104{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 char freplacement[64];
1106 if (PyTime_Check(object))
1107 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1108 else if (PyDateTime_Check(object))
1109 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1110 else
1111 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001114}
1115
Tim Peters2a799bf2002-12-16 20:18:38 +00001116/* I sure don't want to reproduce the strftime code from the time module,
1117 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001118 * giving special meanings to the %z, %Z and %f format codes via a
1119 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001120 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1121 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001122 */
1123static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001124wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1130 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1131 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 const char *pin; /* pointer to next char in input format */
1134 Py_ssize_t flen; /* length of input format */
1135 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 PyObject *newfmt = NULL; /* py string, the output format */
1138 char *pnew; /* pointer to available byte in output format */
1139 size_t totalnew; /* number bytes total in output format buffer,
1140 exclusive of trailing \0 */
1141 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 const char *ptoappend; /* ptr to string to append to output buffer */
1144 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 assert(object && format && timetuple);
1147 assert(PyUnicode_Check(format));
1148 /* Convert the input format to a C string and size */
1149 pin = _PyUnicode_AsStringAndSize(format, &flen);
1150 if (!pin)
1151 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 /* Give up if the year is before 1900.
1154 * Python strftime() plays games with the year, and different
1155 * games depending on whether envar PYTHON2K is set. This makes
1156 * years before 1900 a nightmare, even if the platform strftime
1157 * supports them (and not all do).
1158 * We could get a lot farther here by avoiding Python's strftime
1159 * wrapper and calling the C strftime() directly, but that isn't
1160 * an option in the Python implementation of this module.
1161 */
1162 {
1163 long year;
1164 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1165 if (pyyear == NULL) return NULL;
1166 assert(PyLong_Check(pyyear));
1167 year = PyLong_AsLong(pyyear);
1168 Py_DECREF(pyyear);
1169 if (year < 1900) {
1170 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1171 "1900; the datetime strftime() "
1172 "methods require year >= 1900",
1173 year);
1174 return NULL;
1175 }
1176 }
Tim Petersd6844152002-12-22 20:58:42 +00001177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 /* Scan the input format, looking for %z/%Z/%f escapes, building
1179 * a new format. Since computing the replacements for those codes
1180 * is expensive, don't unless they're actually used.
1181 */
1182 if (flen > INT_MAX - 1) {
1183 PyErr_NoMemory();
1184 goto Done;
1185 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 totalnew = flen + 1; /* realistic if no %z/%Z */
1188 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1189 if (newfmt == NULL) goto Done;
1190 pnew = PyBytes_AsString(newfmt);
1191 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 while ((ch = *pin++) != '\0') {
1194 if (ch != '%') {
1195 ptoappend = pin - 1;
1196 ntoappend = 1;
1197 }
1198 else if ((ch = *pin++) == '\0') {
1199 /* There's a lone trailing %; doesn't make sense. */
1200 PyErr_SetString(PyExc_ValueError, "strftime format "
1201 "ends with raw %");
1202 goto Done;
1203 }
1204 /* A % has been seen and ch is the character after it. */
1205 else if (ch == 'z') {
1206 if (zreplacement == NULL) {
1207 /* format utcoffset */
1208 char buf[100];
1209 PyObject *tzinfo = get_tzinfo_member(object);
1210 zreplacement = PyBytes_FromStringAndSize("", 0);
1211 if (zreplacement == NULL) goto Done;
1212 if (tzinfo != Py_None && tzinfo != NULL) {
1213 assert(tzinfoarg != NULL);
1214 if (format_utcoffset(buf,
1215 sizeof(buf),
1216 "",
1217 tzinfo,
1218 tzinfoarg) < 0)
1219 goto Done;
1220 Py_DECREF(zreplacement);
1221 zreplacement =
1222 PyBytes_FromStringAndSize(buf,
1223 strlen(buf));
1224 if (zreplacement == NULL)
1225 goto Done;
1226 }
1227 }
1228 assert(zreplacement != NULL);
1229 ptoappend = PyBytes_AS_STRING(zreplacement);
1230 ntoappend = PyBytes_GET_SIZE(zreplacement);
1231 }
1232 else if (ch == 'Z') {
1233 /* format tzname */
1234 if (Zreplacement == NULL) {
1235 Zreplacement = make_Zreplacement(object,
1236 tzinfoarg);
1237 if (Zreplacement == NULL)
1238 goto Done;
1239 }
1240 assert(Zreplacement != NULL);
1241 assert(PyUnicode_Check(Zreplacement));
1242 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1243 &ntoappend);
1244 ntoappend = Py_SIZE(Zreplacement);
1245 }
1246 else if (ch == 'f') {
1247 /* format microseconds */
1248 if (freplacement == NULL) {
1249 freplacement = make_freplacement(object);
1250 if (freplacement == NULL)
1251 goto Done;
1252 }
1253 assert(freplacement != NULL);
1254 assert(PyBytes_Check(freplacement));
1255 ptoappend = PyBytes_AS_STRING(freplacement);
1256 ntoappend = PyBytes_GET_SIZE(freplacement);
1257 }
1258 else {
1259 /* percent followed by neither z nor Z */
1260 ptoappend = pin - 2;
1261 ntoappend = 2;
1262 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 /* Append the ntoappend chars starting at ptoappend to
1265 * the new format.
1266 */
1267 if (ntoappend == 0)
1268 continue;
1269 assert(ptoappend != NULL);
1270 assert(ntoappend > 0);
1271 while (usednew + ntoappend > totalnew) {
1272 size_t bigger = totalnew << 1;
1273 if ((bigger >> 1) != totalnew) { /* overflow */
1274 PyErr_NoMemory();
1275 goto Done;
1276 }
1277 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1278 goto Done;
1279 totalnew = bigger;
1280 pnew = PyBytes_AsString(newfmt) + usednew;
1281 }
1282 memcpy(pnew, ptoappend, ntoappend);
1283 pnew += ntoappend;
1284 usednew += ntoappend;
1285 assert(usednew <= totalnew);
1286 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1289 goto Done;
1290 {
1291 PyObject *format;
1292 PyObject *time = PyImport_ImportModuleNoBlock("time");
1293 if (time == NULL)
1294 goto Done;
1295 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1296 if (format != NULL) {
1297 result = PyObject_CallMethod(time, "strftime", "OO",
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001298 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 Py_DECREF(format);
1300 }
1301 Py_DECREF(time);
1302 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001303 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 Py_XDECREF(freplacement);
1305 Py_XDECREF(zreplacement);
1306 Py_XDECREF(Zreplacement);
1307 Py_XDECREF(newfmt);
1308 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001309}
1310
Tim Peters2a799bf2002-12-16 20:18:38 +00001311/* ---------------------------------------------------------------------------
1312 * Wrap functions from the time module. These aren't directly available
1313 * from C. Perhaps they should be.
1314 */
1315
1316/* Call time.time() and return its result (a Python float). */
1317static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001318time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 PyObject *result = NULL;
1321 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 if (time != NULL) {
1324 result = PyObject_CallMethod(time, "time", "()");
1325 Py_DECREF(time);
1326 }
1327 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001328}
1329
1330/* Build a time.struct_time. The weekday and day number are automatically
1331 * computed from the y,m,d args.
1332 */
1333static PyObject *
1334build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 PyObject *time;
1337 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 time = PyImport_ImportModuleNoBlock("time");
1340 if (time != NULL) {
1341 result = PyObject_CallMethod(time, "struct_time",
1342 "((iiiiiiiii))",
1343 y, m, d,
1344 hh, mm, ss,
1345 weekday(y, m, d),
1346 days_before_month(y, m) + d,
1347 dstflag);
1348 Py_DECREF(time);
1349 }
1350 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001351}
1352
1353/* ---------------------------------------------------------------------------
1354 * Miscellaneous helpers.
1355 */
1356
Mark Dickinsone94c6792009-02-02 20:36:42 +00001357/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001358 * The comparisons here all most naturally compute a cmp()-like result.
1359 * This little helper turns that into a bool result for rich comparisons.
1360 */
1361static PyObject *
1362diff_to_bool(int diff, int op)
1363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 PyObject *result;
1365 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 switch (op) {
1368 case Py_EQ: istrue = diff == 0; break;
1369 case Py_NE: istrue = diff != 0; break;
1370 case Py_LE: istrue = diff <= 0; break;
1371 case Py_GE: istrue = diff >= 0; break;
1372 case Py_LT: istrue = diff < 0; break;
1373 case Py_GT: istrue = diff > 0; break;
1374 default:
1375 assert(! "op unknown");
1376 istrue = 0; /* To shut up compiler */
1377 }
1378 result = istrue ? Py_True : Py_False;
1379 Py_INCREF(result);
1380 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001381}
1382
Tim Peters07534a62003-02-07 22:50:28 +00001383/* Raises a "can't compare" TypeError and returns NULL. */
1384static PyObject *
1385cmperror(PyObject *a, PyObject *b)
1386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 PyErr_Format(PyExc_TypeError,
1388 "can't compare %s to %s",
1389 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1390 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001391}
1392
Tim Peters2a799bf2002-12-16 20:18:38 +00001393/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001394 * Cached Python objects; these are set by the module init function.
1395 */
1396
1397/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398static PyObject *us_per_us = NULL; /* 1 */
1399static PyObject *us_per_ms = NULL; /* 1000 */
1400static PyObject *us_per_second = NULL; /* 1000000 */
1401static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1402static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1403static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1404static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001405static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1406
Tim Peters2a799bf2002-12-16 20:18:38 +00001407/* ---------------------------------------------------------------------------
1408 * Class implementations.
1409 */
1410
1411/*
1412 * PyDateTime_Delta implementation.
1413 */
1414
1415/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001417 * as a Python int or long.
1418 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1419 * due to ubiquitous overflow possibilities.
1420 */
1421static PyObject *
1422delta_to_microseconds(PyDateTime_Delta *self)
1423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 PyObject *x1 = NULL;
1425 PyObject *x2 = NULL;
1426 PyObject *x3 = NULL;
1427 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1430 if (x1 == NULL)
1431 goto Done;
1432 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1433 if (x2 == NULL)
1434 goto Done;
1435 Py_DECREF(x1);
1436 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 /* x2 has days in seconds */
1439 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1440 if (x1 == NULL)
1441 goto Done;
1442 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1443 if (x3 == NULL)
1444 goto Done;
1445 Py_DECREF(x1);
1446 Py_DECREF(x2);
1447 x1 = x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 /* x3 has days+seconds in seconds */
1450 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1451 if (x1 == NULL)
1452 goto Done;
1453 Py_DECREF(x3);
1454 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 /* x1 has days+seconds in us */
1457 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1458 if (x2 == NULL)
1459 goto Done;
1460 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001461
1462Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 Py_XDECREF(x1);
1464 Py_XDECREF(x2);
1465 Py_XDECREF(x3);
1466 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001467}
1468
1469/* Convert a number of us (as a Python int or long) to a timedelta.
1470 */
1471static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001472microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001473{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 int us;
1475 int s;
1476 int d;
1477 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 PyObject *tuple = NULL;
1480 PyObject *num = NULL;
1481 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 tuple = PyNumber_Divmod(pyus, us_per_second);
1484 if (tuple == NULL)
1485 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 num = PyTuple_GetItem(tuple, 1); /* us */
1488 if (num == NULL)
1489 goto Done;
1490 temp = PyLong_AsLong(num);
1491 num = NULL;
1492 if (temp == -1 && PyErr_Occurred())
1493 goto Done;
1494 assert(0 <= temp && temp < 1000000);
1495 us = (int)temp;
1496 if (us < 0) {
1497 /* The divisor was positive, so this must be an error. */
1498 assert(PyErr_Occurred());
1499 goto Done;
1500 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1503 if (num == NULL)
1504 goto Done;
1505 Py_INCREF(num);
1506 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 tuple = PyNumber_Divmod(num, seconds_per_day);
1509 if (tuple == NULL)
1510 goto Done;
1511 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 num = PyTuple_GetItem(tuple, 1); /* seconds */
1514 if (num == NULL)
1515 goto Done;
1516 temp = PyLong_AsLong(num);
1517 num = NULL;
1518 if (temp == -1 && PyErr_Occurred())
1519 goto Done;
1520 assert(0 <= temp && temp < 24*3600);
1521 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 if (s < 0) {
1524 /* The divisor was positive, so this must be an error. */
1525 assert(PyErr_Occurred());
1526 goto Done;
1527 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1530 if (num == NULL)
1531 goto Done;
1532 Py_INCREF(num);
1533 temp = PyLong_AsLong(num);
1534 if (temp == -1 && PyErr_Occurred())
1535 goto Done;
1536 d = (int)temp;
1537 if ((long)d != temp) {
1538 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1539 "large to fit in a C int");
1540 goto Done;
1541 }
1542 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001543
1544Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 Py_XDECREF(tuple);
1546 Py_XDECREF(num);
1547 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001548}
1549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550#define microseconds_to_delta(pymicros) \
1551 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001552
Tim Peters2a799bf2002-12-16 20:18:38 +00001553static PyObject *
1554multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 PyObject *pyus_in;
1557 PyObject *pyus_out;
1558 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 pyus_in = delta_to_microseconds(delta);
1561 if (pyus_in == NULL)
1562 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1565 Py_DECREF(pyus_in);
1566 if (pyus_out == NULL)
1567 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 result = microseconds_to_delta(pyus_out);
1570 Py_DECREF(pyus_out);
1571 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001572}
1573
1574static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001575multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1576{
1577 PyObject *result = NULL;
1578 PyObject *pyus_in = NULL, *temp, *pyus_out;
1579 PyObject *ratio = NULL;
1580
1581 pyus_in = delta_to_microseconds(delta);
1582 if (pyus_in == NULL)
1583 return NULL;
1584 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1585 if (ratio == NULL)
1586 goto error;
1587 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1588 Py_DECREF(pyus_in);
1589 pyus_in = NULL;
1590 if (temp == NULL)
1591 goto error;
1592 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1593 Py_DECREF(temp);
1594 if (pyus_out == NULL)
1595 goto error;
1596 result = microseconds_to_delta(pyus_out);
1597 Py_DECREF(pyus_out);
1598 error:
1599 Py_XDECREF(pyus_in);
1600 Py_XDECREF(ratio);
1601
1602 return result;
1603}
1604
1605static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001606divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 PyObject *pyus_in;
1609 PyObject *pyus_out;
1610 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 pyus_in = delta_to_microseconds(delta);
1613 if (pyus_in == NULL)
1614 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1617 Py_DECREF(pyus_in);
1618 if (pyus_out == NULL)
1619 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 result = microseconds_to_delta(pyus_out);
1622 Py_DECREF(pyus_out);
1623 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001624}
1625
1626static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001627divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 PyObject *pyus_left;
1630 PyObject *pyus_right;
1631 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 pyus_left = delta_to_microseconds(left);
1634 if (pyus_left == NULL)
1635 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 pyus_right = delta_to_microseconds(right);
1638 if (pyus_right == NULL) {
1639 Py_DECREF(pyus_left);
1640 return NULL;
1641 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1644 Py_DECREF(pyus_left);
1645 Py_DECREF(pyus_right);
1646 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001647}
1648
1649static PyObject *
1650truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 PyObject *pyus_left;
1653 PyObject *pyus_right;
1654 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 pyus_left = delta_to_microseconds(left);
1657 if (pyus_left == NULL)
1658 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 pyus_right = delta_to_microseconds(right);
1661 if (pyus_right == NULL) {
1662 Py_DECREF(pyus_left);
1663 return NULL;
1664 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1667 Py_DECREF(pyus_left);
1668 Py_DECREF(pyus_right);
1669 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001670}
1671
1672static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001673truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1674{
1675 PyObject *result = NULL;
1676 PyObject *pyus_in = NULL, *temp, *pyus_out;
1677 PyObject *ratio = NULL;
1678
1679 pyus_in = delta_to_microseconds(delta);
1680 if (pyus_in == NULL)
1681 return NULL;
1682 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1683 if (ratio == NULL)
1684 goto error;
1685 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1686 Py_DECREF(pyus_in);
1687 pyus_in = NULL;
1688 if (temp == NULL)
1689 goto error;
1690 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1691 Py_DECREF(temp);
1692 if (pyus_out == NULL)
1693 goto error;
1694 result = microseconds_to_delta(pyus_out);
1695 Py_DECREF(pyus_out);
1696 error:
1697 Py_XDECREF(pyus_in);
1698 Py_XDECREF(ratio);
1699
1700 return result;
1701}
1702
1703static PyObject *
1704truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1705{
1706 PyObject *result;
1707 PyObject *pyus_in, *pyus_out;
1708 pyus_in = delta_to_microseconds(delta);
1709 if (pyus_in == NULL)
1710 return NULL;
1711 pyus_out = divide_nearest(pyus_in, i);
1712 Py_DECREF(pyus_in);
1713 if (pyus_out == NULL)
1714 return NULL;
1715 result = microseconds_to_delta(pyus_out);
1716 Py_DECREF(pyus_out);
1717
1718 return result;
1719}
1720
1721static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001722delta_add(PyObject *left, PyObject *right)
1723{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1727 /* delta + delta */
1728 /* The C-level additions can't overflow because of the
1729 * invariant bounds.
1730 */
1731 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1732 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1733 int microseconds = GET_TD_MICROSECONDS(left) +
1734 GET_TD_MICROSECONDS(right);
1735 result = new_delta(days, seconds, microseconds, 1);
1736 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 if (result == Py_NotImplemented)
1739 Py_INCREF(result);
1740 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001741}
1742
1743static PyObject *
1744delta_negative(PyDateTime_Delta *self)
1745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 return new_delta(-GET_TD_DAYS(self),
1747 -GET_TD_SECONDS(self),
1748 -GET_TD_MICROSECONDS(self),
1749 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001750}
1751
1752static PyObject *
1753delta_positive(PyDateTime_Delta *self)
1754{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 /* Could optimize this (by returning self) if this isn't a
1756 * subclass -- but who uses unary + ? Approximately nobody.
1757 */
1758 return new_delta(GET_TD_DAYS(self),
1759 GET_TD_SECONDS(self),
1760 GET_TD_MICROSECONDS(self),
1761 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001762}
1763
1764static PyObject *
1765delta_abs(PyDateTime_Delta *self)
1766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 assert(GET_TD_MICROSECONDS(self) >= 0);
1770 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 if (GET_TD_DAYS(self) < 0)
1773 result = delta_negative(self);
1774 else
1775 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001778}
1779
1780static PyObject *
1781delta_subtract(PyObject *left, PyObject *right)
1782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001784
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1786 /* delta - delta */
1787 PyObject *minus_right = PyNumber_Negative(right);
1788 if (minus_right) {
1789 result = delta_add(left, minus_right);
1790 Py_DECREF(minus_right);
1791 }
1792 else
1793 result = NULL;
1794 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 if (result == Py_NotImplemented)
1797 Py_INCREF(result);
1798 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001799}
1800
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001801static int
1802delta_cmp(PyObject *self, PyObject *other)
1803{
1804 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1805 if (diff == 0) {
1806 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1807 if (diff == 0)
1808 diff = GET_TD_MICROSECONDS(self) -
1809 GET_TD_MICROSECONDS(other);
1810 }
1811 return diff;
1812}
1813
Tim Peters2a799bf2002-12-16 20:18:38 +00001814static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001815delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001817 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001818 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 return diff_to_bool(diff, op);
1820 }
1821 else {
1822 Py_INCREF(Py_NotImplemented);
1823 return Py_NotImplemented;
1824 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001825}
1826
1827static PyObject *delta_getstate(PyDateTime_Delta *self);
1828
1829static long
1830delta_hash(PyDateTime_Delta *self)
1831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 if (self->hashcode == -1) {
1833 PyObject *temp = delta_getstate(self);
1834 if (temp != NULL) {
1835 self->hashcode = PyObject_Hash(temp);
1836 Py_DECREF(temp);
1837 }
1838 }
1839 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001840}
1841
1842static PyObject *
1843delta_multiply(PyObject *left, PyObject *right)
1844{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 if (PyDelta_Check(left)) {
1848 /* delta * ??? */
1849 if (PyLong_Check(right))
1850 result = multiply_int_timedelta(right,
1851 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001852 else if (PyFloat_Check(right))
1853 result = multiply_float_timedelta(right,
1854 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 }
1856 else if (PyLong_Check(left))
1857 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001858 (PyDateTime_Delta *) right);
1859 else if (PyFloat_Check(left))
1860 result = multiply_float_timedelta(left,
1861 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 if (result == Py_NotImplemented)
1864 Py_INCREF(result);
1865 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001866}
1867
1868static PyObject *
1869delta_divide(PyObject *left, PyObject *right)
1870{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 if (PyDelta_Check(left)) {
1874 /* delta * ??? */
1875 if (PyLong_Check(right))
1876 result = divide_timedelta_int(
1877 (PyDateTime_Delta *)left,
1878 right);
1879 else if (PyDelta_Check(right))
1880 result = divide_timedelta_timedelta(
1881 (PyDateTime_Delta *)left,
1882 (PyDateTime_Delta *)right);
1883 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 if (result == Py_NotImplemented)
1886 Py_INCREF(result);
1887 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001888}
1889
Mark Dickinson7c186e22010-04-20 22:32:49 +00001890static PyObject *
1891delta_truedivide(PyObject *left, PyObject *right)
1892{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 if (PyDelta_Check(left)) {
1896 if (PyDelta_Check(right))
1897 result = truedivide_timedelta_timedelta(
1898 (PyDateTime_Delta *)left,
1899 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001900 else if (PyFloat_Check(right))
1901 result = truedivide_timedelta_float(
1902 (PyDateTime_Delta *)left, right);
1903 else if (PyLong_Check(right))
1904 result = truedivide_timedelta_int(
1905 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 if (result == Py_NotImplemented)
1909 Py_INCREF(result);
1910 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001911}
1912
1913static PyObject *
1914delta_remainder(PyObject *left, PyObject *right)
1915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 PyObject *pyus_left;
1917 PyObject *pyus_right;
1918 PyObject *pyus_remainder;
1919 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
1922 Py_INCREF(Py_NotImplemented);
1923 return Py_NotImplemented;
1924 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1927 if (pyus_left == NULL)
1928 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1931 if (pyus_right == NULL) {
1932 Py_DECREF(pyus_left);
1933 return NULL;
1934 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1937 Py_DECREF(pyus_left);
1938 Py_DECREF(pyus_right);
1939 if (pyus_remainder == NULL)
1940 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 remainder = microseconds_to_delta(pyus_remainder);
1943 Py_DECREF(pyus_remainder);
1944 if (remainder == NULL)
1945 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001948}
1949
1950static PyObject *
1951delta_divmod(PyObject *left, PyObject *right)
1952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 PyObject *pyus_left;
1954 PyObject *pyus_right;
1955 PyObject *divmod;
1956 PyObject *delta;
1957 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
1960 Py_INCREF(Py_NotImplemented);
1961 return Py_NotImplemented;
1962 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1965 if (pyus_left == NULL)
1966 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1969 if (pyus_right == NULL) {
1970 Py_DECREF(pyus_left);
1971 return NULL;
1972 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1975 Py_DECREF(pyus_left);
1976 Py_DECREF(pyus_right);
1977 if (divmod == NULL)
1978 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 assert(PyTuple_Size(divmod) == 2);
1981 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1982 if (delta == NULL) {
1983 Py_DECREF(divmod);
1984 return NULL;
1985 }
1986 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1987 Py_DECREF(delta);
1988 Py_DECREF(divmod);
1989 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001990}
1991
Tim Peters2a799bf2002-12-16 20:18:38 +00001992/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1993 * timedelta constructor. sofar is the # of microseconds accounted for
1994 * so far, and there are factor microseconds per current unit, the number
1995 * of which is given by num. num * factor is added to sofar in a
1996 * numerically careful way, and that's the result. Any fractional
1997 * microseconds left over (this can happen if num is a float type) are
1998 * added into *leftover.
1999 * Note that there are many ways this can give an error (NULL) return.
2000 */
2001static PyObject *
2002accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2003 double *leftover)
2004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 PyObject *prod;
2006 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 if (PyLong_Check(num)) {
2011 prod = PyNumber_Multiply(num, factor);
2012 if (prod == NULL)
2013 return NULL;
2014 sum = PyNumber_Add(sofar, prod);
2015 Py_DECREF(prod);
2016 return sum;
2017 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 if (PyFloat_Check(num)) {
2020 double dnum;
2021 double fracpart;
2022 double intpart;
2023 PyObject *x;
2024 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 /* The Plan: decompose num into an integer part and a
2027 * fractional part, num = intpart + fracpart.
2028 * Then num * factor ==
2029 * intpart * factor + fracpart * factor
2030 * and the LHS can be computed exactly in long arithmetic.
2031 * The RHS is again broken into an int part and frac part.
2032 * and the frac part is added into *leftover.
2033 */
2034 dnum = PyFloat_AsDouble(num);
2035 if (dnum == -1.0 && PyErr_Occurred())
2036 return NULL;
2037 fracpart = modf(dnum, &intpart);
2038 x = PyLong_FromDouble(intpart);
2039 if (x == NULL)
2040 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 prod = PyNumber_Multiply(x, factor);
2043 Py_DECREF(x);
2044 if (prod == NULL)
2045 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 sum = PyNumber_Add(sofar, prod);
2048 Py_DECREF(prod);
2049 if (sum == NULL)
2050 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002052 if (fracpart == 0.0)
2053 return sum;
2054 /* So far we've lost no information. Dealing with the
2055 * fractional part requires float arithmetic, and may
2056 * lose a little info.
2057 */
2058 assert(PyLong_Check(factor));
2059 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 dnum *= fracpart;
2062 fracpart = modf(dnum, &intpart);
2063 x = PyLong_FromDouble(intpart);
2064 if (x == NULL) {
2065 Py_DECREF(sum);
2066 return NULL;
2067 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 y = PyNumber_Add(sum, x);
2070 Py_DECREF(sum);
2071 Py_DECREF(x);
2072 *leftover += fracpart;
2073 return y;
2074 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 PyErr_Format(PyExc_TypeError,
2077 "unsupported type for timedelta %s component: %s",
2078 tag, Py_TYPE(num)->tp_name);
2079 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002080}
2081
2082static PyObject *
2083delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 /* Argument objects. */
2088 PyObject *day = NULL;
2089 PyObject *second = NULL;
2090 PyObject *us = NULL;
2091 PyObject *ms = NULL;
2092 PyObject *minute = NULL;
2093 PyObject *hour = NULL;
2094 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 PyObject *x = NULL; /* running sum of microseconds */
2097 PyObject *y = NULL; /* temp sum of microseconds */
2098 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 static char *keywords[] = {
2101 "days", "seconds", "microseconds", "milliseconds",
2102 "minutes", "hours", "weeks", NULL
2103 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002105 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2106 keywords,
2107 &day, &second, &us,
2108 &ms, &minute, &hour, &week) == 0)
2109 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 x = PyLong_FromLong(0);
2112 if (x == NULL)
2113 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115#define CLEANUP \
2116 Py_DECREF(x); \
2117 x = y; \
2118 if (x == NULL) \
2119 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 if (us) {
2122 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2123 CLEANUP;
2124 }
2125 if (ms) {
2126 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2127 CLEANUP;
2128 }
2129 if (second) {
2130 y = accum("seconds", x, second, us_per_second, &leftover_us);
2131 CLEANUP;
2132 }
2133 if (minute) {
2134 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2135 CLEANUP;
2136 }
2137 if (hour) {
2138 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2139 CLEANUP;
2140 }
2141 if (day) {
2142 y = accum("days", x, day, us_per_day, &leftover_us);
2143 CLEANUP;
2144 }
2145 if (week) {
2146 y = accum("weeks", x, week, us_per_week, &leftover_us);
2147 CLEANUP;
2148 }
2149 if (leftover_us) {
2150 /* Round to nearest whole # of us, and add into x. */
2151 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2152 if (temp == NULL) {
2153 Py_DECREF(x);
2154 goto Done;
2155 }
2156 y = PyNumber_Add(x, temp);
2157 Py_DECREF(temp);
2158 CLEANUP;
2159 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 self = microseconds_to_delta_ex(x, type);
2162 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002163Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002165
2166#undef CLEANUP
2167}
2168
2169static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002170delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 return (GET_TD_DAYS(self) != 0
2173 || GET_TD_SECONDS(self) != 0
2174 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002175}
2176
2177static PyObject *
2178delta_repr(PyDateTime_Delta *self)
2179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 if (GET_TD_MICROSECONDS(self) != 0)
2181 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2182 Py_TYPE(self)->tp_name,
2183 GET_TD_DAYS(self),
2184 GET_TD_SECONDS(self),
2185 GET_TD_MICROSECONDS(self));
2186 if (GET_TD_SECONDS(self) != 0)
2187 return PyUnicode_FromFormat("%s(%d, %d)",
2188 Py_TYPE(self)->tp_name,
2189 GET_TD_DAYS(self),
2190 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 return PyUnicode_FromFormat("%s(%d)",
2193 Py_TYPE(self)->tp_name,
2194 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002195}
2196
2197static PyObject *
2198delta_str(PyDateTime_Delta *self)
2199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002200 int us = GET_TD_MICROSECONDS(self);
2201 int seconds = GET_TD_SECONDS(self);
2202 int minutes = divmod(seconds, 60, &seconds);
2203 int hours = divmod(minutes, 60, &minutes);
2204 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 if (days) {
2207 if (us)
2208 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2209 days, (days == 1 || days == -1) ? "" : "s",
2210 hours, minutes, seconds, us);
2211 else
2212 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2213 days, (days == 1 || days == -1) ? "" : "s",
2214 hours, minutes, seconds);
2215 } else {
2216 if (us)
2217 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2218 hours, minutes, seconds, us);
2219 else
2220 return PyUnicode_FromFormat("%d:%02d:%02d",
2221 hours, minutes, seconds);
2222 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002223
Tim Peters2a799bf2002-12-16 20:18:38 +00002224}
2225
Tim Peters371935f2003-02-01 01:52:50 +00002226/* Pickle support, a simple use of __reduce__. */
2227
Tim Petersb57f8f02003-02-01 02:54:15 +00002228/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002229static PyObject *
2230delta_getstate(PyDateTime_Delta *self)
2231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 return Py_BuildValue("iii", GET_TD_DAYS(self),
2233 GET_TD_SECONDS(self),
2234 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002235}
2236
Tim Peters2a799bf2002-12-16 20:18:38 +00002237static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002238delta_total_seconds(PyObject *self)
2239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 PyObject *total_seconds;
2241 PyObject *total_microseconds;
2242 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2245 if (total_microseconds == NULL)
2246 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 one_million = PyLong_FromLong(1000000L);
2249 if (one_million == NULL) {
2250 Py_DECREF(total_microseconds);
2251 return NULL;
2252 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 Py_DECREF(total_microseconds);
2257 Py_DECREF(one_million);
2258 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002259}
2260
2261static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002262delta_reduce(PyDateTime_Delta* self)
2263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002265}
2266
2267#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2268
2269static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 {"days", T_INT, OFFSET(days), READONLY,
2272 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 {"seconds", T_INT, OFFSET(seconds), READONLY,
2275 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2278 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2279 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002280};
2281
2282static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2284 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2287 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002290};
2291
2292static char delta_doc[] =
2293PyDoc_STR("Difference between two datetime values.");
2294
2295static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 delta_add, /* nb_add */
2297 delta_subtract, /* nb_subtract */
2298 delta_multiply, /* nb_multiply */
2299 delta_remainder, /* nb_remainder */
2300 delta_divmod, /* nb_divmod */
2301 0, /* nb_power */
2302 (unaryfunc)delta_negative, /* nb_negative */
2303 (unaryfunc)delta_positive, /* nb_positive */
2304 (unaryfunc)delta_abs, /* nb_absolute */
2305 (inquiry)delta_bool, /* nb_bool */
2306 0, /*nb_invert*/
2307 0, /*nb_lshift*/
2308 0, /*nb_rshift*/
2309 0, /*nb_and*/
2310 0, /*nb_xor*/
2311 0, /*nb_or*/
2312 0, /*nb_int*/
2313 0, /*nb_reserved*/
2314 0, /*nb_float*/
2315 0, /*nb_inplace_add*/
2316 0, /*nb_inplace_subtract*/
2317 0, /*nb_inplace_multiply*/
2318 0, /*nb_inplace_remainder*/
2319 0, /*nb_inplace_power*/
2320 0, /*nb_inplace_lshift*/
2321 0, /*nb_inplace_rshift*/
2322 0, /*nb_inplace_and*/
2323 0, /*nb_inplace_xor*/
2324 0, /*nb_inplace_or*/
2325 delta_divide, /* nb_floor_divide */
2326 delta_truedivide, /* nb_true_divide */
2327 0, /* nb_inplace_floor_divide */
2328 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002329};
2330
2331static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002332 PyVarObject_HEAD_INIT(NULL, 0)
2333 "datetime.timedelta", /* tp_name */
2334 sizeof(PyDateTime_Delta), /* tp_basicsize */
2335 0, /* tp_itemsize */
2336 0, /* tp_dealloc */
2337 0, /* tp_print */
2338 0, /* tp_getattr */
2339 0, /* tp_setattr */
2340 0, /* tp_reserved */
2341 (reprfunc)delta_repr, /* tp_repr */
2342 &delta_as_number, /* tp_as_number */
2343 0, /* tp_as_sequence */
2344 0, /* tp_as_mapping */
2345 (hashfunc)delta_hash, /* tp_hash */
2346 0, /* tp_call */
2347 (reprfunc)delta_str, /* tp_str */
2348 PyObject_GenericGetAttr, /* tp_getattro */
2349 0, /* tp_setattro */
2350 0, /* tp_as_buffer */
2351 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2352 delta_doc, /* tp_doc */
2353 0, /* tp_traverse */
2354 0, /* tp_clear */
2355 delta_richcompare, /* tp_richcompare */
2356 0, /* tp_weaklistoffset */
2357 0, /* tp_iter */
2358 0, /* tp_iternext */
2359 delta_methods, /* tp_methods */
2360 delta_members, /* tp_members */
2361 0, /* tp_getset */
2362 0, /* tp_base */
2363 0, /* tp_dict */
2364 0, /* tp_descr_get */
2365 0, /* tp_descr_set */
2366 0, /* tp_dictoffset */
2367 0, /* tp_init */
2368 0, /* tp_alloc */
2369 delta_new, /* tp_new */
2370 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002371};
2372
2373/*
2374 * PyDateTime_Date implementation.
2375 */
2376
2377/* Accessor properties. */
2378
2379static PyObject *
2380date_year(PyDateTime_Date *self, void *unused)
2381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002383}
2384
2385static PyObject *
2386date_month(PyDateTime_Date *self, void *unused)
2387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002389}
2390
2391static PyObject *
2392date_day(PyDateTime_Date *self, void *unused)
2393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002395}
2396
2397static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 {"year", (getter)date_year},
2399 {"month", (getter)date_month},
2400 {"day", (getter)date_day},
2401 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002402};
2403
2404/* Constructors. */
2405
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002406static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002407
Tim Peters2a799bf2002-12-16 20:18:38 +00002408static PyObject *
2409date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 PyObject *self = NULL;
2412 PyObject *state;
2413 int year;
2414 int month;
2415 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 /* Check for invocation from pickle with __getstate__ state */
2418 if (PyTuple_GET_SIZE(args) == 1 &&
2419 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2420 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2421 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2422 {
2423 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002425 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2426 if (me != NULL) {
2427 char *pdata = PyBytes_AS_STRING(state);
2428 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2429 me->hashcode = -1;
2430 }
2431 return (PyObject *)me;
2432 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2435 &year, &month, &day)) {
2436 if (check_date_args(year, month, day) < 0)
2437 return NULL;
2438 self = new_date_ex(year, month, day, type);
2439 }
2440 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002441}
2442
2443/* Return new date from localtime(t). */
2444static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002445date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002447 struct tm *tm;
2448 time_t t;
2449 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002451 t = _PyTime_DoubleToTimet(ts);
2452 if (t == (time_t)-1 && PyErr_Occurred())
2453 return NULL;
2454 tm = localtime(&t);
2455 if (tm)
2456 result = PyObject_CallFunction(cls, "iii",
2457 tm->tm_year + 1900,
2458 tm->tm_mon + 1,
2459 tm->tm_mday);
2460 else
2461 PyErr_SetString(PyExc_ValueError,
2462 "timestamp out of range for "
2463 "platform localtime() function");
2464 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002465}
2466
2467/* Return new date from current time.
2468 * We say this is equivalent to fromtimestamp(time.time()), and the
2469 * only way to be sure of that is to *call* time.time(). That's not
2470 * generally the same as calling C's time.
2471 */
2472static PyObject *
2473date_today(PyObject *cls, PyObject *dummy)
2474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 PyObject *time;
2476 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 time = time_time();
2479 if (time == NULL)
2480 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002482 /* Note well: today() is a class method, so this may not call
2483 * date.fromtimestamp. For example, it may call
2484 * datetime.fromtimestamp. That's why we need all the accuracy
2485 * time.time() delivers; if someone were gonzo about optimization,
2486 * date.today() could get away with plain C time().
2487 */
2488 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2489 Py_DECREF(time);
2490 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002491}
2492
2493/* Return new date from given timestamp (Python timestamp -- a double). */
2494static PyObject *
2495date_fromtimestamp(PyObject *cls, PyObject *args)
2496{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002497 double timestamp;
2498 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2501 result = date_local_from_time_t(cls, timestamp);
2502 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002503}
2504
2505/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2506 * the ordinal is out of range.
2507 */
2508static PyObject *
2509date_fromordinal(PyObject *cls, PyObject *args)
2510{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 PyObject *result = NULL;
2512 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002514 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2515 int year;
2516 int month;
2517 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 if (ordinal < 1)
2520 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2521 ">= 1");
2522 else {
2523 ord_to_ymd(ordinal, &year, &month, &day);
2524 result = PyObject_CallFunction(cls, "iii",
2525 year, month, day);
2526 }
2527 }
2528 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002529}
2530
2531/*
2532 * Date arithmetic.
2533 */
2534
2535/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2536 * instead.
2537 */
2538static PyObject *
2539add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002541 PyObject *result = NULL;
2542 int year = GET_YEAR(date);
2543 int month = GET_MONTH(date);
2544 int deltadays = GET_TD_DAYS(delta);
2545 /* C-level overflow is impossible because |deltadays| < 1e9. */
2546 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002548 if (normalize_date(&year, &month, &day) >= 0)
2549 result = new_date(year, month, day);
2550 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002551}
2552
2553static PyObject *
2554date_add(PyObject *left, PyObject *right)
2555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2557 Py_INCREF(Py_NotImplemented);
2558 return Py_NotImplemented;
2559 }
2560 if (PyDate_Check(left)) {
2561 /* date + ??? */
2562 if (PyDelta_Check(right))
2563 /* date + delta */
2564 return add_date_timedelta((PyDateTime_Date *) left,
2565 (PyDateTime_Delta *) right,
2566 0);
2567 }
2568 else {
2569 /* ??? + date
2570 * 'right' must be one of us, or we wouldn't have been called
2571 */
2572 if (PyDelta_Check(left))
2573 /* delta + date */
2574 return add_date_timedelta((PyDateTime_Date *) right,
2575 (PyDateTime_Delta *) left,
2576 0);
2577 }
2578 Py_INCREF(Py_NotImplemented);
2579 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002580}
2581
2582static PyObject *
2583date_subtract(PyObject *left, PyObject *right)
2584{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002585 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2586 Py_INCREF(Py_NotImplemented);
2587 return Py_NotImplemented;
2588 }
2589 if (PyDate_Check(left)) {
2590 if (PyDate_Check(right)) {
2591 /* date - date */
2592 int left_ord = ymd_to_ord(GET_YEAR(left),
2593 GET_MONTH(left),
2594 GET_DAY(left));
2595 int right_ord = ymd_to_ord(GET_YEAR(right),
2596 GET_MONTH(right),
2597 GET_DAY(right));
2598 return new_delta(left_ord - right_ord, 0, 0, 0);
2599 }
2600 if (PyDelta_Check(right)) {
2601 /* date - delta */
2602 return add_date_timedelta((PyDateTime_Date *) left,
2603 (PyDateTime_Delta *) right,
2604 1);
2605 }
2606 }
2607 Py_INCREF(Py_NotImplemented);
2608 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002609}
2610
2611
2612/* Various ways to turn a date into a string. */
2613
2614static PyObject *
2615date_repr(PyDateTime_Date *self)
2616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2618 Py_TYPE(self)->tp_name,
2619 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002620}
2621
2622static PyObject *
2623date_isoformat(PyDateTime_Date *self)
2624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625 return PyUnicode_FromFormat("%04d-%02d-%02d",
2626 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002627}
2628
Tim Peterse2df5ff2003-05-02 18:39:55 +00002629/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002630static PyObject *
2631date_str(PyDateTime_Date *self)
2632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002634}
2635
2636
2637static PyObject *
2638date_ctime(PyDateTime_Date *self)
2639{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002640 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002641}
2642
2643static PyObject *
2644date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 /* This method can be inherited, and needs to call the
2647 * timetuple() method appropriate to self's class.
2648 */
2649 PyObject *result;
2650 PyObject *tuple;
2651 PyObject *format;
2652 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2655 &format))
2656 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2659 if (tuple == NULL)
2660 return NULL;
2661 result = wrap_strftime((PyObject *)self, format, tuple,
2662 (PyObject *)self);
2663 Py_DECREF(tuple);
2664 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002665}
2666
Eric Smith1ba31142007-09-11 18:06:02 +00002667static PyObject *
2668date_format(PyDateTime_Date *self, PyObject *args)
2669{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002672 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2673 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002675 /* if the format is zero length, return str(self) */
2676 if (PyUnicode_GetSize(format) == 0)
2677 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002679 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002680}
2681
Tim Peters2a799bf2002-12-16 20:18:38 +00002682/* ISO methods. */
2683
2684static PyObject *
2685date_isoweekday(PyDateTime_Date *self)
2686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002687 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002689 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002690}
2691
2692static PyObject *
2693date_isocalendar(PyDateTime_Date *self)
2694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002695 int year = GET_YEAR(self);
2696 int week1_monday = iso_week1_monday(year);
2697 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2698 int week;
2699 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002701 week = divmod(today - week1_monday, 7, &day);
2702 if (week < 0) {
2703 --year;
2704 week1_monday = iso_week1_monday(year);
2705 week = divmod(today - week1_monday, 7, &day);
2706 }
2707 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2708 ++year;
2709 week = 0;
2710 }
2711 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002712}
2713
2714/* Miscellaneous methods. */
2715
Tim Peters2a799bf2002-12-16 20:18:38 +00002716static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002717date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002719 if (PyDate_Check(other)) {
2720 int diff = memcmp(((PyDateTime_Date *)self)->data,
2721 ((PyDateTime_Date *)other)->data,
2722 _PyDateTime_DATE_DATASIZE);
2723 return diff_to_bool(diff, op);
2724 }
2725 else {
2726 Py_INCREF(Py_NotImplemented);
2727 return Py_NotImplemented;
2728 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002729}
2730
2731static PyObject *
2732date_timetuple(PyDateTime_Date *self)
2733{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002734 return build_struct_time(GET_YEAR(self),
2735 GET_MONTH(self),
2736 GET_DAY(self),
2737 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002738}
2739
Tim Peters12bf3392002-12-24 05:41:27 +00002740static PyObject *
2741date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002743 PyObject *clone;
2744 PyObject *tuple;
2745 int year = GET_YEAR(self);
2746 int month = GET_MONTH(self);
2747 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002749 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2750 &year, &month, &day))
2751 return NULL;
2752 tuple = Py_BuildValue("iii", year, month, day);
2753 if (tuple == NULL)
2754 return NULL;
2755 clone = date_new(Py_TYPE(self), tuple, NULL);
2756 Py_DECREF(tuple);
2757 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002758}
2759
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002760/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002761 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002762*/
2763static long
2764generic_hash(unsigned char *data, int len)
2765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002766 register unsigned char *p;
2767 register long x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002769 p = (unsigned char *) data;
2770 x = *p << 7;
2771 while (--len >= 0)
2772 x = (1000003*x) ^ *p++;
2773 x ^= len;
2774 if (x == -1)
2775 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002777 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002778}
2779
2780
2781static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002782
2783static long
2784date_hash(PyDateTime_Date *self)
2785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002786 if (self->hashcode == -1)
2787 self->hashcode = generic_hash(
2788 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002790 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002791}
2792
2793static PyObject *
2794date_toordinal(PyDateTime_Date *self)
2795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2797 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002798}
2799
2800static PyObject *
2801date_weekday(PyDateTime_Date *self)
2802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002803 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002806}
2807
Tim Peters371935f2003-02-01 01:52:50 +00002808/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002809
Tim Petersb57f8f02003-02-01 02:54:15 +00002810/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002811static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002812date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 PyObject* field;
2815 field = PyBytes_FromStringAndSize((char*)self->data,
2816 _PyDateTime_DATE_DATASIZE);
2817 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002818}
2819
2820static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002821date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002823 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002824}
2825
2826static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002828 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002830 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2831 METH_CLASS,
2832 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2833 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002835 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2836 METH_CLASS,
2837 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2838 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002840 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2841 PyDoc_STR("Current date or datetime: same as "
2842 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002846 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2847 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2850 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002852 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2853 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002855 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2856 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002858 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2859 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2860 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2863 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002865 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2866 PyDoc_STR("Return the day of the week represented by the date.\n"
2867 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002869 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2870 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2871 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002873 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2874 PyDoc_STR("Return the day of the week represented by the date.\n"
2875 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002877 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2878 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002880 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2881 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002883 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002884};
2885
2886static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002887PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002888
2889static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 date_add, /* nb_add */
2891 date_subtract, /* nb_subtract */
2892 0, /* nb_multiply */
2893 0, /* nb_remainder */
2894 0, /* nb_divmod */
2895 0, /* nb_power */
2896 0, /* nb_negative */
2897 0, /* nb_positive */
2898 0, /* nb_absolute */
2899 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002900};
2901
2902static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002903 PyVarObject_HEAD_INIT(NULL, 0)
2904 "datetime.date", /* tp_name */
2905 sizeof(PyDateTime_Date), /* tp_basicsize */
2906 0, /* tp_itemsize */
2907 0, /* tp_dealloc */
2908 0, /* tp_print */
2909 0, /* tp_getattr */
2910 0, /* tp_setattr */
2911 0, /* tp_reserved */
2912 (reprfunc)date_repr, /* tp_repr */
2913 &date_as_number, /* tp_as_number */
2914 0, /* tp_as_sequence */
2915 0, /* tp_as_mapping */
2916 (hashfunc)date_hash, /* tp_hash */
2917 0, /* tp_call */
2918 (reprfunc)date_str, /* tp_str */
2919 PyObject_GenericGetAttr, /* tp_getattro */
2920 0, /* tp_setattro */
2921 0, /* tp_as_buffer */
2922 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2923 date_doc, /* tp_doc */
2924 0, /* tp_traverse */
2925 0, /* tp_clear */
2926 date_richcompare, /* tp_richcompare */
2927 0, /* tp_weaklistoffset */
2928 0, /* tp_iter */
2929 0, /* tp_iternext */
2930 date_methods, /* tp_methods */
2931 0, /* tp_members */
2932 date_getset, /* tp_getset */
2933 0, /* tp_base */
2934 0, /* tp_dict */
2935 0, /* tp_descr_get */
2936 0, /* tp_descr_set */
2937 0, /* tp_dictoffset */
2938 0, /* tp_init */
2939 0, /* tp_alloc */
2940 date_new, /* tp_new */
2941 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002942};
2943
2944/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002945 * PyDateTime_TZInfo implementation.
2946 */
2947
2948/* This is a pure abstract base class, so doesn't do anything beyond
2949 * raising NotImplemented exceptions. Real tzinfo classes need
2950 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002951 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002952 * be subclasses of this tzinfo class, which is easy and quick to check).
2953 *
2954 * Note: For reasons having to do with pickling of subclasses, we have
2955 * to allow tzinfo objects to be instantiated. This wasn't an issue
2956 * in the Python implementation (__init__() could raise NotImplementedError
2957 * there without ill effect), but doing so in the C implementation hit a
2958 * brick wall.
2959 */
2960
2961static PyObject *
2962tzinfo_nogo(const char* methodname)
2963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002964 PyErr_Format(PyExc_NotImplementedError,
2965 "a tzinfo subclass must implement %s()",
2966 methodname);
2967 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002968}
2969
2970/* Methods. A subclass must implement these. */
2971
Tim Peters52dcce22003-01-23 16:36:11 +00002972static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002973tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2974{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002975 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002976}
2977
Tim Peters52dcce22003-01-23 16:36:11 +00002978static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002979tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002981 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002982}
2983
Tim Peters52dcce22003-01-23 16:36:11 +00002984static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002985tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002987 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002988}
2989
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002990
2991static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2992 PyDateTime_Delta *delta,
2993 int factor);
2994static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2995static PyObject *datetime_dst(PyObject *self, PyObject *);
2996
Tim Peters52dcce22003-01-23 16:36:11 +00002997static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002998tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002999{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003000 PyObject *result = NULL;
3001 PyObject *off = NULL, *dst = NULL;
3002 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003003
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003004 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003005 PyErr_SetString(PyExc_TypeError,
3006 "fromutc: argument must be a datetime");
3007 return NULL;
3008 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003009 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003010 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3011 "is not self");
3012 return NULL;
3013 }
Tim Peters52dcce22003-01-23 16:36:11 +00003014
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003015 off = datetime_utcoffset(dt, NULL);
3016 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003017 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003018 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003019 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3020 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003021 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003022 }
Tim Peters52dcce22003-01-23 16:36:11 +00003023
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003024 dst = datetime_dst(dt, NULL);
3025 if (dst == NULL)
3026 goto Fail;
3027 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003028 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3029 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003030 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003031 }
Tim Peters52dcce22003-01-23 16:36:11 +00003032
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003033 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3034 if (delta == NULL)
3035 goto Fail;
3036 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003037 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003039
3040 Py_DECREF(dst);
3041 dst = call_dst(GET_DT_TZINFO(dt), result);
3042 if (dst == NULL)
3043 goto Fail;
3044 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003045 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003046 if (delta_bool(delta) != 0) {
3047 PyObject *temp = result;
3048 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3049 (PyDateTime_Delta *)dst, 1);
3050 Py_DECREF(temp);
3051 if (result == NULL)
3052 goto Fail;
3053 }
3054 Py_DECREF(delta);
3055 Py_DECREF(dst);
3056 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003057 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003058
3059Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003060 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3061 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003063 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003064Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003065 Py_XDECREF(off);
3066 Py_XDECREF(dst);
3067 Py_XDECREF(delta);
3068 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003069 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003070}
3071
Tim Peters2a799bf2002-12-16 20:18:38 +00003072/*
3073 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003074 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003075 */
3076
Guido van Rossum177e41a2003-01-30 22:06:23 +00003077static PyObject *
3078tzinfo_reduce(PyObject *self)
3079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003080 PyObject *args, *state, *tmp;
3081 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 tmp = PyTuple_New(0);
3084 if (tmp == NULL)
3085 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003087 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3088 if (getinitargs != NULL) {
3089 args = PyObject_CallObject(getinitargs, tmp);
3090 Py_DECREF(getinitargs);
3091 if (args == NULL) {
3092 Py_DECREF(tmp);
3093 return NULL;
3094 }
3095 }
3096 else {
3097 PyErr_Clear();
3098 args = tmp;
3099 Py_INCREF(args);
3100 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003102 getstate = PyObject_GetAttrString(self, "__getstate__");
3103 if (getstate != NULL) {
3104 state = PyObject_CallObject(getstate, tmp);
3105 Py_DECREF(getstate);
3106 if (state == NULL) {
3107 Py_DECREF(args);
3108 Py_DECREF(tmp);
3109 return NULL;
3110 }
3111 }
3112 else {
3113 PyObject **dictptr;
3114 PyErr_Clear();
3115 state = Py_None;
3116 dictptr = _PyObject_GetDictPtr(self);
3117 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3118 state = *dictptr;
3119 Py_INCREF(state);
3120 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003124 if (state == Py_None) {
3125 Py_DECREF(state);
3126 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3127 }
3128 else
3129 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003130}
Tim Peters2a799bf2002-12-16 20:18:38 +00003131
3132static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003134 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3135 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003137 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003138 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3139 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003141 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3142 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003144 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003145 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003147 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3148 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003150 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003151};
3152
3153static char tzinfo_doc[] =
3154PyDoc_STR("Abstract base class for time zone info objects.");
3155
Neal Norwitz227b5332006-03-22 09:28:35 +00003156static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003157 PyVarObject_HEAD_INIT(NULL, 0)
3158 "datetime.tzinfo", /* tp_name */
3159 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3160 0, /* tp_itemsize */
3161 0, /* tp_dealloc */
3162 0, /* tp_print */
3163 0, /* tp_getattr */
3164 0, /* tp_setattr */
3165 0, /* tp_reserved */
3166 0, /* tp_repr */
3167 0, /* tp_as_number */
3168 0, /* tp_as_sequence */
3169 0, /* tp_as_mapping */
3170 0, /* tp_hash */
3171 0, /* tp_call */
3172 0, /* tp_str */
3173 PyObject_GenericGetAttr, /* tp_getattro */
3174 0, /* tp_setattro */
3175 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003176 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003177 tzinfo_doc, /* tp_doc */
3178 0, /* tp_traverse */
3179 0, /* tp_clear */
3180 0, /* tp_richcompare */
3181 0, /* tp_weaklistoffset */
3182 0, /* tp_iter */
3183 0, /* tp_iternext */
3184 tzinfo_methods, /* tp_methods */
3185 0, /* tp_members */
3186 0, /* tp_getset */
3187 0, /* tp_base */
3188 0, /* tp_dict */
3189 0, /* tp_descr_get */
3190 0, /* tp_descr_set */
3191 0, /* tp_dictoffset */
3192 0, /* tp_init */
3193 0, /* tp_alloc */
3194 PyType_GenericNew, /* tp_new */
3195 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003196};
3197
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003198static char *timezone_kws[] = {"offset", "name", NULL};
3199
3200static PyObject *
3201timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3202{
3203 PyObject *offset;
3204 PyObject *name = NULL;
3205 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3206 &PyDateTime_DeltaType, &offset,
3207 &PyUnicode_Type, &name))
3208 return new_timezone(offset, name);
3209
3210 return NULL;
3211}
3212
3213static void
3214timezone_dealloc(PyDateTime_TimeZone *self)
3215{
3216 Py_CLEAR(self->offset);
3217 Py_CLEAR(self->name);
3218 Py_TYPE(self)->tp_free((PyObject *)self);
3219}
3220
3221static PyObject *
3222timezone_richcompare(PyDateTime_TimeZone *self,
3223 PyDateTime_TimeZone *other, int op)
3224{
3225 if (op != Py_EQ && op != Py_NE) {
3226 Py_INCREF(Py_NotImplemented);
3227 return Py_NotImplemented;
3228 }
3229 return delta_richcompare(self->offset, other->offset, op);
3230}
3231
3232static long
3233timezone_hash(PyDateTime_TimeZone *self)
3234{
3235 return delta_hash((PyDateTime_Delta *)self->offset);
3236}
3237
3238/* Check argument type passed to tzname, utcoffset, or dst methods.
3239 Returns 0 for good argument. Returns -1 and sets exception info
3240 otherwise.
3241 */
3242static int
3243_timezone_check_argument(PyObject *dt, const char *meth)
3244{
3245 if (dt == Py_None || PyDateTime_Check(dt))
3246 return 0;
3247 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3248 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3249 return -1;
3250}
3251
3252static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003253timezone_repr(PyDateTime_TimeZone *self)
3254{
3255 /* Note that although timezone is not subclassable, it is convenient
3256 to use Py_TYPE(self)->tp_name here. */
3257 const char *type_name = Py_TYPE(self)->tp_name;
3258
3259 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3260 return PyUnicode_FromFormat("%s.utc", type_name);
3261
3262 if (self->name == NULL)
3263 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3264
3265 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3266 self->name);
3267}
3268
3269
3270static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003271timezone_str(PyDateTime_TimeZone *self)
3272{
3273 char buf[10];
3274 int hours, minutes, seconds;
3275 PyObject *offset;
3276 char sign;
3277
3278 if (self->name != NULL) {
3279 Py_INCREF(self->name);
3280 return self->name;
3281 }
3282 /* Offset is normalized, so it is negative if days < 0 */
3283 if (GET_TD_DAYS(self->offset) < 0) {
3284 sign = '-';
3285 offset = delta_negative((PyDateTime_Delta *)self->offset);
3286 if (offset == NULL)
3287 return NULL;
3288 }
3289 else {
3290 sign = '+';
3291 offset = self->offset;
3292 Py_INCREF(offset);
3293 }
3294 /* Offset is not negative here. */
3295 seconds = GET_TD_SECONDS(offset);
3296 Py_DECREF(offset);
3297 minutes = divmod(seconds, 60, &seconds);
3298 hours = divmod(minutes, 60, &minutes);
3299 assert(seconds == 0);
3300 /* XXX ignore sub-minute data, curently not allowed. */
3301 PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes);
3302
3303 return PyUnicode_FromString(buf);
3304}
3305
3306static PyObject *
3307timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3308{
3309 if (_timezone_check_argument(dt, "tzname") == -1)
3310 return NULL;
3311
3312 return timezone_str(self);
3313}
3314
3315static PyObject *
3316timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3317{
3318 if (_timezone_check_argument(dt, "utcoffset") == -1)
3319 return NULL;
3320
3321 Py_INCREF(self->offset);
3322 return self->offset;
3323}
3324
3325static PyObject *
3326timezone_dst(PyObject *self, PyObject *dt)
3327{
3328 if (_timezone_check_argument(dt, "dst") == -1)
3329 return NULL;
3330
3331 Py_RETURN_NONE;
3332}
3333
3334static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003335timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3336{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003337 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003338 PyErr_SetString(PyExc_TypeError,
3339 "fromutc: argument must be a datetime");
3340 return NULL;
3341 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003342 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003343 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3344 "is not self");
3345 return NULL;
3346 }
3347
3348 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3349}
3350
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003351static PyObject *
3352timezone_getinitargs(PyDateTime_TimeZone *self)
3353{
3354 if (self->name == NULL)
3355 return Py_BuildValue("(O)", self->offset);
3356 return Py_BuildValue("(OO)", self->offset, self->name);
3357}
3358
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003359static PyMethodDef timezone_methods[] = {
3360 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3361 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003362 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003363
3364 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003365 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003366
3367 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003368 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003369
3370 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3371 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3372
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003373 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3374 PyDoc_STR("pickle support")},
3375
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003376 {NULL, NULL}
3377};
3378
3379static char timezone_doc[] =
3380PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3381
3382static PyTypeObject PyDateTime_TimeZoneType = {
3383 PyVarObject_HEAD_INIT(NULL, 0)
3384 "datetime.timezone", /* tp_name */
3385 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3386 0, /* tp_itemsize */
3387 (destructor)timezone_dealloc, /* tp_dealloc */
3388 0, /* tp_print */
3389 0, /* tp_getattr */
3390 0, /* tp_setattr */
3391 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003392 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003393 0, /* tp_as_number */
3394 0, /* tp_as_sequence */
3395 0, /* tp_as_mapping */
3396 (hashfunc)timezone_hash, /* tp_hash */
3397 0, /* tp_call */
3398 (reprfunc)timezone_str, /* tp_str */
3399 0, /* tp_getattro */
3400 0, /* tp_setattro */
3401 0, /* tp_as_buffer */
3402 Py_TPFLAGS_DEFAULT, /* tp_flags */
3403 timezone_doc, /* tp_doc */
3404 0, /* tp_traverse */
3405 0, /* tp_clear */
3406 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3407 0, /* tp_weaklistoffset */
3408 0, /* tp_iter */
3409 0, /* tp_iternext */
3410 timezone_methods, /* tp_methods */
3411 0, /* tp_members */
3412 0, /* tp_getset */
3413 &PyDateTime_TZInfoType, /* tp_base */
3414 0, /* tp_dict */
3415 0, /* tp_descr_get */
3416 0, /* tp_descr_set */
3417 0, /* tp_dictoffset */
3418 0, /* tp_init */
3419 0, /* tp_alloc */
3420 timezone_new, /* tp_new */
3421};
3422
Tim Peters2a799bf2002-12-16 20:18:38 +00003423/*
Tim Peters37f39822003-01-10 03:49:02 +00003424 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003425 */
3426
Tim Peters37f39822003-01-10 03:49:02 +00003427/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003428 */
3429
3430static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003431time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003433 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003434}
3435
Tim Peters37f39822003-01-10 03:49:02 +00003436static PyObject *
3437time_minute(PyDateTime_Time *self, void *unused)
3438{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003439 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003440}
3441
3442/* The name time_second conflicted with some platform header file. */
3443static PyObject *
3444py_time_second(PyDateTime_Time *self, void *unused)
3445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003446 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003447}
3448
3449static PyObject *
3450time_microsecond(PyDateTime_Time *self, void *unused)
3451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003452 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003453}
3454
3455static PyObject *
3456time_tzinfo(PyDateTime_Time *self, void *unused)
3457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003458 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3459 Py_INCREF(result);
3460 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003461}
3462
3463static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003464 {"hour", (getter)time_hour},
3465 {"minute", (getter)time_minute},
3466 {"second", (getter)py_time_second},
3467 {"microsecond", (getter)time_microsecond},
3468 {"tzinfo", (getter)time_tzinfo},
3469 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003470};
3471
3472/*
3473 * Constructors.
3474 */
3475
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003476static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003477 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003478
Tim Peters2a799bf2002-12-16 20:18:38 +00003479static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003480time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003482 PyObject *self = NULL;
3483 PyObject *state;
3484 int hour = 0;
3485 int minute = 0;
3486 int second = 0;
3487 int usecond = 0;
3488 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003490 /* Check for invocation from pickle with __getstate__ state */
3491 if (PyTuple_GET_SIZE(args) >= 1 &&
3492 PyTuple_GET_SIZE(args) <= 2 &&
3493 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3494 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3495 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3496 {
3497 PyDateTime_Time *me;
3498 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003500 if (PyTuple_GET_SIZE(args) == 2) {
3501 tzinfo = PyTuple_GET_ITEM(args, 1);
3502 if (check_tzinfo_subclass(tzinfo) < 0) {
3503 PyErr_SetString(PyExc_TypeError, "bad "
3504 "tzinfo state arg");
3505 return NULL;
3506 }
3507 }
3508 aware = (char)(tzinfo != Py_None);
3509 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3510 if (me != NULL) {
3511 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003513 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3514 me->hashcode = -1;
3515 me->hastzinfo = aware;
3516 if (aware) {
3517 Py_INCREF(tzinfo);
3518 me->tzinfo = tzinfo;
3519 }
3520 }
3521 return (PyObject *)me;
3522 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003524 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3525 &hour, &minute, &second, &usecond,
3526 &tzinfo)) {
3527 if (check_time_args(hour, minute, second, usecond) < 0)
3528 return NULL;
3529 if (check_tzinfo_subclass(tzinfo) < 0)
3530 return NULL;
3531 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3532 type);
3533 }
3534 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003535}
3536
3537/*
3538 * Destructor.
3539 */
3540
3541static void
Tim Peters37f39822003-01-10 03:49:02 +00003542time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003543{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003544 if (HASTZINFO(self)) {
3545 Py_XDECREF(self->tzinfo);
3546 }
3547 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003548}
3549
3550/*
Tim Peters855fe882002-12-22 03:43:39 +00003551 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003552 */
3553
Tim Peters2a799bf2002-12-16 20:18:38 +00003554/* These are all METH_NOARGS, so don't need to check the arglist. */
3555static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003556time_utcoffset(PyObject *self, PyObject *unused) {
3557 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003558}
3559
3560static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003561time_dst(PyObject *self, PyObject *unused) {
3562 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003563}
3564
3565static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003566time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003567 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003568}
3569
3570/*
Tim Peters37f39822003-01-10 03:49:02 +00003571 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003572 */
3573
3574static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003575time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003577 const char *type_name = Py_TYPE(self)->tp_name;
3578 int h = TIME_GET_HOUR(self);
3579 int m = TIME_GET_MINUTE(self);
3580 int s = TIME_GET_SECOND(self);
3581 int us = TIME_GET_MICROSECOND(self);
3582 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003584 if (us)
3585 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3586 type_name, h, m, s, us);
3587 else if (s)
3588 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3589 type_name, h, m, s);
3590 else
3591 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3592 if (result != NULL && HASTZINFO(self))
3593 result = append_keyword_tzinfo(result, self->tzinfo);
3594 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003595}
3596
Tim Peters37f39822003-01-10 03:49:02 +00003597static PyObject *
3598time_str(PyDateTime_Time *self)
3599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003600 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003601}
Tim Peters2a799bf2002-12-16 20:18:38 +00003602
3603static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003604time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003605{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003606 char buf[100];
3607 PyObject *result;
3608 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003610 if (us)
3611 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3612 TIME_GET_HOUR(self),
3613 TIME_GET_MINUTE(self),
3614 TIME_GET_SECOND(self),
3615 us);
3616 else
3617 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3618 TIME_GET_HOUR(self),
3619 TIME_GET_MINUTE(self),
3620 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003621
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003622 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003623 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003625 /* We need to append the UTC offset. */
3626 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3627 Py_None) < 0) {
3628 Py_DECREF(result);
3629 return NULL;
3630 }
3631 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3632 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003633}
3634
Tim Peters37f39822003-01-10 03:49:02 +00003635static PyObject *
3636time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003638 PyObject *result;
3639 PyObject *tuple;
3640 PyObject *format;
3641 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003643 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3644 &format))
3645 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003647 /* Python's strftime does insane things with the year part of the
3648 * timetuple. The year is forced to (the otherwise nonsensical)
3649 * 1900 to worm around that.
3650 */
3651 tuple = Py_BuildValue("iiiiiiiii",
3652 1900, 1, 1, /* year, month, day */
3653 TIME_GET_HOUR(self),
3654 TIME_GET_MINUTE(self),
3655 TIME_GET_SECOND(self),
3656 0, 1, -1); /* weekday, daynum, dst */
3657 if (tuple == NULL)
3658 return NULL;
3659 assert(PyTuple_Size(tuple) == 9);
3660 result = wrap_strftime((PyObject *)self, format, tuple,
3661 Py_None);
3662 Py_DECREF(tuple);
3663 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003664}
Tim Peters2a799bf2002-12-16 20:18:38 +00003665
3666/*
3667 * Miscellaneous methods.
3668 */
3669
Tim Peters37f39822003-01-10 03:49:02 +00003670static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003671time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003672{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003673 PyObject *result = NULL;
3674 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003675 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003677 if (! PyTime_Check(other)) {
3678 Py_INCREF(Py_NotImplemented);
3679 return Py_NotImplemented;
3680 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003681
3682 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003683 diff = memcmp(((PyDateTime_Time *)self)->data,
3684 ((PyDateTime_Time *)other)->data,
3685 _PyDateTime_TIME_DATASIZE);
3686 return diff_to_bool(diff, op);
3687 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003688 offset1 = time_utcoffset(self, NULL);
3689 if (offset1 == NULL)
3690 return NULL;
3691 offset2 = time_utcoffset(other, NULL);
3692 if (offset2 == NULL)
3693 goto done;
3694 /* If they're both naive, or both aware and have the same offsets,
3695 * we get off cheap. Note that if they're both naive, offset1 ==
3696 * offset2 == Py_None at this point.
3697 */
3698 if ((offset1 == offset2) ||
3699 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3700 delta_cmp(offset1, offset2) == 0)) {
3701 diff = memcmp(((PyDateTime_Time *)self)->data,
3702 ((PyDateTime_Time *)other)->data,
3703 _PyDateTime_TIME_DATASIZE);
3704 result = diff_to_bool(diff, op);
3705 }
3706 /* The hard case: both aware with different UTC offsets */
3707 else if (offset1 != Py_None && offset2 != Py_None) {
3708 int offsecs1, offsecs2;
3709 assert(offset1 != offset2); /* else last "if" handled it */
3710 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3711 TIME_GET_MINUTE(self) * 60 +
3712 TIME_GET_SECOND(self) -
3713 GET_TD_DAYS(offset1) * 86400 -
3714 GET_TD_SECONDS(offset1);
3715 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3716 TIME_GET_MINUTE(other) * 60 +
3717 TIME_GET_SECOND(other) -
3718 GET_TD_DAYS(offset2) * 86400 -
3719 GET_TD_SECONDS(offset2);
3720 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003721 if (diff == 0)
3722 diff = TIME_GET_MICROSECOND(self) -
3723 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003724 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003725 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003726 else {
3727 PyErr_SetString(PyExc_TypeError,
3728 "can't compare offset-naive and "
3729 "offset-aware times");
3730 }
3731 done:
3732 Py_DECREF(offset1);
3733 Py_XDECREF(offset2);
3734 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003735}
3736
3737static long
3738time_hash(PyDateTime_Time *self)
3739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003740 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003741 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003742
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003743 offset = time_utcoffset((PyObject *)self, NULL);
3744
3745 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003746 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003748 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003749 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003750 self->hashcode = generic_hash(
3751 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003752 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003753 PyObject *temp1, *temp2;
3754 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003755 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003756 seconds = TIME_GET_HOUR(self) * 3600 +
3757 TIME_GET_MINUTE(self) * 60 +
3758 TIME_GET_SECOND(self);
3759 microseconds = TIME_GET_MICROSECOND(self);
3760 temp1 = new_delta(0, seconds, microseconds, 1);
3761 if (temp1 == NULL) {
3762 Py_DECREF(offset);
3763 return -1;
3764 }
3765 temp2 = delta_subtract(temp1, offset);
3766 Py_DECREF(temp1);
3767 if (temp2 == NULL) {
3768 Py_DECREF(offset);
3769 return -1;
3770 }
3771 self->hashcode = PyObject_Hash(temp2);
3772 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003773 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003774 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003775 }
3776 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003777}
Tim Peters2a799bf2002-12-16 20:18:38 +00003778
Tim Peters12bf3392002-12-24 05:41:27 +00003779static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003780time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003782 PyObject *clone;
3783 PyObject *tuple;
3784 int hh = TIME_GET_HOUR(self);
3785 int mm = TIME_GET_MINUTE(self);
3786 int ss = TIME_GET_SECOND(self);
3787 int us = TIME_GET_MICROSECOND(self);
3788 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003790 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3791 time_kws,
3792 &hh, &mm, &ss, &us, &tzinfo))
3793 return NULL;
3794 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3795 if (tuple == NULL)
3796 return NULL;
3797 clone = time_new(Py_TYPE(self), tuple, NULL);
3798 Py_DECREF(tuple);
3799 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003800}
3801
Tim Peters2a799bf2002-12-16 20:18:38 +00003802static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003803time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003804{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003805 PyObject *offset, *tzinfo;
3806 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003808 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3809 /* Since utcoffset is in whole minutes, nothing can
3810 * alter the conclusion that this is nonzero.
3811 */
3812 return 1;
3813 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003814 tzinfo = GET_TIME_TZINFO(self);
3815 if (tzinfo != Py_None) {
3816 offset = call_utcoffset(tzinfo, Py_None);
3817 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003818 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003819 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3820 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003821 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003822 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003823}
3824
Tim Peters371935f2003-02-01 01:52:50 +00003825/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003826
Tim Peters33e0f382003-01-10 02:05:14 +00003827/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003828 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3829 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003830 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003831 */
3832static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003833time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 PyObject *basestate;
3836 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003838 basestate = PyBytes_FromStringAndSize((char *)self->data,
3839 _PyDateTime_TIME_DATASIZE);
3840 if (basestate != NULL) {
3841 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3842 result = PyTuple_Pack(1, basestate);
3843 else
3844 result = PyTuple_Pack(2, basestate, self->tzinfo);
3845 Py_DECREF(basestate);
3846 }
3847 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003848}
3849
3850static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003851time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003852{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003853 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003854}
3855
Tim Peters37f39822003-01-10 03:49:02 +00003856static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3859 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3860 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003862 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3863 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003865 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3866 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003868 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3869 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003871 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3872 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003874 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3875 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003877 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3878 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003880 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3881 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003884};
3885
Tim Peters37f39822003-01-10 03:49:02 +00003886static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003887PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3888\n\
3889All arguments are optional. tzinfo may be None, or an instance of\n\
3890a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003891
Tim Peters37f39822003-01-10 03:49:02 +00003892static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003893 0, /* nb_add */
3894 0, /* nb_subtract */
3895 0, /* nb_multiply */
3896 0, /* nb_remainder */
3897 0, /* nb_divmod */
3898 0, /* nb_power */
3899 0, /* nb_negative */
3900 0, /* nb_positive */
3901 0, /* nb_absolute */
3902 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003903};
3904
Neal Norwitz227b5332006-03-22 09:28:35 +00003905static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003906 PyVarObject_HEAD_INIT(NULL, 0)
3907 "datetime.time", /* tp_name */
3908 sizeof(PyDateTime_Time), /* tp_basicsize */
3909 0, /* tp_itemsize */
3910 (destructor)time_dealloc, /* tp_dealloc */
3911 0, /* tp_print */
3912 0, /* tp_getattr */
3913 0, /* tp_setattr */
3914 0, /* tp_reserved */
3915 (reprfunc)time_repr, /* tp_repr */
3916 &time_as_number, /* tp_as_number */
3917 0, /* tp_as_sequence */
3918 0, /* tp_as_mapping */
3919 (hashfunc)time_hash, /* tp_hash */
3920 0, /* tp_call */
3921 (reprfunc)time_str, /* tp_str */
3922 PyObject_GenericGetAttr, /* tp_getattro */
3923 0, /* tp_setattro */
3924 0, /* tp_as_buffer */
3925 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3926 time_doc, /* tp_doc */
3927 0, /* tp_traverse */
3928 0, /* tp_clear */
3929 time_richcompare, /* tp_richcompare */
3930 0, /* tp_weaklistoffset */
3931 0, /* tp_iter */
3932 0, /* tp_iternext */
3933 time_methods, /* tp_methods */
3934 0, /* tp_members */
3935 time_getset, /* tp_getset */
3936 0, /* tp_base */
3937 0, /* tp_dict */
3938 0, /* tp_descr_get */
3939 0, /* tp_descr_set */
3940 0, /* tp_dictoffset */
3941 0, /* tp_init */
3942 time_alloc, /* tp_alloc */
3943 time_new, /* tp_new */
3944 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003945};
3946
3947/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003948 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003949 */
3950
Tim Petersa9bc1682003-01-11 03:39:11 +00003951/* Accessor properties. Properties for day, month, and year are inherited
3952 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003953 */
3954
3955static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003956datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003958 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003959}
3960
Tim Petersa9bc1682003-01-11 03:39:11 +00003961static PyObject *
3962datetime_minute(PyDateTime_DateTime *self, void *unused)
3963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003964 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003965}
3966
3967static PyObject *
3968datetime_second(PyDateTime_DateTime *self, void *unused)
3969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003970 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003971}
3972
3973static PyObject *
3974datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003976 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003977}
3978
3979static PyObject *
3980datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003982 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3983 Py_INCREF(result);
3984 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003985}
3986
3987static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003988 {"hour", (getter)datetime_hour},
3989 {"minute", (getter)datetime_minute},
3990 {"second", (getter)datetime_second},
3991 {"microsecond", (getter)datetime_microsecond},
3992 {"tzinfo", (getter)datetime_tzinfo},
3993 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003994};
3995
3996/*
3997 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003998 */
3999
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004000static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 "year", "month", "day", "hour", "minute", "second",
4002 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004003};
4004
Tim Peters2a799bf2002-12-16 20:18:38 +00004005static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004006datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004007{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004008 PyObject *self = NULL;
4009 PyObject *state;
4010 int year;
4011 int month;
4012 int day;
4013 int hour = 0;
4014 int minute = 0;
4015 int second = 0;
4016 int usecond = 0;
4017 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004019 /* Check for invocation from pickle with __getstate__ state */
4020 if (PyTuple_GET_SIZE(args) >= 1 &&
4021 PyTuple_GET_SIZE(args) <= 2 &&
4022 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4023 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4024 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4025 {
4026 PyDateTime_DateTime *me;
4027 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004029 if (PyTuple_GET_SIZE(args) == 2) {
4030 tzinfo = PyTuple_GET_ITEM(args, 1);
4031 if (check_tzinfo_subclass(tzinfo) < 0) {
4032 PyErr_SetString(PyExc_TypeError, "bad "
4033 "tzinfo state arg");
4034 return NULL;
4035 }
4036 }
4037 aware = (char)(tzinfo != Py_None);
4038 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4039 if (me != NULL) {
4040 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004042 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4043 me->hashcode = -1;
4044 me->hastzinfo = aware;
4045 if (aware) {
4046 Py_INCREF(tzinfo);
4047 me->tzinfo = tzinfo;
4048 }
4049 }
4050 return (PyObject *)me;
4051 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004053 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4054 &year, &month, &day, &hour, &minute,
4055 &second, &usecond, &tzinfo)) {
4056 if (check_date_args(year, month, day) < 0)
4057 return NULL;
4058 if (check_time_args(hour, minute, second, usecond) < 0)
4059 return NULL;
4060 if (check_tzinfo_subclass(tzinfo) < 0)
4061 return NULL;
4062 self = new_datetime_ex(year, month, day,
4063 hour, minute, second, usecond,
4064 tzinfo, type);
4065 }
4066 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004067}
4068
Tim Petersa9bc1682003-01-11 03:39:11 +00004069/* TM_FUNC is the shared type of localtime() and gmtime(). */
4070typedef struct tm *(*TM_FUNC)(const time_t *timer);
4071
4072/* Internal helper.
4073 * Build datetime from a time_t and a distinct count of microseconds.
4074 * Pass localtime or gmtime for f, to control the interpretation of timet.
4075 */
4076static PyObject *
4077datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004078 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004080 struct tm *tm;
4081 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004083 tm = f(&timet);
4084 if (tm) {
4085 /* The platform localtime/gmtime may insert leap seconds,
4086 * indicated by tm->tm_sec > 59. We don't care about them,
4087 * except to the extent that passing them on to the datetime
4088 * constructor would raise ValueError for a reason that
4089 * made no sense to the user.
4090 */
4091 if (tm->tm_sec > 59)
4092 tm->tm_sec = 59;
4093 result = PyObject_CallFunction(cls, "iiiiiiiO",
4094 tm->tm_year + 1900,
4095 tm->tm_mon + 1,
4096 tm->tm_mday,
4097 tm->tm_hour,
4098 tm->tm_min,
4099 tm->tm_sec,
4100 us,
4101 tzinfo);
4102 }
4103 else
4104 PyErr_SetString(PyExc_ValueError,
4105 "timestamp out of range for "
4106 "platform localtime()/gmtime() function");
4107 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004108}
4109
4110/* Internal helper.
4111 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4112 * to control the interpretation of the timestamp. Since a double doesn't
4113 * have enough bits to cover a datetime's full range of precision, it's
4114 * better to call datetime_from_timet_and_us provided you have a way
4115 * to get that much precision (e.g., C time() isn't good enough).
4116 */
4117static PyObject *
4118datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004119 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004121 time_t timet;
4122 double fraction;
4123 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004125 timet = _PyTime_DoubleToTimet(timestamp);
4126 if (timet == (time_t)-1 && PyErr_Occurred())
4127 return NULL;
4128 fraction = timestamp - (double)timet;
4129 us = (int)round_to_long(fraction * 1e6);
4130 if (us < 0) {
4131 /* Truncation towards zero is not what we wanted
4132 for negative numbers (Python's mod semantics) */
4133 timet -= 1;
4134 us += 1000000;
4135 }
4136 /* If timestamp is less than one microsecond smaller than a
4137 * full second, round up. Otherwise, ValueErrors are raised
4138 * for some floats. */
4139 if (us == 1000000) {
4140 timet += 1;
4141 us = 0;
4142 }
4143 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004144}
4145
4146/* Internal helper.
4147 * Build most accurate possible datetime for current time. Pass localtime or
4148 * gmtime for f as appropriate.
4149 */
4150static PyObject *
4151datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4152{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004153 _PyTime_timeval t;
4154 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004155 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4156 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004157}
4158
Tim Peters2a799bf2002-12-16 20:18:38 +00004159/* Return best possible local time -- this isn't constrained by the
4160 * precision of a timestamp.
4161 */
4162static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004163datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004165 PyObject *self;
4166 PyObject *tzinfo = Py_None;
4167 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004169 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4170 &tzinfo))
4171 return NULL;
4172 if (check_tzinfo_subclass(tzinfo) < 0)
4173 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004175 self = datetime_best_possible(cls,
4176 tzinfo == Py_None ? localtime : gmtime,
4177 tzinfo);
4178 if (self != NULL && tzinfo != Py_None) {
4179 /* Convert UTC to tzinfo's zone. */
4180 PyObject *temp = self;
4181 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4182 Py_DECREF(temp);
4183 }
4184 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004185}
4186
Tim Petersa9bc1682003-01-11 03:39:11 +00004187/* Return best possible UTC time -- this isn't constrained by the
4188 * precision of a timestamp.
4189 */
4190static PyObject *
4191datetime_utcnow(PyObject *cls, PyObject *dummy)
4192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004194}
4195
Tim Peters2a799bf2002-12-16 20:18:38 +00004196/* Return new local datetime from timestamp (Python timestamp -- a double). */
4197static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004198datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004200 PyObject *self;
4201 double timestamp;
4202 PyObject *tzinfo = Py_None;
4203 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004205 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4206 keywords, &timestamp, &tzinfo))
4207 return NULL;
4208 if (check_tzinfo_subclass(tzinfo) < 0)
4209 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004211 self = datetime_from_timestamp(cls,
4212 tzinfo == Py_None ? localtime : gmtime,
4213 timestamp,
4214 tzinfo);
4215 if (self != NULL && tzinfo != Py_None) {
4216 /* Convert UTC to tzinfo's zone. */
4217 PyObject *temp = self;
4218 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4219 Py_DECREF(temp);
4220 }
4221 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004222}
4223
Tim Petersa9bc1682003-01-11 03:39:11 +00004224/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4225static PyObject *
4226datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4227{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004228 double timestamp;
4229 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004231 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4232 result = datetime_from_timestamp(cls, gmtime, timestamp,
4233 Py_None);
4234 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004235}
4236
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004237/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004238static PyObject *
4239datetime_strptime(PyObject *cls, PyObject *args)
4240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004241 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004242 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004244 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4245 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004246
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004247 if (module == NULL) {
4248 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004249 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004250 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004251 }
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004252 return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4253 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004254}
4255
Tim Petersa9bc1682003-01-11 03:39:11 +00004256/* Return new datetime from date/datetime and time arguments. */
4257static PyObject *
4258datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004260 static char *keywords[] = {"date", "time", NULL};
4261 PyObject *date;
4262 PyObject *time;
4263 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004265 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4266 &PyDateTime_DateType, &date,
4267 &PyDateTime_TimeType, &time)) {
4268 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004270 if (HASTZINFO(time))
4271 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4272 result = PyObject_CallFunction(cls, "iiiiiiiO",
4273 GET_YEAR(date),
4274 GET_MONTH(date),
4275 GET_DAY(date),
4276 TIME_GET_HOUR(time),
4277 TIME_GET_MINUTE(time),
4278 TIME_GET_SECOND(time),
4279 TIME_GET_MICROSECOND(time),
4280 tzinfo);
4281 }
4282 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004283}
Tim Peters2a799bf2002-12-16 20:18:38 +00004284
4285/*
4286 * Destructor.
4287 */
4288
4289static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004290datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004291{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004292 if (HASTZINFO(self)) {
4293 Py_XDECREF(self->tzinfo);
4294 }
4295 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004296}
4297
4298/*
4299 * Indirect access to tzinfo methods.
4300 */
4301
Tim Peters2a799bf2002-12-16 20:18:38 +00004302/* These are all METH_NOARGS, so don't need to check the arglist. */
4303static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004304datetime_utcoffset(PyObject *self, PyObject *unused) {
4305 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004306}
4307
4308static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004309datetime_dst(PyObject *self, PyObject *unused) {
4310 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004311}
4312
4313static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004314datetime_tzname(PyObject *self, PyObject *unused) {
4315 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004316}
4317
4318/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004319 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004320 */
4321
Tim Petersa9bc1682003-01-11 03:39:11 +00004322/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4323 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004324 */
4325static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004326add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004327 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004329 /* Note that the C-level additions can't overflow, because of
4330 * invariant bounds on the member values.
4331 */
4332 int year = GET_YEAR(date);
4333 int month = GET_MONTH(date);
4334 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4335 int hour = DATE_GET_HOUR(date);
4336 int minute = DATE_GET_MINUTE(date);
4337 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4338 int microsecond = DATE_GET_MICROSECOND(date) +
4339 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004341 assert(factor == 1 || factor == -1);
4342 if (normalize_datetime(&year, &month, &day,
4343 &hour, &minute, &second, &microsecond) < 0)
4344 return NULL;
4345 else
4346 return new_datetime(year, month, day,
4347 hour, minute, second, microsecond,
4348 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004349}
4350
4351static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004352datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004354 if (PyDateTime_Check(left)) {
4355 /* datetime + ??? */
4356 if (PyDelta_Check(right))
4357 /* datetime + delta */
4358 return add_datetime_timedelta(
4359 (PyDateTime_DateTime *)left,
4360 (PyDateTime_Delta *)right,
4361 1);
4362 }
4363 else if (PyDelta_Check(left)) {
4364 /* delta + datetime */
4365 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4366 (PyDateTime_Delta *) left,
4367 1);
4368 }
4369 Py_INCREF(Py_NotImplemented);
4370 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004371}
4372
4373static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004374datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004376 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004378 if (PyDateTime_Check(left)) {
4379 /* datetime - ??? */
4380 if (PyDateTime_Check(right)) {
4381 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004382 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004383 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004384
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004385 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4386 offset2 = offset1 = Py_None;
4387 Py_INCREF(offset1);
4388 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004389 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004390 else {
4391 offset1 = datetime_utcoffset(left, NULL);
4392 if (offset1 == NULL)
4393 return NULL;
4394 offset2 = datetime_utcoffset(right, NULL);
4395 if (offset2 == NULL) {
4396 Py_DECREF(offset1);
4397 return NULL;
4398 }
4399 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4400 PyErr_SetString(PyExc_TypeError,
4401 "can't subtract offset-naive and "
4402 "offset-aware datetimes");
4403 Py_DECREF(offset1);
4404 Py_DECREF(offset2);
4405 return NULL;
4406 }
4407 }
4408 if ((offset1 != offset2) &&
4409 delta_cmp(offset1, offset2) != 0) {
4410 offdiff = delta_subtract(offset1, offset2);
4411 if (offdiff == NULL) {
4412 Py_DECREF(offset1);
4413 Py_DECREF(offset2);
4414 return NULL;
4415 }
4416 }
4417 Py_DECREF(offset1);
4418 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004419 delta_d = ymd_to_ord(GET_YEAR(left),
4420 GET_MONTH(left),
4421 GET_DAY(left)) -
4422 ymd_to_ord(GET_YEAR(right),
4423 GET_MONTH(right),
4424 GET_DAY(right));
4425 /* These can't overflow, since the values are
4426 * normalized. At most this gives the number of
4427 * seconds in one day.
4428 */
4429 delta_s = (DATE_GET_HOUR(left) -
4430 DATE_GET_HOUR(right)) * 3600 +
4431 (DATE_GET_MINUTE(left) -
4432 DATE_GET_MINUTE(right)) * 60 +
4433 (DATE_GET_SECOND(left) -
4434 DATE_GET_SECOND(right));
4435 delta_us = DATE_GET_MICROSECOND(left) -
4436 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004437 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004438 if (offdiff != NULL) {
4439 PyObject *temp = result;
4440 result = delta_subtract(result, offdiff);
4441 Py_DECREF(temp);
4442 Py_DECREF(offdiff);
4443 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004444 }
4445 else if (PyDelta_Check(right)) {
4446 /* datetime - delta */
4447 result = add_datetime_timedelta(
4448 (PyDateTime_DateTime *)left,
4449 (PyDateTime_Delta *)right,
4450 -1);
4451 }
4452 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004454 if (result == Py_NotImplemented)
4455 Py_INCREF(result);
4456 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004457}
4458
4459/* Various ways to turn a datetime into a string. */
4460
4461static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004462datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004463{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004464 const char *type_name = Py_TYPE(self)->tp_name;
4465 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004467 if (DATE_GET_MICROSECOND(self)) {
4468 baserepr = PyUnicode_FromFormat(
4469 "%s(%d, %d, %d, %d, %d, %d, %d)",
4470 type_name,
4471 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4472 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4473 DATE_GET_SECOND(self),
4474 DATE_GET_MICROSECOND(self));
4475 }
4476 else if (DATE_GET_SECOND(self)) {
4477 baserepr = PyUnicode_FromFormat(
4478 "%s(%d, %d, %d, %d, %d, %d)",
4479 type_name,
4480 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4481 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4482 DATE_GET_SECOND(self));
4483 }
4484 else {
4485 baserepr = PyUnicode_FromFormat(
4486 "%s(%d, %d, %d, %d, %d)",
4487 type_name,
4488 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4489 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4490 }
4491 if (baserepr == NULL || ! HASTZINFO(self))
4492 return baserepr;
4493 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004494}
4495
Tim Petersa9bc1682003-01-11 03:39:11 +00004496static PyObject *
4497datetime_str(PyDateTime_DateTime *self)
4498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004499 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004500}
Tim Peters2a799bf2002-12-16 20:18:38 +00004501
4502static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004503datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004505 int sep = 'T';
4506 static char *keywords[] = {"sep", NULL};
4507 char buffer[100];
4508 PyObject *result;
4509 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004511 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4512 return NULL;
4513 if (us)
4514 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4515 GET_YEAR(self), GET_MONTH(self),
4516 GET_DAY(self), (int)sep,
4517 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4518 DATE_GET_SECOND(self), us);
4519 else
4520 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4521 GET_YEAR(self), GET_MONTH(self),
4522 GET_DAY(self), (int)sep,
4523 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4524 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004526 if (!result || !HASTZINFO(self))
4527 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004529 /* We need to append the UTC offset. */
4530 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4531 (PyObject *)self) < 0) {
4532 Py_DECREF(result);
4533 return NULL;
4534 }
4535 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4536 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004537}
4538
Tim Petersa9bc1682003-01-11 03:39:11 +00004539static PyObject *
4540datetime_ctime(PyDateTime_DateTime *self)
4541{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004542 return format_ctime((PyDateTime_Date *)self,
4543 DATE_GET_HOUR(self),
4544 DATE_GET_MINUTE(self),
4545 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004546}
4547
Tim Peters2a799bf2002-12-16 20:18:38 +00004548/* Miscellaneous methods. */
4549
Tim Petersa9bc1682003-01-11 03:39:11 +00004550static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004551datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004552{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004553 PyObject *result = NULL;
4554 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004555 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004557 if (! PyDateTime_Check(other)) {
4558 if (PyDate_Check(other)) {
4559 /* Prevent invocation of date_richcompare. We want to
4560 return NotImplemented here to give the other object
4561 a chance. But since DateTime is a subclass of
4562 Date, if the other object is a Date, it would
4563 compute an ordering based on the date part alone,
4564 and we don't want that. So force unequal or
4565 uncomparable here in that case. */
4566 if (op == Py_EQ)
4567 Py_RETURN_FALSE;
4568 if (op == Py_NE)
4569 Py_RETURN_TRUE;
4570 return cmperror(self, other);
4571 }
4572 Py_INCREF(Py_NotImplemented);
4573 return Py_NotImplemented;
4574 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004575
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004576 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004577 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4578 ((PyDateTime_DateTime *)other)->data,
4579 _PyDateTime_DATETIME_DATASIZE);
4580 return diff_to_bool(diff, op);
4581 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004582 offset1 = datetime_utcoffset(self, NULL);
4583 if (offset1 == NULL)
4584 return NULL;
4585 offset2 = datetime_utcoffset(other, NULL);
4586 if (offset2 == NULL)
4587 goto done;
4588 /* If they're both naive, or both aware and have the same offsets,
4589 * we get off cheap. Note that if they're both naive, offset1 ==
4590 * offset2 == Py_None at this point.
4591 */
4592 if ((offset1 == offset2) ||
4593 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4594 delta_cmp(offset1, offset2) == 0)) {
4595 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4596 ((PyDateTime_DateTime *)other)->data,
4597 _PyDateTime_DATETIME_DATASIZE);
4598 result = diff_to_bool(diff, op);
4599 }
4600 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004601 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004602
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004603 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004604 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4605 other);
4606 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004607 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004608 diff = GET_TD_DAYS(delta);
4609 if (diff == 0)
4610 diff = GET_TD_SECONDS(delta) |
4611 GET_TD_MICROSECONDS(delta);
4612 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004613 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004614 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004615 else {
4616 PyErr_SetString(PyExc_TypeError,
4617 "can't compare offset-naive and "
4618 "offset-aware datetimes");
4619 }
4620 done:
4621 Py_DECREF(offset1);
4622 Py_XDECREF(offset2);
4623 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004624}
4625
4626static long
4627datetime_hash(PyDateTime_DateTime *self)
4628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004629 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004630 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004631
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004632 offset = datetime_utcoffset((PyObject *)self, NULL);
4633
4634 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004635 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004637 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004638 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 self->hashcode = generic_hash(
4640 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004641 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004642 PyObject *temp1, *temp2;
4643 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004645 assert(HASTZINFO(self));
4646 days = ymd_to_ord(GET_YEAR(self),
4647 GET_MONTH(self),
4648 GET_DAY(self));
4649 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004650 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004651 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004652 temp1 = new_delta(days, seconds,
4653 DATE_GET_MICROSECOND(self),
4654 1);
4655 if (temp1 == NULL) {
4656 Py_DECREF(offset);
4657 return -1;
4658 }
4659 temp2 = delta_subtract(temp1, offset);
4660 Py_DECREF(temp1);
4661 if (temp2 == NULL) {
4662 Py_DECREF(offset);
4663 return -1;
4664 }
4665 self->hashcode = PyObject_Hash(temp2);
4666 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004667 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004668 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004669 }
4670 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004671}
Tim Peters2a799bf2002-12-16 20:18:38 +00004672
4673static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004674datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004676 PyObject *clone;
4677 PyObject *tuple;
4678 int y = GET_YEAR(self);
4679 int m = GET_MONTH(self);
4680 int d = GET_DAY(self);
4681 int hh = DATE_GET_HOUR(self);
4682 int mm = DATE_GET_MINUTE(self);
4683 int ss = DATE_GET_SECOND(self);
4684 int us = DATE_GET_MICROSECOND(self);
4685 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004687 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4688 datetime_kws,
4689 &y, &m, &d, &hh, &mm, &ss, &us,
4690 &tzinfo))
4691 return NULL;
4692 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4693 if (tuple == NULL)
4694 return NULL;
4695 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4696 Py_DECREF(tuple);
4697 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004698}
4699
4700static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004701datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004702{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004703 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004704 PyObject *offset;
4705 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004706 PyObject *tzinfo;
4707 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004709 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4710 &PyDateTime_TZInfoType, &tzinfo))
4711 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004713 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4714 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004715
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004716 /* Conversion to self's own time zone is a NOP. */
4717 if (self->tzinfo == tzinfo) {
4718 Py_INCREF(self);
4719 return (PyObject *)self;
4720 }
Tim Peters521fc152002-12-31 17:36:56 +00004721
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004722 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004723 offset = datetime_utcoffset((PyObject *)self, NULL);
4724 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004725 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004726 if (offset == Py_None) {
4727 Py_DECREF(offset);
4728 NeedAware:
4729 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4730 "a naive datetime");
4731 return NULL;
4732 }
Tim Petersf3615152003-01-01 21:51:37 +00004733
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004734 /* result = self - offset */
4735 result = add_datetime_timedelta(self,
4736 (PyDateTime_Delta *)offset, -1);
4737 Py_DECREF(offset);
4738 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004739 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004741 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004742 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4743 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4744 Py_INCREF(tzinfo);
4745 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004746
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004747 temp = result;
4748 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4749 Py_DECREF(temp);
4750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004751 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004752}
4753
4754static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004755datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004757 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004759 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004760 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004761
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004762 dst = call_dst(self->tzinfo, (PyObject *)self);
4763 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004764 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004765
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004766 if (dst != Py_None)
4767 dstflag = delta_bool((PyDateTime_Delta *)dst);
4768 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004769 }
4770 return build_struct_time(GET_YEAR(self),
4771 GET_MONTH(self),
4772 GET_DAY(self),
4773 DATE_GET_HOUR(self),
4774 DATE_GET_MINUTE(self),
4775 DATE_GET_SECOND(self),
4776 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004777}
4778
4779static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004780datetime_getdate(PyDateTime_DateTime *self)
4781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004782 return new_date(GET_YEAR(self),
4783 GET_MONTH(self),
4784 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004785}
4786
4787static PyObject *
4788datetime_gettime(PyDateTime_DateTime *self)
4789{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004790 return new_time(DATE_GET_HOUR(self),
4791 DATE_GET_MINUTE(self),
4792 DATE_GET_SECOND(self),
4793 DATE_GET_MICROSECOND(self),
4794 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004795}
4796
4797static PyObject *
4798datetime_gettimetz(PyDateTime_DateTime *self)
4799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004800 return new_time(DATE_GET_HOUR(self),
4801 DATE_GET_MINUTE(self),
4802 DATE_GET_SECOND(self),
4803 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004804 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004805}
4806
4807static PyObject *
4808datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004809{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004810 int y, m, d, hh, mm, ss;
4811 PyObject *tzinfo;
4812 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004813
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004814 tzinfo = GET_DT_TZINFO(self);
4815 if (tzinfo == Py_None) {
4816 utcself = self;
4817 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004818 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004819 else {
4820 PyObject *offset;
4821 offset = call_utcoffset(tzinfo, (PyObject *)self);
4822 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004823 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004824 if (offset == Py_None) {
4825 Py_DECREF(offset);
4826 utcself = self;
4827 Py_INCREF(utcself);
4828 }
4829 else {
4830 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4831 (PyDateTime_Delta *)offset, -1);
4832 Py_DECREF(offset);
4833 if (utcself == NULL)
4834 return NULL;
4835 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004836 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004837 y = GET_YEAR(utcself);
4838 m = GET_MONTH(utcself);
4839 d = GET_DAY(utcself);
4840 hh = DATE_GET_HOUR(utcself);
4841 mm = DATE_GET_MINUTE(utcself);
4842 ss = DATE_GET_SECOND(utcself);
4843
4844 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004845 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004846}
4847
Tim Peters371935f2003-02-01 01:52:50 +00004848/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004849
Tim Petersa9bc1682003-01-11 03:39:11 +00004850/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004851 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4852 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004853 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004854 */
4855static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004856datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004858 PyObject *basestate;
4859 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004861 basestate = PyBytes_FromStringAndSize((char *)self->data,
4862 _PyDateTime_DATETIME_DATASIZE);
4863 if (basestate != NULL) {
4864 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4865 result = PyTuple_Pack(1, basestate);
4866 else
4867 result = PyTuple_Pack(2, basestate, self->tzinfo);
4868 Py_DECREF(basestate);
4869 }
4870 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004871}
4872
4873static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004874datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004876 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004877}
4878
Tim Petersa9bc1682003-01-11 03:39:11 +00004879static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004881 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004883 {"now", (PyCFunction)datetime_now,
4884 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4885 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004887 {"utcnow", (PyCFunction)datetime_utcnow,
4888 METH_NOARGS | METH_CLASS,
4889 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004891 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4892 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4893 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004895 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4896 METH_VARARGS | METH_CLASS,
4897 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4898 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004900 {"strptime", (PyCFunction)datetime_strptime,
4901 METH_VARARGS | METH_CLASS,
4902 PyDoc_STR("string, format -> new datetime parsed from a string "
4903 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004905 {"combine", (PyCFunction)datetime_combine,
4906 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4907 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004909 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004911 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4912 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004914 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4915 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004917 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4918 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004920 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4921 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004923 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4924 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004926 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4927 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004929 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4930 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4931 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4932 "sep is used to separate the year from the time, and "
4933 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004935 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4936 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004938 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4939 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004941 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4942 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004944 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4945 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004947 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4948 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004950 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4951 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004953 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004954};
4955
Tim Petersa9bc1682003-01-11 03:39:11 +00004956static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004957PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4958\n\
4959The year, month and day arguments are required. tzinfo may be None, or an\n\
4960instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004961
Tim Petersa9bc1682003-01-11 03:39:11 +00004962static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004963 datetime_add, /* nb_add */
4964 datetime_subtract, /* nb_subtract */
4965 0, /* nb_multiply */
4966 0, /* nb_remainder */
4967 0, /* nb_divmod */
4968 0, /* nb_power */
4969 0, /* nb_negative */
4970 0, /* nb_positive */
4971 0, /* nb_absolute */
4972 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004973};
4974
Neal Norwitz227b5332006-03-22 09:28:35 +00004975static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004976 PyVarObject_HEAD_INIT(NULL, 0)
4977 "datetime.datetime", /* tp_name */
4978 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4979 0, /* tp_itemsize */
4980 (destructor)datetime_dealloc, /* tp_dealloc */
4981 0, /* tp_print */
4982 0, /* tp_getattr */
4983 0, /* tp_setattr */
4984 0, /* tp_reserved */
4985 (reprfunc)datetime_repr, /* tp_repr */
4986 &datetime_as_number, /* tp_as_number */
4987 0, /* tp_as_sequence */
4988 0, /* tp_as_mapping */
4989 (hashfunc)datetime_hash, /* tp_hash */
4990 0, /* tp_call */
4991 (reprfunc)datetime_str, /* tp_str */
4992 PyObject_GenericGetAttr, /* tp_getattro */
4993 0, /* tp_setattro */
4994 0, /* tp_as_buffer */
4995 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4996 datetime_doc, /* tp_doc */
4997 0, /* tp_traverse */
4998 0, /* tp_clear */
4999 datetime_richcompare, /* tp_richcompare */
5000 0, /* tp_weaklistoffset */
5001 0, /* tp_iter */
5002 0, /* tp_iternext */
5003 datetime_methods, /* tp_methods */
5004 0, /* tp_members */
5005 datetime_getset, /* tp_getset */
5006 &PyDateTime_DateType, /* tp_base */
5007 0, /* tp_dict */
5008 0, /* tp_descr_get */
5009 0, /* tp_descr_set */
5010 0, /* tp_dictoffset */
5011 0, /* tp_init */
5012 datetime_alloc, /* tp_alloc */
5013 datetime_new, /* tp_new */
5014 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005015};
5016
5017/* ---------------------------------------------------------------------------
5018 * Module methods and initialization.
5019 */
5020
5021static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005022 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005023};
5024
Tim Peters9ddf40b2004-06-20 22:41:32 +00005025/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5026 * datetime.h.
5027 */
5028static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005029 &PyDateTime_DateType,
5030 &PyDateTime_DateTimeType,
5031 &PyDateTime_TimeType,
5032 &PyDateTime_DeltaType,
5033 &PyDateTime_TZInfoType,
5034 new_date_ex,
5035 new_datetime_ex,
5036 new_time_ex,
5037 new_delta_ex,
5038 datetime_fromtimestamp,
5039 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005040};
5041
5042
Martin v. Löwis1a214512008-06-11 05:26:20 +00005043
5044static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005045 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005046 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005047 "Fast implementation of the datetime type.",
5048 -1,
5049 module_methods,
5050 NULL,
5051 NULL,
5052 NULL,
5053 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005054};
5055
Tim Peters2a799bf2002-12-16 20:18:38 +00005056PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005057PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005059 PyObject *m; /* a module object */
5060 PyObject *d; /* its dict */
5061 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005062 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005064 m = PyModule_Create(&datetimemodule);
5065 if (m == NULL)
5066 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005068 if (PyType_Ready(&PyDateTime_DateType) < 0)
5069 return NULL;
5070 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5071 return NULL;
5072 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5073 return NULL;
5074 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5075 return NULL;
5076 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5077 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005078 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5079 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005081 /* timedelta values */
5082 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005084 x = new_delta(0, 0, 1, 0);
5085 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5086 return NULL;
5087 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005089 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5090 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5091 return NULL;
5092 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005094 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5095 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5096 return NULL;
5097 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005099 /* date values */
5100 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005102 x = new_date(1, 1, 1);
5103 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5104 return NULL;
5105 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005107 x = new_date(MAXYEAR, 12, 31);
5108 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5109 return NULL;
5110 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005112 x = new_delta(1, 0, 0, 0);
5113 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5114 return NULL;
5115 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005117 /* time values */
5118 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005120 x = new_time(0, 0, 0, 0, Py_None);
5121 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5122 return NULL;
5123 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005125 x = new_time(23, 59, 59, 999999, Py_None);
5126 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5127 return NULL;
5128 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005130 x = new_delta(0, 0, 1, 0);
5131 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5132 return NULL;
5133 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005135 /* datetime values */
5136 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005138 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5139 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5140 return NULL;
5141 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005143 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5144 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5145 return NULL;
5146 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005148 x = new_delta(0, 0, 1, 0);
5149 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5150 return NULL;
5151 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005152
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005153 /* timezone values */
5154 d = PyDateTime_TimeZoneType.tp_dict;
5155
5156 delta = new_delta(0, 0, 0, 0);
5157 if (delta == NULL)
5158 return NULL;
5159 x = new_timezone(delta, NULL);
5160 Py_DECREF(delta);
5161 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5162 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005163 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005164
5165 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5166 if (delta == NULL)
5167 return NULL;
5168 x = new_timezone(delta, NULL);
5169 Py_DECREF(delta);
5170 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5171 return NULL;
5172 Py_DECREF(x);
5173
5174 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5175 if (delta == NULL)
5176 return NULL;
5177 x = new_timezone(delta, NULL);
5178 Py_DECREF(delta);
5179 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5180 return NULL;
5181 Py_DECREF(x);
5182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005183 /* module initialization */
5184 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5185 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005187 Py_INCREF(&PyDateTime_DateType);
5188 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005190 Py_INCREF(&PyDateTime_DateTimeType);
5191 PyModule_AddObject(m, "datetime",
5192 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005194 Py_INCREF(&PyDateTime_TimeType);
5195 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005197 Py_INCREF(&PyDateTime_DeltaType);
5198 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005200 Py_INCREF(&PyDateTime_TZInfoType);
5201 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005202
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005203 Py_INCREF(&PyDateTime_TimeZoneType);
5204 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005206 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5207 if (x == NULL)
5208 return NULL;
5209 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005211 /* A 4-year cycle has an extra leap day over what we'd get from
5212 * pasting together 4 single years.
5213 */
5214 assert(DI4Y == 4 * 365 + 1);
5215 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005217 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5218 * get from pasting together 4 100-year cycles.
5219 */
5220 assert(DI400Y == 4 * DI100Y + 1);
5221 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005223 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5224 * pasting together 25 4-year cycles.
5225 */
5226 assert(DI100Y == 25 * DI4Y - 1);
5227 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005229 us_per_us = PyLong_FromLong(1);
5230 us_per_ms = PyLong_FromLong(1000);
5231 us_per_second = PyLong_FromLong(1000000);
5232 us_per_minute = PyLong_FromLong(60000000);
5233 seconds_per_day = PyLong_FromLong(24 * 3600);
5234 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5235 us_per_minute == NULL || seconds_per_day == NULL)
5236 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005238 /* The rest are too big for 32-bit ints, but even
5239 * us_per_week fits in 40 bits, so doubles should be exact.
5240 */
5241 us_per_hour = PyLong_FromDouble(3600000000.0);
5242 us_per_day = PyLong_FromDouble(86400000000.0);
5243 us_per_week = PyLong_FromDouble(604800000000.0);
5244 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5245 return NULL;
5246 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005247}
Tim Petersf3615152003-01-01 21:51:37 +00005248
5249/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005250Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005251 x.n = x stripped of its timezone -- its naive time.
5252 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005253 return None
Tim Petersf3615152003-01-01 21:51:37 +00005254 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005255 return None
Tim Petersf3615152003-01-01 21:51:37 +00005256 x.s = x's standard offset, x.o - x.d
5257
5258Now some derived rules, where k is a duration (timedelta).
5259
52601. x.o = x.s + x.d
5261 This follows from the definition of x.s.
5262
Tim Petersc5dc4da2003-01-02 17:55:03 +000052632. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005264 This is actually a requirement, an assumption we need to make about
5265 sane tzinfo classes.
5266
52673. The naive UTC time corresponding to x is x.n - x.o.
5268 This is again a requirement for a sane tzinfo class.
5269
52704. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005271 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005272
Tim Petersc5dc4da2003-01-02 17:55:03 +000052735. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005274 Again follows from how arithmetic is defined.
5275
Tim Peters8bb5ad22003-01-24 02:44:45 +00005276Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005277(meaning that the various tzinfo methods exist, and don't blow up or return
5278None when called).
5279
Tim Petersa9bc1682003-01-11 03:39:11 +00005280The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005281x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005282
5283By #3, we want
5284
Tim Peters8bb5ad22003-01-24 02:44:45 +00005285 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005286
5287The algorithm starts by attaching tz to x.n, and calling that y. So
5288x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5289becomes true; in effect, we want to solve [2] for k:
5290
Tim Peters8bb5ad22003-01-24 02:44:45 +00005291 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005292
5293By #1, this is the same as
5294
Tim Peters8bb5ad22003-01-24 02:44:45 +00005295 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005296
5297By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5298Substituting that into [3],
5299
Tim Peters8bb5ad22003-01-24 02:44:45 +00005300 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5301 k - (y+k).s - (y+k).d = 0; rearranging,
5302 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5303 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005304
Tim Peters8bb5ad22003-01-24 02:44:45 +00005305On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5306approximate k by ignoring the (y+k).d term at first. Note that k can't be
5307very large, since all offset-returning methods return a duration of magnitude
5308less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5309be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005310
5311In any case, the new value is
5312
Tim Peters8bb5ad22003-01-24 02:44:45 +00005313 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005314
Tim Peters8bb5ad22003-01-24 02:44:45 +00005315It's helpful to step back at look at [4] from a higher level: it's simply
5316mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005317
5318At this point, if
5319
Tim Peters8bb5ad22003-01-24 02:44:45 +00005320 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005321
5322we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005323at the start of daylight time. Picture US Eastern for concreteness. The wall
5324time 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 +00005325sense then. The docs ask that an Eastern tzinfo class consider such a time to
5326be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5327on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005328the only spelling that makes sense on the local wall clock.
5329
Tim Petersc5dc4da2003-01-02 17:55:03 +00005330In fact, if [5] holds at this point, we do have the standard-time spelling,
5331but that takes a bit of proof. We first prove a stronger result. What's the
5332difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005333
Tim Peters8bb5ad22003-01-24 02:44:45 +00005334 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005335
Tim Petersc5dc4da2003-01-02 17:55:03 +00005336Now
5337 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005338 (y + y.s).n = by #5
5339 y.n + y.s = since y.n = x.n
5340 x.n + y.s = since z and y are have the same tzinfo member,
5341 y.s = z.s by #2
5342 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005343
Tim Petersc5dc4da2003-01-02 17:55:03 +00005344Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005345
Tim Petersc5dc4da2003-01-02 17:55:03 +00005346 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005347 x.n - ((x.n + z.s) - z.o) = expanding
5348 x.n - x.n - z.s + z.o = cancelling
5349 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005350 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005351
Tim Petersc5dc4da2003-01-02 17:55:03 +00005352So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005353
Tim Petersc5dc4da2003-01-02 17:55:03 +00005354If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005355spelling we wanted in the endcase described above. We're done. Contrarily,
5356if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005357
Tim Petersc5dc4da2003-01-02 17:55:03 +00005358If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5359add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005360local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005361
Tim Petersc5dc4da2003-01-02 17:55:03 +00005362Let
Tim Petersf3615152003-01-01 21:51:37 +00005363
Tim Peters4fede1a2003-01-04 00:26:59 +00005364 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005365
Tim Peters4fede1a2003-01-04 00:26:59 +00005366and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005367
Tim Peters8bb5ad22003-01-24 02:44:45 +00005368 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005369
Tim Peters8bb5ad22003-01-24 02:44:45 +00005370If so, we're done. If not, the tzinfo class is insane, according to the
5371assumptions we've made. This also requires a bit of proof. As before, let's
5372compute the difference between the LHS and RHS of [8] (and skipping some of
5373the justifications for the kinds of substitutions we've done several times
5374already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005375
Tim Peters8bb5ad22003-01-24 02:44:45 +00005376 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005377 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5378 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5379 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5380 - z.n + z.n - z.o + z'.o = cancel z.n
5381 - z.o + z'.o = #1 twice
5382 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5383 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005384
5385So 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 +00005386we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5387return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005388
Tim Peters8bb5ad22003-01-24 02:44:45 +00005389How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5390a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5391would have to change the result dst() returns: we start in DST, and moving
5392a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005393
Tim Peters8bb5ad22003-01-24 02:44:45 +00005394There isn't a sane case where this can happen. The closest it gets is at
5395the end of DST, where there's an hour in UTC with no spelling in a hybrid
5396tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5397that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5398UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5399time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5400clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5401standard time. Since that's what the local clock *does*, we want to map both
5402UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005403in local time, but so it goes -- it's the way the local clock works.
5404
Tim Peters8bb5ad22003-01-24 02:44:45 +00005405When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5406so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5407z' = 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 +00005408(correctly) concludes that z' is not UTC-equivalent to x.
5409
5410Because we know z.d said z was in daylight time (else [5] would have held and
5411we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005412and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005413return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5414but the reasoning doesn't depend on the example -- it depends on there being
5415two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005416z' must be in standard time, and is the spelling we want in this case.
5417
5418Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5419concerned (because it takes z' as being in standard time rather than the
5420daylight time we intend here), but returning it gives the real-life "local
5421clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5422tz.
5423
5424When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5425the 1:MM standard time spelling we want.
5426
5427So how can this break? One of the assumptions must be violated. Two
5428possibilities:
5429
54301) [2] effectively says that y.s is invariant across all y belong to a given
5431 time zone. This isn't true if, for political reasons or continental drift,
5432 a region decides to change its base offset from UTC.
5433
54342) There may be versions of "double daylight" time where the tail end of
5435 the analysis gives up a step too early. I haven't thought about that
5436 enough to say.
5437
5438In any case, it's clear that the default fromutc() is strong enough to handle
5439"almost all" time zones: so long as the standard offset is invariant, it
5440doesn't matter if daylight time transition points change from year to year, or
5441if daylight time is skipped in some years; it doesn't matter how large or
5442small dst() may get within its bounds; and it doesn't even matter if some
5443perverse time zone returns a negative dst()). So a breaking case must be
5444pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005445--------------------------------------------------------------------------- */