blob: 192b1ea89ac716a2f6aa34063e0e7e0c0123d227 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
6#include "modsupport.h"
7#include "structmember.h"
8
9#include <time.h>
10
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000011#include "_time.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000012
13/* Differentiate between building the core module and building extension
14 * modules.
15 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000016#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000017#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000018#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000019#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000020#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000021
22/* We require that C int be at least 32 bits, and use int virtually
23 * everywhere. In just a few cases we use a temp long, where a Python
24 * API returns a C long. In such cases, we have to ensure that the
25 * final result fits in a C int (this can be an issue on 64-bit boxes).
26 */
27#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000028# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000029#endif
30
31#define MINYEAR 1
32#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000033#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000034
35/* Nine decimal digits is easy to communicate, and leaves enough room
36 * so that two delta days can be added w/o fear of overflowing a signed
37 * 32-bit int, and with plenty of room left over to absorb any possible
38 * carries from adding seconds.
39 */
40#define MAX_DELTA_DAYS 999999999
41
42/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043#define GET_YEAR PyDateTime_GET_YEAR
44#define GET_MONTH PyDateTime_GET_MONTH
45#define GET_DAY PyDateTime_GET_DAY
46#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
47#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
48#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
49#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000050
51/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
53 ((o)->data[1] = ((v) & 0x00ff)))
54#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
55#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000056
57/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
59#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
60#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
61#define DATE_SET_MICROSECOND(o, v) \
62 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
63 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
64 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000065
66/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
68#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
69#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
70#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
71#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
72#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
73#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
74#define TIME_SET_MICROSECOND(o, v) \
75 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
76 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
77 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000078
79/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
81#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
82#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084#define SET_TD_DAYS(o, v) ((o)->days = (v))
85#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000086#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
87
Tim Petersa032d2e2003-01-11 00:15:54 +000088/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
89 * p->hastzinfo.
90 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +000091#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
92#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
93 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
94#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
95 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +000096/* M is a char or int claiming to be a valid month. The macro is equivalent
97 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +000099 */
100#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
101
Tim Peters2a799bf2002-12-16 20:18:38 +0000102/* Forward declarations. */
103static PyTypeObject PyDateTime_DateType;
104static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000105static PyTypeObject PyDateTime_DeltaType;
106static PyTypeObject PyDateTime_TimeType;
107static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000108static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000109
110/* ---------------------------------------------------------------------------
111 * Math utilities.
112 */
113
114/* k = i+j overflows iff k differs in sign from both inputs,
115 * iff k^i has sign bit set and k^j has sign bit set,
116 * iff (k^i)&(k^j) has sign bit set.
117 */
118#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000120
121/* Compute Python divmod(x, y), returning the quotient and storing the
122 * remainder into *r. The quotient is the floor of x/y, and that's
123 * the real point of this. C will probably truncate instead (C99
124 * requires truncation; C89 left it implementation-defined).
125 * Simplification: we *require* that y > 0 here. That's appropriate
126 * for all the uses made of it. This simplifies the code and makes
127 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
128 * overflow case).
129 */
130static int
131divmod(int x, int y, int *r)
132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 assert(y > 0);
136 quo = x / y;
137 *r = x - quo * y;
138 if (*r < 0) {
139 --quo;
140 *r += y;
141 }
142 assert(0 <= *r && *r < y);
143 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000144}
145
Tim Peters5d644dd2003-01-02 16:32:54 +0000146/* Round a double to the nearest long. |x| must be small enough to fit
147 * in a C long; this is not checked.
148 */
149static long
150round_to_long(double x)
151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 if (x >= 0.0)
153 x = floor(x + 0.5);
154 else
155 x = ceil(x - 0.5);
156 return (long)x;
Tim Peters5d644dd2003-01-02 16:32:54 +0000157}
158
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000159/* Nearest integer to m / n for integers m and n. Half-integer results
160 * are rounded to even.
161 */
162static PyObject *
163divide_nearest(PyObject *m, PyObject *n)
164{
165 PyObject *result;
166 PyObject *temp;
167
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000168 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000169 if (temp == NULL)
170 return NULL;
171 result = PyTuple_GET_ITEM(temp, 0);
172 Py_INCREF(result);
173 Py_DECREF(temp);
174
175 return result;
176}
177
Tim Peters2a799bf2002-12-16 20:18:38 +0000178/* ---------------------------------------------------------------------------
179 * General calendrical helper functions
180 */
181
182/* For each month ordinal in 1..12, the number of days in that month,
183 * and the number of days before that month in the same year. These
184 * are correct for non-leap years only.
185 */
186static int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 0, /* unused; this vector uses 1-based indexing */
188 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000189};
190
191static int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 0, /* unused; this vector uses 1-based indexing */
193 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000194};
195
196/* year -> 1 if leap year, else 0. */
197static int
198is_leap(int year)
199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 /* Cast year to unsigned. The result is the same either way, but
201 * C can generate faster code for unsigned mod than for signed
202 * mod (especially for % 4 -- a good compiler should just grab
203 * the last 2 bits when the LHS is unsigned).
204 */
205 const unsigned int ayear = (unsigned int)year;
206 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000207}
208
209/* year, month -> number of days in that month in that year */
210static int
211days_in_month(int year, int month)
212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 assert(month >= 1);
214 assert(month <= 12);
215 if (month == 2 && is_leap(year))
216 return 29;
217 else
218 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000219}
220
221/* year, month -> number of days in year preceeding first day of month */
222static int
223days_before_month(int year, int month)
224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 assert(month >= 1);
228 assert(month <= 12);
229 days = _days_before_month[month];
230 if (month > 2 && is_leap(year))
231 ++days;
232 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000233}
234
235/* year -> number of days before January 1st of year. Remember that we
236 * start with year 1, so days_before_year(1) == 0.
237 */
238static int
239days_before_year(int year)
240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 int y = year - 1;
242 /* This is incorrect if year <= 0; we really want the floor
243 * here. But so long as MINYEAR is 1, the smallest year this
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{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004169 _PyTime_timeval t;
4170 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004171 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4172 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004173}
4174
Tim Peters2a799bf2002-12-16 20:18:38 +00004175/* Return best possible local time -- this isn't constrained by the
4176 * precision of a timestamp.
4177 */
4178static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004179datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004181 PyObject *self;
4182 PyObject *tzinfo = Py_None;
4183 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004185 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4186 &tzinfo))
4187 return NULL;
4188 if (check_tzinfo_subclass(tzinfo) < 0)
4189 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 self = datetime_best_possible(cls,
4192 tzinfo == Py_None ? localtime : gmtime,
4193 tzinfo);
4194 if (self != NULL && tzinfo != Py_None) {
4195 /* Convert UTC to tzinfo's zone. */
4196 PyObject *temp = self;
4197 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4198 Py_DECREF(temp);
4199 }
4200 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004201}
4202
Tim Petersa9bc1682003-01-11 03:39:11 +00004203/* Return best possible UTC time -- this isn't constrained by the
4204 * precision of a timestamp.
4205 */
4206static PyObject *
4207datetime_utcnow(PyObject *cls, PyObject *dummy)
4208{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004209 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004210}
4211
Tim Peters2a799bf2002-12-16 20:18:38 +00004212/* Return new local datetime from timestamp (Python timestamp -- a double). */
4213static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004214datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004215{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004216 PyObject *self;
4217 double timestamp;
4218 PyObject *tzinfo = Py_None;
4219 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004221 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4222 keywords, &timestamp, &tzinfo))
4223 return NULL;
4224 if (check_tzinfo_subclass(tzinfo) < 0)
4225 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004227 self = datetime_from_timestamp(cls,
4228 tzinfo == Py_None ? localtime : gmtime,
4229 timestamp,
4230 tzinfo);
4231 if (self != NULL && tzinfo != Py_None) {
4232 /* Convert UTC to tzinfo's zone. */
4233 PyObject *temp = self;
4234 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4235 Py_DECREF(temp);
4236 }
4237 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004238}
4239
Tim Petersa9bc1682003-01-11 03:39:11 +00004240/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4241static PyObject *
4242datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004244 double timestamp;
4245 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004247 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4248 result = datetime_from_timestamp(cls, gmtime, timestamp,
4249 Py_None);
4250 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004251}
4252
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004253/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004254static PyObject *
4255datetime_strptime(PyObject *cls, PyObject *args)
4256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004257 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004258 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004260 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4261 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004262
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004263 if (module == NULL) {
4264 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004265 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004266 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004267 }
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004268 return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4269 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004270}
4271
Tim Petersa9bc1682003-01-11 03:39:11 +00004272/* Return new datetime from date/datetime and time arguments. */
4273static PyObject *
4274datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4275{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004276 static char *keywords[] = {"date", "time", NULL};
4277 PyObject *date;
4278 PyObject *time;
4279 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004281 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4282 &PyDateTime_DateType, &date,
4283 &PyDateTime_TimeType, &time)) {
4284 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004286 if (HASTZINFO(time))
4287 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4288 result = PyObject_CallFunction(cls, "iiiiiiiO",
4289 GET_YEAR(date),
4290 GET_MONTH(date),
4291 GET_DAY(date),
4292 TIME_GET_HOUR(time),
4293 TIME_GET_MINUTE(time),
4294 TIME_GET_SECOND(time),
4295 TIME_GET_MICROSECOND(time),
4296 tzinfo);
4297 }
4298 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004299}
Tim Peters2a799bf2002-12-16 20:18:38 +00004300
4301/*
4302 * Destructor.
4303 */
4304
4305static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004306datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004308 if (HASTZINFO(self)) {
4309 Py_XDECREF(self->tzinfo);
4310 }
4311 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004312}
4313
4314/*
4315 * Indirect access to tzinfo methods.
4316 */
4317
Tim Peters2a799bf2002-12-16 20:18:38 +00004318/* These are all METH_NOARGS, so don't need to check the arglist. */
4319static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004320datetime_utcoffset(PyObject *self, PyObject *unused) {
4321 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004322}
4323
4324static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004325datetime_dst(PyObject *self, PyObject *unused) {
4326 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004327}
4328
4329static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004330datetime_tzname(PyObject *self, PyObject *unused) {
4331 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004332}
4333
4334/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004335 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004336 */
4337
Tim Petersa9bc1682003-01-11 03:39:11 +00004338/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4339 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004340 */
4341static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004342add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004343 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004345 /* Note that the C-level additions can't overflow, because of
4346 * invariant bounds on the member values.
4347 */
4348 int year = GET_YEAR(date);
4349 int month = GET_MONTH(date);
4350 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4351 int hour = DATE_GET_HOUR(date);
4352 int minute = DATE_GET_MINUTE(date);
4353 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4354 int microsecond = DATE_GET_MICROSECOND(date) +
4355 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004357 assert(factor == 1 || factor == -1);
4358 if (normalize_datetime(&year, &month, &day,
4359 &hour, &minute, &second, &microsecond) < 0)
4360 return NULL;
4361 else
4362 return new_datetime(year, month, day,
4363 hour, minute, second, microsecond,
4364 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004365}
4366
4367static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004368datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004370 if (PyDateTime_Check(left)) {
4371 /* datetime + ??? */
4372 if (PyDelta_Check(right))
4373 /* datetime + delta */
4374 return add_datetime_timedelta(
4375 (PyDateTime_DateTime *)left,
4376 (PyDateTime_Delta *)right,
4377 1);
4378 }
4379 else if (PyDelta_Check(left)) {
4380 /* delta + datetime */
4381 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4382 (PyDateTime_Delta *) left,
4383 1);
4384 }
4385 Py_INCREF(Py_NotImplemented);
4386 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004387}
4388
4389static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004390datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004391{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004392 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004394 if (PyDateTime_Check(left)) {
4395 /* datetime - ??? */
4396 if (PyDateTime_Check(right)) {
4397 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004398 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004399 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004400
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004401 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4402 offset2 = offset1 = Py_None;
4403 Py_INCREF(offset1);
4404 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004405 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004406 else {
4407 offset1 = datetime_utcoffset(left, NULL);
4408 if (offset1 == NULL)
4409 return NULL;
4410 offset2 = datetime_utcoffset(right, NULL);
4411 if (offset2 == NULL) {
4412 Py_DECREF(offset1);
4413 return NULL;
4414 }
4415 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4416 PyErr_SetString(PyExc_TypeError,
4417 "can't subtract offset-naive and "
4418 "offset-aware datetimes");
4419 Py_DECREF(offset1);
4420 Py_DECREF(offset2);
4421 return NULL;
4422 }
4423 }
4424 if ((offset1 != offset2) &&
4425 delta_cmp(offset1, offset2) != 0) {
4426 offdiff = delta_subtract(offset1, offset2);
4427 if (offdiff == NULL) {
4428 Py_DECREF(offset1);
4429 Py_DECREF(offset2);
4430 return NULL;
4431 }
4432 }
4433 Py_DECREF(offset1);
4434 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004435 delta_d = ymd_to_ord(GET_YEAR(left),
4436 GET_MONTH(left),
4437 GET_DAY(left)) -
4438 ymd_to_ord(GET_YEAR(right),
4439 GET_MONTH(right),
4440 GET_DAY(right));
4441 /* These can't overflow, since the values are
4442 * normalized. At most this gives the number of
4443 * seconds in one day.
4444 */
4445 delta_s = (DATE_GET_HOUR(left) -
4446 DATE_GET_HOUR(right)) * 3600 +
4447 (DATE_GET_MINUTE(left) -
4448 DATE_GET_MINUTE(right)) * 60 +
4449 (DATE_GET_SECOND(left) -
4450 DATE_GET_SECOND(right));
4451 delta_us = DATE_GET_MICROSECOND(left) -
4452 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004453 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004454 if (offdiff != NULL) {
4455 PyObject *temp = result;
4456 result = delta_subtract(result, offdiff);
4457 Py_DECREF(temp);
4458 Py_DECREF(offdiff);
4459 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004460 }
4461 else if (PyDelta_Check(right)) {
4462 /* datetime - delta */
4463 result = add_datetime_timedelta(
4464 (PyDateTime_DateTime *)left,
4465 (PyDateTime_Delta *)right,
4466 -1);
4467 }
4468 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004470 if (result == Py_NotImplemented)
4471 Py_INCREF(result);
4472 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004473}
4474
4475/* Various ways to turn a datetime into a string. */
4476
4477static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004478datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004479{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004480 const char *type_name = Py_TYPE(self)->tp_name;
4481 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004483 if (DATE_GET_MICROSECOND(self)) {
4484 baserepr = PyUnicode_FromFormat(
4485 "%s(%d, %d, %d, %d, %d, %d, %d)",
4486 type_name,
4487 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4488 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4489 DATE_GET_SECOND(self),
4490 DATE_GET_MICROSECOND(self));
4491 }
4492 else if (DATE_GET_SECOND(self)) {
4493 baserepr = PyUnicode_FromFormat(
4494 "%s(%d, %d, %d, %d, %d, %d)",
4495 type_name,
4496 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4497 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4498 DATE_GET_SECOND(self));
4499 }
4500 else {
4501 baserepr = PyUnicode_FromFormat(
4502 "%s(%d, %d, %d, %d, %d)",
4503 type_name,
4504 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4505 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4506 }
4507 if (baserepr == NULL || ! HASTZINFO(self))
4508 return baserepr;
4509 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004510}
4511
Tim Petersa9bc1682003-01-11 03:39:11 +00004512static PyObject *
4513datetime_str(PyDateTime_DateTime *self)
4514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004515 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004516}
Tim Peters2a799bf2002-12-16 20:18:38 +00004517
4518static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004519datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004521 int sep = 'T';
4522 static char *keywords[] = {"sep", NULL};
4523 char buffer[100];
4524 PyObject *result;
4525 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004527 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4528 return NULL;
4529 if (us)
4530 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4531 GET_YEAR(self), GET_MONTH(self),
4532 GET_DAY(self), (int)sep,
4533 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4534 DATE_GET_SECOND(self), us);
4535 else
4536 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4537 GET_YEAR(self), GET_MONTH(self),
4538 GET_DAY(self), (int)sep,
4539 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4540 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004542 if (!result || !HASTZINFO(self))
4543 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004545 /* We need to append the UTC offset. */
4546 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4547 (PyObject *)self) < 0) {
4548 Py_DECREF(result);
4549 return NULL;
4550 }
4551 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4552 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004553}
4554
Tim Petersa9bc1682003-01-11 03:39:11 +00004555static PyObject *
4556datetime_ctime(PyDateTime_DateTime *self)
4557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004558 return format_ctime((PyDateTime_Date *)self,
4559 DATE_GET_HOUR(self),
4560 DATE_GET_MINUTE(self),
4561 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004562}
4563
Tim Peters2a799bf2002-12-16 20:18:38 +00004564/* Miscellaneous methods. */
4565
Tim Petersa9bc1682003-01-11 03:39:11 +00004566static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004567datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004568{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004569 PyObject *result = NULL;
4570 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004571 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 if (! PyDateTime_Check(other)) {
4574 if (PyDate_Check(other)) {
4575 /* Prevent invocation of date_richcompare. We want to
4576 return NotImplemented here to give the other object
4577 a chance. But since DateTime is a subclass of
4578 Date, if the other object is a Date, it would
4579 compute an ordering based on the date part alone,
4580 and we don't want that. So force unequal or
4581 uncomparable here in that case. */
4582 if (op == Py_EQ)
4583 Py_RETURN_FALSE;
4584 if (op == Py_NE)
4585 Py_RETURN_TRUE;
4586 return cmperror(self, other);
4587 }
4588 Py_INCREF(Py_NotImplemented);
4589 return Py_NotImplemented;
4590 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004591
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004592 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004593 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4594 ((PyDateTime_DateTime *)other)->data,
4595 _PyDateTime_DATETIME_DATASIZE);
4596 return diff_to_bool(diff, op);
4597 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004598 offset1 = datetime_utcoffset(self, NULL);
4599 if (offset1 == NULL)
4600 return NULL;
4601 offset2 = datetime_utcoffset(other, NULL);
4602 if (offset2 == NULL)
4603 goto done;
4604 /* If they're both naive, or both aware and have the same offsets,
4605 * we get off cheap. Note that if they're both naive, offset1 ==
4606 * offset2 == Py_None at this point.
4607 */
4608 if ((offset1 == offset2) ||
4609 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4610 delta_cmp(offset1, offset2) == 0)) {
4611 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4612 ((PyDateTime_DateTime *)other)->data,
4613 _PyDateTime_DATETIME_DATASIZE);
4614 result = diff_to_bool(diff, op);
4615 }
4616 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004617 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004618
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004619 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004620 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4621 other);
4622 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004623 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004624 diff = GET_TD_DAYS(delta);
4625 if (diff == 0)
4626 diff = GET_TD_SECONDS(delta) |
4627 GET_TD_MICROSECONDS(delta);
4628 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004629 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004630 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004631 else {
4632 PyErr_SetString(PyExc_TypeError,
4633 "can't compare offset-naive and "
4634 "offset-aware datetimes");
4635 }
4636 done:
4637 Py_DECREF(offset1);
4638 Py_XDECREF(offset2);
4639 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004640}
4641
4642static long
4643datetime_hash(PyDateTime_DateTime *self)
4644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004645 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004646 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004647
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004648 offset = datetime_utcoffset((PyObject *)self, NULL);
4649
4650 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004651 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004653 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004654 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004655 self->hashcode = generic_hash(
4656 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004657 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004658 PyObject *temp1, *temp2;
4659 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004661 assert(HASTZINFO(self));
4662 days = ymd_to_ord(GET_YEAR(self),
4663 GET_MONTH(self),
4664 GET_DAY(self));
4665 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004666 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004667 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004668 temp1 = new_delta(days, seconds,
4669 DATE_GET_MICROSECOND(self),
4670 1);
4671 if (temp1 == NULL) {
4672 Py_DECREF(offset);
4673 return -1;
4674 }
4675 temp2 = delta_subtract(temp1, offset);
4676 Py_DECREF(temp1);
4677 if (temp2 == NULL) {
4678 Py_DECREF(offset);
4679 return -1;
4680 }
4681 self->hashcode = PyObject_Hash(temp2);
4682 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004684 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004685 }
4686 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004687}
Tim Peters2a799bf2002-12-16 20:18:38 +00004688
4689static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004690datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004692 PyObject *clone;
4693 PyObject *tuple;
4694 int y = GET_YEAR(self);
4695 int m = GET_MONTH(self);
4696 int d = GET_DAY(self);
4697 int hh = DATE_GET_HOUR(self);
4698 int mm = DATE_GET_MINUTE(self);
4699 int ss = DATE_GET_SECOND(self);
4700 int us = DATE_GET_MICROSECOND(self);
4701 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004703 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4704 datetime_kws,
4705 &y, &m, &d, &hh, &mm, &ss, &us,
4706 &tzinfo))
4707 return NULL;
4708 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4709 if (tuple == NULL)
4710 return NULL;
4711 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4712 Py_DECREF(tuple);
4713 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004714}
4715
4716static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004717datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004719 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004720 PyObject *offset;
4721 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004722 PyObject *tzinfo;
4723 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004725 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4726 &PyDateTime_TZInfoType, &tzinfo))
4727 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004729 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4730 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004731
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004732 /* Conversion to self's own time zone is a NOP. */
4733 if (self->tzinfo == tzinfo) {
4734 Py_INCREF(self);
4735 return (PyObject *)self;
4736 }
Tim Peters521fc152002-12-31 17:36:56 +00004737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004738 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004739 offset = datetime_utcoffset((PyObject *)self, NULL);
4740 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004741 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004742 if (offset == Py_None) {
4743 Py_DECREF(offset);
4744 NeedAware:
4745 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4746 "a naive datetime");
4747 return NULL;
4748 }
Tim Petersf3615152003-01-01 21:51:37 +00004749
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004750 /* result = self - offset */
4751 result = add_datetime_timedelta(self,
4752 (PyDateTime_Delta *)offset, -1);
4753 Py_DECREF(offset);
4754 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004755 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004757 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004758 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4759 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4760 Py_INCREF(tzinfo);
4761 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004762
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004763 temp = result;
4764 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4765 Py_DECREF(temp);
4766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004767 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004768}
4769
4770static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004771datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004773 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004775 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004776 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004777
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004778 dst = call_dst(self->tzinfo, (PyObject *)self);
4779 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004780 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004781
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004782 if (dst != Py_None)
4783 dstflag = delta_bool((PyDateTime_Delta *)dst);
4784 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004785 }
4786 return build_struct_time(GET_YEAR(self),
4787 GET_MONTH(self),
4788 GET_DAY(self),
4789 DATE_GET_HOUR(self),
4790 DATE_GET_MINUTE(self),
4791 DATE_GET_SECOND(self),
4792 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004793}
4794
4795static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004796datetime_getdate(PyDateTime_DateTime *self)
4797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004798 return new_date(GET_YEAR(self),
4799 GET_MONTH(self),
4800 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004801}
4802
4803static PyObject *
4804datetime_gettime(PyDateTime_DateTime *self)
4805{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004806 return new_time(DATE_GET_HOUR(self),
4807 DATE_GET_MINUTE(self),
4808 DATE_GET_SECOND(self),
4809 DATE_GET_MICROSECOND(self),
4810 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004811}
4812
4813static PyObject *
4814datetime_gettimetz(PyDateTime_DateTime *self)
4815{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004816 return new_time(DATE_GET_HOUR(self),
4817 DATE_GET_MINUTE(self),
4818 DATE_GET_SECOND(self),
4819 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004820 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004821}
4822
4823static PyObject *
4824datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004825{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004826 int y, m, d, hh, mm, ss;
4827 PyObject *tzinfo;
4828 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004829
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004830 tzinfo = GET_DT_TZINFO(self);
4831 if (tzinfo == Py_None) {
4832 utcself = self;
4833 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004834 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004835 else {
4836 PyObject *offset;
4837 offset = call_utcoffset(tzinfo, (PyObject *)self);
4838 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004839 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004840 if (offset == Py_None) {
4841 Py_DECREF(offset);
4842 utcself = self;
4843 Py_INCREF(utcself);
4844 }
4845 else {
4846 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4847 (PyDateTime_Delta *)offset, -1);
4848 Py_DECREF(offset);
4849 if (utcself == NULL)
4850 return NULL;
4851 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004852 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004853 y = GET_YEAR(utcself);
4854 m = GET_MONTH(utcself);
4855 d = GET_DAY(utcself);
4856 hh = DATE_GET_HOUR(utcself);
4857 mm = DATE_GET_MINUTE(utcself);
4858 ss = DATE_GET_SECOND(utcself);
4859
4860 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004861 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004862}
4863
Tim Peters371935f2003-02-01 01:52:50 +00004864/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004865
Tim Petersa9bc1682003-01-11 03:39:11 +00004866/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004867 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4868 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004869 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004870 */
4871static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004872datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004873{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004874 PyObject *basestate;
4875 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004877 basestate = PyBytes_FromStringAndSize((char *)self->data,
4878 _PyDateTime_DATETIME_DATASIZE);
4879 if (basestate != NULL) {
4880 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4881 result = PyTuple_Pack(1, basestate);
4882 else
4883 result = PyTuple_Pack(2, basestate, self->tzinfo);
4884 Py_DECREF(basestate);
4885 }
4886 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004887}
4888
4889static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004890datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004892 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004893}
4894
Tim Petersa9bc1682003-01-11 03:39:11 +00004895static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004897 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004899 {"now", (PyCFunction)datetime_now,
4900 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4901 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004903 {"utcnow", (PyCFunction)datetime_utcnow,
4904 METH_NOARGS | METH_CLASS,
4905 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004907 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4908 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4909 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004911 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4912 METH_VARARGS | METH_CLASS,
4913 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4914 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004916 {"strptime", (PyCFunction)datetime_strptime,
4917 METH_VARARGS | METH_CLASS,
4918 PyDoc_STR("string, format -> new datetime parsed from a string "
4919 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004921 {"combine", (PyCFunction)datetime_combine,
4922 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4923 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004925 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004927 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4928 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004930 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4931 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004933 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4934 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004936 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4937 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004939 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4940 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004942 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4943 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004945 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4946 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4947 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4948 "sep is used to separate the year from the time, and "
4949 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004951 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4952 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004954 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4955 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004957 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4958 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004960 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4961 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004963 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4964 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004966 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4967 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004969 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004970};
4971
Tim Petersa9bc1682003-01-11 03:39:11 +00004972static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004973PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4974\n\
4975The year, month and day arguments are required. tzinfo may be None, or an\n\
4976instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004977
Tim Petersa9bc1682003-01-11 03:39:11 +00004978static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004979 datetime_add, /* nb_add */
4980 datetime_subtract, /* nb_subtract */
4981 0, /* nb_multiply */
4982 0, /* nb_remainder */
4983 0, /* nb_divmod */
4984 0, /* nb_power */
4985 0, /* nb_negative */
4986 0, /* nb_positive */
4987 0, /* nb_absolute */
4988 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004989};
4990
Neal Norwitz227b5332006-03-22 09:28:35 +00004991static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004992 PyVarObject_HEAD_INIT(NULL, 0)
4993 "datetime.datetime", /* tp_name */
4994 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4995 0, /* tp_itemsize */
4996 (destructor)datetime_dealloc, /* tp_dealloc */
4997 0, /* tp_print */
4998 0, /* tp_getattr */
4999 0, /* tp_setattr */
5000 0, /* tp_reserved */
5001 (reprfunc)datetime_repr, /* tp_repr */
5002 &datetime_as_number, /* tp_as_number */
5003 0, /* tp_as_sequence */
5004 0, /* tp_as_mapping */
5005 (hashfunc)datetime_hash, /* tp_hash */
5006 0, /* tp_call */
5007 (reprfunc)datetime_str, /* tp_str */
5008 PyObject_GenericGetAttr, /* tp_getattro */
5009 0, /* tp_setattro */
5010 0, /* tp_as_buffer */
5011 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5012 datetime_doc, /* tp_doc */
5013 0, /* tp_traverse */
5014 0, /* tp_clear */
5015 datetime_richcompare, /* tp_richcompare */
5016 0, /* tp_weaklistoffset */
5017 0, /* tp_iter */
5018 0, /* tp_iternext */
5019 datetime_methods, /* tp_methods */
5020 0, /* tp_members */
5021 datetime_getset, /* tp_getset */
5022 &PyDateTime_DateType, /* tp_base */
5023 0, /* tp_dict */
5024 0, /* tp_descr_get */
5025 0, /* tp_descr_set */
5026 0, /* tp_dictoffset */
5027 0, /* tp_init */
5028 datetime_alloc, /* tp_alloc */
5029 datetime_new, /* tp_new */
5030 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005031};
5032
5033/* ---------------------------------------------------------------------------
5034 * Module methods and initialization.
5035 */
5036
5037static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005038 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005039};
5040
Tim Peters9ddf40b2004-06-20 22:41:32 +00005041/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5042 * datetime.h.
5043 */
5044static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005045 &PyDateTime_DateType,
5046 &PyDateTime_DateTimeType,
5047 &PyDateTime_TimeType,
5048 &PyDateTime_DeltaType,
5049 &PyDateTime_TZInfoType,
5050 new_date_ex,
5051 new_datetime_ex,
5052 new_time_ex,
5053 new_delta_ex,
5054 datetime_fromtimestamp,
5055 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005056};
5057
5058
Martin v. Löwis1a214512008-06-11 05:26:20 +00005059
5060static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005061 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005062 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005063 "Fast implementation of the datetime type.",
5064 -1,
5065 module_methods,
5066 NULL,
5067 NULL,
5068 NULL,
5069 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005070};
5071
Tim Peters2a799bf2002-12-16 20:18:38 +00005072PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005073PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005075 PyObject *m; /* a module object */
5076 PyObject *d; /* its dict */
5077 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005078 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005080 m = PyModule_Create(&datetimemodule);
5081 if (m == NULL)
5082 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005084 if (PyType_Ready(&PyDateTime_DateType) < 0)
5085 return NULL;
5086 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5087 return NULL;
5088 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5089 return NULL;
5090 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5091 return NULL;
5092 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5093 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005094 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5095 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005097 /* timedelta values */
5098 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005100 x = new_delta(0, 0, 1, 0);
5101 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5102 return NULL;
5103 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005105 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5106 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5107 return NULL;
5108 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005110 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5111 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5112 return NULL;
5113 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005115 /* date values */
5116 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005118 x = new_date(1, 1, 1);
5119 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5120 return NULL;
5121 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005123 x = new_date(MAXYEAR, 12, 31);
5124 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5125 return NULL;
5126 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005128 x = new_delta(1, 0, 0, 0);
5129 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5130 return NULL;
5131 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005133 /* time values */
5134 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005136 x = new_time(0, 0, 0, 0, Py_None);
5137 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5138 return NULL;
5139 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005141 x = new_time(23, 59, 59, 999999, Py_None);
5142 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5143 return NULL;
5144 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005146 x = new_delta(0, 0, 1, 0);
5147 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5148 return NULL;
5149 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005151 /* datetime values */
5152 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005154 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5155 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5156 return NULL;
5157 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005159 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5160 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5161 return NULL;
5162 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005164 x = new_delta(0, 0, 1, 0);
5165 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5166 return NULL;
5167 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005168
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005169 /* timezone values */
5170 d = PyDateTime_TimeZoneType.tp_dict;
5171
5172 delta = new_delta(0, 0, 0, 0);
5173 if (delta == NULL)
5174 return NULL;
5175 x = new_timezone(delta, NULL);
5176 Py_DECREF(delta);
5177 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5178 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005179 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005180
5181 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5182 if (delta == NULL)
5183 return NULL;
5184 x = new_timezone(delta, NULL);
5185 Py_DECREF(delta);
5186 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5187 return NULL;
5188 Py_DECREF(x);
5189
5190 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5191 if (delta == NULL)
5192 return NULL;
5193 x = new_timezone(delta, NULL);
5194 Py_DECREF(delta);
5195 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5196 return NULL;
5197 Py_DECREF(x);
5198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005199 /* module initialization */
5200 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5201 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005203 Py_INCREF(&PyDateTime_DateType);
5204 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005206 Py_INCREF(&PyDateTime_DateTimeType);
5207 PyModule_AddObject(m, "datetime",
5208 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005210 Py_INCREF(&PyDateTime_TimeType);
5211 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005213 Py_INCREF(&PyDateTime_DeltaType);
5214 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005216 Py_INCREF(&PyDateTime_TZInfoType);
5217 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005218
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005219 Py_INCREF(&PyDateTime_TimeZoneType);
5220 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005222 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5223 if (x == NULL)
5224 return NULL;
5225 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005227 /* A 4-year cycle has an extra leap day over what we'd get from
5228 * pasting together 4 single years.
5229 */
5230 assert(DI4Y == 4 * 365 + 1);
5231 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005233 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5234 * get from pasting together 4 100-year cycles.
5235 */
5236 assert(DI400Y == 4 * DI100Y + 1);
5237 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005239 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5240 * pasting together 25 4-year cycles.
5241 */
5242 assert(DI100Y == 25 * DI4Y - 1);
5243 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005245 us_per_us = PyLong_FromLong(1);
5246 us_per_ms = PyLong_FromLong(1000);
5247 us_per_second = PyLong_FromLong(1000000);
5248 us_per_minute = PyLong_FromLong(60000000);
5249 seconds_per_day = PyLong_FromLong(24 * 3600);
5250 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5251 us_per_minute == NULL || seconds_per_day == NULL)
5252 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005254 /* The rest are too big for 32-bit ints, but even
5255 * us_per_week fits in 40 bits, so doubles should be exact.
5256 */
5257 us_per_hour = PyLong_FromDouble(3600000000.0);
5258 us_per_day = PyLong_FromDouble(86400000000.0);
5259 us_per_week = PyLong_FromDouble(604800000000.0);
5260 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5261 return NULL;
5262 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005263}
Tim Petersf3615152003-01-01 21:51:37 +00005264
5265/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005266Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005267 x.n = x stripped of its timezone -- its naive time.
5268 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005269 return None
Tim Petersf3615152003-01-01 21:51:37 +00005270 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005271 return None
Tim Petersf3615152003-01-01 21:51:37 +00005272 x.s = x's standard offset, x.o - x.d
5273
5274Now some derived rules, where k is a duration (timedelta).
5275
52761. x.o = x.s + x.d
5277 This follows from the definition of x.s.
5278
Tim Petersc5dc4da2003-01-02 17:55:03 +000052792. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005280 This is actually a requirement, an assumption we need to make about
5281 sane tzinfo classes.
5282
52833. The naive UTC time corresponding to x is x.n - x.o.
5284 This is again a requirement for a sane tzinfo class.
5285
52864. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005287 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005288
Tim Petersc5dc4da2003-01-02 17:55:03 +000052895. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005290 Again follows from how arithmetic is defined.
5291
Tim Peters8bb5ad22003-01-24 02:44:45 +00005292Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005293(meaning that the various tzinfo methods exist, and don't blow up or return
5294None when called).
5295
Tim Petersa9bc1682003-01-11 03:39:11 +00005296The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005297x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005298
5299By #3, we want
5300
Tim Peters8bb5ad22003-01-24 02:44:45 +00005301 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005302
5303The algorithm starts by attaching tz to x.n, and calling that y. So
5304x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5305becomes true; in effect, we want to solve [2] for k:
5306
Tim Peters8bb5ad22003-01-24 02:44:45 +00005307 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005308
5309By #1, this is the same as
5310
Tim Peters8bb5ad22003-01-24 02:44:45 +00005311 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005312
5313By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5314Substituting that into [3],
5315
Tim Peters8bb5ad22003-01-24 02:44:45 +00005316 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5317 k - (y+k).s - (y+k).d = 0; rearranging,
5318 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5319 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005320
Tim Peters8bb5ad22003-01-24 02:44:45 +00005321On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5322approximate k by ignoring the (y+k).d term at first. Note that k can't be
5323very large, since all offset-returning methods return a duration of magnitude
5324less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5325be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005326
5327In any case, the new value is
5328
Tim Peters8bb5ad22003-01-24 02:44:45 +00005329 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005330
Tim Peters8bb5ad22003-01-24 02:44:45 +00005331It's helpful to step back at look at [4] from a higher level: it's simply
5332mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005333
5334At this point, if
5335
Tim Peters8bb5ad22003-01-24 02:44:45 +00005336 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005337
5338we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005339at the start of daylight time. Picture US Eastern for concreteness. The wall
5340time 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 +00005341sense then. The docs ask that an Eastern tzinfo class consider such a time to
5342be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5343on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005344the only spelling that makes sense on the local wall clock.
5345
Tim Petersc5dc4da2003-01-02 17:55:03 +00005346In fact, if [5] holds at this point, we do have the standard-time spelling,
5347but that takes a bit of proof. We first prove a stronger result. What's the
5348difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005349
Tim Peters8bb5ad22003-01-24 02:44:45 +00005350 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005351
Tim Petersc5dc4da2003-01-02 17:55:03 +00005352Now
5353 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005354 (y + y.s).n = by #5
5355 y.n + y.s = since y.n = x.n
5356 x.n + y.s = since z and y are have the same tzinfo member,
5357 y.s = z.s by #2
5358 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005359
Tim Petersc5dc4da2003-01-02 17:55:03 +00005360Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005361
Tim Petersc5dc4da2003-01-02 17:55:03 +00005362 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005363 x.n - ((x.n + z.s) - z.o) = expanding
5364 x.n - x.n - z.s + z.o = cancelling
5365 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005366 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005367
Tim Petersc5dc4da2003-01-02 17:55:03 +00005368So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005369
Tim Petersc5dc4da2003-01-02 17:55:03 +00005370If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005371spelling we wanted in the endcase described above. We're done. Contrarily,
5372if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005373
Tim Petersc5dc4da2003-01-02 17:55:03 +00005374If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5375add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005376local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005377
Tim Petersc5dc4da2003-01-02 17:55:03 +00005378Let
Tim Petersf3615152003-01-01 21:51:37 +00005379
Tim Peters4fede1a2003-01-04 00:26:59 +00005380 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005381
Tim Peters4fede1a2003-01-04 00:26:59 +00005382and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005383
Tim Peters8bb5ad22003-01-24 02:44:45 +00005384 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005385
Tim Peters8bb5ad22003-01-24 02:44:45 +00005386If so, we're done. If not, the tzinfo class is insane, according to the
5387assumptions we've made. This also requires a bit of proof. As before, let's
5388compute the difference between the LHS and RHS of [8] (and skipping some of
5389the justifications for the kinds of substitutions we've done several times
5390already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005391
Tim Peters8bb5ad22003-01-24 02:44:45 +00005392 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005393 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5394 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5395 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5396 - z.n + z.n - z.o + z'.o = cancel z.n
5397 - z.o + z'.o = #1 twice
5398 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5399 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005400
5401So 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 +00005402we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5403return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005404
Tim Peters8bb5ad22003-01-24 02:44:45 +00005405How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5406a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5407would have to change the result dst() returns: we start in DST, and moving
5408a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005409
Tim Peters8bb5ad22003-01-24 02:44:45 +00005410There isn't a sane case where this can happen. The closest it gets is at
5411the end of DST, where there's an hour in UTC with no spelling in a hybrid
5412tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5413that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5414UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5415time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5416clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5417standard time. Since that's what the local clock *does*, we want to map both
5418UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005419in local time, but so it goes -- it's the way the local clock works.
5420
Tim Peters8bb5ad22003-01-24 02:44:45 +00005421When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5422so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5423z' = 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 +00005424(correctly) concludes that z' is not UTC-equivalent to x.
5425
5426Because we know z.d said z was in daylight time (else [5] would have held and
5427we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005428and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005429return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5430but the reasoning doesn't depend on the example -- it depends on there being
5431two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005432z' must be in standard time, and is the spelling we want in this case.
5433
5434Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5435concerned (because it takes z' as being in standard time rather than the
5436daylight time we intend here), but returning it gives the real-life "local
5437clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5438tz.
5439
5440When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5441the 1:MM standard time spelling we want.
5442
5443So how can this break? One of the assumptions must be violated. Two
5444possibilities:
5445
54461) [2] effectively says that y.s is invariant across all y belong to a given
5447 time zone. This isn't true if, for political reasons or continental drift,
5448 a region decides to change its base offset from UTC.
5449
54502) There may be versions of "double daylight" time where the tail end of
5451 the analysis gives up a step too early. I haven't thought about that
5452 enough to say.
5453
5454In any case, it's clear that the default fromutc() is strong enough to handle
5455"almost all" time zones: so long as the standard offset is invariant, it
5456doesn't matter if daylight time transition points change from year to year, or
5457if daylight time is skipped in some years; it doesn't matter how large or
5458small dst() may get within its bounds; and it doesn't even matter if some
5459perverse time zone returns a negative dst()). So a breaking case must be
5460pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005461--------------------------------------------------------------------------- */