blob: b2505d1d7d934286caaa42083d094c5b938d1907 [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
Tim Peters1b6f7a92004-06-20 02:50:16 +000011#include "timefuncs.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
244 * can see is 0 (this can happen in some normalization endcases),
245 * so we'll just special-case that.
246 */
247 assert (year >= 0);
248 if (y >= 0)
249 return y*365 + y/4 - y/100 + y/400;
250 else {
251 assert(y == -1);
252 return -366;
253 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000254}
255
256/* Number of days in 4, 100, and 400 year cycles. That these have
257 * the correct values is asserted in the module init function.
258 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259#define DI4Y 1461 /* days_before_year(5); days in 4 years */
260#define DI100Y 36524 /* days_before_year(101); days in 100 years */
261#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000262
263/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
264static void
265ord_to_ymd(int ordinal, int *year, int *month, int *day)
266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
270 * leap years repeats exactly every 400 years. The basic strategy is
271 * to find the closest 400-year boundary at or before ordinal, then
272 * work with the offset from that boundary to ordinal. Life is much
273 * clearer if we subtract 1 from ordinal first -- then the values
274 * of ordinal at 400-year boundaries are exactly those divisible
275 * by DI400Y:
276 *
277 * D M Y n n-1
278 * -- --- ---- ---------- ----------------
279 * 31 Dec -400 -DI400Y -DI400Y -1
280 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
281 * ...
282 * 30 Dec 000 -1 -2
283 * 31 Dec 000 0 -1
284 * 1 Jan 001 1 0 400-year boundary
285 * 2 Jan 001 2 1
286 * 3 Jan 001 3 2
287 * ...
288 * 31 Dec 400 DI400Y DI400Y -1
289 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
290 */
291 assert(ordinal >= 1);
292 --ordinal;
293 n400 = ordinal / DI400Y;
294 n = ordinal % DI400Y;
295 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 /* Now n is the (non-negative) offset, in days, from January 1 of
298 * year, to the desired date. Now compute how many 100-year cycles
299 * precede n.
300 * Note that it's possible for n100 to equal 4! In that case 4 full
301 * 100-year cycles precede the desired day, which implies the
302 * desired day is December 31 at the end of a 400-year cycle.
303 */
304 n100 = n / DI100Y;
305 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 /* Now compute how many 4-year cycles precede it. */
308 n4 = n / DI4Y;
309 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 /* And now how many single years. Again n1 can be 4, and again
312 * meaning that the desired day is December 31 at the end of the
313 * 4-year cycle.
314 */
315 n1 = n / 365;
316 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 *year += n100 * 100 + n4 * 4 + n1;
319 if (n1 == 4 || n100 == 4) {
320 assert(n == 0);
321 *year -= 1;
322 *month = 12;
323 *day = 31;
324 return;
325 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 /* Now the year is correct, and n is the offset from January 1. We
328 * find the month via an estimate that's either exact or one too
329 * large.
330 */
331 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
332 assert(leapyear == is_leap(*year));
333 *month = (n + 50) >> 5;
334 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
335 if (preceding > n) {
336 /* estimate is too large */
337 *month -= 1;
338 preceding -= days_in_month(*year, *month);
339 }
340 n -= preceding;
341 assert(0 <= n);
342 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000345}
346
347/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
348static int
349ymd_to_ord(int year, int month, int day)
350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000352}
353
354/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
355static int
356weekday(int year, int month, int day)
357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000359}
360
361/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
362 * first calendar week containing a Thursday.
363 */
364static int
365iso_week1_monday(int year)
366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
368 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
369 int first_weekday = (first_day + 6) % 7;
370 /* ordinal of closest Monday at or before 1/1 */
371 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
374 week1_monday += 7;
375 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000376}
377
378/* ---------------------------------------------------------------------------
379 * Range checkers.
380 */
381
382/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
383 * If not, raise OverflowError and return -1.
384 */
385static int
386check_delta_day_range(int days)
387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
389 return 0;
390 PyErr_Format(PyExc_OverflowError,
391 "days=%d; must have magnitude <= %d",
392 days, MAX_DELTA_DAYS);
393 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000394}
395
396/* Check that date arguments are in range. Return 0 if they are. If they
397 * aren't, raise ValueError and return -1.
398 */
399static int
400check_date_args(int year, int month, int day)
401{
402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 if (year < MINYEAR || year > MAXYEAR) {
404 PyErr_SetString(PyExc_ValueError,
405 "year is out of range");
406 return -1;
407 }
408 if (month < 1 || month > 12) {
409 PyErr_SetString(PyExc_ValueError,
410 "month must be in 1..12");
411 return -1;
412 }
413 if (day < 1 || day > days_in_month(year, month)) {
414 PyErr_SetString(PyExc_ValueError,
415 "day is out of range for month");
416 return -1;
417 }
418 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000419}
420
421/* Check that time arguments are in range. Return 0 if they are. If they
422 * aren't, raise ValueError and return -1.
423 */
424static int
425check_time_args(int h, int m, int s, int us)
426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 if (h < 0 || h > 23) {
428 PyErr_SetString(PyExc_ValueError,
429 "hour must be in 0..23");
430 return -1;
431 }
432 if (m < 0 || m > 59) {
433 PyErr_SetString(PyExc_ValueError,
434 "minute must be in 0..59");
435 return -1;
436 }
437 if (s < 0 || s > 59) {
438 PyErr_SetString(PyExc_ValueError,
439 "second must be in 0..59");
440 return -1;
441 }
442 if (us < 0 || us > 999999) {
443 PyErr_SetString(PyExc_ValueError,
444 "microsecond must be in 0..999999");
445 return -1;
446 }
447 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000448}
449
450/* ---------------------------------------------------------------------------
451 * Normalization utilities.
452 */
453
454/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
455 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
456 * at least factor, enough of *lo is converted into "hi" units so that
457 * 0 <= *lo < factor. The input values must be such that int overflow
458 * is impossible.
459 */
460static void
461normalize_pair(int *hi, int *lo, int factor)
462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 assert(factor > 0);
464 assert(lo != hi);
465 if (*lo < 0 || *lo >= factor) {
466 const int num_hi = divmod(*lo, factor, lo);
467 const int new_hi = *hi + num_hi;
468 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
469 *hi = new_hi;
470 }
471 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000472}
473
474/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 * 0 <= *s < 24*3600
476 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000477 * The input values must be such that the internals don't overflow.
478 * The way this routine is used, we don't get close.
479 */
480static void
481normalize_d_s_us(int *d, int *s, int *us)
482{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 if (*us < 0 || *us >= 1000000) {
484 normalize_pair(s, us, 1000000);
485 /* |s| can't be bigger than about
486 * |original s| + |original us|/1000000 now.
487 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 }
490 if (*s < 0 || *s >= 24*3600) {
491 normalize_pair(d, s, 24*3600);
492 /* |d| can't be bigger than about
493 * |original d| +
494 * (|original s| + |original us|/1000000) / (24*3600) now.
495 */
496 }
497 assert(0 <= *s && *s < 24*3600);
498 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000499}
500
501/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 * 1 <= *m <= 12
503 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000504 * The input values must be such that the internals don't overflow.
505 * The way this routine is used, we don't get close.
506 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000507static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000508normalize_y_m_d(int *y, int *m, int *d)
509{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 /* This gets muddy: the proper range for day can't be determined
513 * without knowing the correct month and year, but if day is, e.g.,
514 * plus or minus a million, the current month and year values make
515 * no sense (and may also be out of bounds themselves).
516 * Saying 12 months == 1 year should be non-controversial.
517 */
518 if (*m < 1 || *m > 12) {
519 --*m;
520 normalize_pair(y, m, 12);
521 ++*m;
522 /* |y| can't be bigger than about
523 * |original y| + |original m|/12 now.
524 */
525 }
526 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 /* Now only day can be out of bounds (year may also be out of bounds
529 * for a datetime object, but we don't care about that here).
530 * If day is out of bounds, what to do is arguable, but at least the
531 * method here is principled and explainable.
532 */
533 dim = days_in_month(*y, *m);
534 if (*d < 1 || *d > dim) {
535 /* Move day-1 days from the first of the month. First try to
536 * get off cheap if we're only one day out of range
537 * (adjustments for timezone alone can't be worse than that).
538 */
539 if (*d == 0) {
540 --*m;
541 if (*m > 0)
542 *d = days_in_month(*y, *m);
543 else {
544 --*y;
545 *m = 12;
546 *d = 31;
547 }
548 }
549 else if (*d == dim + 1) {
550 /* move forward a day */
551 ++*m;
552 *d = 1;
553 if (*m > 12) {
554 *m = 1;
555 ++*y;
556 }
557 }
558 else {
559 int ordinal = ymd_to_ord(*y, *m, 1) +
560 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000561 if (ordinal < 1 || ordinal > MAXORDINAL) {
562 goto error;
563 } else {
564 ord_to_ymd(ordinal, y, m, d);
565 return 0;
566 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 }
568 }
569 assert(*m > 0);
570 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000571 if (MINYEAR <= *y && *y <= MAXYEAR)
572 return 0;
573 error:
574 PyErr_SetString(PyExc_OverflowError,
575 "date value out of range");
576 return -1;
577
Tim Peters2a799bf2002-12-16 20:18:38 +0000578}
579
580/* Fiddle out-of-bounds months and days so that the result makes some kind
581 * of sense. The parameters are both inputs and outputs. Returns < 0 on
582 * failure, where failure means the adjusted year is out of bounds.
583 */
584static int
585normalize_date(int *year, int *month, int *day)
586{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000587 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000588}
589
590/* Force all the datetime fields into range. The parameters are both
591 * inputs and outputs. Returns < 0 on error.
592 */
593static int
594normalize_datetime(int *year, int *month, int *day,
595 int *hour, int *minute, int *second,
596 int *microsecond)
597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 normalize_pair(second, microsecond, 1000000);
599 normalize_pair(minute, second, 60);
600 normalize_pair(hour, minute, 60);
601 normalize_pair(day, hour, 24);
602 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000603}
604
605/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000606 * Basic object allocation: tp_alloc implementations. These allocate
607 * Python objects of the right size and type, and do the Python object-
608 * initialization bit. If there's not enough memory, they return NULL after
609 * setting MemoryError. All data members remain uninitialized trash.
610 *
611 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000612 * member is needed. This is ugly, imprecise, and possibly insecure.
613 * tp_basicsize for the time and datetime types is set to the size of the
614 * struct that has room for the tzinfo member, so subclasses in Python will
615 * allocate enough space for a tzinfo member whether or not one is actually
616 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
617 * part is that PyType_GenericAlloc() (which subclasses in Python end up
618 * using) just happens today to effectively ignore the nitems argument
619 * when tp_itemsize is 0, which it is for these type objects. If that
620 * changes, perhaps the callers of tp_alloc slots in this file should
621 * be changed to force a 0 nitems argument unless the type being allocated
622 * is a base type implemented in this file (so that tp_alloc is time_alloc
623 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000624 */
625
626static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000627time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 self = (PyObject *)
632 PyObject_MALLOC(aware ?
633 sizeof(PyDateTime_Time) :
634 sizeof(_PyDateTime_BaseTime));
635 if (self == NULL)
636 return (PyObject *)PyErr_NoMemory();
637 PyObject_INIT(self, type);
638 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000639}
640
641static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000642datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 self = (PyObject *)
647 PyObject_MALLOC(aware ?
648 sizeof(PyDateTime_DateTime) :
649 sizeof(_PyDateTime_BaseDateTime));
650 if (self == NULL)
651 return (PyObject *)PyErr_NoMemory();
652 PyObject_INIT(self, type);
653 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000654}
655
656/* ---------------------------------------------------------------------------
657 * Helpers for setting object fields. These work on pointers to the
658 * appropriate base class.
659 */
660
661/* For date and datetime. */
662static void
663set_date_fields(PyDateTime_Date *self, int y, int m, int d)
664{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 self->hashcode = -1;
666 SET_YEAR(self, y);
667 SET_MONTH(self, m);
668 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000669}
670
671/* ---------------------------------------------------------------------------
672 * Create various objects, mostly without range checking.
673 */
674
675/* Create a date instance with no range checking. */
676static PyObject *
677new_date_ex(int year, int month, int day, PyTypeObject *type)
678{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
682 if (self != NULL)
683 set_date_fields(self, year, month, day);
684 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000685}
686
687#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000689
690/* Create a datetime instance with no range checking. */
691static PyObject *
692new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 PyDateTime_DateTime *self;
696 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
699 if (self != NULL) {
700 self->hastzinfo = aware;
701 set_date_fields((PyDateTime_Date *)self, year, month, day);
702 DATE_SET_HOUR(self, hour);
703 DATE_SET_MINUTE(self, minute);
704 DATE_SET_SECOND(self, second);
705 DATE_SET_MICROSECOND(self, usecond);
706 if (aware) {
707 Py_INCREF(tzinfo);
708 self->tzinfo = tzinfo;
709 }
710 }
711 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000712}
713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
715 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
716 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000717
718/* Create a time instance with no range checking. */
719static PyObject *
720new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000722{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 PyDateTime_Time *self;
724 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
727 if (self != NULL) {
728 self->hastzinfo = aware;
729 self->hashcode = -1;
730 TIME_SET_HOUR(self, hour);
731 TIME_SET_MINUTE(self, minute);
732 TIME_SET_SECOND(self, second);
733 TIME_SET_MICROSECOND(self, usecond);
734 if (aware) {
735 Py_INCREF(tzinfo);
736 self->tzinfo = tzinfo;
737 }
738 }
739 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000740}
741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742#define new_time(hh, mm, ss, us, tzinfo) \
743 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000744
745/* Create a timedelta instance. Normalize the members iff normalize is
746 * true. Passing false is a speed optimization, if you know for sure
747 * that seconds and microseconds are already in their proper ranges. In any
748 * case, raises OverflowError and returns NULL if the normalized days is out
749 * of range).
750 */
751static PyObject *
752new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000754{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000757 if (normalize)
758 normalize_d_s_us(&days, &seconds, &microseconds);
759 assert(0 <= seconds && seconds < 24*3600);
760 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 if (check_delta_day_range(days) < 0)
763 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
766 if (self != NULL) {
767 self->hashcode = -1;
768 SET_TD_DAYS(self, days);
769 SET_TD_SECONDS(self, seconds);
770 SET_TD_MICROSECONDS(self, microseconds);
771 }
772 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000773}
774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775#define new_delta(d, s, us, normalize) \
776 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000777
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000778
779typedef struct
780{
781 PyObject_HEAD
782 PyObject *offset;
783 PyObject *name;
784} PyDateTime_TimeZone;
785
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000786PyObject *PyDateTime_TimeZone_UTC;
787
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000788/* Create new timezone instance checking offset range. This
789 function does not check the name argument. Caller must assure
790 that offset is a timedelta instance and name is either NULL
791 or a unicode object. */
792static PyObject *
793new_timezone(PyObject *offset, PyObject *name)
794{
795 PyDateTime_TimeZone *self;
796 PyTypeObject *type = &PyDateTime_TimeZoneType;
797
798 assert(offset != NULL);
799 assert(PyDelta_Check(offset));
800 assert(name == NULL || PyUnicode_Check(name));
801
802 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
803 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
804 " representing a whole number of minutes");
805 return NULL;
806 }
807 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
808 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
809 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
810 " strictly between -timedelta(hours=24) and"
811 " timedelta(hours=24).");
812 return NULL;
813 }
814
815 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
816 if (self == NULL) {
817 return NULL;
818 }
819 Py_INCREF(offset);
820 self->offset = offset;
821 Py_XINCREF(name);
822 self->name = name;
823 return (PyObject *)self;
824}
825
Tim Petersb0c854d2003-05-17 15:57:00 +0000826/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000827 * tzinfo helpers.
828 */
829
Tim Peters855fe882002-12-22 03:43:39 +0000830/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
831 * raise TypeError and return -1.
832 */
833static int
834check_tzinfo_subclass(PyObject *p)
835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 if (p == Py_None || PyTZInfo_Check(p))
837 return 0;
838 PyErr_Format(PyExc_TypeError,
839 "tzinfo argument must be None or of a tzinfo subclass, "
840 "not type '%s'",
841 Py_TYPE(p)->tp_name);
842 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000843}
844
Tim Peters2a799bf2002-12-16 20:18:38 +0000845/* If self has a tzinfo member, return a BORROWED reference to it. Else
846 * return NULL, which is NOT AN ERROR. There are no error returns here,
847 * and the caller must not decref the result.
848 */
849static PyObject *
850get_tzinfo_member(PyObject *self)
851{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 if (PyDateTime_Check(self) && HASTZINFO(self))
855 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
856 else if (PyTime_Check(self) && HASTZINFO(self))
857 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000860}
861
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000862/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
863 * be an instance of the tzinfo class. If the method returns None, this
864 * returns None. If the method doesn't return None or timedelta, TypeError is
865 * raised and this returns NULL. If it returns a timedelta and the value is
866 * out of range or isn't a whole number of minutes, ValueError is raised and
867 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000868 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000869static PyObject *
870call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000871{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000872 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000875 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000877
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000878 if (tzinfo == Py_None)
879 Py_RETURN_NONE;
880 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
881 if (offset == Py_None || offset == NULL)
882 return offset;
883 if (PyDelta_Check(offset)) {
884 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
885 Py_DECREF(offset);
886 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
887 " representing a whole number of minutes");
888 return NULL;
889 }
890 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
891 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
892 Py_DECREF(offset);
893 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
894 " strictly between -timedelta(hours=24) and"
895 " timedelta(hours=24).");
896 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 }
898 }
899 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000900 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 PyErr_Format(PyExc_TypeError,
902 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000903 "timedelta, not '%.200s'",
904 name, Py_TYPE(offset)->tp_name);
905 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000907
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000908 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000909}
910
911/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
912 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
913 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000914 * doesn't return None or timedelta, TypeError is raised and this returns -1.
915 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
916 * # of minutes), ValueError is raised and this returns -1. Else *none is
917 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000918 */
Tim Peters855fe882002-12-22 03:43:39 +0000919static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000920call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
921{
922 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000923}
924
Tim Peters2a799bf2002-12-16 20:18:38 +0000925/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
926 * result. tzinfo must be an instance of the tzinfo class. If dst()
927 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000928 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000929 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000930 * ValueError is raised and this returns -1. Else *none is set to 0 and
931 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000932 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000933static PyObject *
934call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000935{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000936 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000937}
938
Tim Petersbad8ff02002-12-30 20:52:32 +0000939/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000940 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000941 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000942 * returns NULL. If the result is a string, we ensure it is a Unicode
943 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000944 */
945static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000946call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 assert(tzinfo != NULL);
951 assert(check_tzinfo_subclass(tzinfo) >= 0);
952 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000955 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000956
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000957 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
958
959 if (result == NULL || result == Py_None)
960 return result;
961
962 if (!PyUnicode_Check(result)) {
963 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
964 "return None or a string, not '%s'",
965 Py_TYPE(result)->tp_name);
966 Py_DECREF(result);
967 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000969
970 return result;
Tim Peters00237032002-12-27 02:21:51 +0000971}
972
Tim Peters2a799bf2002-12-16 20:18:38 +0000973/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
974 * stuff
975 * ", tzinfo=" + repr(tzinfo)
976 * before the closing ")".
977 */
978static PyObject *
979append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 assert(PyUnicode_Check(repr));
984 assert(tzinfo);
985 if (tzinfo == Py_None)
986 return repr;
987 /* Get rid of the trailing ')'. */
988 assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
989 temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
990 PyUnicode_GET_SIZE(repr) - 1);
991 Py_DECREF(repr);
992 if (temp == NULL)
993 return NULL;
994 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
995 Py_DECREF(temp);
996 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +0000997}
998
999/* ---------------------------------------------------------------------------
1000 * String format helpers.
1001 */
1002
1003static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001004format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 static const char *DayNames[] = {
1007 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1008 };
1009 static const char *MonthNames[] = {
1010 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1011 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1012 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1017 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1018 GET_DAY(date), hours, minutes, seconds,
1019 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001020}
1021
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001022static PyObject *delta_negative(PyDateTime_Delta *self);
1023
Tim Peters2a799bf2002-12-16 20:18:38 +00001024/* Add an hours & minutes UTC offset string to buf. buf has no more than
1025 * buflen bytes remaining. The UTC offset is gotten by calling
1026 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1027 * *buf, and that's all. Else the returned value is checked for sanity (an
1028 * integer in range), and if that's OK it's converted to an hours & minutes
1029 * string of the form
1030 * sign HH sep MM
1031 * Returns 0 if everything is OK. If the return value from utcoffset() is
1032 * bogus, an appropriate exception is set and -1 is returned.
1033 */
1034static int
Tim Peters328fff72002-12-20 01:31:27 +00001035format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001037{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001038 PyObject *offset;
1039 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001043
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001044 offset = call_utcoffset(tzinfo, tzinfoarg);
1045 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001047 if (offset == Py_None) {
1048 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 *buf = '\0';
1050 return 0;
1051 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001052 /* Offset is normalized, so it is negative if days < 0 */
1053 if (GET_TD_DAYS(offset) < 0) {
1054 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001056 offset = delta_negative((PyDateTime_Delta *)offset);
1057 Py_DECREF(temp);
1058 if (offset == NULL)
1059 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001061 else {
1062 sign = '+';
1063 }
1064 /* Offset is not negative here. */
1065 seconds = GET_TD_SECONDS(offset);
1066 Py_DECREF(offset);
1067 minutes = divmod(seconds, 60, &seconds);
1068 hours = divmod(minutes, 60, &minutes);
1069 assert(seconds == 0);
1070 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001074}
1075
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001076static PyObject *
1077make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 PyObject *temp;
1080 PyObject *tzinfo = get_tzinfo_member(object);
1081 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1082 if (Zreplacement == NULL)
1083 return NULL;
1084 if (tzinfo == Py_None || tzinfo == NULL)
1085 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 assert(tzinfoarg != NULL);
1088 temp = call_tzname(tzinfo, tzinfoarg);
1089 if (temp == NULL)
1090 goto Error;
1091 if (temp == Py_None) {
1092 Py_DECREF(temp);
1093 return Zreplacement;
1094 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 assert(PyUnicode_Check(temp));
1097 /* Since the tzname is getting stuffed into the
1098 * format, we have to double any % signs so that
1099 * strftime doesn't treat them as format codes.
1100 */
1101 Py_DECREF(Zreplacement);
1102 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1103 Py_DECREF(temp);
1104 if (Zreplacement == NULL)
1105 return NULL;
1106 if (!PyUnicode_Check(Zreplacement)) {
1107 PyErr_SetString(PyExc_TypeError,
1108 "tzname.replace() did not return a string");
1109 goto Error;
1110 }
1111 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001112
1113 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 Py_DECREF(Zreplacement);
1115 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001116}
1117
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001118static PyObject *
1119make_freplacement(PyObject *object)
1120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 char freplacement[64];
1122 if (PyTime_Check(object))
1123 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1124 else if (PyDateTime_Check(object))
1125 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1126 else
1127 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001130}
1131
Tim Peters2a799bf2002-12-16 20:18:38 +00001132/* I sure don't want to reproduce the strftime code from the time module,
1133 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001134 * giving special meanings to the %z, %Z and %f format codes via a
1135 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001136 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1137 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001138 */
1139static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001140wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1146 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1147 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 const char *pin; /* pointer to next char in input format */
1150 Py_ssize_t flen; /* length of input format */
1151 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 PyObject *newfmt = NULL; /* py string, the output format */
1154 char *pnew; /* pointer to available byte in output format */
1155 size_t totalnew; /* number bytes total in output format buffer,
1156 exclusive of trailing \0 */
1157 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 const char *ptoappend; /* ptr to string to append to output buffer */
1160 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 assert(object && format && timetuple);
1163 assert(PyUnicode_Check(format));
1164 /* Convert the input format to a C string and size */
1165 pin = _PyUnicode_AsStringAndSize(format, &flen);
1166 if (!pin)
1167 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 /* Give up if the year is before 1900.
1170 * Python strftime() plays games with the year, and different
1171 * games depending on whether envar PYTHON2K is set. This makes
1172 * years before 1900 a nightmare, even if the platform strftime
1173 * supports them (and not all do).
1174 * We could get a lot farther here by avoiding Python's strftime
1175 * wrapper and calling the C strftime() directly, but that isn't
1176 * an option in the Python implementation of this module.
1177 */
1178 {
1179 long year;
1180 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1181 if (pyyear == NULL) return NULL;
1182 assert(PyLong_Check(pyyear));
1183 year = PyLong_AsLong(pyyear);
1184 Py_DECREF(pyyear);
1185 if (year < 1900) {
1186 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1187 "1900; the datetime strftime() "
1188 "methods require year >= 1900",
1189 year);
1190 return NULL;
1191 }
1192 }
Tim Petersd6844152002-12-22 20:58:42 +00001193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 /* Scan the input format, looking for %z/%Z/%f escapes, building
1195 * a new format. Since computing the replacements for those codes
1196 * is expensive, don't unless they're actually used.
1197 */
1198 if (flen > INT_MAX - 1) {
1199 PyErr_NoMemory();
1200 goto Done;
1201 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 totalnew = flen + 1; /* realistic if no %z/%Z */
1204 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1205 if (newfmt == NULL) goto Done;
1206 pnew = PyBytes_AsString(newfmt);
1207 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 while ((ch = *pin++) != '\0') {
1210 if (ch != '%') {
1211 ptoappend = pin - 1;
1212 ntoappend = 1;
1213 }
1214 else if ((ch = *pin++) == '\0') {
1215 /* There's a lone trailing %; doesn't make sense. */
1216 PyErr_SetString(PyExc_ValueError, "strftime format "
1217 "ends with raw %");
1218 goto Done;
1219 }
1220 /* A % has been seen and ch is the character after it. */
1221 else if (ch == 'z') {
1222 if (zreplacement == NULL) {
1223 /* format utcoffset */
1224 char buf[100];
1225 PyObject *tzinfo = get_tzinfo_member(object);
1226 zreplacement = PyBytes_FromStringAndSize("", 0);
1227 if (zreplacement == NULL) goto Done;
1228 if (tzinfo != Py_None && tzinfo != NULL) {
1229 assert(tzinfoarg != NULL);
1230 if (format_utcoffset(buf,
1231 sizeof(buf),
1232 "",
1233 tzinfo,
1234 tzinfoarg) < 0)
1235 goto Done;
1236 Py_DECREF(zreplacement);
1237 zreplacement =
1238 PyBytes_FromStringAndSize(buf,
1239 strlen(buf));
1240 if (zreplacement == NULL)
1241 goto Done;
1242 }
1243 }
1244 assert(zreplacement != NULL);
1245 ptoappend = PyBytes_AS_STRING(zreplacement);
1246 ntoappend = PyBytes_GET_SIZE(zreplacement);
1247 }
1248 else if (ch == 'Z') {
1249 /* format tzname */
1250 if (Zreplacement == NULL) {
1251 Zreplacement = make_Zreplacement(object,
1252 tzinfoarg);
1253 if (Zreplacement == NULL)
1254 goto Done;
1255 }
1256 assert(Zreplacement != NULL);
1257 assert(PyUnicode_Check(Zreplacement));
1258 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1259 &ntoappend);
1260 ntoappend = Py_SIZE(Zreplacement);
1261 }
1262 else if (ch == 'f') {
1263 /* format microseconds */
1264 if (freplacement == NULL) {
1265 freplacement = make_freplacement(object);
1266 if (freplacement == NULL)
1267 goto Done;
1268 }
1269 assert(freplacement != NULL);
1270 assert(PyBytes_Check(freplacement));
1271 ptoappend = PyBytes_AS_STRING(freplacement);
1272 ntoappend = PyBytes_GET_SIZE(freplacement);
1273 }
1274 else {
1275 /* percent followed by neither z nor Z */
1276 ptoappend = pin - 2;
1277 ntoappend = 2;
1278 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 /* Append the ntoappend chars starting at ptoappend to
1281 * the new format.
1282 */
1283 if (ntoappend == 0)
1284 continue;
1285 assert(ptoappend != NULL);
1286 assert(ntoappend > 0);
1287 while (usednew + ntoappend > totalnew) {
1288 size_t bigger = totalnew << 1;
1289 if ((bigger >> 1) != totalnew) { /* overflow */
1290 PyErr_NoMemory();
1291 goto Done;
1292 }
1293 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1294 goto Done;
1295 totalnew = bigger;
1296 pnew = PyBytes_AsString(newfmt) + usednew;
1297 }
1298 memcpy(pnew, ptoappend, ntoappend);
1299 pnew += ntoappend;
1300 usednew += ntoappend;
1301 assert(usednew <= totalnew);
1302 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1305 goto Done;
1306 {
1307 PyObject *format;
1308 PyObject *time = PyImport_ImportModuleNoBlock("time");
1309 if (time == NULL)
1310 goto Done;
1311 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1312 if (format != NULL) {
1313 result = PyObject_CallMethod(time, "strftime", "OO",
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001314 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 Py_DECREF(format);
1316 }
1317 Py_DECREF(time);
1318 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001319 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 Py_XDECREF(freplacement);
1321 Py_XDECREF(zreplacement);
1322 Py_XDECREF(Zreplacement);
1323 Py_XDECREF(newfmt);
1324 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001325}
1326
Tim Peters2a799bf2002-12-16 20:18:38 +00001327/* ---------------------------------------------------------------------------
1328 * Wrap functions from the time module. These aren't directly available
1329 * from C. Perhaps they should be.
1330 */
1331
1332/* Call time.time() and return its result (a Python float). */
1333static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001334time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 PyObject *result = NULL;
1337 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 if (time != NULL) {
1340 result = PyObject_CallMethod(time, "time", "()");
1341 Py_DECREF(time);
1342 }
1343 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001344}
1345
1346/* Build a time.struct_time. The weekday and day number are automatically
1347 * computed from the y,m,d args.
1348 */
1349static PyObject *
1350build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 PyObject *time;
1353 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 time = PyImport_ImportModuleNoBlock("time");
1356 if (time != NULL) {
1357 result = PyObject_CallMethod(time, "struct_time",
1358 "((iiiiiiiii))",
1359 y, m, d,
1360 hh, mm, ss,
1361 weekday(y, m, d),
1362 days_before_month(y, m) + d,
1363 dstflag);
1364 Py_DECREF(time);
1365 }
1366 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001367}
1368
1369/* ---------------------------------------------------------------------------
1370 * Miscellaneous helpers.
1371 */
1372
Mark Dickinsone94c6792009-02-02 20:36:42 +00001373/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001374 * The comparisons here all most naturally compute a cmp()-like result.
1375 * This little helper turns that into a bool result for rich comparisons.
1376 */
1377static PyObject *
1378diff_to_bool(int diff, int op)
1379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 PyObject *result;
1381 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 switch (op) {
1384 case Py_EQ: istrue = diff == 0; break;
1385 case Py_NE: istrue = diff != 0; break;
1386 case Py_LE: istrue = diff <= 0; break;
1387 case Py_GE: istrue = diff >= 0; break;
1388 case Py_LT: istrue = diff < 0; break;
1389 case Py_GT: istrue = diff > 0; break;
1390 default:
1391 assert(! "op unknown");
1392 istrue = 0; /* To shut up compiler */
1393 }
1394 result = istrue ? Py_True : Py_False;
1395 Py_INCREF(result);
1396 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001397}
1398
Tim Peters07534a62003-02-07 22:50:28 +00001399/* Raises a "can't compare" TypeError and returns NULL. */
1400static PyObject *
1401cmperror(PyObject *a, PyObject *b)
1402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 PyErr_Format(PyExc_TypeError,
1404 "can't compare %s to %s",
1405 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1406 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001407}
1408
Tim Peters2a799bf2002-12-16 20:18:38 +00001409/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001410 * Cached Python objects; these are set by the module init function.
1411 */
1412
1413/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414static PyObject *us_per_us = NULL; /* 1 */
1415static PyObject *us_per_ms = NULL; /* 1000 */
1416static PyObject *us_per_second = NULL; /* 1000000 */
1417static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1418static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1419static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1420static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001421static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1422
Tim Peters2a799bf2002-12-16 20:18:38 +00001423/* ---------------------------------------------------------------------------
1424 * Class implementations.
1425 */
1426
1427/*
1428 * PyDateTime_Delta implementation.
1429 */
1430
1431/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001433 * as a Python int or long.
1434 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1435 * due to ubiquitous overflow possibilities.
1436 */
1437static PyObject *
1438delta_to_microseconds(PyDateTime_Delta *self)
1439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 PyObject *x1 = NULL;
1441 PyObject *x2 = NULL;
1442 PyObject *x3 = NULL;
1443 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001444
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1446 if (x1 == NULL)
1447 goto Done;
1448 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1449 if (x2 == NULL)
1450 goto Done;
1451 Py_DECREF(x1);
1452 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 /* x2 has days in seconds */
1455 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1456 if (x1 == NULL)
1457 goto Done;
1458 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1459 if (x3 == NULL)
1460 goto Done;
1461 Py_DECREF(x1);
1462 Py_DECREF(x2);
1463 x1 = x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 /* x3 has days+seconds in seconds */
1466 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1467 if (x1 == NULL)
1468 goto Done;
1469 Py_DECREF(x3);
1470 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 /* x1 has days+seconds in us */
1473 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1474 if (x2 == NULL)
1475 goto Done;
1476 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001477
1478Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 Py_XDECREF(x1);
1480 Py_XDECREF(x2);
1481 Py_XDECREF(x3);
1482 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001483}
1484
1485/* Convert a number of us (as a Python int or long) to a timedelta.
1486 */
1487static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001488microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 int us;
1491 int s;
1492 int d;
1493 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 PyObject *tuple = NULL;
1496 PyObject *num = NULL;
1497 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 tuple = PyNumber_Divmod(pyus, us_per_second);
1500 if (tuple == NULL)
1501 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 num = PyTuple_GetItem(tuple, 1); /* us */
1504 if (num == NULL)
1505 goto Done;
1506 temp = PyLong_AsLong(num);
1507 num = NULL;
1508 if (temp == -1 && PyErr_Occurred())
1509 goto Done;
1510 assert(0 <= temp && temp < 1000000);
1511 us = (int)temp;
1512 if (us < 0) {
1513 /* The divisor was positive, so this must be an error. */
1514 assert(PyErr_Occurred());
1515 goto Done;
1516 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1519 if (num == NULL)
1520 goto Done;
1521 Py_INCREF(num);
1522 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 tuple = PyNumber_Divmod(num, seconds_per_day);
1525 if (tuple == NULL)
1526 goto Done;
1527 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 num = PyTuple_GetItem(tuple, 1); /* seconds */
1530 if (num == NULL)
1531 goto Done;
1532 temp = PyLong_AsLong(num);
1533 num = NULL;
1534 if (temp == -1 && PyErr_Occurred())
1535 goto Done;
1536 assert(0 <= temp && temp < 24*3600);
1537 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 if (s < 0) {
1540 /* The divisor was positive, so this must be an error. */
1541 assert(PyErr_Occurred());
1542 goto Done;
1543 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1546 if (num == NULL)
1547 goto Done;
1548 Py_INCREF(num);
1549 temp = PyLong_AsLong(num);
1550 if (temp == -1 && PyErr_Occurred())
1551 goto Done;
1552 d = (int)temp;
1553 if ((long)d != temp) {
1554 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1555 "large to fit in a C int");
1556 goto Done;
1557 }
1558 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001559
1560Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 Py_XDECREF(tuple);
1562 Py_XDECREF(num);
1563 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001564}
1565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566#define microseconds_to_delta(pymicros) \
1567 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001568
Tim Peters2a799bf2002-12-16 20:18:38 +00001569static PyObject *
1570multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1571{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 PyObject *pyus_in;
1573 PyObject *pyus_out;
1574 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 pyus_in = delta_to_microseconds(delta);
1577 if (pyus_in == NULL)
1578 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1581 Py_DECREF(pyus_in);
1582 if (pyus_out == NULL)
1583 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 result = microseconds_to_delta(pyus_out);
1586 Py_DECREF(pyus_out);
1587 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001588}
1589
1590static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001591multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1592{
1593 PyObject *result = NULL;
1594 PyObject *pyus_in = NULL, *temp, *pyus_out;
1595 PyObject *ratio = NULL;
1596
1597 pyus_in = delta_to_microseconds(delta);
1598 if (pyus_in == NULL)
1599 return NULL;
1600 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1601 if (ratio == NULL)
1602 goto error;
1603 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1604 Py_DECREF(pyus_in);
1605 pyus_in = NULL;
1606 if (temp == NULL)
1607 goto error;
1608 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1609 Py_DECREF(temp);
1610 if (pyus_out == NULL)
1611 goto error;
1612 result = microseconds_to_delta(pyus_out);
1613 Py_DECREF(pyus_out);
1614 error:
1615 Py_XDECREF(pyus_in);
1616 Py_XDECREF(ratio);
1617
1618 return result;
1619}
1620
1621static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001622divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 PyObject *pyus_in;
1625 PyObject *pyus_out;
1626 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 pyus_in = delta_to_microseconds(delta);
1629 if (pyus_in == NULL)
1630 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1633 Py_DECREF(pyus_in);
1634 if (pyus_out == NULL)
1635 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 result = microseconds_to_delta(pyus_out);
1638 Py_DECREF(pyus_out);
1639 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001640}
1641
1642static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001643divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 PyObject *pyus_left;
1646 PyObject *pyus_right;
1647 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649 pyus_left = delta_to_microseconds(left);
1650 if (pyus_left == NULL)
1651 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 pyus_right = delta_to_microseconds(right);
1654 if (pyus_right == NULL) {
1655 Py_DECREF(pyus_left);
1656 return NULL;
1657 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1660 Py_DECREF(pyus_left);
1661 Py_DECREF(pyus_right);
1662 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001663}
1664
1665static PyObject *
1666truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1667{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 PyObject *pyus_left;
1669 PyObject *pyus_right;
1670 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 pyus_left = delta_to_microseconds(left);
1673 if (pyus_left == NULL)
1674 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 pyus_right = delta_to_microseconds(right);
1677 if (pyus_right == NULL) {
1678 Py_DECREF(pyus_left);
1679 return NULL;
1680 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001682 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1683 Py_DECREF(pyus_left);
1684 Py_DECREF(pyus_right);
1685 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001686}
1687
1688static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001689truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1690{
1691 PyObject *result = NULL;
1692 PyObject *pyus_in = NULL, *temp, *pyus_out;
1693 PyObject *ratio = NULL;
1694
1695 pyus_in = delta_to_microseconds(delta);
1696 if (pyus_in == NULL)
1697 return NULL;
1698 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1699 if (ratio == NULL)
1700 goto error;
1701 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1702 Py_DECREF(pyus_in);
1703 pyus_in = NULL;
1704 if (temp == NULL)
1705 goto error;
1706 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1707 Py_DECREF(temp);
1708 if (pyus_out == NULL)
1709 goto error;
1710 result = microseconds_to_delta(pyus_out);
1711 Py_DECREF(pyus_out);
1712 error:
1713 Py_XDECREF(pyus_in);
1714 Py_XDECREF(ratio);
1715
1716 return result;
1717}
1718
1719static PyObject *
1720truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1721{
1722 PyObject *result;
1723 PyObject *pyus_in, *pyus_out;
1724 pyus_in = delta_to_microseconds(delta);
1725 if (pyus_in == NULL)
1726 return NULL;
1727 pyus_out = divide_nearest(pyus_in, i);
1728 Py_DECREF(pyus_in);
1729 if (pyus_out == NULL)
1730 return NULL;
1731 result = microseconds_to_delta(pyus_out);
1732 Py_DECREF(pyus_out);
1733
1734 return result;
1735}
1736
1737static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001738delta_add(PyObject *left, PyObject *right)
1739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1743 /* delta + delta */
1744 /* The C-level additions can't overflow because of the
1745 * invariant bounds.
1746 */
1747 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1748 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1749 int microseconds = GET_TD_MICROSECONDS(left) +
1750 GET_TD_MICROSECONDS(right);
1751 result = new_delta(days, seconds, microseconds, 1);
1752 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 if (result == Py_NotImplemented)
1755 Py_INCREF(result);
1756 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001757}
1758
1759static PyObject *
1760delta_negative(PyDateTime_Delta *self)
1761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 return new_delta(-GET_TD_DAYS(self),
1763 -GET_TD_SECONDS(self),
1764 -GET_TD_MICROSECONDS(self),
1765 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001766}
1767
1768static PyObject *
1769delta_positive(PyDateTime_Delta *self)
1770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 /* Could optimize this (by returning self) if this isn't a
1772 * subclass -- but who uses unary + ? Approximately nobody.
1773 */
1774 return new_delta(GET_TD_DAYS(self),
1775 GET_TD_SECONDS(self),
1776 GET_TD_MICROSECONDS(self),
1777 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001778}
1779
1780static PyObject *
1781delta_abs(PyDateTime_Delta *self)
1782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001784
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 assert(GET_TD_MICROSECONDS(self) >= 0);
1786 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 if (GET_TD_DAYS(self) < 0)
1789 result = delta_negative(self);
1790 else
1791 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001794}
1795
1796static PyObject *
1797delta_subtract(PyObject *left, PyObject *right)
1798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1802 /* delta - delta */
1803 PyObject *minus_right = PyNumber_Negative(right);
1804 if (minus_right) {
1805 result = delta_add(left, minus_right);
1806 Py_DECREF(minus_right);
1807 }
1808 else
1809 result = NULL;
1810 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 if (result == Py_NotImplemented)
1813 Py_INCREF(result);
1814 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001815}
1816
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001817static int
1818delta_cmp(PyObject *self, PyObject *other)
1819{
1820 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1821 if (diff == 0) {
1822 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1823 if (diff == 0)
1824 diff = GET_TD_MICROSECONDS(self) -
1825 GET_TD_MICROSECONDS(other);
1826 }
1827 return diff;
1828}
1829
Tim Peters2a799bf2002-12-16 20:18:38 +00001830static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001831delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001834 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 return diff_to_bool(diff, op);
1836 }
1837 else {
1838 Py_INCREF(Py_NotImplemented);
1839 return Py_NotImplemented;
1840 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001841}
1842
1843static PyObject *delta_getstate(PyDateTime_Delta *self);
1844
1845static long
1846delta_hash(PyDateTime_Delta *self)
1847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 if (self->hashcode == -1) {
1849 PyObject *temp = delta_getstate(self);
1850 if (temp != NULL) {
1851 self->hashcode = PyObject_Hash(temp);
1852 Py_DECREF(temp);
1853 }
1854 }
1855 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001856}
1857
1858static PyObject *
1859delta_multiply(PyObject *left, PyObject *right)
1860{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 if (PyDelta_Check(left)) {
1864 /* delta * ??? */
1865 if (PyLong_Check(right))
1866 result = multiply_int_timedelta(right,
1867 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001868 else if (PyFloat_Check(right))
1869 result = multiply_float_timedelta(right,
1870 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 }
1872 else if (PyLong_Check(left))
1873 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001874 (PyDateTime_Delta *) right);
1875 else if (PyFloat_Check(left))
1876 result = multiply_float_timedelta(left,
1877 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 if (result == Py_NotImplemented)
1880 Py_INCREF(result);
1881 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001882}
1883
1884static PyObject *
1885delta_divide(PyObject *left, PyObject *right)
1886{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 if (PyDelta_Check(left)) {
1890 /* delta * ??? */
1891 if (PyLong_Check(right))
1892 result = divide_timedelta_int(
1893 (PyDateTime_Delta *)left,
1894 right);
1895 else if (PyDelta_Check(right))
1896 result = divide_timedelta_timedelta(
1897 (PyDateTime_Delta *)left,
1898 (PyDateTime_Delta *)right);
1899 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 if (result == Py_NotImplemented)
1902 Py_INCREF(result);
1903 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001904}
1905
Mark Dickinson7c186e22010-04-20 22:32:49 +00001906static PyObject *
1907delta_truedivide(PyObject *left, PyObject *right)
1908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (PyDelta_Check(left)) {
1912 if (PyDelta_Check(right))
1913 result = truedivide_timedelta_timedelta(
1914 (PyDateTime_Delta *)left,
1915 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001916 else if (PyFloat_Check(right))
1917 result = truedivide_timedelta_float(
1918 (PyDateTime_Delta *)left, right);
1919 else if (PyLong_Check(right))
1920 result = truedivide_timedelta_int(
1921 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 if (result == Py_NotImplemented)
1925 Py_INCREF(result);
1926 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001927}
1928
1929static PyObject *
1930delta_remainder(PyObject *left, PyObject *right)
1931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 PyObject *pyus_left;
1933 PyObject *pyus_right;
1934 PyObject *pyus_remainder;
1935 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
1938 Py_INCREF(Py_NotImplemented);
1939 return Py_NotImplemented;
1940 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1943 if (pyus_left == NULL)
1944 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1947 if (pyus_right == NULL) {
1948 Py_DECREF(pyus_left);
1949 return NULL;
1950 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1953 Py_DECREF(pyus_left);
1954 Py_DECREF(pyus_right);
1955 if (pyus_remainder == NULL)
1956 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 remainder = microseconds_to_delta(pyus_remainder);
1959 Py_DECREF(pyus_remainder);
1960 if (remainder == NULL)
1961 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001963 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001964}
1965
1966static PyObject *
1967delta_divmod(PyObject *left, PyObject *right)
1968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 PyObject *pyus_left;
1970 PyObject *pyus_right;
1971 PyObject *divmod;
1972 PyObject *delta;
1973 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
1976 Py_INCREF(Py_NotImplemented);
1977 return Py_NotImplemented;
1978 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1981 if (pyus_left == NULL)
1982 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001984 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1985 if (pyus_right == NULL) {
1986 Py_DECREF(pyus_left);
1987 return NULL;
1988 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1991 Py_DECREF(pyus_left);
1992 Py_DECREF(pyus_right);
1993 if (divmod == NULL)
1994 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 assert(PyTuple_Size(divmod) == 2);
1997 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1998 if (delta == NULL) {
1999 Py_DECREF(divmod);
2000 return NULL;
2001 }
2002 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2003 Py_DECREF(delta);
2004 Py_DECREF(divmod);
2005 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002006}
2007
Tim Peters2a799bf2002-12-16 20:18:38 +00002008/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2009 * timedelta constructor. sofar is the # of microseconds accounted for
2010 * so far, and there are factor microseconds per current unit, the number
2011 * of which is given by num. num * factor is added to sofar in a
2012 * numerically careful way, and that's the result. Any fractional
2013 * microseconds left over (this can happen if num is a float type) are
2014 * added into *leftover.
2015 * Note that there are many ways this can give an error (NULL) return.
2016 */
2017static PyObject *
2018accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2019 double *leftover)
2020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002021 PyObject *prod;
2022 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 if (PyLong_Check(num)) {
2027 prod = PyNumber_Multiply(num, factor);
2028 if (prod == NULL)
2029 return NULL;
2030 sum = PyNumber_Add(sofar, prod);
2031 Py_DECREF(prod);
2032 return sum;
2033 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 if (PyFloat_Check(num)) {
2036 double dnum;
2037 double fracpart;
2038 double intpart;
2039 PyObject *x;
2040 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 /* The Plan: decompose num into an integer part and a
2043 * fractional part, num = intpart + fracpart.
2044 * Then num * factor ==
2045 * intpart * factor + fracpart * factor
2046 * and the LHS can be computed exactly in long arithmetic.
2047 * The RHS is again broken into an int part and frac part.
2048 * and the frac part is added into *leftover.
2049 */
2050 dnum = PyFloat_AsDouble(num);
2051 if (dnum == -1.0 && PyErr_Occurred())
2052 return NULL;
2053 fracpart = modf(dnum, &intpart);
2054 x = PyLong_FromDouble(intpart);
2055 if (x == NULL)
2056 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 prod = PyNumber_Multiply(x, factor);
2059 Py_DECREF(x);
2060 if (prod == NULL)
2061 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 sum = PyNumber_Add(sofar, prod);
2064 Py_DECREF(prod);
2065 if (sum == NULL)
2066 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 if (fracpart == 0.0)
2069 return sum;
2070 /* So far we've lost no information. Dealing with the
2071 * fractional part requires float arithmetic, and may
2072 * lose a little info.
2073 */
2074 assert(PyLong_Check(factor));
2075 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 dnum *= fracpart;
2078 fracpart = modf(dnum, &intpart);
2079 x = PyLong_FromDouble(intpart);
2080 if (x == NULL) {
2081 Py_DECREF(sum);
2082 return NULL;
2083 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 y = PyNumber_Add(sum, x);
2086 Py_DECREF(sum);
2087 Py_DECREF(x);
2088 *leftover += fracpart;
2089 return y;
2090 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002092 PyErr_Format(PyExc_TypeError,
2093 "unsupported type for timedelta %s component: %s",
2094 tag, Py_TYPE(num)->tp_name);
2095 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002096}
2097
2098static PyObject *
2099delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 /* Argument objects. */
2104 PyObject *day = NULL;
2105 PyObject *second = NULL;
2106 PyObject *us = NULL;
2107 PyObject *ms = NULL;
2108 PyObject *minute = NULL;
2109 PyObject *hour = NULL;
2110 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 PyObject *x = NULL; /* running sum of microseconds */
2113 PyObject *y = NULL; /* temp sum of microseconds */
2114 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 static char *keywords[] = {
2117 "days", "seconds", "microseconds", "milliseconds",
2118 "minutes", "hours", "weeks", NULL
2119 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2122 keywords,
2123 &day, &second, &us,
2124 &ms, &minute, &hour, &week) == 0)
2125 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 x = PyLong_FromLong(0);
2128 if (x == NULL)
2129 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131#define CLEANUP \
2132 Py_DECREF(x); \
2133 x = y; \
2134 if (x == NULL) \
2135 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 if (us) {
2138 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2139 CLEANUP;
2140 }
2141 if (ms) {
2142 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2143 CLEANUP;
2144 }
2145 if (second) {
2146 y = accum("seconds", x, second, us_per_second, &leftover_us);
2147 CLEANUP;
2148 }
2149 if (minute) {
2150 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2151 CLEANUP;
2152 }
2153 if (hour) {
2154 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2155 CLEANUP;
2156 }
2157 if (day) {
2158 y = accum("days", x, day, us_per_day, &leftover_us);
2159 CLEANUP;
2160 }
2161 if (week) {
2162 y = accum("weeks", x, week, us_per_week, &leftover_us);
2163 CLEANUP;
2164 }
2165 if (leftover_us) {
2166 /* Round to nearest whole # of us, and add into x. */
2167 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2168 if (temp == NULL) {
2169 Py_DECREF(x);
2170 goto Done;
2171 }
2172 y = PyNumber_Add(x, temp);
2173 Py_DECREF(temp);
2174 CLEANUP;
2175 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 self = microseconds_to_delta_ex(x, type);
2178 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002179Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002181
2182#undef CLEANUP
2183}
2184
2185static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002186delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 return (GET_TD_DAYS(self) != 0
2189 || GET_TD_SECONDS(self) != 0
2190 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002191}
2192
2193static PyObject *
2194delta_repr(PyDateTime_Delta *self)
2195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 if (GET_TD_MICROSECONDS(self) != 0)
2197 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2198 Py_TYPE(self)->tp_name,
2199 GET_TD_DAYS(self),
2200 GET_TD_SECONDS(self),
2201 GET_TD_MICROSECONDS(self));
2202 if (GET_TD_SECONDS(self) != 0)
2203 return PyUnicode_FromFormat("%s(%d, %d)",
2204 Py_TYPE(self)->tp_name,
2205 GET_TD_DAYS(self),
2206 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002208 return PyUnicode_FromFormat("%s(%d)",
2209 Py_TYPE(self)->tp_name,
2210 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002211}
2212
2213static PyObject *
2214delta_str(PyDateTime_Delta *self)
2215{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002216 int us = GET_TD_MICROSECONDS(self);
2217 int seconds = GET_TD_SECONDS(self);
2218 int minutes = divmod(seconds, 60, &seconds);
2219 int hours = divmod(minutes, 60, &minutes);
2220 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 if (days) {
2223 if (us)
2224 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2225 days, (days == 1 || days == -1) ? "" : "s",
2226 hours, minutes, seconds, us);
2227 else
2228 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2229 days, (days == 1 || days == -1) ? "" : "s",
2230 hours, minutes, seconds);
2231 } else {
2232 if (us)
2233 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2234 hours, minutes, seconds, us);
2235 else
2236 return PyUnicode_FromFormat("%d:%02d:%02d",
2237 hours, minutes, seconds);
2238 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002239
Tim Peters2a799bf2002-12-16 20:18:38 +00002240}
2241
Tim Peters371935f2003-02-01 01:52:50 +00002242/* Pickle support, a simple use of __reduce__. */
2243
Tim Petersb57f8f02003-02-01 02:54:15 +00002244/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002245static PyObject *
2246delta_getstate(PyDateTime_Delta *self)
2247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 return Py_BuildValue("iii", GET_TD_DAYS(self),
2249 GET_TD_SECONDS(self),
2250 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002251}
2252
Tim Peters2a799bf2002-12-16 20:18:38 +00002253static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002254delta_total_seconds(PyObject *self)
2255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 PyObject *total_seconds;
2257 PyObject *total_microseconds;
2258 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002260 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2261 if (total_microseconds == NULL)
2262 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 one_million = PyLong_FromLong(1000000L);
2265 if (one_million == NULL) {
2266 Py_DECREF(total_microseconds);
2267 return NULL;
2268 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 Py_DECREF(total_microseconds);
2273 Py_DECREF(one_million);
2274 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002275}
2276
2277static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002278delta_reduce(PyDateTime_Delta* self)
2279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002281}
2282
2283#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2284
2285static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 {"days", T_INT, OFFSET(days), READONLY,
2288 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 {"seconds", T_INT, OFFSET(seconds), READONLY,
2291 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2294 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2295 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002296};
2297
2298static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2300 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2303 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002306};
2307
2308static char delta_doc[] =
2309PyDoc_STR("Difference between two datetime values.");
2310
2311static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 delta_add, /* nb_add */
2313 delta_subtract, /* nb_subtract */
2314 delta_multiply, /* nb_multiply */
2315 delta_remainder, /* nb_remainder */
2316 delta_divmod, /* nb_divmod */
2317 0, /* nb_power */
2318 (unaryfunc)delta_negative, /* nb_negative */
2319 (unaryfunc)delta_positive, /* nb_positive */
2320 (unaryfunc)delta_abs, /* nb_absolute */
2321 (inquiry)delta_bool, /* nb_bool */
2322 0, /*nb_invert*/
2323 0, /*nb_lshift*/
2324 0, /*nb_rshift*/
2325 0, /*nb_and*/
2326 0, /*nb_xor*/
2327 0, /*nb_or*/
2328 0, /*nb_int*/
2329 0, /*nb_reserved*/
2330 0, /*nb_float*/
2331 0, /*nb_inplace_add*/
2332 0, /*nb_inplace_subtract*/
2333 0, /*nb_inplace_multiply*/
2334 0, /*nb_inplace_remainder*/
2335 0, /*nb_inplace_power*/
2336 0, /*nb_inplace_lshift*/
2337 0, /*nb_inplace_rshift*/
2338 0, /*nb_inplace_and*/
2339 0, /*nb_inplace_xor*/
2340 0, /*nb_inplace_or*/
2341 delta_divide, /* nb_floor_divide */
2342 delta_truedivide, /* nb_true_divide */
2343 0, /* nb_inplace_floor_divide */
2344 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002345};
2346
2347static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 PyVarObject_HEAD_INIT(NULL, 0)
2349 "datetime.timedelta", /* tp_name */
2350 sizeof(PyDateTime_Delta), /* tp_basicsize */
2351 0, /* tp_itemsize */
2352 0, /* tp_dealloc */
2353 0, /* tp_print */
2354 0, /* tp_getattr */
2355 0, /* tp_setattr */
2356 0, /* tp_reserved */
2357 (reprfunc)delta_repr, /* tp_repr */
2358 &delta_as_number, /* tp_as_number */
2359 0, /* tp_as_sequence */
2360 0, /* tp_as_mapping */
2361 (hashfunc)delta_hash, /* tp_hash */
2362 0, /* tp_call */
2363 (reprfunc)delta_str, /* tp_str */
2364 PyObject_GenericGetAttr, /* tp_getattro */
2365 0, /* tp_setattro */
2366 0, /* tp_as_buffer */
2367 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2368 delta_doc, /* tp_doc */
2369 0, /* tp_traverse */
2370 0, /* tp_clear */
2371 delta_richcompare, /* tp_richcompare */
2372 0, /* tp_weaklistoffset */
2373 0, /* tp_iter */
2374 0, /* tp_iternext */
2375 delta_methods, /* tp_methods */
2376 delta_members, /* tp_members */
2377 0, /* tp_getset */
2378 0, /* tp_base */
2379 0, /* tp_dict */
2380 0, /* tp_descr_get */
2381 0, /* tp_descr_set */
2382 0, /* tp_dictoffset */
2383 0, /* tp_init */
2384 0, /* tp_alloc */
2385 delta_new, /* tp_new */
2386 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002387};
2388
2389/*
2390 * PyDateTime_Date implementation.
2391 */
2392
2393/* Accessor properties. */
2394
2395static PyObject *
2396date_year(PyDateTime_Date *self, void *unused)
2397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002399}
2400
2401static PyObject *
2402date_month(PyDateTime_Date *self, void *unused)
2403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002405}
2406
2407static PyObject *
2408date_day(PyDateTime_Date *self, void *unused)
2409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002411}
2412
2413static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 {"year", (getter)date_year},
2415 {"month", (getter)date_month},
2416 {"day", (getter)date_day},
2417 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002418};
2419
2420/* Constructors. */
2421
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002422static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002423
Tim Peters2a799bf2002-12-16 20:18:38 +00002424static PyObject *
2425date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 PyObject *self = NULL;
2428 PyObject *state;
2429 int year;
2430 int month;
2431 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 /* Check for invocation from pickle with __getstate__ state */
2434 if (PyTuple_GET_SIZE(args) == 1 &&
2435 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2436 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2437 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2438 {
2439 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002441 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2442 if (me != NULL) {
2443 char *pdata = PyBytes_AS_STRING(state);
2444 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2445 me->hashcode = -1;
2446 }
2447 return (PyObject *)me;
2448 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2451 &year, &month, &day)) {
2452 if (check_date_args(year, month, day) < 0)
2453 return NULL;
2454 self = new_date_ex(year, month, day, type);
2455 }
2456 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002457}
2458
2459/* Return new date from localtime(t). */
2460static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002461date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 struct tm *tm;
2464 time_t t;
2465 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 t = _PyTime_DoubleToTimet(ts);
2468 if (t == (time_t)-1 && PyErr_Occurred())
2469 return NULL;
2470 tm = localtime(&t);
2471 if (tm)
2472 result = PyObject_CallFunction(cls, "iii",
2473 tm->tm_year + 1900,
2474 tm->tm_mon + 1,
2475 tm->tm_mday);
2476 else
2477 PyErr_SetString(PyExc_ValueError,
2478 "timestamp out of range for "
2479 "platform localtime() function");
2480 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002481}
2482
2483/* Return new date from current time.
2484 * We say this is equivalent to fromtimestamp(time.time()), and the
2485 * only way to be sure of that is to *call* time.time(). That's not
2486 * generally the same as calling C's time.
2487 */
2488static PyObject *
2489date_today(PyObject *cls, PyObject *dummy)
2490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002491 PyObject *time;
2492 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002494 time = time_time();
2495 if (time == NULL)
2496 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 /* Note well: today() is a class method, so this may not call
2499 * date.fromtimestamp. For example, it may call
2500 * datetime.fromtimestamp. That's why we need all the accuracy
2501 * time.time() delivers; if someone were gonzo about optimization,
2502 * date.today() could get away with plain C time().
2503 */
2504 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2505 Py_DECREF(time);
2506 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002507}
2508
2509/* Return new date from given timestamp (Python timestamp -- a double). */
2510static PyObject *
2511date_fromtimestamp(PyObject *cls, PyObject *args)
2512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002513 double timestamp;
2514 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2517 result = date_local_from_time_t(cls, timestamp);
2518 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002519}
2520
2521/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2522 * the ordinal is out of range.
2523 */
2524static PyObject *
2525date_fromordinal(PyObject *cls, PyObject *args)
2526{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002527 PyObject *result = NULL;
2528 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002530 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2531 int year;
2532 int month;
2533 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002535 if (ordinal < 1)
2536 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2537 ">= 1");
2538 else {
2539 ord_to_ymd(ordinal, &year, &month, &day);
2540 result = PyObject_CallFunction(cls, "iii",
2541 year, month, day);
2542 }
2543 }
2544 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002545}
2546
2547/*
2548 * Date arithmetic.
2549 */
2550
2551/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2552 * instead.
2553 */
2554static PyObject *
2555add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002557 PyObject *result = NULL;
2558 int year = GET_YEAR(date);
2559 int month = GET_MONTH(date);
2560 int deltadays = GET_TD_DAYS(delta);
2561 /* C-level overflow is impossible because |deltadays| < 1e9. */
2562 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 if (normalize_date(&year, &month, &day) >= 0)
2565 result = new_date(year, month, day);
2566 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002567}
2568
2569static PyObject *
2570date_add(PyObject *left, PyObject *right)
2571{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002572 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2573 Py_INCREF(Py_NotImplemented);
2574 return Py_NotImplemented;
2575 }
2576 if (PyDate_Check(left)) {
2577 /* date + ??? */
2578 if (PyDelta_Check(right))
2579 /* date + delta */
2580 return add_date_timedelta((PyDateTime_Date *) left,
2581 (PyDateTime_Delta *) right,
2582 0);
2583 }
2584 else {
2585 /* ??? + date
2586 * 'right' must be one of us, or we wouldn't have been called
2587 */
2588 if (PyDelta_Check(left))
2589 /* delta + date */
2590 return add_date_timedelta((PyDateTime_Date *) right,
2591 (PyDateTime_Delta *) left,
2592 0);
2593 }
2594 Py_INCREF(Py_NotImplemented);
2595 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002596}
2597
2598static PyObject *
2599date_subtract(PyObject *left, PyObject *right)
2600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2602 Py_INCREF(Py_NotImplemented);
2603 return Py_NotImplemented;
2604 }
2605 if (PyDate_Check(left)) {
2606 if (PyDate_Check(right)) {
2607 /* date - date */
2608 int left_ord = ymd_to_ord(GET_YEAR(left),
2609 GET_MONTH(left),
2610 GET_DAY(left));
2611 int right_ord = ymd_to_ord(GET_YEAR(right),
2612 GET_MONTH(right),
2613 GET_DAY(right));
2614 return new_delta(left_ord - right_ord, 0, 0, 0);
2615 }
2616 if (PyDelta_Check(right)) {
2617 /* date - delta */
2618 return add_date_timedelta((PyDateTime_Date *) left,
2619 (PyDateTime_Delta *) right,
2620 1);
2621 }
2622 }
2623 Py_INCREF(Py_NotImplemented);
2624 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002625}
2626
2627
2628/* Various ways to turn a date into a string. */
2629
2630static PyObject *
2631date_repr(PyDateTime_Date *self)
2632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2634 Py_TYPE(self)->tp_name,
2635 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002636}
2637
2638static PyObject *
2639date_isoformat(PyDateTime_Date *self)
2640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 return PyUnicode_FromFormat("%04d-%02d-%02d",
2642 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002643}
2644
Tim Peterse2df5ff2003-05-02 18:39:55 +00002645/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002646static PyObject *
2647date_str(PyDateTime_Date *self)
2648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002649 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002650}
2651
2652
2653static PyObject *
2654date_ctime(PyDateTime_Date *self)
2655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002656 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002657}
2658
2659static PyObject *
2660date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 /* This method can be inherited, and needs to call the
2663 * timetuple() method appropriate to self's class.
2664 */
2665 PyObject *result;
2666 PyObject *tuple;
2667 PyObject *format;
2668 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2671 &format))
2672 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002674 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2675 if (tuple == NULL)
2676 return NULL;
2677 result = wrap_strftime((PyObject *)self, format, tuple,
2678 (PyObject *)self);
2679 Py_DECREF(tuple);
2680 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002681}
2682
Eric Smith1ba31142007-09-11 18:06:02 +00002683static PyObject *
2684date_format(PyDateTime_Date *self, PyObject *args)
2685{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002686 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002688 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2689 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002691 /* if the format is zero length, return str(self) */
2692 if (PyUnicode_GetSize(format) == 0)
2693 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002695 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002696}
2697
Tim Peters2a799bf2002-12-16 20:18:38 +00002698/* ISO methods. */
2699
2700static PyObject *
2701date_isoweekday(PyDateTime_Date *self)
2702{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002703 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002705 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002706}
2707
2708static PyObject *
2709date_isocalendar(PyDateTime_Date *self)
2710{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002711 int year = GET_YEAR(self);
2712 int week1_monday = iso_week1_monday(year);
2713 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2714 int week;
2715 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002717 week = divmod(today - week1_monday, 7, &day);
2718 if (week < 0) {
2719 --year;
2720 week1_monday = iso_week1_monday(year);
2721 week = divmod(today - week1_monday, 7, &day);
2722 }
2723 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2724 ++year;
2725 week = 0;
2726 }
2727 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002728}
2729
2730/* Miscellaneous methods. */
2731
Tim Peters2a799bf2002-12-16 20:18:38 +00002732static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002733date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002735 if (PyDate_Check(other)) {
2736 int diff = memcmp(((PyDateTime_Date *)self)->data,
2737 ((PyDateTime_Date *)other)->data,
2738 _PyDateTime_DATE_DATASIZE);
2739 return diff_to_bool(diff, op);
2740 }
2741 else {
2742 Py_INCREF(Py_NotImplemented);
2743 return Py_NotImplemented;
2744 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002745}
2746
2747static PyObject *
2748date_timetuple(PyDateTime_Date *self)
2749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002750 return build_struct_time(GET_YEAR(self),
2751 GET_MONTH(self),
2752 GET_DAY(self),
2753 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002754}
2755
Tim Peters12bf3392002-12-24 05:41:27 +00002756static PyObject *
2757date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002759 PyObject *clone;
2760 PyObject *tuple;
2761 int year = GET_YEAR(self);
2762 int month = GET_MONTH(self);
2763 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002765 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2766 &year, &month, &day))
2767 return NULL;
2768 tuple = Py_BuildValue("iii", year, month, day);
2769 if (tuple == NULL)
2770 return NULL;
2771 clone = date_new(Py_TYPE(self), tuple, NULL);
2772 Py_DECREF(tuple);
2773 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002774}
2775
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002776/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002777 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002778*/
2779static long
2780generic_hash(unsigned char *data, int len)
2781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002782 register unsigned char *p;
2783 register long x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002784
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002785 p = (unsigned char *) data;
2786 x = *p << 7;
2787 while (--len >= 0)
2788 x = (1000003*x) ^ *p++;
2789 x ^= len;
2790 if (x == -1)
2791 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002793 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002794}
2795
2796
2797static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002798
2799static long
2800date_hash(PyDateTime_Date *self)
2801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002802 if (self->hashcode == -1)
2803 self->hashcode = generic_hash(
2804 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002806 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002807}
2808
2809static PyObject *
2810date_toordinal(PyDateTime_Date *self)
2811{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002812 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2813 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002814}
2815
2816static PyObject *
2817date_weekday(PyDateTime_Date *self)
2818{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002819 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002821 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002822}
2823
Tim Peters371935f2003-02-01 01:52:50 +00002824/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002825
Tim Petersb57f8f02003-02-01 02:54:15 +00002826/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002827static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002828date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002830 PyObject* field;
2831 field = PyBytes_FromStringAndSize((char*)self->data,
2832 _PyDateTime_DATE_DATASIZE);
2833 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002834}
2835
2836static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002837date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002838{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002839 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002840}
2841
2842static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002846 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2847 METH_CLASS,
2848 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2849 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2852 METH_CLASS,
2853 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2854 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2857 PyDoc_STR("Current date or datetime: same as "
2858 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002860 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2863 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002865 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2866 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2869 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002871 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2872 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002874 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2875 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2876 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2879 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002881 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2882 PyDoc_STR("Return the day of the week represented by the date.\n"
2883 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002885 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2886 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2887 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002889 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2890 PyDoc_STR("Return the day of the week represented by the date.\n"
2891 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2894 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002896 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2897 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002899 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002900};
2901
2902static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002903PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002904
2905static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002906 date_add, /* nb_add */
2907 date_subtract, /* nb_subtract */
2908 0, /* nb_multiply */
2909 0, /* nb_remainder */
2910 0, /* nb_divmod */
2911 0, /* nb_power */
2912 0, /* nb_negative */
2913 0, /* nb_positive */
2914 0, /* nb_absolute */
2915 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002916};
2917
2918static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002919 PyVarObject_HEAD_INIT(NULL, 0)
2920 "datetime.date", /* tp_name */
2921 sizeof(PyDateTime_Date), /* tp_basicsize */
2922 0, /* tp_itemsize */
2923 0, /* tp_dealloc */
2924 0, /* tp_print */
2925 0, /* tp_getattr */
2926 0, /* tp_setattr */
2927 0, /* tp_reserved */
2928 (reprfunc)date_repr, /* tp_repr */
2929 &date_as_number, /* tp_as_number */
2930 0, /* tp_as_sequence */
2931 0, /* tp_as_mapping */
2932 (hashfunc)date_hash, /* tp_hash */
2933 0, /* tp_call */
2934 (reprfunc)date_str, /* tp_str */
2935 PyObject_GenericGetAttr, /* tp_getattro */
2936 0, /* tp_setattro */
2937 0, /* tp_as_buffer */
2938 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2939 date_doc, /* tp_doc */
2940 0, /* tp_traverse */
2941 0, /* tp_clear */
2942 date_richcompare, /* tp_richcompare */
2943 0, /* tp_weaklistoffset */
2944 0, /* tp_iter */
2945 0, /* tp_iternext */
2946 date_methods, /* tp_methods */
2947 0, /* tp_members */
2948 date_getset, /* tp_getset */
2949 0, /* tp_base */
2950 0, /* tp_dict */
2951 0, /* tp_descr_get */
2952 0, /* tp_descr_set */
2953 0, /* tp_dictoffset */
2954 0, /* tp_init */
2955 0, /* tp_alloc */
2956 date_new, /* tp_new */
2957 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002958};
2959
2960/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002961 * PyDateTime_TZInfo implementation.
2962 */
2963
2964/* This is a pure abstract base class, so doesn't do anything beyond
2965 * raising NotImplemented exceptions. Real tzinfo classes need
2966 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002967 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002968 * be subclasses of this tzinfo class, which is easy and quick to check).
2969 *
2970 * Note: For reasons having to do with pickling of subclasses, we have
2971 * to allow tzinfo objects to be instantiated. This wasn't an issue
2972 * in the Python implementation (__init__() could raise NotImplementedError
2973 * there without ill effect), but doing so in the C implementation hit a
2974 * brick wall.
2975 */
2976
2977static PyObject *
2978tzinfo_nogo(const char* methodname)
2979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002980 PyErr_Format(PyExc_NotImplementedError,
2981 "a tzinfo subclass must implement %s()",
2982 methodname);
2983 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002984}
2985
2986/* Methods. A subclass must implement these. */
2987
Tim Peters52dcce22003-01-23 16:36:11 +00002988static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002989tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2990{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002991 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002992}
2993
Tim Peters52dcce22003-01-23 16:36:11 +00002994static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002995tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2996{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002997 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002998}
2999
Tim Peters52dcce22003-01-23 16:36:11 +00003000static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003001tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003003 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003004}
3005
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003006
3007static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3008 PyDateTime_Delta *delta,
3009 int factor);
3010static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3011static PyObject *datetime_dst(PyObject *self, PyObject *);
3012
Tim Peters52dcce22003-01-23 16:36:11 +00003013static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003014tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003015{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003016 PyObject *result = NULL;
3017 PyObject *off = NULL, *dst = NULL;
3018 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003019
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003020 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003021 PyErr_SetString(PyExc_TypeError,
3022 "fromutc: argument must be a datetime");
3023 return NULL;
3024 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003025 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003026 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3027 "is not self");
3028 return NULL;
3029 }
Tim Peters52dcce22003-01-23 16:36:11 +00003030
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003031 off = datetime_utcoffset(dt, NULL);
3032 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003033 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003034 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003035 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3036 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003037 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 }
Tim Peters52dcce22003-01-23 16:36:11 +00003039
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003040 dst = datetime_dst(dt, NULL);
3041 if (dst == NULL)
3042 goto Fail;
3043 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003044 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3045 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003046 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003047 }
Tim Peters52dcce22003-01-23 16:36:11 +00003048
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003049 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3050 if (delta == NULL)
3051 goto Fail;
3052 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003053 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003054 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003055
3056 Py_DECREF(dst);
3057 dst = call_dst(GET_DT_TZINFO(dt), result);
3058 if (dst == NULL)
3059 goto Fail;
3060 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003061 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003062 if (delta_bool(delta) != 0) {
3063 PyObject *temp = result;
3064 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3065 (PyDateTime_Delta *)dst, 1);
3066 Py_DECREF(temp);
3067 if (result == NULL)
3068 goto Fail;
3069 }
3070 Py_DECREF(delta);
3071 Py_DECREF(dst);
3072 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003073 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003074
3075Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003076 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3077 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003079 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003080Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003081 Py_XDECREF(off);
3082 Py_XDECREF(dst);
3083 Py_XDECREF(delta);
3084 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003085 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003086}
3087
Tim Peters2a799bf2002-12-16 20:18:38 +00003088/*
3089 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003090 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003091 */
3092
Guido van Rossum177e41a2003-01-30 22:06:23 +00003093static PyObject *
3094tzinfo_reduce(PyObject *self)
3095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003096 PyObject *args, *state, *tmp;
3097 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003099 tmp = PyTuple_New(0);
3100 if (tmp == NULL)
3101 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003103 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3104 if (getinitargs != NULL) {
3105 args = PyObject_CallObject(getinitargs, tmp);
3106 Py_DECREF(getinitargs);
3107 if (args == NULL) {
3108 Py_DECREF(tmp);
3109 return NULL;
3110 }
3111 }
3112 else {
3113 PyErr_Clear();
3114 args = tmp;
3115 Py_INCREF(args);
3116 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003118 getstate = PyObject_GetAttrString(self, "__getstate__");
3119 if (getstate != NULL) {
3120 state = PyObject_CallObject(getstate, tmp);
3121 Py_DECREF(getstate);
3122 if (state == NULL) {
3123 Py_DECREF(args);
3124 Py_DECREF(tmp);
3125 return NULL;
3126 }
3127 }
3128 else {
3129 PyObject **dictptr;
3130 PyErr_Clear();
3131 state = Py_None;
3132 dictptr = _PyObject_GetDictPtr(self);
3133 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3134 state = *dictptr;
3135 Py_INCREF(state);
3136 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003138 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003140 if (state == Py_None) {
3141 Py_DECREF(state);
3142 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3143 }
3144 else
3145 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003146}
Tim Peters2a799bf2002-12-16 20:18:38 +00003147
3148static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003150 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3151 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003153 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003154 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3155 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003157 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3158 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003160 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003161 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003163 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3164 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003166 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003167};
3168
3169static char tzinfo_doc[] =
3170PyDoc_STR("Abstract base class for time zone info objects.");
3171
Neal Norwitz227b5332006-03-22 09:28:35 +00003172static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003173 PyVarObject_HEAD_INIT(NULL, 0)
3174 "datetime.tzinfo", /* tp_name */
3175 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3176 0, /* tp_itemsize */
3177 0, /* tp_dealloc */
3178 0, /* tp_print */
3179 0, /* tp_getattr */
3180 0, /* tp_setattr */
3181 0, /* tp_reserved */
3182 0, /* tp_repr */
3183 0, /* tp_as_number */
3184 0, /* tp_as_sequence */
3185 0, /* tp_as_mapping */
3186 0, /* tp_hash */
3187 0, /* tp_call */
3188 0, /* tp_str */
3189 PyObject_GenericGetAttr, /* tp_getattro */
3190 0, /* tp_setattro */
3191 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003192 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003193 tzinfo_doc, /* tp_doc */
3194 0, /* tp_traverse */
3195 0, /* tp_clear */
3196 0, /* tp_richcompare */
3197 0, /* tp_weaklistoffset */
3198 0, /* tp_iter */
3199 0, /* tp_iternext */
3200 tzinfo_methods, /* tp_methods */
3201 0, /* tp_members */
3202 0, /* tp_getset */
3203 0, /* tp_base */
3204 0, /* tp_dict */
3205 0, /* tp_descr_get */
3206 0, /* tp_descr_set */
3207 0, /* tp_dictoffset */
3208 0, /* tp_init */
3209 0, /* tp_alloc */
3210 PyType_GenericNew, /* tp_new */
3211 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003212};
3213
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003214static char *timezone_kws[] = {"offset", "name", NULL};
3215
3216static PyObject *
3217timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3218{
3219 PyObject *offset;
3220 PyObject *name = NULL;
3221 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3222 &PyDateTime_DeltaType, &offset,
3223 &PyUnicode_Type, &name))
3224 return new_timezone(offset, name);
3225
3226 return NULL;
3227}
3228
3229static void
3230timezone_dealloc(PyDateTime_TimeZone *self)
3231{
3232 Py_CLEAR(self->offset);
3233 Py_CLEAR(self->name);
3234 Py_TYPE(self)->tp_free((PyObject *)self);
3235}
3236
3237static PyObject *
3238timezone_richcompare(PyDateTime_TimeZone *self,
3239 PyDateTime_TimeZone *other, int op)
3240{
3241 if (op != Py_EQ && op != Py_NE) {
3242 Py_INCREF(Py_NotImplemented);
3243 return Py_NotImplemented;
3244 }
3245 return delta_richcompare(self->offset, other->offset, op);
3246}
3247
3248static long
3249timezone_hash(PyDateTime_TimeZone *self)
3250{
3251 return delta_hash((PyDateTime_Delta *)self->offset);
3252}
3253
3254/* Check argument type passed to tzname, utcoffset, or dst methods.
3255 Returns 0 for good argument. Returns -1 and sets exception info
3256 otherwise.
3257 */
3258static int
3259_timezone_check_argument(PyObject *dt, const char *meth)
3260{
3261 if (dt == Py_None || PyDateTime_Check(dt))
3262 return 0;
3263 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3264 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3265 return -1;
3266}
3267
3268static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003269timezone_repr(PyDateTime_TimeZone *self)
3270{
3271 /* Note that although timezone is not subclassable, it is convenient
3272 to use Py_TYPE(self)->tp_name here. */
3273 const char *type_name = Py_TYPE(self)->tp_name;
3274
3275 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3276 return PyUnicode_FromFormat("%s.utc", type_name);
3277
3278 if (self->name == NULL)
3279 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3280
3281 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3282 self->name);
3283}
3284
3285
3286static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003287timezone_str(PyDateTime_TimeZone *self)
3288{
3289 char buf[10];
3290 int hours, minutes, seconds;
3291 PyObject *offset;
3292 char sign;
3293
3294 if (self->name != NULL) {
3295 Py_INCREF(self->name);
3296 return self->name;
3297 }
3298 /* Offset is normalized, so it is negative if days < 0 */
3299 if (GET_TD_DAYS(self->offset) < 0) {
3300 sign = '-';
3301 offset = delta_negative((PyDateTime_Delta *)self->offset);
3302 if (offset == NULL)
3303 return NULL;
3304 }
3305 else {
3306 sign = '+';
3307 offset = self->offset;
3308 Py_INCREF(offset);
3309 }
3310 /* Offset is not negative here. */
3311 seconds = GET_TD_SECONDS(offset);
3312 Py_DECREF(offset);
3313 minutes = divmod(seconds, 60, &seconds);
3314 hours = divmod(minutes, 60, &minutes);
3315 assert(seconds == 0);
3316 /* XXX ignore sub-minute data, curently not allowed. */
3317 PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes);
3318
3319 return PyUnicode_FromString(buf);
3320}
3321
3322static PyObject *
3323timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3324{
3325 if (_timezone_check_argument(dt, "tzname") == -1)
3326 return NULL;
3327
3328 return timezone_str(self);
3329}
3330
3331static PyObject *
3332timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3333{
3334 if (_timezone_check_argument(dt, "utcoffset") == -1)
3335 return NULL;
3336
3337 Py_INCREF(self->offset);
3338 return self->offset;
3339}
3340
3341static PyObject *
3342timezone_dst(PyObject *self, PyObject *dt)
3343{
3344 if (_timezone_check_argument(dt, "dst") == -1)
3345 return NULL;
3346
3347 Py_RETURN_NONE;
3348}
3349
3350static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003351timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3352{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003353 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003354 PyErr_SetString(PyExc_TypeError,
3355 "fromutc: argument must be a datetime");
3356 return NULL;
3357 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003358 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003359 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3360 "is not self");
3361 return NULL;
3362 }
3363
3364 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3365}
3366
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003367static PyObject *
3368timezone_getinitargs(PyDateTime_TimeZone *self)
3369{
3370 if (self->name == NULL)
3371 return Py_BuildValue("(O)", self->offset);
3372 return Py_BuildValue("(OO)", self->offset, self->name);
3373}
3374
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003375static PyMethodDef timezone_methods[] = {
3376 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3377 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003378 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003379
3380 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003381 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003382
3383 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003384 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003385
3386 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3387 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3388
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003389 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3390 PyDoc_STR("pickle support")},
3391
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003392 {NULL, NULL}
3393};
3394
3395static char timezone_doc[] =
3396PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3397
3398static PyTypeObject PyDateTime_TimeZoneType = {
3399 PyVarObject_HEAD_INIT(NULL, 0)
3400 "datetime.timezone", /* tp_name */
3401 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3402 0, /* tp_itemsize */
3403 (destructor)timezone_dealloc, /* tp_dealloc */
3404 0, /* tp_print */
3405 0, /* tp_getattr */
3406 0, /* tp_setattr */
3407 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003408 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003409 0, /* tp_as_number */
3410 0, /* tp_as_sequence */
3411 0, /* tp_as_mapping */
3412 (hashfunc)timezone_hash, /* tp_hash */
3413 0, /* tp_call */
3414 (reprfunc)timezone_str, /* tp_str */
3415 0, /* tp_getattro */
3416 0, /* tp_setattro */
3417 0, /* tp_as_buffer */
3418 Py_TPFLAGS_DEFAULT, /* tp_flags */
3419 timezone_doc, /* tp_doc */
3420 0, /* tp_traverse */
3421 0, /* tp_clear */
3422 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3423 0, /* tp_weaklistoffset */
3424 0, /* tp_iter */
3425 0, /* tp_iternext */
3426 timezone_methods, /* tp_methods */
3427 0, /* tp_members */
3428 0, /* tp_getset */
3429 &PyDateTime_TZInfoType, /* tp_base */
3430 0, /* tp_dict */
3431 0, /* tp_descr_get */
3432 0, /* tp_descr_set */
3433 0, /* tp_dictoffset */
3434 0, /* tp_init */
3435 0, /* tp_alloc */
3436 timezone_new, /* tp_new */
3437};
3438
Tim Peters2a799bf2002-12-16 20:18:38 +00003439/*
Tim Peters37f39822003-01-10 03:49:02 +00003440 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003441 */
3442
Tim Peters37f39822003-01-10 03:49:02 +00003443/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003444 */
3445
3446static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003447time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003449 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003450}
3451
Tim Peters37f39822003-01-10 03:49:02 +00003452static PyObject *
3453time_minute(PyDateTime_Time *self, void *unused)
3454{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003455 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003456}
3457
3458/* The name time_second conflicted with some platform header file. */
3459static PyObject *
3460py_time_second(PyDateTime_Time *self, void *unused)
3461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003462 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003463}
3464
3465static PyObject *
3466time_microsecond(PyDateTime_Time *self, void *unused)
3467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003468 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003469}
3470
3471static PyObject *
3472time_tzinfo(PyDateTime_Time *self, void *unused)
3473{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003474 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3475 Py_INCREF(result);
3476 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003477}
3478
3479static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003480 {"hour", (getter)time_hour},
3481 {"minute", (getter)time_minute},
3482 {"second", (getter)py_time_second},
3483 {"microsecond", (getter)time_microsecond},
3484 {"tzinfo", (getter)time_tzinfo},
3485 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003486};
3487
3488/*
3489 * Constructors.
3490 */
3491
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003492static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003493 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003494
Tim Peters2a799bf2002-12-16 20:18:38 +00003495static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003496time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003498 PyObject *self = NULL;
3499 PyObject *state;
3500 int hour = 0;
3501 int minute = 0;
3502 int second = 0;
3503 int usecond = 0;
3504 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003506 /* Check for invocation from pickle with __getstate__ state */
3507 if (PyTuple_GET_SIZE(args) >= 1 &&
3508 PyTuple_GET_SIZE(args) <= 2 &&
3509 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3510 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3511 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3512 {
3513 PyDateTime_Time *me;
3514 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003516 if (PyTuple_GET_SIZE(args) == 2) {
3517 tzinfo = PyTuple_GET_ITEM(args, 1);
3518 if (check_tzinfo_subclass(tzinfo) < 0) {
3519 PyErr_SetString(PyExc_TypeError, "bad "
3520 "tzinfo state arg");
3521 return NULL;
3522 }
3523 }
3524 aware = (char)(tzinfo != Py_None);
3525 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3526 if (me != NULL) {
3527 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003529 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3530 me->hashcode = -1;
3531 me->hastzinfo = aware;
3532 if (aware) {
3533 Py_INCREF(tzinfo);
3534 me->tzinfo = tzinfo;
3535 }
3536 }
3537 return (PyObject *)me;
3538 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003540 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3541 &hour, &minute, &second, &usecond,
3542 &tzinfo)) {
3543 if (check_time_args(hour, minute, second, usecond) < 0)
3544 return NULL;
3545 if (check_tzinfo_subclass(tzinfo) < 0)
3546 return NULL;
3547 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3548 type);
3549 }
3550 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003551}
3552
3553/*
3554 * Destructor.
3555 */
3556
3557static void
Tim Peters37f39822003-01-10 03:49:02 +00003558time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003560 if (HASTZINFO(self)) {
3561 Py_XDECREF(self->tzinfo);
3562 }
3563 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003564}
3565
3566/*
Tim Peters855fe882002-12-22 03:43:39 +00003567 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003568 */
3569
Tim Peters2a799bf2002-12-16 20:18:38 +00003570/* These are all METH_NOARGS, so don't need to check the arglist. */
3571static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003572time_utcoffset(PyObject *self, PyObject *unused) {
3573 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003574}
3575
3576static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003577time_dst(PyObject *self, PyObject *unused) {
3578 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003579}
3580
3581static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003582time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003583 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003584}
3585
3586/*
Tim Peters37f39822003-01-10 03:49:02 +00003587 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003588 */
3589
3590static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003591time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003592{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003593 const char *type_name = Py_TYPE(self)->tp_name;
3594 int h = TIME_GET_HOUR(self);
3595 int m = TIME_GET_MINUTE(self);
3596 int s = TIME_GET_SECOND(self);
3597 int us = TIME_GET_MICROSECOND(self);
3598 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003600 if (us)
3601 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3602 type_name, h, m, s, us);
3603 else if (s)
3604 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3605 type_name, h, m, s);
3606 else
3607 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3608 if (result != NULL && HASTZINFO(self))
3609 result = append_keyword_tzinfo(result, self->tzinfo);
3610 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003611}
3612
Tim Peters37f39822003-01-10 03:49:02 +00003613static PyObject *
3614time_str(PyDateTime_Time *self)
3615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003616 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003617}
Tim Peters2a799bf2002-12-16 20:18:38 +00003618
3619static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003620time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003622 char buf[100];
3623 PyObject *result;
3624 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003626 if (us)
3627 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3628 TIME_GET_HOUR(self),
3629 TIME_GET_MINUTE(self),
3630 TIME_GET_SECOND(self),
3631 us);
3632 else
3633 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3634 TIME_GET_HOUR(self),
3635 TIME_GET_MINUTE(self),
3636 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003637
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003638 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003639 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003641 /* We need to append the UTC offset. */
3642 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3643 Py_None) < 0) {
3644 Py_DECREF(result);
3645 return NULL;
3646 }
3647 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3648 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003649}
3650
Tim Peters37f39822003-01-10 03:49:02 +00003651static PyObject *
3652time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003654 PyObject *result;
3655 PyObject *tuple;
3656 PyObject *format;
3657 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003659 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3660 &format))
3661 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003663 /* Python's strftime does insane things with the year part of the
3664 * timetuple. The year is forced to (the otherwise nonsensical)
3665 * 1900 to worm around that.
3666 */
3667 tuple = Py_BuildValue("iiiiiiiii",
3668 1900, 1, 1, /* year, month, day */
3669 TIME_GET_HOUR(self),
3670 TIME_GET_MINUTE(self),
3671 TIME_GET_SECOND(self),
3672 0, 1, -1); /* weekday, daynum, dst */
3673 if (tuple == NULL)
3674 return NULL;
3675 assert(PyTuple_Size(tuple) == 9);
3676 result = wrap_strftime((PyObject *)self, format, tuple,
3677 Py_None);
3678 Py_DECREF(tuple);
3679 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003680}
Tim Peters2a799bf2002-12-16 20:18:38 +00003681
3682/*
3683 * Miscellaneous methods.
3684 */
3685
Tim Peters37f39822003-01-10 03:49:02 +00003686static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003687time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003688{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003689 PyObject *result = NULL;
3690 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003691 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003693 if (! PyTime_Check(other)) {
3694 Py_INCREF(Py_NotImplemented);
3695 return Py_NotImplemented;
3696 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003697
3698 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003699 diff = memcmp(((PyDateTime_Time *)self)->data,
3700 ((PyDateTime_Time *)other)->data,
3701 _PyDateTime_TIME_DATASIZE);
3702 return diff_to_bool(diff, op);
3703 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003704 offset1 = time_utcoffset(self, NULL);
3705 if (offset1 == NULL)
3706 return NULL;
3707 offset2 = time_utcoffset(other, NULL);
3708 if (offset2 == NULL)
3709 goto done;
3710 /* If they're both naive, or both aware and have the same offsets,
3711 * we get off cheap. Note that if they're both naive, offset1 ==
3712 * offset2 == Py_None at this point.
3713 */
3714 if ((offset1 == offset2) ||
3715 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3716 delta_cmp(offset1, offset2) == 0)) {
3717 diff = memcmp(((PyDateTime_Time *)self)->data,
3718 ((PyDateTime_Time *)other)->data,
3719 _PyDateTime_TIME_DATASIZE);
3720 result = diff_to_bool(diff, op);
3721 }
3722 /* The hard case: both aware with different UTC offsets */
3723 else if (offset1 != Py_None && offset2 != Py_None) {
3724 int offsecs1, offsecs2;
3725 assert(offset1 != offset2); /* else last "if" handled it */
3726 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3727 TIME_GET_MINUTE(self) * 60 +
3728 TIME_GET_SECOND(self) -
3729 GET_TD_DAYS(offset1) * 86400 -
3730 GET_TD_SECONDS(offset1);
3731 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3732 TIME_GET_MINUTE(other) * 60 +
3733 TIME_GET_SECOND(other) -
3734 GET_TD_DAYS(offset2) * 86400 -
3735 GET_TD_SECONDS(offset2);
3736 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003737 if (diff == 0)
3738 diff = TIME_GET_MICROSECOND(self) -
3739 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003740 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003741 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003742 else {
3743 PyErr_SetString(PyExc_TypeError,
3744 "can't compare offset-naive and "
3745 "offset-aware times");
3746 }
3747 done:
3748 Py_DECREF(offset1);
3749 Py_XDECREF(offset2);
3750 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003751}
3752
3753static long
3754time_hash(PyDateTime_Time *self)
3755{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003756 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003757 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003758
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003759 offset = time_utcoffset((PyObject *)self, NULL);
3760
3761 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003762 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003764 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003765 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003766 self->hashcode = generic_hash(
3767 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003768 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003769 PyObject *temp1, *temp2;
3770 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003771 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003772 seconds = TIME_GET_HOUR(self) * 3600 +
3773 TIME_GET_MINUTE(self) * 60 +
3774 TIME_GET_SECOND(self);
3775 microseconds = TIME_GET_MICROSECOND(self);
3776 temp1 = new_delta(0, seconds, microseconds, 1);
3777 if (temp1 == NULL) {
3778 Py_DECREF(offset);
3779 return -1;
3780 }
3781 temp2 = delta_subtract(temp1, offset);
3782 Py_DECREF(temp1);
3783 if (temp2 == NULL) {
3784 Py_DECREF(offset);
3785 return -1;
3786 }
3787 self->hashcode = PyObject_Hash(temp2);
3788 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003789 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003790 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003791 }
3792 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003793}
Tim Peters2a799bf2002-12-16 20:18:38 +00003794
Tim Peters12bf3392002-12-24 05:41:27 +00003795static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003796time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003798 PyObject *clone;
3799 PyObject *tuple;
3800 int hh = TIME_GET_HOUR(self);
3801 int mm = TIME_GET_MINUTE(self);
3802 int ss = TIME_GET_SECOND(self);
3803 int us = TIME_GET_MICROSECOND(self);
3804 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003806 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3807 time_kws,
3808 &hh, &mm, &ss, &us, &tzinfo))
3809 return NULL;
3810 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3811 if (tuple == NULL)
3812 return NULL;
3813 clone = time_new(Py_TYPE(self), tuple, NULL);
3814 Py_DECREF(tuple);
3815 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003816}
3817
Tim Peters2a799bf2002-12-16 20:18:38 +00003818static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003819time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003820{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003821 PyObject *offset, *tzinfo;
3822 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003824 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3825 /* Since utcoffset is in whole minutes, nothing can
3826 * alter the conclusion that this is nonzero.
3827 */
3828 return 1;
3829 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003830 tzinfo = GET_TIME_TZINFO(self);
3831 if (tzinfo != Py_None) {
3832 offset = call_utcoffset(tzinfo, Py_None);
3833 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003834 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003835 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3836 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003837 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003838 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003839}
3840
Tim Peters371935f2003-02-01 01:52:50 +00003841/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003842
Tim Peters33e0f382003-01-10 02:05:14 +00003843/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003844 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3845 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003846 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003847 */
3848static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003849time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003851 PyObject *basestate;
3852 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003854 basestate = PyBytes_FromStringAndSize((char *)self->data,
3855 _PyDateTime_TIME_DATASIZE);
3856 if (basestate != NULL) {
3857 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3858 result = PyTuple_Pack(1, basestate);
3859 else
3860 result = PyTuple_Pack(2, basestate, self->tzinfo);
3861 Py_DECREF(basestate);
3862 }
3863 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003864}
3865
3866static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003867time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003869 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003870}
3871
Tim Peters37f39822003-01-10 03:49:02 +00003872static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003874 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3875 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3876 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003878 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3879 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003881 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3882 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003884 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3885 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003887 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3888 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003890 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3891 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003893 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3894 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003896 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3897 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003899 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003900};
3901
Tim Peters37f39822003-01-10 03:49:02 +00003902static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003903PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3904\n\
3905All arguments are optional. tzinfo may be None, or an instance of\n\
3906a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003907
Tim Peters37f39822003-01-10 03:49:02 +00003908static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003909 0, /* nb_add */
3910 0, /* nb_subtract */
3911 0, /* nb_multiply */
3912 0, /* nb_remainder */
3913 0, /* nb_divmod */
3914 0, /* nb_power */
3915 0, /* nb_negative */
3916 0, /* nb_positive */
3917 0, /* nb_absolute */
3918 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003919};
3920
Neal Norwitz227b5332006-03-22 09:28:35 +00003921static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003922 PyVarObject_HEAD_INIT(NULL, 0)
3923 "datetime.time", /* tp_name */
3924 sizeof(PyDateTime_Time), /* tp_basicsize */
3925 0, /* tp_itemsize */
3926 (destructor)time_dealloc, /* tp_dealloc */
3927 0, /* tp_print */
3928 0, /* tp_getattr */
3929 0, /* tp_setattr */
3930 0, /* tp_reserved */
3931 (reprfunc)time_repr, /* tp_repr */
3932 &time_as_number, /* tp_as_number */
3933 0, /* tp_as_sequence */
3934 0, /* tp_as_mapping */
3935 (hashfunc)time_hash, /* tp_hash */
3936 0, /* tp_call */
3937 (reprfunc)time_str, /* tp_str */
3938 PyObject_GenericGetAttr, /* tp_getattro */
3939 0, /* tp_setattro */
3940 0, /* tp_as_buffer */
3941 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3942 time_doc, /* tp_doc */
3943 0, /* tp_traverse */
3944 0, /* tp_clear */
3945 time_richcompare, /* tp_richcompare */
3946 0, /* tp_weaklistoffset */
3947 0, /* tp_iter */
3948 0, /* tp_iternext */
3949 time_methods, /* tp_methods */
3950 0, /* tp_members */
3951 time_getset, /* tp_getset */
3952 0, /* tp_base */
3953 0, /* tp_dict */
3954 0, /* tp_descr_get */
3955 0, /* tp_descr_set */
3956 0, /* tp_dictoffset */
3957 0, /* tp_init */
3958 time_alloc, /* tp_alloc */
3959 time_new, /* tp_new */
3960 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003961};
3962
3963/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003964 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003965 */
3966
Tim Petersa9bc1682003-01-11 03:39:11 +00003967/* Accessor properties. Properties for day, month, and year are inherited
3968 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003969 */
3970
3971static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003972datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003974 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003975}
3976
Tim Petersa9bc1682003-01-11 03:39:11 +00003977static PyObject *
3978datetime_minute(PyDateTime_DateTime *self, void *unused)
3979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003981}
3982
3983static PyObject *
3984datetime_second(PyDateTime_DateTime *self, void *unused)
3985{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003986 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003987}
3988
3989static PyObject *
3990datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003992 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003993}
3994
3995static PyObject *
3996datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3997{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003998 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3999 Py_INCREF(result);
4000 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004001}
4002
4003static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 {"hour", (getter)datetime_hour},
4005 {"minute", (getter)datetime_minute},
4006 {"second", (getter)datetime_second},
4007 {"microsecond", (getter)datetime_microsecond},
4008 {"tzinfo", (getter)datetime_tzinfo},
4009 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004010};
4011
4012/*
4013 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004014 */
4015
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004016static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004017 "year", "month", "day", "hour", "minute", "second",
4018 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004019};
4020
Tim Peters2a799bf2002-12-16 20:18:38 +00004021static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004022datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004023{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004024 PyObject *self = NULL;
4025 PyObject *state;
4026 int year;
4027 int month;
4028 int day;
4029 int hour = 0;
4030 int minute = 0;
4031 int second = 0;
4032 int usecond = 0;
4033 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004035 /* Check for invocation from pickle with __getstate__ state */
4036 if (PyTuple_GET_SIZE(args) >= 1 &&
4037 PyTuple_GET_SIZE(args) <= 2 &&
4038 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4039 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4040 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4041 {
4042 PyDateTime_DateTime *me;
4043 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004045 if (PyTuple_GET_SIZE(args) == 2) {
4046 tzinfo = PyTuple_GET_ITEM(args, 1);
4047 if (check_tzinfo_subclass(tzinfo) < 0) {
4048 PyErr_SetString(PyExc_TypeError, "bad "
4049 "tzinfo state arg");
4050 return NULL;
4051 }
4052 }
4053 aware = (char)(tzinfo != Py_None);
4054 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4055 if (me != NULL) {
4056 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004058 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4059 me->hashcode = -1;
4060 me->hastzinfo = aware;
4061 if (aware) {
4062 Py_INCREF(tzinfo);
4063 me->tzinfo = tzinfo;
4064 }
4065 }
4066 return (PyObject *)me;
4067 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004069 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4070 &year, &month, &day, &hour, &minute,
4071 &second, &usecond, &tzinfo)) {
4072 if (check_date_args(year, month, day) < 0)
4073 return NULL;
4074 if (check_time_args(hour, minute, second, usecond) < 0)
4075 return NULL;
4076 if (check_tzinfo_subclass(tzinfo) < 0)
4077 return NULL;
4078 self = new_datetime_ex(year, month, day,
4079 hour, minute, second, usecond,
4080 tzinfo, type);
4081 }
4082 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004083}
4084
Tim Petersa9bc1682003-01-11 03:39:11 +00004085/* TM_FUNC is the shared type of localtime() and gmtime(). */
4086typedef struct tm *(*TM_FUNC)(const time_t *timer);
4087
4088/* Internal helper.
4089 * Build datetime from a time_t and a distinct count of microseconds.
4090 * Pass localtime or gmtime for f, to control the interpretation of timet.
4091 */
4092static PyObject *
4093datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004094 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004096 struct tm *tm;
4097 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 tm = f(&timet);
4100 if (tm) {
4101 /* The platform localtime/gmtime may insert leap seconds,
4102 * indicated by tm->tm_sec > 59. We don't care about them,
4103 * except to the extent that passing them on to the datetime
4104 * constructor would raise ValueError for a reason that
4105 * made no sense to the user.
4106 */
4107 if (tm->tm_sec > 59)
4108 tm->tm_sec = 59;
4109 result = PyObject_CallFunction(cls, "iiiiiiiO",
4110 tm->tm_year + 1900,
4111 tm->tm_mon + 1,
4112 tm->tm_mday,
4113 tm->tm_hour,
4114 tm->tm_min,
4115 tm->tm_sec,
4116 us,
4117 tzinfo);
4118 }
4119 else
4120 PyErr_SetString(PyExc_ValueError,
4121 "timestamp out of range for "
4122 "platform localtime()/gmtime() function");
4123 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004124}
4125
4126/* Internal helper.
4127 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4128 * to control the interpretation of the timestamp. Since a double doesn't
4129 * have enough bits to cover a datetime's full range of precision, it's
4130 * better to call datetime_from_timet_and_us provided you have a way
4131 * to get that much precision (e.g., C time() isn't good enough).
4132 */
4133static PyObject *
4134datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004135 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004136{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004137 time_t timet;
4138 double fraction;
4139 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004141 timet = _PyTime_DoubleToTimet(timestamp);
4142 if (timet == (time_t)-1 && PyErr_Occurred())
4143 return NULL;
4144 fraction = timestamp - (double)timet;
4145 us = (int)round_to_long(fraction * 1e6);
4146 if (us < 0) {
4147 /* Truncation towards zero is not what we wanted
4148 for negative numbers (Python's mod semantics) */
4149 timet -= 1;
4150 us += 1000000;
4151 }
4152 /* If timestamp is less than one microsecond smaller than a
4153 * full second, round up. Otherwise, ValueErrors are raised
4154 * for some floats. */
4155 if (us == 1000000) {
4156 timet += 1;
4157 us = 0;
4158 }
4159 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004160}
4161
4162/* Internal helper.
4163 * Build most accurate possible datetime for current time. Pass localtime or
4164 * gmtime for f as appropriate.
4165 */
4166static PyObject *
4167datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4168{
4169#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004170 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00004171
4172#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004173 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00004174#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004175 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00004176#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4178 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004180#else /* ! HAVE_GETTIMEOFDAY */
4181 /* No flavor of gettimeofday exists on this platform. Python's
4182 * time.time() does a lot of other platform tricks to get the
4183 * best time it can on the platform, and we're not going to do
4184 * better than that (if we could, the better code would belong
4185 * in time.time()!) We're limited by the precision of a double,
4186 * though.
4187 */
4188 PyObject *time;
4189 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00004190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 time = time_time();
4192 if (time == NULL)
4193 return NULL;
4194 dtime = PyFloat_AsDouble(time);
4195 Py_DECREF(time);
4196 if (dtime == -1.0 && PyErr_Occurred())
4197 return NULL;
4198 return datetime_from_timestamp(cls, f, dtime, tzinfo);
4199#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00004200}
4201
Tim Peters2a799bf2002-12-16 20:18:38 +00004202/* Return best possible local time -- this isn't constrained by the
4203 * precision of a timestamp.
4204 */
4205static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004206datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004208 PyObject *self;
4209 PyObject *tzinfo = Py_None;
4210 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004212 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4213 &tzinfo))
4214 return NULL;
4215 if (check_tzinfo_subclass(tzinfo) < 0)
4216 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004218 self = datetime_best_possible(cls,
4219 tzinfo == Py_None ? localtime : gmtime,
4220 tzinfo);
4221 if (self != NULL && tzinfo != Py_None) {
4222 /* Convert UTC to tzinfo's zone. */
4223 PyObject *temp = self;
4224 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4225 Py_DECREF(temp);
4226 }
4227 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004228}
4229
Tim Petersa9bc1682003-01-11 03:39:11 +00004230/* Return best possible UTC time -- this isn't constrained by the
4231 * precision of a timestamp.
4232 */
4233static PyObject *
4234datetime_utcnow(PyObject *cls, PyObject *dummy)
4235{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004236 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004237}
4238
Tim Peters2a799bf2002-12-16 20:18:38 +00004239/* Return new local datetime from timestamp (Python timestamp -- a double). */
4240static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004241datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004242{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004243 PyObject *self;
4244 double timestamp;
4245 PyObject *tzinfo = Py_None;
4246 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004248 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4249 keywords, &timestamp, &tzinfo))
4250 return NULL;
4251 if (check_tzinfo_subclass(tzinfo) < 0)
4252 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004254 self = datetime_from_timestamp(cls,
4255 tzinfo == Py_None ? localtime : gmtime,
4256 timestamp,
4257 tzinfo);
4258 if (self != NULL && tzinfo != Py_None) {
4259 /* Convert UTC to tzinfo's zone. */
4260 PyObject *temp = self;
4261 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4262 Py_DECREF(temp);
4263 }
4264 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004265}
4266
Tim Petersa9bc1682003-01-11 03:39:11 +00004267/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4268static PyObject *
4269datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004271 double timestamp;
4272 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004274 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4275 result = datetime_from_timestamp(cls, gmtime, timestamp,
4276 Py_None);
4277 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004278}
4279
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004280/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004281static PyObject *
4282datetime_strptime(PyObject *cls, PyObject *args)
4283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004284 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004285 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004287 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4288 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004289
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004290 if (module == NULL) {
4291 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004292 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004293 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004294 }
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004295 return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4296 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004297}
4298
Tim Petersa9bc1682003-01-11 03:39:11 +00004299/* Return new datetime from date/datetime and time arguments. */
4300static PyObject *
4301datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 static char *keywords[] = {"date", "time", NULL};
4304 PyObject *date;
4305 PyObject *time;
4306 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004308 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4309 &PyDateTime_DateType, &date,
4310 &PyDateTime_TimeType, &time)) {
4311 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004313 if (HASTZINFO(time))
4314 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4315 result = PyObject_CallFunction(cls, "iiiiiiiO",
4316 GET_YEAR(date),
4317 GET_MONTH(date),
4318 GET_DAY(date),
4319 TIME_GET_HOUR(time),
4320 TIME_GET_MINUTE(time),
4321 TIME_GET_SECOND(time),
4322 TIME_GET_MICROSECOND(time),
4323 tzinfo);
4324 }
4325 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004326}
Tim Peters2a799bf2002-12-16 20:18:38 +00004327
4328/*
4329 * Destructor.
4330 */
4331
4332static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004333datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004335 if (HASTZINFO(self)) {
4336 Py_XDECREF(self->tzinfo);
4337 }
4338 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004339}
4340
4341/*
4342 * Indirect access to tzinfo methods.
4343 */
4344
Tim Peters2a799bf2002-12-16 20:18:38 +00004345/* These are all METH_NOARGS, so don't need to check the arglist. */
4346static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004347datetime_utcoffset(PyObject *self, PyObject *unused) {
4348 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004349}
4350
4351static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004352datetime_dst(PyObject *self, PyObject *unused) {
4353 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004354}
4355
4356static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004357datetime_tzname(PyObject *self, PyObject *unused) {
4358 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004359}
4360
4361/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004362 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004363 */
4364
Tim Petersa9bc1682003-01-11 03:39:11 +00004365/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4366 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004367 */
4368static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004369add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004370 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004372 /* Note that the C-level additions can't overflow, because of
4373 * invariant bounds on the member values.
4374 */
4375 int year = GET_YEAR(date);
4376 int month = GET_MONTH(date);
4377 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4378 int hour = DATE_GET_HOUR(date);
4379 int minute = DATE_GET_MINUTE(date);
4380 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4381 int microsecond = DATE_GET_MICROSECOND(date) +
4382 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 assert(factor == 1 || factor == -1);
4385 if (normalize_datetime(&year, &month, &day,
4386 &hour, &minute, &second, &microsecond) < 0)
4387 return NULL;
4388 else
4389 return new_datetime(year, month, day,
4390 hour, minute, second, microsecond,
4391 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004392}
4393
4394static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004395datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004397 if (PyDateTime_Check(left)) {
4398 /* datetime + ??? */
4399 if (PyDelta_Check(right))
4400 /* datetime + delta */
4401 return add_datetime_timedelta(
4402 (PyDateTime_DateTime *)left,
4403 (PyDateTime_Delta *)right,
4404 1);
4405 }
4406 else if (PyDelta_Check(left)) {
4407 /* delta + datetime */
4408 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4409 (PyDateTime_Delta *) left,
4410 1);
4411 }
4412 Py_INCREF(Py_NotImplemented);
4413 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004414}
4415
4416static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004417datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004419 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004421 if (PyDateTime_Check(left)) {
4422 /* datetime - ??? */
4423 if (PyDateTime_Check(right)) {
4424 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004425 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004426 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004427
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004428 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4429 offset2 = offset1 = Py_None;
4430 Py_INCREF(offset1);
4431 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004432 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004433 else {
4434 offset1 = datetime_utcoffset(left, NULL);
4435 if (offset1 == NULL)
4436 return NULL;
4437 offset2 = datetime_utcoffset(right, NULL);
4438 if (offset2 == NULL) {
4439 Py_DECREF(offset1);
4440 return NULL;
4441 }
4442 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4443 PyErr_SetString(PyExc_TypeError,
4444 "can't subtract offset-naive and "
4445 "offset-aware datetimes");
4446 Py_DECREF(offset1);
4447 Py_DECREF(offset2);
4448 return NULL;
4449 }
4450 }
4451 if ((offset1 != offset2) &&
4452 delta_cmp(offset1, offset2) != 0) {
4453 offdiff = delta_subtract(offset1, offset2);
4454 if (offdiff == NULL) {
4455 Py_DECREF(offset1);
4456 Py_DECREF(offset2);
4457 return NULL;
4458 }
4459 }
4460 Py_DECREF(offset1);
4461 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004462 delta_d = ymd_to_ord(GET_YEAR(left),
4463 GET_MONTH(left),
4464 GET_DAY(left)) -
4465 ymd_to_ord(GET_YEAR(right),
4466 GET_MONTH(right),
4467 GET_DAY(right));
4468 /* These can't overflow, since the values are
4469 * normalized. At most this gives the number of
4470 * seconds in one day.
4471 */
4472 delta_s = (DATE_GET_HOUR(left) -
4473 DATE_GET_HOUR(right)) * 3600 +
4474 (DATE_GET_MINUTE(left) -
4475 DATE_GET_MINUTE(right)) * 60 +
4476 (DATE_GET_SECOND(left) -
4477 DATE_GET_SECOND(right));
4478 delta_us = DATE_GET_MICROSECOND(left) -
4479 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004480 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004481 if (offdiff != NULL) {
4482 PyObject *temp = result;
4483 result = delta_subtract(result, offdiff);
4484 Py_DECREF(temp);
4485 Py_DECREF(offdiff);
4486 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004487 }
4488 else if (PyDelta_Check(right)) {
4489 /* datetime - delta */
4490 result = add_datetime_timedelta(
4491 (PyDateTime_DateTime *)left,
4492 (PyDateTime_Delta *)right,
4493 -1);
4494 }
4495 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004497 if (result == Py_NotImplemented)
4498 Py_INCREF(result);
4499 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004500}
4501
4502/* Various ways to turn a datetime into a string. */
4503
4504static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004505datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004506{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004507 const char *type_name = Py_TYPE(self)->tp_name;
4508 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004510 if (DATE_GET_MICROSECOND(self)) {
4511 baserepr = PyUnicode_FromFormat(
4512 "%s(%d, %d, %d, %d, %d, %d, %d)",
4513 type_name,
4514 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4515 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4516 DATE_GET_SECOND(self),
4517 DATE_GET_MICROSECOND(self));
4518 }
4519 else if (DATE_GET_SECOND(self)) {
4520 baserepr = PyUnicode_FromFormat(
4521 "%s(%d, %d, %d, %d, %d, %d)",
4522 type_name,
4523 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4524 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4525 DATE_GET_SECOND(self));
4526 }
4527 else {
4528 baserepr = PyUnicode_FromFormat(
4529 "%s(%d, %d, %d, %d, %d)",
4530 type_name,
4531 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4532 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4533 }
4534 if (baserepr == NULL || ! HASTZINFO(self))
4535 return baserepr;
4536 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004537}
4538
Tim Petersa9bc1682003-01-11 03:39:11 +00004539static PyObject *
4540datetime_str(PyDateTime_DateTime *self)
4541{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004542 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004543}
Tim Peters2a799bf2002-12-16 20:18:38 +00004544
4545static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004546datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004548 int sep = 'T';
4549 static char *keywords[] = {"sep", NULL};
4550 char buffer[100];
4551 PyObject *result;
4552 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004554 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4555 return NULL;
4556 if (us)
4557 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4558 GET_YEAR(self), GET_MONTH(self),
4559 GET_DAY(self), (int)sep,
4560 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4561 DATE_GET_SECOND(self), us);
4562 else
4563 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4564 GET_YEAR(self), GET_MONTH(self),
4565 GET_DAY(self), (int)sep,
4566 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4567 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004569 if (!result || !HASTZINFO(self))
4570 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004572 /* We need to append the UTC offset. */
4573 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4574 (PyObject *)self) < 0) {
4575 Py_DECREF(result);
4576 return NULL;
4577 }
4578 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4579 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004580}
4581
Tim Petersa9bc1682003-01-11 03:39:11 +00004582static PyObject *
4583datetime_ctime(PyDateTime_DateTime *self)
4584{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004585 return format_ctime((PyDateTime_Date *)self,
4586 DATE_GET_HOUR(self),
4587 DATE_GET_MINUTE(self),
4588 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004589}
4590
Tim Peters2a799bf2002-12-16 20:18:38 +00004591/* Miscellaneous methods. */
4592
Tim Petersa9bc1682003-01-11 03:39:11 +00004593static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004594datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004595{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004596 PyObject *result = NULL;
4597 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004598 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004600 if (! PyDateTime_Check(other)) {
4601 if (PyDate_Check(other)) {
4602 /* Prevent invocation of date_richcompare. We want to
4603 return NotImplemented here to give the other object
4604 a chance. But since DateTime is a subclass of
4605 Date, if the other object is a Date, it would
4606 compute an ordering based on the date part alone,
4607 and we don't want that. So force unequal or
4608 uncomparable here in that case. */
4609 if (op == Py_EQ)
4610 Py_RETURN_FALSE;
4611 if (op == Py_NE)
4612 Py_RETURN_TRUE;
4613 return cmperror(self, other);
4614 }
4615 Py_INCREF(Py_NotImplemented);
4616 return Py_NotImplemented;
4617 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004618
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004619 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004620 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4621 ((PyDateTime_DateTime *)other)->data,
4622 _PyDateTime_DATETIME_DATASIZE);
4623 return diff_to_bool(diff, op);
4624 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004625 offset1 = datetime_utcoffset(self, NULL);
4626 if (offset1 == NULL)
4627 return NULL;
4628 offset2 = datetime_utcoffset(other, NULL);
4629 if (offset2 == NULL)
4630 goto done;
4631 /* If they're both naive, or both aware and have the same offsets,
4632 * we get off cheap. Note that if they're both naive, offset1 ==
4633 * offset2 == Py_None at this point.
4634 */
4635 if ((offset1 == offset2) ||
4636 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4637 delta_cmp(offset1, offset2) == 0)) {
4638 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4639 ((PyDateTime_DateTime *)other)->data,
4640 _PyDateTime_DATETIME_DATASIZE);
4641 result = diff_to_bool(diff, op);
4642 }
4643 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004644 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004645
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004646 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004647 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4648 other);
4649 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004650 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004651 diff = GET_TD_DAYS(delta);
4652 if (diff == 0)
4653 diff = GET_TD_SECONDS(delta) |
4654 GET_TD_MICROSECONDS(delta);
4655 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004656 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004657 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004658 else {
4659 PyErr_SetString(PyExc_TypeError,
4660 "can't compare offset-naive and "
4661 "offset-aware datetimes");
4662 }
4663 done:
4664 Py_DECREF(offset1);
4665 Py_XDECREF(offset2);
4666 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004667}
4668
4669static long
4670datetime_hash(PyDateTime_DateTime *self)
4671{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004672 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004673 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004674
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004675 offset = datetime_utcoffset((PyObject *)self, NULL);
4676
4677 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004678 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004680 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004681 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004682 self->hashcode = generic_hash(
4683 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004684 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004685 PyObject *temp1, *temp2;
4686 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004688 assert(HASTZINFO(self));
4689 days = ymd_to_ord(GET_YEAR(self),
4690 GET_MONTH(self),
4691 GET_DAY(self));
4692 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004693 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004694 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004695 temp1 = new_delta(days, seconds,
4696 DATE_GET_MICROSECOND(self),
4697 1);
4698 if (temp1 == NULL) {
4699 Py_DECREF(offset);
4700 return -1;
4701 }
4702 temp2 = delta_subtract(temp1, offset);
4703 Py_DECREF(temp1);
4704 if (temp2 == NULL) {
4705 Py_DECREF(offset);
4706 return -1;
4707 }
4708 self->hashcode = PyObject_Hash(temp2);
4709 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004710 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004711 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004712 }
4713 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004714}
Tim Peters2a799bf2002-12-16 20:18:38 +00004715
4716static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004717datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004719 PyObject *clone;
4720 PyObject *tuple;
4721 int y = GET_YEAR(self);
4722 int m = GET_MONTH(self);
4723 int d = GET_DAY(self);
4724 int hh = DATE_GET_HOUR(self);
4725 int mm = DATE_GET_MINUTE(self);
4726 int ss = DATE_GET_SECOND(self);
4727 int us = DATE_GET_MICROSECOND(self);
4728 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004730 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4731 datetime_kws,
4732 &y, &m, &d, &hh, &mm, &ss, &us,
4733 &tzinfo))
4734 return NULL;
4735 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4736 if (tuple == NULL)
4737 return NULL;
4738 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4739 Py_DECREF(tuple);
4740 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004741}
4742
4743static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004744datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004746 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004747 PyObject *offset;
4748 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004749 PyObject *tzinfo;
4750 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004752 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4753 &PyDateTime_TZInfoType, &tzinfo))
4754 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004756 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4757 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004759 /* Conversion to self's own time zone is a NOP. */
4760 if (self->tzinfo == tzinfo) {
4761 Py_INCREF(self);
4762 return (PyObject *)self;
4763 }
Tim Peters521fc152002-12-31 17:36:56 +00004764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004765 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004766 offset = datetime_utcoffset((PyObject *)self, NULL);
4767 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004768 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004769 if (offset == Py_None) {
4770 Py_DECREF(offset);
4771 NeedAware:
4772 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4773 "a naive datetime");
4774 return NULL;
4775 }
Tim Petersf3615152003-01-01 21:51:37 +00004776
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004777 /* result = self - offset */
4778 result = add_datetime_timedelta(self,
4779 (PyDateTime_Delta *)offset, -1);
4780 Py_DECREF(offset);
4781 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004782 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004784 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004785 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4786 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4787 Py_INCREF(tzinfo);
4788 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004789
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004790 temp = result;
4791 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4792 Py_DECREF(temp);
4793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004794 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004795}
4796
4797static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004798datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004800 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004802 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004803 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004804
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004805 dst = call_dst(self->tzinfo, (PyObject *)self);
4806 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004807 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004808
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004809 if (dst != Py_None)
4810 dstflag = delta_bool((PyDateTime_Delta *)dst);
4811 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004812 }
4813 return build_struct_time(GET_YEAR(self),
4814 GET_MONTH(self),
4815 GET_DAY(self),
4816 DATE_GET_HOUR(self),
4817 DATE_GET_MINUTE(self),
4818 DATE_GET_SECOND(self),
4819 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004820}
4821
4822static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004823datetime_getdate(PyDateTime_DateTime *self)
4824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004825 return new_date(GET_YEAR(self),
4826 GET_MONTH(self),
4827 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004828}
4829
4830static PyObject *
4831datetime_gettime(PyDateTime_DateTime *self)
4832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004833 return new_time(DATE_GET_HOUR(self),
4834 DATE_GET_MINUTE(self),
4835 DATE_GET_SECOND(self),
4836 DATE_GET_MICROSECOND(self),
4837 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004838}
4839
4840static PyObject *
4841datetime_gettimetz(PyDateTime_DateTime *self)
4842{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004843 return new_time(DATE_GET_HOUR(self),
4844 DATE_GET_MINUTE(self),
4845 DATE_GET_SECOND(self),
4846 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004847 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004848}
4849
4850static PyObject *
4851datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004852{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004853 int y, m, d, hh, mm, ss;
4854 PyObject *tzinfo;
4855 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004856
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004857 tzinfo = GET_DT_TZINFO(self);
4858 if (tzinfo == Py_None) {
4859 utcself = self;
4860 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004861 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004862 else {
4863 PyObject *offset;
4864 offset = call_utcoffset(tzinfo, (PyObject *)self);
4865 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004866 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004867 if (offset == Py_None) {
4868 Py_DECREF(offset);
4869 utcself = self;
4870 Py_INCREF(utcself);
4871 }
4872 else {
4873 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4874 (PyDateTime_Delta *)offset, -1);
4875 Py_DECREF(offset);
4876 if (utcself == NULL)
4877 return NULL;
4878 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004879 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004880 y = GET_YEAR(utcself);
4881 m = GET_MONTH(utcself);
4882 d = GET_DAY(utcself);
4883 hh = DATE_GET_HOUR(utcself);
4884 mm = DATE_GET_MINUTE(utcself);
4885 ss = DATE_GET_SECOND(utcself);
4886
4887 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004888 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004889}
4890
Tim Peters371935f2003-02-01 01:52:50 +00004891/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004892
Tim Petersa9bc1682003-01-11 03:39:11 +00004893/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004894 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4895 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004896 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004897 */
4898static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004899datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004900{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004901 PyObject *basestate;
4902 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004904 basestate = PyBytes_FromStringAndSize((char *)self->data,
4905 _PyDateTime_DATETIME_DATASIZE);
4906 if (basestate != NULL) {
4907 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4908 result = PyTuple_Pack(1, basestate);
4909 else
4910 result = PyTuple_Pack(2, basestate, self->tzinfo);
4911 Py_DECREF(basestate);
4912 }
4913 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004914}
4915
4916static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004917datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004918{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004919 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004920}
4921
Tim Petersa9bc1682003-01-11 03:39:11 +00004922static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004924 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004926 {"now", (PyCFunction)datetime_now,
4927 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4928 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004930 {"utcnow", (PyCFunction)datetime_utcnow,
4931 METH_NOARGS | METH_CLASS,
4932 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4935 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4936 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004938 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4939 METH_VARARGS | METH_CLASS,
4940 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4941 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004943 {"strptime", (PyCFunction)datetime_strptime,
4944 METH_VARARGS | METH_CLASS,
4945 PyDoc_STR("string, format -> new datetime parsed from a string "
4946 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004948 {"combine", (PyCFunction)datetime_combine,
4949 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4950 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004952 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004954 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4955 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004957 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4958 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004960 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4961 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004963 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4964 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004966 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4967 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004969 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4970 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004972 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4973 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4974 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4975 "sep is used to separate the year from the time, and "
4976 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004978 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4979 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004981 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4982 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004984 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4985 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004987 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4988 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004990 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4991 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004993 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4994 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004996 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004997};
4998
Tim Petersa9bc1682003-01-11 03:39:11 +00004999static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005000PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5001\n\
5002The year, month and day arguments are required. tzinfo may be None, or an\n\
5003instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005004
Tim Petersa9bc1682003-01-11 03:39:11 +00005005static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005006 datetime_add, /* nb_add */
5007 datetime_subtract, /* nb_subtract */
5008 0, /* nb_multiply */
5009 0, /* nb_remainder */
5010 0, /* nb_divmod */
5011 0, /* nb_power */
5012 0, /* nb_negative */
5013 0, /* nb_positive */
5014 0, /* nb_absolute */
5015 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005016};
5017
Neal Norwitz227b5332006-03-22 09:28:35 +00005018static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005019 PyVarObject_HEAD_INIT(NULL, 0)
5020 "datetime.datetime", /* tp_name */
5021 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5022 0, /* tp_itemsize */
5023 (destructor)datetime_dealloc, /* tp_dealloc */
5024 0, /* tp_print */
5025 0, /* tp_getattr */
5026 0, /* tp_setattr */
5027 0, /* tp_reserved */
5028 (reprfunc)datetime_repr, /* tp_repr */
5029 &datetime_as_number, /* tp_as_number */
5030 0, /* tp_as_sequence */
5031 0, /* tp_as_mapping */
5032 (hashfunc)datetime_hash, /* tp_hash */
5033 0, /* tp_call */
5034 (reprfunc)datetime_str, /* tp_str */
5035 PyObject_GenericGetAttr, /* tp_getattro */
5036 0, /* tp_setattro */
5037 0, /* tp_as_buffer */
5038 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5039 datetime_doc, /* tp_doc */
5040 0, /* tp_traverse */
5041 0, /* tp_clear */
5042 datetime_richcompare, /* tp_richcompare */
5043 0, /* tp_weaklistoffset */
5044 0, /* tp_iter */
5045 0, /* tp_iternext */
5046 datetime_methods, /* tp_methods */
5047 0, /* tp_members */
5048 datetime_getset, /* tp_getset */
5049 &PyDateTime_DateType, /* tp_base */
5050 0, /* tp_dict */
5051 0, /* tp_descr_get */
5052 0, /* tp_descr_set */
5053 0, /* tp_dictoffset */
5054 0, /* tp_init */
5055 datetime_alloc, /* tp_alloc */
5056 datetime_new, /* tp_new */
5057 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005058};
5059
5060/* ---------------------------------------------------------------------------
5061 * Module methods and initialization.
5062 */
5063
5064static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005065 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005066};
5067
Tim Peters9ddf40b2004-06-20 22:41:32 +00005068/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5069 * datetime.h.
5070 */
5071static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005072 &PyDateTime_DateType,
5073 &PyDateTime_DateTimeType,
5074 &PyDateTime_TimeType,
5075 &PyDateTime_DeltaType,
5076 &PyDateTime_TZInfoType,
5077 new_date_ex,
5078 new_datetime_ex,
5079 new_time_ex,
5080 new_delta_ex,
5081 datetime_fromtimestamp,
5082 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005083};
5084
5085
Martin v. Löwis1a214512008-06-11 05:26:20 +00005086
5087static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005088 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005089 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005090 "Fast implementation of the datetime type.",
5091 -1,
5092 module_methods,
5093 NULL,
5094 NULL,
5095 NULL,
5096 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005097};
5098
Tim Peters2a799bf2002-12-16 20:18:38 +00005099PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005100PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005102 PyObject *m; /* a module object */
5103 PyObject *d; /* its dict */
5104 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005105 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005107 m = PyModule_Create(&datetimemodule);
5108 if (m == NULL)
5109 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005111 if (PyType_Ready(&PyDateTime_DateType) < 0)
5112 return NULL;
5113 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5114 return NULL;
5115 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5116 return NULL;
5117 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5118 return NULL;
5119 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5120 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005121 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5122 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005124 /* timedelta values */
5125 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005127 x = new_delta(0, 0, 1, 0);
5128 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5129 return NULL;
5130 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005132 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5133 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5134 return NULL;
5135 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005137 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5138 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5139 return NULL;
5140 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005142 /* date values */
5143 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005145 x = new_date(1, 1, 1);
5146 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5147 return NULL;
5148 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005150 x = new_date(MAXYEAR, 12, 31);
5151 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5152 return NULL;
5153 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005155 x = new_delta(1, 0, 0, 0);
5156 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5157 return NULL;
5158 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005160 /* time values */
5161 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005163 x = new_time(0, 0, 0, 0, Py_None);
5164 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5165 return NULL;
5166 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005168 x = new_time(23, 59, 59, 999999, Py_None);
5169 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5170 return NULL;
5171 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005173 x = new_delta(0, 0, 1, 0);
5174 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5175 return NULL;
5176 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005178 /* datetime values */
5179 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005181 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5182 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5183 return NULL;
5184 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005186 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5187 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5188 return NULL;
5189 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005191 x = new_delta(0, 0, 1, 0);
5192 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5193 return NULL;
5194 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005195
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005196 /* timezone values */
5197 d = PyDateTime_TimeZoneType.tp_dict;
5198
5199 delta = new_delta(0, 0, 0, 0);
5200 if (delta == NULL)
5201 return NULL;
5202 x = new_timezone(delta, NULL);
5203 Py_DECREF(delta);
5204 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5205 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005206 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005207
5208 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5209 if (delta == NULL)
5210 return NULL;
5211 x = new_timezone(delta, NULL);
5212 Py_DECREF(delta);
5213 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5214 return NULL;
5215 Py_DECREF(x);
5216
5217 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5218 if (delta == NULL)
5219 return NULL;
5220 x = new_timezone(delta, NULL);
5221 Py_DECREF(delta);
5222 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5223 return NULL;
5224 Py_DECREF(x);
5225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005226 /* module initialization */
5227 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5228 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005230 Py_INCREF(&PyDateTime_DateType);
5231 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005233 Py_INCREF(&PyDateTime_DateTimeType);
5234 PyModule_AddObject(m, "datetime",
5235 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005237 Py_INCREF(&PyDateTime_TimeType);
5238 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005240 Py_INCREF(&PyDateTime_DeltaType);
5241 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 Py_INCREF(&PyDateTime_TZInfoType);
5244 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005245
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005246 Py_INCREF(&PyDateTime_TimeZoneType);
5247 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005249 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5250 if (x == NULL)
5251 return NULL;
5252 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005254 /* A 4-year cycle has an extra leap day over what we'd get from
5255 * pasting together 4 single years.
5256 */
5257 assert(DI4Y == 4 * 365 + 1);
5258 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005260 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5261 * get from pasting together 4 100-year cycles.
5262 */
5263 assert(DI400Y == 4 * DI100Y + 1);
5264 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005266 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5267 * pasting together 25 4-year cycles.
5268 */
5269 assert(DI100Y == 25 * DI4Y - 1);
5270 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005272 us_per_us = PyLong_FromLong(1);
5273 us_per_ms = PyLong_FromLong(1000);
5274 us_per_second = PyLong_FromLong(1000000);
5275 us_per_minute = PyLong_FromLong(60000000);
5276 seconds_per_day = PyLong_FromLong(24 * 3600);
5277 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5278 us_per_minute == NULL || seconds_per_day == NULL)
5279 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005281 /* The rest are too big for 32-bit ints, but even
5282 * us_per_week fits in 40 bits, so doubles should be exact.
5283 */
5284 us_per_hour = PyLong_FromDouble(3600000000.0);
5285 us_per_day = PyLong_FromDouble(86400000000.0);
5286 us_per_week = PyLong_FromDouble(604800000000.0);
5287 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5288 return NULL;
5289 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005290}
Tim Petersf3615152003-01-01 21:51:37 +00005291
5292/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005293Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005294 x.n = x stripped of its timezone -- its naive time.
5295 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005296 return None
Tim Petersf3615152003-01-01 21:51:37 +00005297 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005298 return None
Tim Petersf3615152003-01-01 21:51:37 +00005299 x.s = x's standard offset, x.o - x.d
5300
5301Now some derived rules, where k is a duration (timedelta).
5302
53031. x.o = x.s + x.d
5304 This follows from the definition of x.s.
5305
Tim Petersc5dc4da2003-01-02 17:55:03 +000053062. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005307 This is actually a requirement, an assumption we need to make about
5308 sane tzinfo classes.
5309
53103. The naive UTC time corresponding to x is x.n - x.o.
5311 This is again a requirement for a sane tzinfo class.
5312
53134. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005314 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005315
Tim Petersc5dc4da2003-01-02 17:55:03 +000053165. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005317 Again follows from how arithmetic is defined.
5318
Tim Peters8bb5ad22003-01-24 02:44:45 +00005319Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005320(meaning that the various tzinfo methods exist, and don't blow up or return
5321None when called).
5322
Tim Petersa9bc1682003-01-11 03:39:11 +00005323The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005324x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005325
5326By #3, we want
5327
Tim Peters8bb5ad22003-01-24 02:44:45 +00005328 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005329
5330The algorithm starts by attaching tz to x.n, and calling that y. So
5331x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5332becomes true; in effect, we want to solve [2] for k:
5333
Tim Peters8bb5ad22003-01-24 02:44:45 +00005334 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005335
5336By #1, this is the same as
5337
Tim Peters8bb5ad22003-01-24 02:44:45 +00005338 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005339
5340By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5341Substituting that into [3],
5342
Tim Peters8bb5ad22003-01-24 02:44:45 +00005343 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5344 k - (y+k).s - (y+k).d = 0; rearranging,
5345 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5346 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005347
Tim Peters8bb5ad22003-01-24 02:44:45 +00005348On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5349approximate k by ignoring the (y+k).d term at first. Note that k can't be
5350very large, since all offset-returning methods return a duration of magnitude
5351less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5352be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005353
5354In any case, the new value is
5355
Tim Peters8bb5ad22003-01-24 02:44:45 +00005356 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005357
Tim Peters8bb5ad22003-01-24 02:44:45 +00005358It's helpful to step back at look at [4] from a higher level: it's simply
5359mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005360
5361At this point, if
5362
Tim Peters8bb5ad22003-01-24 02:44:45 +00005363 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005364
5365we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005366at the start of daylight time. Picture US Eastern for concreteness. The wall
5367time 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 +00005368sense then. The docs ask that an Eastern tzinfo class consider such a time to
5369be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5370on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005371the only spelling that makes sense on the local wall clock.
5372
Tim Petersc5dc4da2003-01-02 17:55:03 +00005373In fact, if [5] holds at this point, we do have the standard-time spelling,
5374but that takes a bit of proof. We first prove a stronger result. What's the
5375difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005376
Tim Peters8bb5ad22003-01-24 02:44:45 +00005377 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005378
Tim Petersc5dc4da2003-01-02 17:55:03 +00005379Now
5380 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005381 (y + y.s).n = by #5
5382 y.n + y.s = since y.n = x.n
5383 x.n + y.s = since z and y are have the same tzinfo member,
5384 y.s = z.s by #2
5385 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005386
Tim Petersc5dc4da2003-01-02 17:55:03 +00005387Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005388
Tim Petersc5dc4da2003-01-02 17:55:03 +00005389 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005390 x.n - ((x.n + z.s) - z.o) = expanding
5391 x.n - x.n - z.s + z.o = cancelling
5392 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005393 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005394
Tim Petersc5dc4da2003-01-02 17:55:03 +00005395So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005396
Tim Petersc5dc4da2003-01-02 17:55:03 +00005397If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005398spelling we wanted in the endcase described above. We're done. Contrarily,
5399if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005400
Tim Petersc5dc4da2003-01-02 17:55:03 +00005401If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5402add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005403local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005404
Tim Petersc5dc4da2003-01-02 17:55:03 +00005405Let
Tim Petersf3615152003-01-01 21:51:37 +00005406
Tim Peters4fede1a2003-01-04 00:26:59 +00005407 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005408
Tim Peters4fede1a2003-01-04 00:26:59 +00005409and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005410
Tim Peters8bb5ad22003-01-24 02:44:45 +00005411 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005412
Tim Peters8bb5ad22003-01-24 02:44:45 +00005413If so, we're done. If not, the tzinfo class is insane, according to the
5414assumptions we've made. This also requires a bit of proof. As before, let's
5415compute the difference between the LHS and RHS of [8] (and skipping some of
5416the justifications for the kinds of substitutions we've done several times
5417already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005418
Tim Peters8bb5ad22003-01-24 02:44:45 +00005419 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005420 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5421 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5422 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5423 - z.n + z.n - z.o + z'.o = cancel z.n
5424 - z.o + z'.o = #1 twice
5425 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5426 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005427
5428So 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 +00005429we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5430return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005431
Tim Peters8bb5ad22003-01-24 02:44:45 +00005432How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5433a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5434would have to change the result dst() returns: we start in DST, and moving
5435a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005436
Tim Peters8bb5ad22003-01-24 02:44:45 +00005437There isn't a sane case where this can happen. The closest it gets is at
5438the end of DST, where there's an hour in UTC with no spelling in a hybrid
5439tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5440that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5441UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5442time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5443clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5444standard time. Since that's what the local clock *does*, we want to map both
5445UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005446in local time, but so it goes -- it's the way the local clock works.
5447
Tim Peters8bb5ad22003-01-24 02:44:45 +00005448When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5449so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5450z' = 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 +00005451(correctly) concludes that z' is not UTC-equivalent to x.
5452
5453Because we know z.d said z was in daylight time (else [5] would have held and
5454we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005455and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005456return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5457but the reasoning doesn't depend on the example -- it depends on there being
5458two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005459z' must be in standard time, and is the spelling we want in this case.
5460
5461Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5462concerned (because it takes z' as being in standard time rather than the
5463daylight time we intend here), but returning it gives the real-life "local
5464clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5465tz.
5466
5467When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5468the 1:MM standard time spelling we want.
5469
5470So how can this break? One of the assumptions must be violated. Two
5471possibilities:
5472
54731) [2] effectively says that y.s is invariant across all y belong to a given
5474 time zone. This isn't true if, for political reasons or continental drift,
5475 a region decides to change its base offset from UTC.
5476
54772) There may be versions of "double daylight" time where the tail end of
5478 the analysis gives up a step too early. I haven't thought about that
5479 enough to say.
5480
5481In any case, it's clear that the default fromutc() is strong enough to handle
5482"almost all" time zones: so long as the standard offset is invariant, it
5483doesn't matter if daylight time transition points change from year to year, or
5484if daylight time is skipped in some years; it doesn't matter how large or
5485small dst() may get within its bounds; and it doesn't even matter if some
5486perverse time zone returns a negative dst()). So a breaking case must be
5487pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005488--------------------------------------------------------------------------- */