blob: a7156a46523051418c0b247153144943b04ea26f [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
Tim Peters2a799bf2002-12-16 20:18:38 +00006#include "structmember.h"
7
8#include <time.h>
9
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000010#include "_time.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000011
12/* Differentiate between building the core module and building extension
13 * modules.
14 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000015#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000016#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000017#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000018#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000019#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000020
21/* We require that C int be at least 32 bits, and use int virtually
22 * everywhere. In just a few cases we use a temp long, where a Python
23 * API returns a C long. In such cases, we have to ensure that the
24 * final result fits in a C int (this can be an issue on 64-bit boxes).
25 */
26#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000027# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000028#endif
29
30#define MINYEAR 1
31#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000032#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000033
34/* Nine decimal digits is easy to communicate, and leaves enough room
35 * so that two delta days can be added w/o fear of overflowing a signed
36 * 32-bit int, and with plenty of room left over to absorb any possible
37 * carries from adding seconds.
38 */
39#define MAX_DELTA_DAYS 999999999
40
41/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042#define GET_YEAR PyDateTime_GET_YEAR
43#define GET_MONTH PyDateTime_GET_MONTH
44#define GET_DAY PyDateTime_GET_DAY
45#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
46#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
47#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
48#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000049
50/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
52 ((o)->data[1] = ((v) & 0x00ff)))
53#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
54#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000055
56/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000057#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
58#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
59#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
60#define DATE_SET_MICROSECOND(o, v) \
61 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
62 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
63 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000064
65/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
67#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
68#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
69#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
70#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
71#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
72#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
73#define TIME_SET_MICROSECOND(o, v) \
74 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
75 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
76 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000077
78/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
80#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
81#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083#define SET_TD_DAYS(o, v) ((o)->days = (v))
84#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000085#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
86
Tim Petersa032d2e2003-01-11 00:15:54 +000087/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
88 * p->hastzinfo.
89 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +000090#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
91#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
92 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
93#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
94 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +000095/* M is a char or int claiming to be a valid month. The macro is equivalent
96 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +000098 */
99#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
100
Tim Peters2a799bf2002-12-16 20:18:38 +0000101/* Forward declarations. */
102static PyTypeObject PyDateTime_DateType;
103static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000104static PyTypeObject PyDateTime_DeltaType;
105static PyTypeObject PyDateTime_TimeType;
106static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000107static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000108
109/* ---------------------------------------------------------------------------
110 * Math utilities.
111 */
112
113/* k = i+j overflows iff k differs in sign from both inputs,
114 * iff k^i has sign bit set and k^j has sign bit set,
115 * iff (k^i)&(k^j) has sign bit set.
116 */
117#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000119
120/* Compute Python divmod(x, y), returning the quotient and storing the
121 * remainder into *r. The quotient is the floor of x/y, and that's
122 * the real point of this. C will probably truncate instead (C99
123 * requires truncation; C89 left it implementation-defined).
124 * Simplification: we *require* that y > 0 here. That's appropriate
125 * for all the uses made of it. This simplifies the code and makes
126 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
127 * overflow case).
128 */
129static int
130divmod(int x, int y, int *r)
131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 assert(y > 0);
135 quo = x / y;
136 *r = x - quo * y;
137 if (*r < 0) {
138 --quo;
139 *r += y;
140 }
141 assert(0 <= *r && *r < y);
142 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000143}
144
Tim Peters5d644dd2003-01-02 16:32:54 +0000145/* Round a double to the nearest long. |x| must be small enough to fit
146 * in a C long; this is not checked.
147 */
148static long
149round_to_long(double x)
150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 if (x >= 0.0)
152 x = floor(x + 0.5);
153 else
154 x = ceil(x - 0.5);
155 return (long)x;
Tim Peters5d644dd2003-01-02 16:32:54 +0000156}
157
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000158/* Nearest integer to m / n for integers m and n. Half-integer results
159 * are rounded to even.
160 */
161static PyObject *
162divide_nearest(PyObject *m, PyObject *n)
163{
164 PyObject *result;
165 PyObject *temp;
166
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000167 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000168 if (temp == NULL)
169 return NULL;
170 result = PyTuple_GET_ITEM(temp, 0);
171 Py_INCREF(result);
172 Py_DECREF(temp);
173
174 return result;
175}
176
Tim Peters2a799bf2002-12-16 20:18:38 +0000177/* ---------------------------------------------------------------------------
178 * General calendrical helper functions
179 */
180
181/* For each month ordinal in 1..12, the number of days in that month,
182 * and the number of days before that month in the same year. These
183 * are correct for non-leap years only.
184 */
185static int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 0, /* unused; this vector uses 1-based indexing */
187 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000188};
189
190static int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 0, /* unused; this vector uses 1-based indexing */
192 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000193};
194
195/* year -> 1 if leap year, else 0. */
196static int
197is_leap(int year)
198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 /* Cast year to unsigned. The result is the same either way, but
200 * C can generate faster code for unsigned mod than for signed
201 * mod (especially for % 4 -- a good compiler should just grab
202 * the last 2 bits when the LHS is unsigned).
203 */
204 const unsigned int ayear = (unsigned int)year;
205 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000206}
207
208/* year, month -> number of days in that month in that year */
209static int
210days_in_month(int year, int month)
211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 assert(month >= 1);
213 assert(month <= 12);
214 if (month == 2 && is_leap(year))
215 return 29;
216 else
217 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000218}
219
220/* year, month -> number of days in year preceeding first day of month */
221static int
222days_before_month(int year, int month)
223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 assert(month >= 1);
227 assert(month <= 12);
228 days = _days_before_month[month];
229 if (month > 2 && is_leap(year))
230 ++days;
231 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000232}
233
234/* year -> number of days before January 1st of year. Remember that we
235 * start with year 1, so days_before_year(1) == 0.
236 */
237static int
238days_before_year(int year)
239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 int y = year - 1;
241 /* This is incorrect if year <= 0; we really want the floor
242 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000243 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000245 assert (year >= 1);
246 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000247}
248
249/* Number of days in 4, 100, and 400 year cycles. That these have
250 * the correct values is asserted in the module init function.
251 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252#define DI4Y 1461 /* days_before_year(5); days in 4 years */
253#define DI100Y 36524 /* days_before_year(101); days in 100 years */
254#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000255
256/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
257static void
258ord_to_ymd(int ordinal, int *year, int *month, int *day)
259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
263 * leap years repeats exactly every 400 years. The basic strategy is
264 * to find the closest 400-year boundary at or before ordinal, then
265 * work with the offset from that boundary to ordinal. Life is much
266 * clearer if we subtract 1 from ordinal first -- then the values
267 * of ordinal at 400-year boundaries are exactly those divisible
268 * by DI400Y:
269 *
270 * D M Y n n-1
271 * -- --- ---- ---------- ----------------
272 * 31 Dec -400 -DI400Y -DI400Y -1
273 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
274 * ...
275 * 30 Dec 000 -1 -2
276 * 31 Dec 000 0 -1
277 * 1 Jan 001 1 0 400-year boundary
278 * 2 Jan 001 2 1
279 * 3 Jan 001 3 2
280 * ...
281 * 31 Dec 400 DI400Y DI400Y -1
282 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
283 */
284 assert(ordinal >= 1);
285 --ordinal;
286 n400 = ordinal / DI400Y;
287 n = ordinal % DI400Y;
288 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 /* Now n is the (non-negative) offset, in days, from January 1 of
291 * year, to the desired date. Now compute how many 100-year cycles
292 * precede n.
293 * Note that it's possible for n100 to equal 4! In that case 4 full
294 * 100-year cycles precede the desired day, which implies the
295 * desired day is December 31 at the end of a 400-year cycle.
296 */
297 n100 = n / DI100Y;
298 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 /* Now compute how many 4-year cycles precede it. */
301 n4 = n / DI4Y;
302 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 /* And now how many single years. Again n1 can be 4, and again
305 * meaning that the desired day is December 31 at the end of the
306 * 4-year cycle.
307 */
308 n1 = n / 365;
309 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 *year += n100 * 100 + n4 * 4 + n1;
312 if (n1 == 4 || n100 == 4) {
313 assert(n == 0);
314 *year -= 1;
315 *month = 12;
316 *day = 31;
317 return;
318 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 /* Now the year is correct, and n is the offset from January 1. We
321 * find the month via an estimate that's either exact or one too
322 * large.
323 */
324 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
325 assert(leapyear == is_leap(*year));
326 *month = (n + 50) >> 5;
327 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
328 if (preceding > n) {
329 /* estimate is too large */
330 *month -= 1;
331 preceding -= days_in_month(*year, *month);
332 }
333 n -= preceding;
334 assert(0 <= n);
335 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000338}
339
340/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
341static int
342ymd_to_ord(int year, int month, int day)
343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000345}
346
347/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
348static int
349weekday(int year, int month, int day)
350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000352}
353
354/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
355 * first calendar week containing a Thursday.
356 */
357static int
358iso_week1_monday(int year)
359{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
361 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
362 int first_weekday = (first_day + 6) % 7;
363 /* ordinal of closest Monday at or before 1/1 */
364 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
367 week1_monday += 7;
368 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000369}
370
371/* ---------------------------------------------------------------------------
372 * Range checkers.
373 */
374
375/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
376 * If not, raise OverflowError and return -1.
377 */
378static int
379check_delta_day_range(int days)
380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
382 return 0;
383 PyErr_Format(PyExc_OverflowError,
384 "days=%d; must have magnitude <= %d",
385 days, MAX_DELTA_DAYS);
386 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000387}
388
389/* Check that date arguments are in range. Return 0 if they are. If they
390 * aren't, raise ValueError and return -1.
391 */
392static int
393check_date_args(int year, int month, int day)
394{
395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 if (year < MINYEAR || year > MAXYEAR) {
397 PyErr_SetString(PyExc_ValueError,
398 "year is out of range");
399 return -1;
400 }
401 if (month < 1 || month > 12) {
402 PyErr_SetString(PyExc_ValueError,
403 "month must be in 1..12");
404 return -1;
405 }
406 if (day < 1 || day > days_in_month(year, month)) {
407 PyErr_SetString(PyExc_ValueError,
408 "day is out of range for month");
409 return -1;
410 }
411 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000412}
413
414/* Check that time arguments are in range. Return 0 if they are. If they
415 * aren't, raise ValueError and return -1.
416 */
417static int
418check_time_args(int h, int m, int s, int us)
419{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 if (h < 0 || h > 23) {
421 PyErr_SetString(PyExc_ValueError,
422 "hour must be in 0..23");
423 return -1;
424 }
425 if (m < 0 || m > 59) {
426 PyErr_SetString(PyExc_ValueError,
427 "minute must be in 0..59");
428 return -1;
429 }
430 if (s < 0 || s > 59) {
431 PyErr_SetString(PyExc_ValueError,
432 "second must be in 0..59");
433 return -1;
434 }
435 if (us < 0 || us > 999999) {
436 PyErr_SetString(PyExc_ValueError,
437 "microsecond must be in 0..999999");
438 return -1;
439 }
440 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000441}
442
443/* ---------------------------------------------------------------------------
444 * Normalization utilities.
445 */
446
447/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
448 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
449 * at least factor, enough of *lo is converted into "hi" units so that
450 * 0 <= *lo < factor. The input values must be such that int overflow
451 * is impossible.
452 */
453static void
454normalize_pair(int *hi, int *lo, int factor)
455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 assert(factor > 0);
457 assert(lo != hi);
458 if (*lo < 0 || *lo >= factor) {
459 const int num_hi = divmod(*lo, factor, lo);
460 const int new_hi = *hi + num_hi;
461 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
462 *hi = new_hi;
463 }
464 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000465}
466
467/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 * 0 <= *s < 24*3600
469 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000470 * The input values must be such that the internals don't overflow.
471 * The way this routine is used, we don't get close.
472 */
473static void
474normalize_d_s_us(int *d, int *s, int *us)
475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 if (*us < 0 || *us >= 1000000) {
477 normalize_pair(s, us, 1000000);
478 /* |s| can't be bigger than about
479 * |original s| + |original us|/1000000 now.
480 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 }
483 if (*s < 0 || *s >= 24*3600) {
484 normalize_pair(d, s, 24*3600);
485 /* |d| can't be bigger than about
486 * |original d| +
487 * (|original s| + |original us|/1000000) / (24*3600) now.
488 */
489 }
490 assert(0 <= *s && *s < 24*3600);
491 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000492}
493
494/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 * 1 <= *m <= 12
496 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000497 * The input values must be such that the internals don't overflow.
498 * The way this routine is used, we don't get close.
499 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000500static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000501normalize_y_m_d(int *y, int *m, int *d)
502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000504
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000505 /* In actual use, m is always the month component extracted from a
506 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 /* Now only day can be out of bounds (year may also be out of bounds
512 * for a datetime object, but we don't care about that here).
513 * If day is out of bounds, what to do is arguable, but at least the
514 * method here is principled and explainable.
515 */
516 dim = days_in_month(*y, *m);
517 if (*d < 1 || *d > dim) {
518 /* Move day-1 days from the first of the month. First try to
519 * get off cheap if we're only one day out of range
520 * (adjustments for timezone alone can't be worse than that).
521 */
522 if (*d == 0) {
523 --*m;
524 if (*m > 0)
525 *d = days_in_month(*y, *m);
526 else {
527 --*y;
528 *m = 12;
529 *d = 31;
530 }
531 }
532 else if (*d == dim + 1) {
533 /* move forward a day */
534 ++*m;
535 *d = 1;
536 if (*m > 12) {
537 *m = 1;
538 ++*y;
539 }
540 }
541 else {
542 int ordinal = ymd_to_ord(*y, *m, 1) +
543 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000544 if (ordinal < 1 || ordinal > MAXORDINAL) {
545 goto error;
546 } else {
547 ord_to_ymd(ordinal, y, m, d);
548 return 0;
549 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 }
551 }
552 assert(*m > 0);
553 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000554 if (MINYEAR <= *y && *y <= MAXYEAR)
555 return 0;
556 error:
557 PyErr_SetString(PyExc_OverflowError,
558 "date value out of range");
559 return -1;
560
Tim Peters2a799bf2002-12-16 20:18:38 +0000561}
562
563/* Fiddle out-of-bounds months and days so that the result makes some kind
564 * of sense. The parameters are both inputs and outputs. Returns < 0 on
565 * failure, where failure means the adjusted year is out of bounds.
566 */
567static int
568normalize_date(int *year, int *month, int *day)
569{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000570 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000571}
572
573/* Force all the datetime fields into range. The parameters are both
574 * inputs and outputs. Returns < 0 on error.
575 */
576static int
577normalize_datetime(int *year, int *month, int *day,
578 int *hour, int *minute, int *second,
579 int *microsecond)
580{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 normalize_pair(second, microsecond, 1000000);
582 normalize_pair(minute, second, 60);
583 normalize_pair(hour, minute, 60);
584 normalize_pair(day, hour, 24);
585 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000586}
587
588/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000589 * Basic object allocation: tp_alloc implementations. These allocate
590 * Python objects of the right size and type, and do the Python object-
591 * initialization bit. If there's not enough memory, they return NULL after
592 * setting MemoryError. All data members remain uninitialized trash.
593 *
594 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000595 * member is needed. This is ugly, imprecise, and possibly insecure.
596 * tp_basicsize for the time and datetime types is set to the size of the
597 * struct that has room for the tzinfo member, so subclasses in Python will
598 * allocate enough space for a tzinfo member whether or not one is actually
599 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
600 * part is that PyType_GenericAlloc() (which subclasses in Python end up
601 * using) just happens today to effectively ignore the nitems argument
602 * when tp_itemsize is 0, which it is for these type objects. If that
603 * changes, perhaps the callers of tp_alloc slots in this file should
604 * be changed to force a 0 nitems argument unless the type being allocated
605 * is a base type implemented in this file (so that tp_alloc is time_alloc
606 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000607 */
608
609static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000610time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 self = (PyObject *)
615 PyObject_MALLOC(aware ?
616 sizeof(PyDateTime_Time) :
617 sizeof(_PyDateTime_BaseTime));
618 if (self == NULL)
619 return (PyObject *)PyErr_NoMemory();
620 PyObject_INIT(self, type);
621 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000622}
623
624static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000625datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 self = (PyObject *)
630 PyObject_MALLOC(aware ?
631 sizeof(PyDateTime_DateTime) :
632 sizeof(_PyDateTime_BaseDateTime));
633 if (self == NULL)
634 return (PyObject *)PyErr_NoMemory();
635 PyObject_INIT(self, type);
636 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000637}
638
639/* ---------------------------------------------------------------------------
640 * Helpers for setting object fields. These work on pointers to the
641 * appropriate base class.
642 */
643
644/* For date and datetime. */
645static void
646set_date_fields(PyDateTime_Date *self, int y, int m, int d)
647{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 self->hashcode = -1;
649 SET_YEAR(self, y);
650 SET_MONTH(self, m);
651 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000652}
653
654/* ---------------------------------------------------------------------------
655 * Create various objects, mostly without range checking.
656 */
657
658/* Create a date instance with no range checking. */
659static PyObject *
660new_date_ex(int year, int month, int day, PyTypeObject *type)
661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
665 if (self != NULL)
666 set_date_fields(self, year, month, day);
667 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000668}
669
670#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000672
673/* Create a datetime instance with no range checking. */
674static PyObject *
675new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 PyDateTime_DateTime *self;
679 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
682 if (self != NULL) {
683 self->hastzinfo = aware;
684 set_date_fields((PyDateTime_Date *)self, year, month, day);
685 DATE_SET_HOUR(self, hour);
686 DATE_SET_MINUTE(self, minute);
687 DATE_SET_SECOND(self, second);
688 DATE_SET_MICROSECOND(self, usecond);
689 if (aware) {
690 Py_INCREF(tzinfo);
691 self->tzinfo = tzinfo;
692 }
693 }
694 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000695}
696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
698 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
699 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000700
701/* Create a time instance with no range checking. */
702static PyObject *
703new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000705{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 PyDateTime_Time *self;
707 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
710 if (self != NULL) {
711 self->hastzinfo = aware;
712 self->hashcode = -1;
713 TIME_SET_HOUR(self, hour);
714 TIME_SET_MINUTE(self, minute);
715 TIME_SET_SECOND(self, second);
716 TIME_SET_MICROSECOND(self, usecond);
717 if (aware) {
718 Py_INCREF(tzinfo);
719 self->tzinfo = tzinfo;
720 }
721 }
722 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000723}
724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725#define new_time(hh, mm, ss, us, tzinfo) \
726 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000727
728/* Create a timedelta instance. Normalize the members iff normalize is
729 * true. Passing false is a speed optimization, if you know for sure
730 * that seconds and microseconds are already in their proper ranges. In any
731 * case, raises OverflowError and returns NULL if the normalized days is out
732 * of range).
733 */
734static PyObject *
735new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 if (normalize)
741 normalize_d_s_us(&days, &seconds, &microseconds);
742 assert(0 <= seconds && seconds < 24*3600);
743 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 if (check_delta_day_range(days) < 0)
746 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
749 if (self != NULL) {
750 self->hashcode = -1;
751 SET_TD_DAYS(self, days);
752 SET_TD_SECONDS(self, seconds);
753 SET_TD_MICROSECONDS(self, microseconds);
754 }
755 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000756}
757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758#define new_delta(d, s, us, normalize) \
759 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000760
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000761
762typedef struct
763{
764 PyObject_HEAD
765 PyObject *offset;
766 PyObject *name;
767} PyDateTime_TimeZone;
768
Victor Stinner6ced7c42011-03-21 18:15:42 +0100769/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000770static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000771
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000772/* Create new timezone instance checking offset range. This
773 function does not check the name argument. Caller must assure
774 that offset is a timedelta instance and name is either NULL
775 or a unicode object. */
776static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000777create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000778{
779 PyDateTime_TimeZone *self;
780 PyTypeObject *type = &PyDateTime_TimeZoneType;
781
782 assert(offset != NULL);
783 assert(PyDelta_Check(offset));
784 assert(name == NULL || PyUnicode_Check(name));
785
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000786 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
787 if (self == NULL) {
788 return NULL;
789 }
790 Py_INCREF(offset);
791 self->offset = offset;
792 Py_XINCREF(name);
793 self->name = name;
794 return (PyObject *)self;
795}
796
797static int delta_bool(PyDateTime_Delta *self);
798
799static PyObject *
800new_timezone(PyObject *offset, PyObject *name)
801{
802 assert(offset != NULL);
803 assert(PyDelta_Check(offset));
804 assert(name == NULL || PyUnicode_Check(name));
805
806 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
807 Py_INCREF(PyDateTime_TimeZone_UTC);
808 return PyDateTime_TimeZone_UTC;
809 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000810 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
811 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
812 " representing a whole number of minutes");
813 return NULL;
814 }
815 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
816 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
817 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
818 " strictly between -timedelta(hours=24) and"
819 " timedelta(hours=24).");
820 return NULL;
821 }
822
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000823 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000824}
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 ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200988 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
989 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 Py_DECREF(repr);
991 if (temp == NULL)
992 return NULL;
993 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
994 Py_DECREF(temp);
995 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +0000996}
997
998/* ---------------------------------------------------------------------------
999 * String format helpers.
1000 */
1001
1002static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001003format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 static const char *DayNames[] = {
1006 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1007 };
1008 static const char *MonthNames[] = {
1009 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1010 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1011 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1016 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1017 GET_DAY(date), hours, minutes, seconds,
1018 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001019}
1020
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001021static PyObject *delta_negative(PyDateTime_Delta *self);
1022
Tim Peters2a799bf2002-12-16 20:18:38 +00001023/* Add an hours & minutes UTC offset string to buf. buf has no more than
1024 * buflen bytes remaining. The UTC offset is gotten by calling
1025 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1026 * *buf, and that's all. Else the returned value is checked for sanity (an
1027 * integer in range), and if that's OK it's converted to an hours & minutes
1028 * string of the form
1029 * sign HH sep MM
1030 * Returns 0 if everything is OK. If the return value from utcoffset() is
1031 * bogus, an appropriate exception is set and -1 is returned.
1032 */
1033static int
Tim Peters328fff72002-12-20 01:31:27 +00001034format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001036{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001037 PyObject *offset;
1038 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001042
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001043 offset = call_utcoffset(tzinfo, tzinfoarg);
1044 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001046 if (offset == Py_None) {
1047 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 *buf = '\0';
1049 return 0;
1050 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001051 /* Offset is normalized, so it is negative if days < 0 */
1052 if (GET_TD_DAYS(offset) < 0) {
1053 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001055 offset = delta_negative((PyDateTime_Delta *)offset);
1056 Py_DECREF(temp);
1057 if (offset == NULL)
1058 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001060 else {
1061 sign = '+';
1062 }
1063 /* Offset is not negative here. */
1064 seconds = GET_TD_SECONDS(offset);
1065 Py_DECREF(offset);
1066 minutes = divmod(seconds, 60, &seconds);
1067 hours = divmod(minutes, 60, &minutes);
1068 assert(seconds == 0);
1069 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001073}
1074
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001075static PyObject *
1076make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 PyObject *temp;
1079 PyObject *tzinfo = get_tzinfo_member(object);
1080 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1081 if (Zreplacement == NULL)
1082 return NULL;
1083 if (tzinfo == Py_None || tzinfo == NULL)
1084 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 assert(tzinfoarg != NULL);
1087 temp = call_tzname(tzinfo, tzinfoarg);
1088 if (temp == NULL)
1089 goto Error;
1090 if (temp == Py_None) {
1091 Py_DECREF(temp);
1092 return Zreplacement;
1093 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 assert(PyUnicode_Check(temp));
1096 /* Since the tzname is getting stuffed into the
1097 * format, we have to double any % signs so that
1098 * strftime doesn't treat them as format codes.
1099 */
1100 Py_DECREF(Zreplacement);
1101 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1102 Py_DECREF(temp);
1103 if (Zreplacement == NULL)
1104 return NULL;
1105 if (!PyUnicode_Check(Zreplacement)) {
1106 PyErr_SetString(PyExc_TypeError,
1107 "tzname.replace() did not return a string");
1108 goto Error;
1109 }
1110 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001111
1112 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 Py_DECREF(Zreplacement);
1114 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001115}
1116
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001117static PyObject *
1118make_freplacement(PyObject *object)
1119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 char freplacement[64];
1121 if (PyTime_Check(object))
1122 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1123 else if (PyDateTime_Check(object))
1124 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1125 else
1126 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001129}
1130
Tim Peters2a799bf2002-12-16 20:18:38 +00001131/* I sure don't want to reproduce the strftime code from the time module,
1132 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001133 * giving special meanings to the %z, %Z and %f format codes via a
1134 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001135 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1136 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001137 */
1138static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001139wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1145 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1146 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 const char *pin; /* pointer to next char in input format */
1149 Py_ssize_t flen; /* length of input format */
1150 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 PyObject *newfmt = NULL; /* py string, the output format */
1153 char *pnew; /* pointer to available byte in output format */
1154 size_t totalnew; /* number bytes total in output format buffer,
1155 exclusive of trailing \0 */
1156 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 const char *ptoappend; /* ptr to string to append to output buffer */
1159 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 assert(object && format && timetuple);
1162 assert(PyUnicode_Check(format));
1163 /* Convert the input format to a C string and size */
1164 pin = _PyUnicode_AsStringAndSize(format, &flen);
1165 if (!pin)
1166 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 /* Scan the input format, looking for %z/%Z/%f escapes, building
1169 * a new format. Since computing the replacements for those codes
1170 * is expensive, don't unless they're actually used.
1171 */
1172 if (flen > INT_MAX - 1) {
1173 PyErr_NoMemory();
1174 goto Done;
1175 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 totalnew = flen + 1; /* realistic if no %z/%Z */
1178 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1179 if (newfmt == NULL) goto Done;
1180 pnew = PyBytes_AsString(newfmt);
1181 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 while ((ch = *pin++) != '\0') {
1184 if (ch != '%') {
1185 ptoappend = pin - 1;
1186 ntoappend = 1;
1187 }
1188 else if ((ch = *pin++) == '\0') {
1189 /* There's a lone trailing %; doesn't make sense. */
1190 PyErr_SetString(PyExc_ValueError, "strftime format "
1191 "ends with raw %");
1192 goto Done;
1193 }
1194 /* A % has been seen and ch is the character after it. */
1195 else if (ch == 'z') {
1196 if (zreplacement == NULL) {
1197 /* format utcoffset */
1198 char buf[100];
1199 PyObject *tzinfo = get_tzinfo_member(object);
1200 zreplacement = PyBytes_FromStringAndSize("", 0);
1201 if (zreplacement == NULL) goto Done;
1202 if (tzinfo != Py_None && tzinfo != NULL) {
1203 assert(tzinfoarg != NULL);
1204 if (format_utcoffset(buf,
1205 sizeof(buf),
1206 "",
1207 tzinfo,
1208 tzinfoarg) < 0)
1209 goto Done;
1210 Py_DECREF(zreplacement);
1211 zreplacement =
1212 PyBytes_FromStringAndSize(buf,
1213 strlen(buf));
1214 if (zreplacement == NULL)
1215 goto Done;
1216 }
1217 }
1218 assert(zreplacement != NULL);
1219 ptoappend = PyBytes_AS_STRING(zreplacement);
1220 ntoappend = PyBytes_GET_SIZE(zreplacement);
1221 }
1222 else if (ch == 'Z') {
1223 /* format tzname */
1224 if (Zreplacement == NULL) {
1225 Zreplacement = make_Zreplacement(object,
1226 tzinfoarg);
1227 if (Zreplacement == NULL)
1228 goto Done;
1229 }
1230 assert(Zreplacement != NULL);
1231 assert(PyUnicode_Check(Zreplacement));
1232 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1233 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001234 if (ptoappend == NULL)
1235 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 }
1237 else if (ch == 'f') {
1238 /* format microseconds */
1239 if (freplacement == NULL) {
1240 freplacement = make_freplacement(object);
1241 if (freplacement == NULL)
1242 goto Done;
1243 }
1244 assert(freplacement != NULL);
1245 assert(PyBytes_Check(freplacement));
1246 ptoappend = PyBytes_AS_STRING(freplacement);
1247 ntoappend = PyBytes_GET_SIZE(freplacement);
1248 }
1249 else {
1250 /* percent followed by neither z nor Z */
1251 ptoappend = pin - 2;
1252 ntoappend = 2;
1253 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 /* Append the ntoappend chars starting at ptoappend to
1256 * the new format.
1257 */
1258 if (ntoappend == 0)
1259 continue;
1260 assert(ptoappend != NULL);
1261 assert(ntoappend > 0);
1262 while (usednew + ntoappend > totalnew) {
1263 size_t bigger = totalnew << 1;
1264 if ((bigger >> 1) != totalnew) { /* overflow */
1265 PyErr_NoMemory();
1266 goto Done;
1267 }
1268 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1269 goto Done;
1270 totalnew = bigger;
1271 pnew = PyBytes_AsString(newfmt) + usednew;
1272 }
1273 memcpy(pnew, ptoappend, ntoappend);
1274 pnew += ntoappend;
1275 usednew += ntoappend;
1276 assert(usednew <= totalnew);
1277 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1280 goto Done;
1281 {
1282 PyObject *format;
1283 PyObject *time = PyImport_ImportModuleNoBlock("time");
1284 if (time == NULL)
1285 goto Done;
1286 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1287 if (format != NULL) {
1288 result = PyObject_CallMethod(time, "strftime", "OO",
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001289 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 Py_DECREF(format);
1291 }
1292 Py_DECREF(time);
1293 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001294 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 Py_XDECREF(freplacement);
1296 Py_XDECREF(zreplacement);
1297 Py_XDECREF(Zreplacement);
1298 Py_XDECREF(newfmt);
1299 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001300}
1301
Tim Peters2a799bf2002-12-16 20:18:38 +00001302/* ---------------------------------------------------------------------------
1303 * Wrap functions from the time module. These aren't directly available
1304 * from C. Perhaps they should be.
1305 */
1306
1307/* Call time.time() and return its result (a Python float). */
1308static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001309time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001310{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 PyObject *result = NULL;
1312 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 if (time != NULL) {
1315 result = PyObject_CallMethod(time, "time", "()");
1316 Py_DECREF(time);
1317 }
1318 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001319}
1320
1321/* Build a time.struct_time. The weekday and day number are automatically
1322 * computed from the y,m,d args.
1323 */
1324static PyObject *
1325build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 PyObject *time;
1328 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 time = PyImport_ImportModuleNoBlock("time");
1331 if (time != NULL) {
1332 result = PyObject_CallMethod(time, "struct_time",
1333 "((iiiiiiiii))",
1334 y, m, d,
1335 hh, mm, ss,
1336 weekday(y, m, d),
1337 days_before_month(y, m) + d,
1338 dstflag);
1339 Py_DECREF(time);
1340 }
1341 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001342}
1343
1344/* ---------------------------------------------------------------------------
1345 * Miscellaneous helpers.
1346 */
1347
Mark Dickinsone94c6792009-02-02 20:36:42 +00001348/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001349 * The comparisons here all most naturally compute a cmp()-like result.
1350 * This little helper turns that into a bool result for rich comparisons.
1351 */
1352static PyObject *
1353diff_to_bool(int diff, int op)
1354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 PyObject *result;
1356 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 switch (op) {
1359 case Py_EQ: istrue = diff == 0; break;
1360 case Py_NE: istrue = diff != 0; break;
1361 case Py_LE: istrue = diff <= 0; break;
1362 case Py_GE: istrue = diff >= 0; break;
1363 case Py_LT: istrue = diff < 0; break;
1364 case Py_GT: istrue = diff > 0; break;
1365 default:
1366 assert(! "op unknown");
1367 istrue = 0; /* To shut up compiler */
1368 }
1369 result = istrue ? Py_True : Py_False;
1370 Py_INCREF(result);
1371 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001372}
1373
Tim Peters07534a62003-02-07 22:50:28 +00001374/* Raises a "can't compare" TypeError and returns NULL. */
1375static PyObject *
1376cmperror(PyObject *a, PyObject *b)
1377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 PyErr_Format(PyExc_TypeError,
1379 "can't compare %s to %s",
1380 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1381 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001382}
1383
Tim Peters2a799bf2002-12-16 20:18:38 +00001384/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001385 * Cached Python objects; these are set by the module init function.
1386 */
1387
1388/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389static PyObject *us_per_us = NULL; /* 1 */
1390static PyObject *us_per_ms = NULL; /* 1000 */
1391static PyObject *us_per_second = NULL; /* 1000000 */
1392static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1393static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1394static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1395static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001396static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1397
Tim Peters2a799bf2002-12-16 20:18:38 +00001398/* ---------------------------------------------------------------------------
1399 * Class implementations.
1400 */
1401
1402/*
1403 * PyDateTime_Delta implementation.
1404 */
1405
1406/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001408 * as a Python int or long.
1409 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1410 * due to ubiquitous overflow possibilities.
1411 */
1412static PyObject *
1413delta_to_microseconds(PyDateTime_Delta *self)
1414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 PyObject *x1 = NULL;
1416 PyObject *x2 = NULL;
1417 PyObject *x3 = NULL;
1418 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1421 if (x1 == NULL)
1422 goto Done;
1423 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1424 if (x2 == NULL)
1425 goto Done;
1426 Py_DECREF(x1);
1427 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 /* x2 has days in seconds */
1430 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1431 if (x1 == NULL)
1432 goto Done;
1433 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1434 if (x3 == NULL)
1435 goto Done;
1436 Py_DECREF(x1);
1437 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001438 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 /* x3 has days+seconds in seconds */
1441 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1442 if (x1 == NULL)
1443 goto Done;
1444 Py_DECREF(x3);
1445 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 /* x1 has days+seconds in us */
1448 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1449 if (x2 == NULL)
1450 goto Done;
1451 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001452
1453Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 Py_XDECREF(x1);
1455 Py_XDECREF(x2);
1456 Py_XDECREF(x3);
1457 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001458}
1459
1460/* Convert a number of us (as a Python int or long) to a timedelta.
1461 */
1462static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001463microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 int us;
1466 int s;
1467 int d;
1468 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 PyObject *tuple = NULL;
1471 PyObject *num = NULL;
1472 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 tuple = PyNumber_Divmod(pyus, us_per_second);
1475 if (tuple == NULL)
1476 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 num = PyTuple_GetItem(tuple, 1); /* us */
1479 if (num == NULL)
1480 goto Done;
1481 temp = PyLong_AsLong(num);
1482 num = NULL;
1483 if (temp == -1 && PyErr_Occurred())
1484 goto Done;
1485 assert(0 <= temp && temp < 1000000);
1486 us = (int)temp;
1487 if (us < 0) {
1488 /* The divisor was positive, so this must be an error. */
1489 assert(PyErr_Occurred());
1490 goto Done;
1491 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1494 if (num == NULL)
1495 goto Done;
1496 Py_INCREF(num);
1497 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 tuple = PyNumber_Divmod(num, seconds_per_day);
1500 if (tuple == NULL)
1501 goto Done;
1502 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 num = PyTuple_GetItem(tuple, 1); /* seconds */
1505 if (num == NULL)
1506 goto Done;
1507 temp = PyLong_AsLong(num);
1508 num = NULL;
1509 if (temp == -1 && PyErr_Occurred())
1510 goto Done;
1511 assert(0 <= temp && temp < 24*3600);
1512 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 if (s < 0) {
1515 /* The divisor was positive, so this must be an error. */
1516 assert(PyErr_Occurred());
1517 goto Done;
1518 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1521 if (num == NULL)
1522 goto Done;
1523 Py_INCREF(num);
1524 temp = PyLong_AsLong(num);
1525 if (temp == -1 && PyErr_Occurred())
1526 goto Done;
1527 d = (int)temp;
1528 if ((long)d != temp) {
1529 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1530 "large to fit in a C int");
1531 goto Done;
1532 }
1533 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001534
1535Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 Py_XDECREF(tuple);
1537 Py_XDECREF(num);
1538 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001539}
1540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541#define microseconds_to_delta(pymicros) \
1542 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001543
Tim Peters2a799bf2002-12-16 20:18:38 +00001544static PyObject *
1545multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 PyObject *pyus_in;
1548 PyObject *pyus_out;
1549 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 pyus_in = delta_to_microseconds(delta);
1552 if (pyus_in == NULL)
1553 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1556 Py_DECREF(pyus_in);
1557 if (pyus_out == NULL)
1558 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 result = microseconds_to_delta(pyus_out);
1561 Py_DECREF(pyus_out);
1562 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001563}
1564
1565static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001566multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1567{
1568 PyObject *result = NULL;
1569 PyObject *pyus_in = NULL, *temp, *pyus_out;
1570 PyObject *ratio = NULL;
1571
1572 pyus_in = delta_to_microseconds(delta);
1573 if (pyus_in == NULL)
1574 return NULL;
1575 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1576 if (ratio == NULL)
1577 goto error;
1578 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1579 Py_DECREF(pyus_in);
1580 pyus_in = NULL;
1581 if (temp == NULL)
1582 goto error;
1583 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1584 Py_DECREF(temp);
1585 if (pyus_out == NULL)
1586 goto error;
1587 result = microseconds_to_delta(pyus_out);
1588 Py_DECREF(pyus_out);
1589 error:
1590 Py_XDECREF(pyus_in);
1591 Py_XDECREF(ratio);
1592
1593 return result;
1594}
1595
1596static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001597divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1598{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 PyObject *pyus_in;
1600 PyObject *pyus_out;
1601 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 pyus_in = delta_to_microseconds(delta);
1604 if (pyus_in == NULL)
1605 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1608 Py_DECREF(pyus_in);
1609 if (pyus_out == NULL)
1610 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 result = microseconds_to_delta(pyus_out);
1613 Py_DECREF(pyus_out);
1614 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001615}
1616
1617static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001618divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 PyObject *pyus_left;
1621 PyObject *pyus_right;
1622 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 pyus_left = delta_to_microseconds(left);
1625 if (pyus_left == NULL)
1626 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 pyus_right = delta_to_microseconds(right);
1629 if (pyus_right == NULL) {
1630 Py_DECREF(pyus_left);
1631 return NULL;
1632 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1635 Py_DECREF(pyus_left);
1636 Py_DECREF(pyus_right);
1637 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001638}
1639
1640static PyObject *
1641truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1642{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 PyObject *pyus_left;
1644 PyObject *pyus_right;
1645 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 pyus_left = delta_to_microseconds(left);
1648 if (pyus_left == NULL)
1649 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 pyus_right = delta_to_microseconds(right);
1652 if (pyus_right == NULL) {
1653 Py_DECREF(pyus_left);
1654 return NULL;
1655 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1658 Py_DECREF(pyus_left);
1659 Py_DECREF(pyus_right);
1660 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001661}
1662
1663static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001664truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1665{
1666 PyObject *result = NULL;
1667 PyObject *pyus_in = NULL, *temp, *pyus_out;
1668 PyObject *ratio = NULL;
1669
1670 pyus_in = delta_to_microseconds(delta);
1671 if (pyus_in == NULL)
1672 return NULL;
1673 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1674 if (ratio == NULL)
1675 goto error;
1676 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1677 Py_DECREF(pyus_in);
1678 pyus_in = NULL;
1679 if (temp == NULL)
1680 goto error;
1681 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1682 Py_DECREF(temp);
1683 if (pyus_out == NULL)
1684 goto error;
1685 result = microseconds_to_delta(pyus_out);
1686 Py_DECREF(pyus_out);
1687 error:
1688 Py_XDECREF(pyus_in);
1689 Py_XDECREF(ratio);
1690
1691 return result;
1692}
1693
1694static PyObject *
1695truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1696{
1697 PyObject *result;
1698 PyObject *pyus_in, *pyus_out;
1699 pyus_in = delta_to_microseconds(delta);
1700 if (pyus_in == NULL)
1701 return NULL;
1702 pyus_out = divide_nearest(pyus_in, i);
1703 Py_DECREF(pyus_in);
1704 if (pyus_out == NULL)
1705 return NULL;
1706 result = microseconds_to_delta(pyus_out);
1707 Py_DECREF(pyus_out);
1708
1709 return result;
1710}
1711
1712static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001713delta_add(PyObject *left, PyObject *right)
1714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1718 /* delta + delta */
1719 /* The C-level additions can't overflow because of the
1720 * invariant bounds.
1721 */
1722 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1723 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1724 int microseconds = GET_TD_MICROSECONDS(left) +
1725 GET_TD_MICROSECONDS(right);
1726 result = new_delta(days, seconds, microseconds, 1);
1727 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 if (result == Py_NotImplemented)
1730 Py_INCREF(result);
1731 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001732}
1733
1734static PyObject *
1735delta_negative(PyDateTime_Delta *self)
1736{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 return new_delta(-GET_TD_DAYS(self),
1738 -GET_TD_SECONDS(self),
1739 -GET_TD_MICROSECONDS(self),
1740 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001741}
1742
1743static PyObject *
1744delta_positive(PyDateTime_Delta *self)
1745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 /* Could optimize this (by returning self) if this isn't a
1747 * subclass -- but who uses unary + ? Approximately nobody.
1748 */
1749 return new_delta(GET_TD_DAYS(self),
1750 GET_TD_SECONDS(self),
1751 GET_TD_MICROSECONDS(self),
1752 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001753}
1754
1755static PyObject *
1756delta_abs(PyDateTime_Delta *self)
1757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 assert(GET_TD_MICROSECONDS(self) >= 0);
1761 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 if (GET_TD_DAYS(self) < 0)
1764 result = delta_negative(self);
1765 else
1766 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001769}
1770
1771static PyObject *
1772delta_subtract(PyObject *left, PyObject *right)
1773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1777 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001778 /* The C-level additions can't overflow because of the
1779 * invariant bounds.
1780 */
1781 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1782 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1783 int microseconds = GET_TD_MICROSECONDS(left) -
1784 GET_TD_MICROSECONDS(right);
1785 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 if (result == Py_NotImplemented)
1789 Py_INCREF(result);
1790 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001791}
1792
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001793static int
1794delta_cmp(PyObject *self, PyObject *other)
1795{
1796 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1797 if (diff == 0) {
1798 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1799 if (diff == 0)
1800 diff = GET_TD_MICROSECONDS(self) -
1801 GET_TD_MICROSECONDS(other);
1802 }
1803 return diff;
1804}
1805
Tim Peters2a799bf2002-12-16 20:18:38 +00001806static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001807delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001810 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001811 return diff_to_bool(diff, op);
1812 }
1813 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001814 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001815 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001816}
1817
1818static PyObject *delta_getstate(PyDateTime_Delta *self);
1819
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001820static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001821delta_hash(PyDateTime_Delta *self)
1822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 if (self->hashcode == -1) {
1824 PyObject *temp = delta_getstate(self);
1825 if (temp != NULL) {
1826 self->hashcode = PyObject_Hash(temp);
1827 Py_DECREF(temp);
1828 }
1829 }
1830 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001831}
1832
1833static PyObject *
1834delta_multiply(PyObject *left, PyObject *right)
1835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 if (PyDelta_Check(left)) {
1839 /* delta * ??? */
1840 if (PyLong_Check(right))
1841 result = multiply_int_timedelta(right,
1842 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001843 else if (PyFloat_Check(right))
1844 result = multiply_float_timedelta(right,
1845 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 }
1847 else if (PyLong_Check(left))
1848 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001849 (PyDateTime_Delta *) right);
1850 else if (PyFloat_Check(left))
1851 result = multiply_float_timedelta(left,
1852 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 if (result == Py_NotImplemented)
1855 Py_INCREF(result);
1856 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001857}
1858
1859static PyObject *
1860delta_divide(PyObject *left, PyObject *right)
1861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 if (PyDelta_Check(left)) {
1865 /* delta * ??? */
1866 if (PyLong_Check(right))
1867 result = divide_timedelta_int(
1868 (PyDateTime_Delta *)left,
1869 right);
1870 else if (PyDelta_Check(right))
1871 result = divide_timedelta_timedelta(
1872 (PyDateTime_Delta *)left,
1873 (PyDateTime_Delta *)right);
1874 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 if (result == Py_NotImplemented)
1877 Py_INCREF(result);
1878 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001879}
1880
Mark Dickinson7c186e22010-04-20 22:32:49 +00001881static PyObject *
1882delta_truedivide(PyObject *left, PyObject *right)
1883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (PyDelta_Check(left)) {
1887 if (PyDelta_Check(right))
1888 result = truedivide_timedelta_timedelta(
1889 (PyDateTime_Delta *)left,
1890 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001891 else if (PyFloat_Check(right))
1892 result = truedivide_timedelta_float(
1893 (PyDateTime_Delta *)left, right);
1894 else if (PyLong_Check(right))
1895 result = truedivide_timedelta_int(
1896 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 if (result == Py_NotImplemented)
1900 Py_INCREF(result);
1901 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001902}
1903
1904static PyObject *
1905delta_remainder(PyObject *left, PyObject *right)
1906{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 PyObject *pyus_left;
1908 PyObject *pyus_right;
1909 PyObject *pyus_remainder;
1910 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001911
Brian Curtindfc80e32011-08-10 20:28:54 -05001912 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1913 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1916 if (pyus_left == NULL)
1917 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1920 if (pyus_right == NULL) {
1921 Py_DECREF(pyus_left);
1922 return NULL;
1923 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1926 Py_DECREF(pyus_left);
1927 Py_DECREF(pyus_right);
1928 if (pyus_remainder == NULL)
1929 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 remainder = microseconds_to_delta(pyus_remainder);
1932 Py_DECREF(pyus_remainder);
1933 if (remainder == NULL)
1934 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001937}
1938
1939static PyObject *
1940delta_divmod(PyObject *left, PyObject *right)
1941{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 PyObject *pyus_left;
1943 PyObject *pyus_right;
1944 PyObject *divmod;
1945 PyObject *delta;
1946 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001947
Brian Curtindfc80e32011-08-10 20:28:54 -05001948 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1949 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1952 if (pyus_left == NULL)
1953 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1956 if (pyus_right == NULL) {
1957 Py_DECREF(pyus_left);
1958 return NULL;
1959 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1962 Py_DECREF(pyus_left);
1963 Py_DECREF(pyus_right);
1964 if (divmod == NULL)
1965 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 assert(PyTuple_Size(divmod) == 2);
1968 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1969 if (delta == NULL) {
1970 Py_DECREF(divmod);
1971 return NULL;
1972 }
1973 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1974 Py_DECREF(delta);
1975 Py_DECREF(divmod);
1976 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001977}
1978
Tim Peters2a799bf2002-12-16 20:18:38 +00001979/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1980 * timedelta constructor. sofar is the # of microseconds accounted for
1981 * so far, and there are factor microseconds per current unit, the number
1982 * of which is given by num. num * factor is added to sofar in a
1983 * numerically careful way, and that's the result. Any fractional
1984 * microseconds left over (this can happen if num is a float type) are
1985 * added into *leftover.
1986 * Note that there are many ways this can give an error (NULL) return.
1987 */
1988static PyObject *
1989accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1990 double *leftover)
1991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 PyObject *prod;
1993 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00001994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 if (PyLong_Check(num)) {
1998 prod = PyNumber_Multiply(num, factor);
1999 if (prod == NULL)
2000 return NULL;
2001 sum = PyNumber_Add(sofar, prod);
2002 Py_DECREF(prod);
2003 return sum;
2004 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 if (PyFloat_Check(num)) {
2007 double dnum;
2008 double fracpart;
2009 double intpart;
2010 PyObject *x;
2011 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 /* The Plan: decompose num into an integer part and a
2014 * fractional part, num = intpart + fracpart.
2015 * Then num * factor ==
2016 * intpart * factor + fracpart * factor
2017 * and the LHS can be computed exactly in long arithmetic.
2018 * The RHS is again broken into an int part and frac part.
2019 * and the frac part is added into *leftover.
2020 */
2021 dnum = PyFloat_AsDouble(num);
2022 if (dnum == -1.0 && PyErr_Occurred())
2023 return NULL;
2024 fracpart = modf(dnum, &intpart);
2025 x = PyLong_FromDouble(intpart);
2026 if (x == NULL)
2027 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 prod = PyNumber_Multiply(x, factor);
2030 Py_DECREF(x);
2031 if (prod == NULL)
2032 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 sum = PyNumber_Add(sofar, prod);
2035 Py_DECREF(prod);
2036 if (sum == NULL)
2037 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 if (fracpart == 0.0)
2040 return sum;
2041 /* So far we've lost no information. Dealing with the
2042 * fractional part requires float arithmetic, and may
2043 * lose a little info.
2044 */
2045 assert(PyLong_Check(factor));
2046 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 dnum *= fracpart;
2049 fracpart = modf(dnum, &intpart);
2050 x = PyLong_FromDouble(intpart);
2051 if (x == NULL) {
2052 Py_DECREF(sum);
2053 return NULL;
2054 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 y = PyNumber_Add(sum, x);
2057 Py_DECREF(sum);
2058 Py_DECREF(x);
2059 *leftover += fracpart;
2060 return y;
2061 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 PyErr_Format(PyExc_TypeError,
2064 "unsupported type for timedelta %s component: %s",
2065 tag, Py_TYPE(num)->tp_name);
2066 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002067}
2068
2069static PyObject *
2070delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002072 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 /* Argument objects. */
2075 PyObject *day = NULL;
2076 PyObject *second = NULL;
2077 PyObject *us = NULL;
2078 PyObject *ms = NULL;
2079 PyObject *minute = NULL;
2080 PyObject *hour = NULL;
2081 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 PyObject *x = NULL; /* running sum of microseconds */
2084 PyObject *y = NULL; /* temp sum of microseconds */
2085 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 static char *keywords[] = {
2088 "days", "seconds", "microseconds", "milliseconds",
2089 "minutes", "hours", "weeks", NULL
2090 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002092 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2093 keywords,
2094 &day, &second, &us,
2095 &ms, &minute, &hour, &week) == 0)
2096 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 x = PyLong_FromLong(0);
2099 if (x == NULL)
2100 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102#define CLEANUP \
2103 Py_DECREF(x); \
2104 x = y; \
2105 if (x == NULL) \
2106 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 if (us) {
2109 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2110 CLEANUP;
2111 }
2112 if (ms) {
2113 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2114 CLEANUP;
2115 }
2116 if (second) {
2117 y = accum("seconds", x, second, us_per_second, &leftover_us);
2118 CLEANUP;
2119 }
2120 if (minute) {
2121 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2122 CLEANUP;
2123 }
2124 if (hour) {
2125 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2126 CLEANUP;
2127 }
2128 if (day) {
2129 y = accum("days", x, day, us_per_day, &leftover_us);
2130 CLEANUP;
2131 }
2132 if (week) {
2133 y = accum("weeks", x, week, us_per_week, &leftover_us);
2134 CLEANUP;
2135 }
2136 if (leftover_us) {
2137 /* Round to nearest whole # of us, and add into x. */
2138 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2139 if (temp == NULL) {
2140 Py_DECREF(x);
2141 goto Done;
2142 }
2143 y = PyNumber_Add(x, temp);
2144 Py_DECREF(temp);
2145 CLEANUP;
2146 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002148 self = microseconds_to_delta_ex(x, type);
2149 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002150Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002152
2153#undef CLEANUP
2154}
2155
2156static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002157delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 return (GET_TD_DAYS(self) != 0
2160 || GET_TD_SECONDS(self) != 0
2161 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002162}
2163
2164static PyObject *
2165delta_repr(PyDateTime_Delta *self)
2166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 if (GET_TD_MICROSECONDS(self) != 0)
2168 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2169 Py_TYPE(self)->tp_name,
2170 GET_TD_DAYS(self),
2171 GET_TD_SECONDS(self),
2172 GET_TD_MICROSECONDS(self));
2173 if (GET_TD_SECONDS(self) != 0)
2174 return PyUnicode_FromFormat("%s(%d, %d)",
2175 Py_TYPE(self)->tp_name,
2176 GET_TD_DAYS(self),
2177 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 return PyUnicode_FromFormat("%s(%d)",
2180 Py_TYPE(self)->tp_name,
2181 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002182}
2183
2184static PyObject *
2185delta_str(PyDateTime_Delta *self)
2186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 int us = GET_TD_MICROSECONDS(self);
2188 int seconds = GET_TD_SECONDS(self);
2189 int minutes = divmod(seconds, 60, &seconds);
2190 int hours = divmod(minutes, 60, &minutes);
2191 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 if (days) {
2194 if (us)
2195 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2196 days, (days == 1 || days == -1) ? "" : "s",
2197 hours, minutes, seconds, us);
2198 else
2199 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2200 days, (days == 1 || days == -1) ? "" : "s",
2201 hours, minutes, seconds);
2202 } else {
2203 if (us)
2204 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2205 hours, minutes, seconds, us);
2206 else
2207 return PyUnicode_FromFormat("%d:%02d:%02d",
2208 hours, minutes, seconds);
2209 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002210
Tim Peters2a799bf2002-12-16 20:18:38 +00002211}
2212
Tim Peters371935f2003-02-01 01:52:50 +00002213/* Pickle support, a simple use of __reduce__. */
2214
Tim Petersb57f8f02003-02-01 02:54:15 +00002215/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002216static PyObject *
2217delta_getstate(PyDateTime_Delta *self)
2218{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219 return Py_BuildValue("iii", GET_TD_DAYS(self),
2220 GET_TD_SECONDS(self),
2221 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002222}
2223
Tim Peters2a799bf2002-12-16 20:18:38 +00002224static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002225delta_total_seconds(PyObject *self)
2226{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 PyObject *total_seconds;
2228 PyObject *total_microseconds;
2229 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2232 if (total_microseconds == NULL)
2233 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 one_million = PyLong_FromLong(1000000L);
2236 if (one_million == NULL) {
2237 Py_DECREF(total_microseconds);
2238 return NULL;
2239 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 Py_DECREF(total_microseconds);
2244 Py_DECREF(one_million);
2245 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002246}
2247
2248static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002249delta_reduce(PyDateTime_Delta* self)
2250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002252}
2253
2254#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2255
2256static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 {"days", T_INT, OFFSET(days), READONLY,
2259 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 {"seconds", T_INT, OFFSET(seconds), READONLY,
2262 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2265 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2266 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002267};
2268
2269static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2271 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2274 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002277};
2278
2279static char delta_doc[] =
2280PyDoc_STR("Difference between two datetime values.");
2281
2282static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 delta_add, /* nb_add */
2284 delta_subtract, /* nb_subtract */
2285 delta_multiply, /* nb_multiply */
2286 delta_remainder, /* nb_remainder */
2287 delta_divmod, /* nb_divmod */
2288 0, /* nb_power */
2289 (unaryfunc)delta_negative, /* nb_negative */
2290 (unaryfunc)delta_positive, /* nb_positive */
2291 (unaryfunc)delta_abs, /* nb_absolute */
2292 (inquiry)delta_bool, /* nb_bool */
2293 0, /*nb_invert*/
2294 0, /*nb_lshift*/
2295 0, /*nb_rshift*/
2296 0, /*nb_and*/
2297 0, /*nb_xor*/
2298 0, /*nb_or*/
2299 0, /*nb_int*/
2300 0, /*nb_reserved*/
2301 0, /*nb_float*/
2302 0, /*nb_inplace_add*/
2303 0, /*nb_inplace_subtract*/
2304 0, /*nb_inplace_multiply*/
2305 0, /*nb_inplace_remainder*/
2306 0, /*nb_inplace_power*/
2307 0, /*nb_inplace_lshift*/
2308 0, /*nb_inplace_rshift*/
2309 0, /*nb_inplace_and*/
2310 0, /*nb_inplace_xor*/
2311 0, /*nb_inplace_or*/
2312 delta_divide, /* nb_floor_divide */
2313 delta_truedivide, /* nb_true_divide */
2314 0, /* nb_inplace_floor_divide */
2315 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002316};
2317
2318static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002319 PyVarObject_HEAD_INIT(NULL, 0)
2320 "datetime.timedelta", /* tp_name */
2321 sizeof(PyDateTime_Delta), /* tp_basicsize */
2322 0, /* tp_itemsize */
2323 0, /* tp_dealloc */
2324 0, /* tp_print */
2325 0, /* tp_getattr */
2326 0, /* tp_setattr */
2327 0, /* tp_reserved */
2328 (reprfunc)delta_repr, /* tp_repr */
2329 &delta_as_number, /* tp_as_number */
2330 0, /* tp_as_sequence */
2331 0, /* tp_as_mapping */
2332 (hashfunc)delta_hash, /* tp_hash */
2333 0, /* tp_call */
2334 (reprfunc)delta_str, /* tp_str */
2335 PyObject_GenericGetAttr, /* tp_getattro */
2336 0, /* tp_setattro */
2337 0, /* tp_as_buffer */
2338 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2339 delta_doc, /* tp_doc */
2340 0, /* tp_traverse */
2341 0, /* tp_clear */
2342 delta_richcompare, /* tp_richcompare */
2343 0, /* tp_weaklistoffset */
2344 0, /* tp_iter */
2345 0, /* tp_iternext */
2346 delta_methods, /* tp_methods */
2347 delta_members, /* tp_members */
2348 0, /* tp_getset */
2349 0, /* tp_base */
2350 0, /* tp_dict */
2351 0, /* tp_descr_get */
2352 0, /* tp_descr_set */
2353 0, /* tp_dictoffset */
2354 0, /* tp_init */
2355 0, /* tp_alloc */
2356 delta_new, /* tp_new */
2357 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002358};
2359
2360/*
2361 * PyDateTime_Date implementation.
2362 */
2363
2364/* Accessor properties. */
2365
2366static PyObject *
2367date_year(PyDateTime_Date *self, void *unused)
2368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002370}
2371
2372static PyObject *
2373date_month(PyDateTime_Date *self, void *unused)
2374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002376}
2377
2378static PyObject *
2379date_day(PyDateTime_Date *self, void *unused)
2380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002382}
2383
2384static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 {"year", (getter)date_year},
2386 {"month", (getter)date_month},
2387 {"day", (getter)date_day},
2388 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002389};
2390
2391/* Constructors. */
2392
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002393static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002394
Tim Peters2a799bf2002-12-16 20:18:38 +00002395static PyObject *
2396date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 PyObject *self = NULL;
2399 PyObject *state;
2400 int year;
2401 int month;
2402 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 /* Check for invocation from pickle with __getstate__ state */
2405 if (PyTuple_GET_SIZE(args) == 1 &&
2406 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2407 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2408 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2409 {
2410 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2413 if (me != NULL) {
2414 char *pdata = PyBytes_AS_STRING(state);
2415 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2416 me->hashcode = -1;
2417 }
2418 return (PyObject *)me;
2419 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2422 &year, &month, &day)) {
2423 if (check_date_args(year, month, day) < 0)
2424 return NULL;
2425 self = new_date_ex(year, month, day, type);
2426 }
2427 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002428}
2429
2430/* Return new date from localtime(t). */
2431static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002432date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002433{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 struct tm *tm;
2435 time_t t;
2436 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002438 t = _PyTime_DoubleToTimet(ts);
2439 if (t == (time_t)-1 && PyErr_Occurred())
2440 return NULL;
2441 tm = localtime(&t);
2442 if (tm)
2443 result = PyObject_CallFunction(cls, "iii",
2444 tm->tm_year + 1900,
2445 tm->tm_mon + 1,
2446 tm->tm_mday);
2447 else
2448 PyErr_SetString(PyExc_ValueError,
2449 "timestamp out of range for "
2450 "platform localtime() function");
2451 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002452}
2453
2454/* Return new date from current time.
2455 * We say this is equivalent to fromtimestamp(time.time()), and the
2456 * only way to be sure of that is to *call* time.time(). That's not
2457 * generally the same as calling C's time.
2458 */
2459static PyObject *
2460date_today(PyObject *cls, PyObject *dummy)
2461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 PyObject *time;
2463 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 time = time_time();
2466 if (time == NULL)
2467 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 /* Note well: today() is a class method, so this may not call
2470 * date.fromtimestamp. For example, it may call
2471 * datetime.fromtimestamp. That's why we need all the accuracy
2472 * time.time() delivers; if someone were gonzo about optimization,
2473 * date.today() could get away with plain C time().
2474 */
2475 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2476 Py_DECREF(time);
2477 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002478}
2479
2480/* Return new date from given timestamp (Python timestamp -- a double). */
2481static PyObject *
2482date_fromtimestamp(PyObject *cls, PyObject *args)
2483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002484 double timestamp;
2485 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2488 result = date_local_from_time_t(cls, timestamp);
2489 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002490}
2491
2492/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2493 * the ordinal is out of range.
2494 */
2495static PyObject *
2496date_fromordinal(PyObject *cls, PyObject *args)
2497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 PyObject *result = NULL;
2499 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002501 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2502 int year;
2503 int month;
2504 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002506 if (ordinal < 1)
2507 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2508 ">= 1");
2509 else {
2510 ord_to_ymd(ordinal, &year, &month, &day);
2511 result = PyObject_CallFunction(cls, "iii",
2512 year, month, day);
2513 }
2514 }
2515 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002516}
2517
2518/*
2519 * Date arithmetic.
2520 */
2521
2522/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2523 * instead.
2524 */
2525static PyObject *
2526add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 PyObject *result = NULL;
2529 int year = GET_YEAR(date);
2530 int month = GET_MONTH(date);
2531 int deltadays = GET_TD_DAYS(delta);
2532 /* C-level overflow is impossible because |deltadays| < 1e9. */
2533 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002535 if (normalize_date(&year, &month, &day) >= 0)
2536 result = new_date(year, month, day);
2537 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002538}
2539
2540static PyObject *
2541date_add(PyObject *left, PyObject *right)
2542{
Brian Curtindfc80e32011-08-10 20:28:54 -05002543 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2544 Py_RETURN_NOTIMPLEMENTED;
2545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002546 if (PyDate_Check(left)) {
2547 /* date + ??? */
2548 if (PyDelta_Check(right))
2549 /* date + delta */
2550 return add_date_timedelta((PyDateTime_Date *) left,
2551 (PyDateTime_Delta *) right,
2552 0);
2553 }
2554 else {
2555 /* ??? + date
2556 * 'right' must be one of us, or we wouldn't have been called
2557 */
2558 if (PyDelta_Check(left))
2559 /* delta + date */
2560 return add_date_timedelta((PyDateTime_Date *) right,
2561 (PyDateTime_Delta *) left,
2562 0);
2563 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002564 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002565}
2566
2567static PyObject *
2568date_subtract(PyObject *left, PyObject *right)
2569{
Brian Curtindfc80e32011-08-10 20:28:54 -05002570 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2571 Py_RETURN_NOTIMPLEMENTED;
2572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002573 if (PyDate_Check(left)) {
2574 if (PyDate_Check(right)) {
2575 /* date - date */
2576 int left_ord = ymd_to_ord(GET_YEAR(left),
2577 GET_MONTH(left),
2578 GET_DAY(left));
2579 int right_ord = ymd_to_ord(GET_YEAR(right),
2580 GET_MONTH(right),
2581 GET_DAY(right));
2582 return new_delta(left_ord - right_ord, 0, 0, 0);
2583 }
2584 if (PyDelta_Check(right)) {
2585 /* date - delta */
2586 return add_date_timedelta((PyDateTime_Date *) left,
2587 (PyDateTime_Delta *) right,
2588 1);
2589 }
2590 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002591 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002592}
2593
2594
2595/* Various ways to turn a date into a string. */
2596
2597static PyObject *
2598date_repr(PyDateTime_Date *self)
2599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2601 Py_TYPE(self)->tp_name,
2602 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002603}
2604
2605static PyObject *
2606date_isoformat(PyDateTime_Date *self)
2607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 return PyUnicode_FromFormat("%04d-%02d-%02d",
2609 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002610}
2611
Tim Peterse2df5ff2003-05-02 18:39:55 +00002612/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002613static PyObject *
2614date_str(PyDateTime_Date *self)
2615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002617}
2618
2619
2620static PyObject *
2621date_ctime(PyDateTime_Date *self)
2622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002623 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002624}
2625
2626static PyObject *
2627date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002629 /* This method can be inherited, and needs to call the
2630 * timetuple() method appropriate to self's class.
2631 */
2632 PyObject *result;
2633 PyObject *tuple;
2634 PyObject *format;
2635 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002637 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2638 &format))
2639 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2642 if (tuple == NULL)
2643 return NULL;
2644 result = wrap_strftime((PyObject *)self, format, tuple,
2645 (PyObject *)self);
2646 Py_DECREF(tuple);
2647 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002648}
2649
Eric Smith1ba31142007-09-11 18:06:02 +00002650static PyObject *
2651date_format(PyDateTime_Date *self, PyObject *args)
2652{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002655 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2656 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 /* if the format is zero length, return str(self) */
2659 if (PyUnicode_GetSize(format) == 0)
2660 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002663}
2664
Tim Peters2a799bf2002-12-16 20:18:38 +00002665/* ISO methods. */
2666
2667static PyObject *
2668date_isoweekday(PyDateTime_Date *self)
2669{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002672 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002673}
2674
2675static PyObject *
2676date_isocalendar(PyDateTime_Date *self)
2677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002678 int year = GET_YEAR(self);
2679 int week1_monday = iso_week1_monday(year);
2680 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2681 int week;
2682 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002684 week = divmod(today - week1_monday, 7, &day);
2685 if (week < 0) {
2686 --year;
2687 week1_monday = iso_week1_monday(year);
2688 week = divmod(today - week1_monday, 7, &day);
2689 }
2690 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2691 ++year;
2692 week = 0;
2693 }
2694 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002695}
2696
2697/* Miscellaneous methods. */
2698
Tim Peters2a799bf2002-12-16 20:18:38 +00002699static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002700date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002701{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002702 if (PyDate_Check(other)) {
2703 int diff = memcmp(((PyDateTime_Date *)self)->data,
2704 ((PyDateTime_Date *)other)->data,
2705 _PyDateTime_DATE_DATASIZE);
2706 return diff_to_bool(diff, op);
2707 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002708 else
2709 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002710}
2711
2712static PyObject *
2713date_timetuple(PyDateTime_Date *self)
2714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002715 return build_struct_time(GET_YEAR(self),
2716 GET_MONTH(self),
2717 GET_DAY(self),
2718 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002719}
2720
Tim Peters12bf3392002-12-24 05:41:27 +00002721static PyObject *
2722date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2723{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002724 PyObject *clone;
2725 PyObject *tuple;
2726 int year = GET_YEAR(self);
2727 int month = GET_MONTH(self);
2728 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002730 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2731 &year, &month, &day))
2732 return NULL;
2733 tuple = Py_BuildValue("iii", year, month, day);
2734 if (tuple == NULL)
2735 return NULL;
2736 clone = date_new(Py_TYPE(self), tuple, NULL);
2737 Py_DECREF(tuple);
2738 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002739}
2740
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002741/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002742 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002743*/
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002744static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002745generic_hash(unsigned char *data, int len)
2746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002747 register unsigned char *p;
Mark Dickinsonc7d93b72011-09-25 15:34:32 +01002748 register Py_uhash_t x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002750 p = (unsigned char *) data;
Mark Dickinsonc7d93b72011-09-25 15:34:32 +01002751 x = (Py_uhash_t)*p << 7;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002752 while (--len >= 0)
Mark Dickinsonc7d93b72011-09-25 15:34:32 +01002753 x = (1000003U*x) ^ (Py_uhash_t)*p++;
2754 x ^= (Py_uhash_t)len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002755 if (x == -1)
2756 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002758 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002759}
2760
2761
2762static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002763
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002764static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002765date_hash(PyDateTime_Date *self)
2766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002767 if (self->hashcode == -1)
2768 self->hashcode = generic_hash(
2769 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002771 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002772}
2773
2774static PyObject *
2775date_toordinal(PyDateTime_Date *self)
2776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002777 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2778 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002779}
2780
2781static PyObject *
2782date_weekday(PyDateTime_Date *self)
2783{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002784 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002786 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002787}
2788
Tim Peters371935f2003-02-01 01:52:50 +00002789/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002790
Tim Petersb57f8f02003-02-01 02:54:15 +00002791/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002792static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002793date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002794{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002795 PyObject* field;
2796 field = PyBytes_FromStringAndSize((char*)self->data,
2797 _PyDateTime_DATE_DATASIZE);
2798 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002799}
2800
2801static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002802date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002803{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002804 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002805}
2806
2807static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002809 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002810
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002811 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2812 METH_CLASS,
2813 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2814 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002816 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2817 METH_CLASS,
2818 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2819 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002821 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2822 PyDoc_STR("Current date or datetime: same as "
2823 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002824
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002825 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002827 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2828 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002830 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2831 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002833 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2834 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2837 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002839 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2840 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2841 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002843 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2844 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002846 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2847 PyDoc_STR("Return the day of the week represented by the date.\n"
2848 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2851 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2852 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2855 PyDoc_STR("Return the day of the week represented by the date.\n"
2856 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002858 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2859 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002861 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2862 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002865};
2866
2867static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002868PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002869
2870static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002871 date_add, /* nb_add */
2872 date_subtract, /* nb_subtract */
2873 0, /* nb_multiply */
2874 0, /* nb_remainder */
2875 0, /* nb_divmod */
2876 0, /* nb_power */
2877 0, /* nb_negative */
2878 0, /* nb_positive */
2879 0, /* nb_absolute */
2880 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002881};
2882
2883static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 PyVarObject_HEAD_INIT(NULL, 0)
2885 "datetime.date", /* tp_name */
2886 sizeof(PyDateTime_Date), /* tp_basicsize */
2887 0, /* tp_itemsize */
2888 0, /* tp_dealloc */
2889 0, /* tp_print */
2890 0, /* tp_getattr */
2891 0, /* tp_setattr */
2892 0, /* tp_reserved */
2893 (reprfunc)date_repr, /* tp_repr */
2894 &date_as_number, /* tp_as_number */
2895 0, /* tp_as_sequence */
2896 0, /* tp_as_mapping */
2897 (hashfunc)date_hash, /* tp_hash */
2898 0, /* tp_call */
2899 (reprfunc)date_str, /* tp_str */
2900 PyObject_GenericGetAttr, /* tp_getattro */
2901 0, /* tp_setattro */
2902 0, /* tp_as_buffer */
2903 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2904 date_doc, /* tp_doc */
2905 0, /* tp_traverse */
2906 0, /* tp_clear */
2907 date_richcompare, /* tp_richcompare */
2908 0, /* tp_weaklistoffset */
2909 0, /* tp_iter */
2910 0, /* tp_iternext */
2911 date_methods, /* tp_methods */
2912 0, /* tp_members */
2913 date_getset, /* tp_getset */
2914 0, /* tp_base */
2915 0, /* tp_dict */
2916 0, /* tp_descr_get */
2917 0, /* tp_descr_set */
2918 0, /* tp_dictoffset */
2919 0, /* tp_init */
2920 0, /* tp_alloc */
2921 date_new, /* tp_new */
2922 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002923};
2924
2925/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002926 * PyDateTime_TZInfo implementation.
2927 */
2928
2929/* This is a pure abstract base class, so doesn't do anything beyond
2930 * raising NotImplemented exceptions. Real tzinfo classes need
2931 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002932 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002933 * be subclasses of this tzinfo class, which is easy and quick to check).
2934 *
2935 * Note: For reasons having to do with pickling of subclasses, we have
2936 * to allow tzinfo objects to be instantiated. This wasn't an issue
2937 * in the Python implementation (__init__() could raise NotImplementedError
2938 * there without ill effect), but doing so in the C implementation hit a
2939 * brick wall.
2940 */
2941
2942static PyObject *
2943tzinfo_nogo(const char* methodname)
2944{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002945 PyErr_Format(PyExc_NotImplementedError,
2946 "a tzinfo subclass must implement %s()",
2947 methodname);
2948 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002949}
2950
2951/* Methods. A subclass must implement these. */
2952
Tim Peters52dcce22003-01-23 16:36:11 +00002953static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002954tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2955{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002956 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002957}
2958
Tim Peters52dcce22003-01-23 16:36:11 +00002959static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002960tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002962 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002963}
2964
Tim Peters52dcce22003-01-23 16:36:11 +00002965static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002966tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002968 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002969}
2970
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002971
2972static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2973 PyDateTime_Delta *delta,
2974 int factor);
2975static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2976static PyObject *datetime_dst(PyObject *self, PyObject *);
2977
Tim Peters52dcce22003-01-23 16:36:11 +00002978static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002979tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002980{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002981 PyObject *result = NULL;
2982 PyObject *off = NULL, *dst = NULL;
2983 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002984
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002985 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002986 PyErr_SetString(PyExc_TypeError,
2987 "fromutc: argument must be a datetime");
2988 return NULL;
2989 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002990 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002991 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2992 "is not self");
2993 return NULL;
2994 }
Tim Peters52dcce22003-01-23 16:36:11 +00002995
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002996 off = datetime_utcoffset(dt, NULL);
2997 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002998 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002999 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003000 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3001 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003002 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003003 }
Tim Peters52dcce22003-01-23 16:36:11 +00003004
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003005 dst = datetime_dst(dt, NULL);
3006 if (dst == NULL)
3007 goto Fail;
3008 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003009 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3010 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003011 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003012 }
Tim Peters52dcce22003-01-23 16:36:11 +00003013
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003014 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3015 if (delta == NULL)
3016 goto Fail;
3017 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003018 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003019 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003020
3021 Py_DECREF(dst);
3022 dst = call_dst(GET_DT_TZINFO(dt), result);
3023 if (dst == NULL)
3024 goto Fail;
3025 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003026 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003027 if (delta_bool(delta) != 0) {
3028 PyObject *temp = result;
3029 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3030 (PyDateTime_Delta *)dst, 1);
3031 Py_DECREF(temp);
3032 if (result == NULL)
3033 goto Fail;
3034 }
3035 Py_DECREF(delta);
3036 Py_DECREF(dst);
3037 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003039
3040Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003041 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3042 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003044 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003045Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003046 Py_XDECREF(off);
3047 Py_XDECREF(dst);
3048 Py_XDECREF(delta);
3049 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003050 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003051}
3052
Tim Peters2a799bf2002-12-16 20:18:38 +00003053/*
3054 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003055 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003056 */
3057
Guido van Rossum177e41a2003-01-30 22:06:23 +00003058static PyObject *
3059tzinfo_reduce(PyObject *self)
3060{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003061 PyObject *args, *state, *tmp;
3062 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003064 tmp = PyTuple_New(0);
3065 if (tmp == NULL)
3066 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003068 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3069 if (getinitargs != NULL) {
3070 args = PyObject_CallObject(getinitargs, tmp);
3071 Py_DECREF(getinitargs);
3072 if (args == NULL) {
3073 Py_DECREF(tmp);
3074 return NULL;
3075 }
3076 }
3077 else {
3078 PyErr_Clear();
3079 args = tmp;
3080 Py_INCREF(args);
3081 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 getstate = PyObject_GetAttrString(self, "__getstate__");
3084 if (getstate != NULL) {
3085 state = PyObject_CallObject(getstate, tmp);
3086 Py_DECREF(getstate);
3087 if (state == NULL) {
3088 Py_DECREF(args);
3089 Py_DECREF(tmp);
3090 return NULL;
3091 }
3092 }
3093 else {
3094 PyObject **dictptr;
3095 PyErr_Clear();
3096 state = Py_None;
3097 dictptr = _PyObject_GetDictPtr(self);
3098 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3099 state = *dictptr;
3100 Py_INCREF(state);
3101 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003103 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003105 if (state == Py_None) {
3106 Py_DECREF(state);
3107 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3108 }
3109 else
3110 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003111}
Tim Peters2a799bf2002-12-16 20:18:38 +00003112
3113static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003115 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3116 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003118 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003119 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3120 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3123 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003126 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3129 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003131 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003132};
3133
3134static char tzinfo_doc[] =
3135PyDoc_STR("Abstract base class for time zone info objects.");
3136
Neal Norwitz227b5332006-03-22 09:28:35 +00003137static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003138 PyVarObject_HEAD_INIT(NULL, 0)
3139 "datetime.tzinfo", /* tp_name */
3140 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3141 0, /* tp_itemsize */
3142 0, /* tp_dealloc */
3143 0, /* tp_print */
3144 0, /* tp_getattr */
3145 0, /* tp_setattr */
3146 0, /* tp_reserved */
3147 0, /* tp_repr */
3148 0, /* tp_as_number */
3149 0, /* tp_as_sequence */
3150 0, /* tp_as_mapping */
3151 0, /* tp_hash */
3152 0, /* tp_call */
3153 0, /* tp_str */
3154 PyObject_GenericGetAttr, /* tp_getattro */
3155 0, /* tp_setattro */
3156 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003157 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003158 tzinfo_doc, /* tp_doc */
3159 0, /* tp_traverse */
3160 0, /* tp_clear */
3161 0, /* tp_richcompare */
3162 0, /* tp_weaklistoffset */
3163 0, /* tp_iter */
3164 0, /* tp_iternext */
3165 tzinfo_methods, /* tp_methods */
3166 0, /* tp_members */
3167 0, /* tp_getset */
3168 0, /* tp_base */
3169 0, /* tp_dict */
3170 0, /* tp_descr_get */
3171 0, /* tp_descr_set */
3172 0, /* tp_dictoffset */
3173 0, /* tp_init */
3174 0, /* tp_alloc */
3175 PyType_GenericNew, /* tp_new */
3176 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003177};
3178
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003179static char *timezone_kws[] = {"offset", "name", NULL};
3180
3181static PyObject *
3182timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3183{
3184 PyObject *offset;
3185 PyObject *name = NULL;
3186 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3187 &PyDateTime_DeltaType, &offset,
3188 &PyUnicode_Type, &name))
3189 return new_timezone(offset, name);
3190
3191 return NULL;
3192}
3193
3194static void
3195timezone_dealloc(PyDateTime_TimeZone *self)
3196{
3197 Py_CLEAR(self->offset);
3198 Py_CLEAR(self->name);
3199 Py_TYPE(self)->tp_free((PyObject *)self);
3200}
3201
3202static PyObject *
3203timezone_richcompare(PyDateTime_TimeZone *self,
3204 PyDateTime_TimeZone *other, int op)
3205{
Brian Curtindfc80e32011-08-10 20:28:54 -05003206 if (op != Py_EQ && op != Py_NE)
3207 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003208 return delta_richcompare(self->offset, other->offset, op);
3209}
3210
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003211static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003212timezone_hash(PyDateTime_TimeZone *self)
3213{
3214 return delta_hash((PyDateTime_Delta *)self->offset);
3215}
3216
3217/* Check argument type passed to tzname, utcoffset, or dst methods.
3218 Returns 0 for good argument. Returns -1 and sets exception info
3219 otherwise.
3220 */
3221static int
3222_timezone_check_argument(PyObject *dt, const char *meth)
3223{
3224 if (dt == Py_None || PyDateTime_Check(dt))
3225 return 0;
3226 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3227 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3228 return -1;
3229}
3230
3231static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003232timezone_repr(PyDateTime_TimeZone *self)
3233{
3234 /* Note that although timezone is not subclassable, it is convenient
3235 to use Py_TYPE(self)->tp_name here. */
3236 const char *type_name = Py_TYPE(self)->tp_name;
3237
3238 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3239 return PyUnicode_FromFormat("%s.utc", type_name);
3240
3241 if (self->name == NULL)
3242 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3243
3244 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3245 self->name);
3246}
3247
3248
3249static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003250timezone_str(PyDateTime_TimeZone *self)
3251{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003252 int hours, minutes, seconds;
3253 PyObject *offset;
3254 char sign;
3255
3256 if (self->name != NULL) {
3257 Py_INCREF(self->name);
3258 return self->name;
3259 }
3260 /* Offset is normalized, so it is negative if days < 0 */
3261 if (GET_TD_DAYS(self->offset) < 0) {
3262 sign = '-';
3263 offset = delta_negative((PyDateTime_Delta *)self->offset);
3264 if (offset == NULL)
3265 return NULL;
3266 }
3267 else {
3268 sign = '+';
3269 offset = self->offset;
3270 Py_INCREF(offset);
3271 }
3272 /* Offset is not negative here. */
3273 seconds = GET_TD_SECONDS(offset);
3274 Py_DECREF(offset);
3275 minutes = divmod(seconds, 60, &seconds);
3276 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003277 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003278 assert(seconds == 0);
3279 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003280}
3281
3282static PyObject *
3283timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3284{
3285 if (_timezone_check_argument(dt, "tzname") == -1)
3286 return NULL;
3287
3288 return timezone_str(self);
3289}
3290
3291static PyObject *
3292timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3293{
3294 if (_timezone_check_argument(dt, "utcoffset") == -1)
3295 return NULL;
3296
3297 Py_INCREF(self->offset);
3298 return self->offset;
3299}
3300
3301static PyObject *
3302timezone_dst(PyObject *self, PyObject *dt)
3303{
3304 if (_timezone_check_argument(dt, "dst") == -1)
3305 return NULL;
3306
3307 Py_RETURN_NONE;
3308}
3309
3310static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003311timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3312{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003313 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003314 PyErr_SetString(PyExc_TypeError,
3315 "fromutc: argument must be a datetime");
3316 return NULL;
3317 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003318 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003319 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3320 "is not self");
3321 return NULL;
3322 }
3323
3324 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3325}
3326
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003327static PyObject *
3328timezone_getinitargs(PyDateTime_TimeZone *self)
3329{
3330 if (self->name == NULL)
3331 return Py_BuildValue("(O)", self->offset);
3332 return Py_BuildValue("(OO)", self->offset, self->name);
3333}
3334
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003335static PyMethodDef timezone_methods[] = {
3336 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3337 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003338 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003339
3340 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003341 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003342
3343 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003344 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003345
3346 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3347 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3348
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003349 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3350 PyDoc_STR("pickle support")},
3351
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003352 {NULL, NULL}
3353};
3354
3355static char timezone_doc[] =
3356PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3357
3358static PyTypeObject PyDateTime_TimeZoneType = {
3359 PyVarObject_HEAD_INIT(NULL, 0)
3360 "datetime.timezone", /* tp_name */
3361 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3362 0, /* tp_itemsize */
3363 (destructor)timezone_dealloc, /* tp_dealloc */
3364 0, /* tp_print */
3365 0, /* tp_getattr */
3366 0, /* tp_setattr */
3367 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003368 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003369 0, /* tp_as_number */
3370 0, /* tp_as_sequence */
3371 0, /* tp_as_mapping */
3372 (hashfunc)timezone_hash, /* tp_hash */
3373 0, /* tp_call */
3374 (reprfunc)timezone_str, /* tp_str */
3375 0, /* tp_getattro */
3376 0, /* tp_setattro */
3377 0, /* tp_as_buffer */
3378 Py_TPFLAGS_DEFAULT, /* tp_flags */
3379 timezone_doc, /* tp_doc */
3380 0, /* tp_traverse */
3381 0, /* tp_clear */
3382 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3383 0, /* tp_weaklistoffset */
3384 0, /* tp_iter */
3385 0, /* tp_iternext */
3386 timezone_methods, /* tp_methods */
3387 0, /* tp_members */
3388 0, /* tp_getset */
3389 &PyDateTime_TZInfoType, /* tp_base */
3390 0, /* tp_dict */
3391 0, /* tp_descr_get */
3392 0, /* tp_descr_set */
3393 0, /* tp_dictoffset */
3394 0, /* tp_init */
3395 0, /* tp_alloc */
3396 timezone_new, /* tp_new */
3397};
3398
Tim Peters2a799bf2002-12-16 20:18:38 +00003399/*
Tim Peters37f39822003-01-10 03:49:02 +00003400 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003401 */
3402
Tim Peters37f39822003-01-10 03:49:02 +00003403/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003404 */
3405
3406static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003407time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003409 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003410}
3411
Tim Peters37f39822003-01-10 03:49:02 +00003412static PyObject *
3413time_minute(PyDateTime_Time *self, void *unused)
3414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003415 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003416}
3417
3418/* The name time_second conflicted with some platform header file. */
3419static PyObject *
3420py_time_second(PyDateTime_Time *self, void *unused)
3421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003422 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003423}
3424
3425static PyObject *
3426time_microsecond(PyDateTime_Time *self, void *unused)
3427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003428 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003429}
3430
3431static PyObject *
3432time_tzinfo(PyDateTime_Time *self, void *unused)
3433{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003434 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3435 Py_INCREF(result);
3436 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003437}
3438
3439static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003440 {"hour", (getter)time_hour},
3441 {"minute", (getter)time_minute},
3442 {"second", (getter)py_time_second},
3443 {"microsecond", (getter)time_microsecond},
3444 {"tzinfo", (getter)time_tzinfo},
3445 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003446};
3447
3448/*
3449 * Constructors.
3450 */
3451
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003452static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003453 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003454
Tim Peters2a799bf2002-12-16 20:18:38 +00003455static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003456time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003458 PyObject *self = NULL;
3459 PyObject *state;
3460 int hour = 0;
3461 int minute = 0;
3462 int second = 0;
3463 int usecond = 0;
3464 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003466 /* Check for invocation from pickle with __getstate__ state */
3467 if (PyTuple_GET_SIZE(args) >= 1 &&
3468 PyTuple_GET_SIZE(args) <= 2 &&
3469 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3470 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3471 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3472 {
3473 PyDateTime_Time *me;
3474 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003476 if (PyTuple_GET_SIZE(args) == 2) {
3477 tzinfo = PyTuple_GET_ITEM(args, 1);
3478 if (check_tzinfo_subclass(tzinfo) < 0) {
3479 PyErr_SetString(PyExc_TypeError, "bad "
3480 "tzinfo state arg");
3481 return NULL;
3482 }
3483 }
3484 aware = (char)(tzinfo != Py_None);
3485 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3486 if (me != NULL) {
3487 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3490 me->hashcode = -1;
3491 me->hastzinfo = aware;
3492 if (aware) {
3493 Py_INCREF(tzinfo);
3494 me->tzinfo = tzinfo;
3495 }
3496 }
3497 return (PyObject *)me;
3498 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003500 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3501 &hour, &minute, &second, &usecond,
3502 &tzinfo)) {
3503 if (check_time_args(hour, minute, second, usecond) < 0)
3504 return NULL;
3505 if (check_tzinfo_subclass(tzinfo) < 0)
3506 return NULL;
3507 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3508 type);
3509 }
3510 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003511}
3512
3513/*
3514 * Destructor.
3515 */
3516
3517static void
Tim Peters37f39822003-01-10 03:49:02 +00003518time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003519{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003520 if (HASTZINFO(self)) {
3521 Py_XDECREF(self->tzinfo);
3522 }
3523 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003524}
3525
3526/*
Tim Peters855fe882002-12-22 03:43:39 +00003527 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003528 */
3529
Tim Peters2a799bf2002-12-16 20:18:38 +00003530/* These are all METH_NOARGS, so don't need to check the arglist. */
3531static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003532time_utcoffset(PyObject *self, PyObject *unused) {
3533 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003534}
3535
3536static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003537time_dst(PyObject *self, PyObject *unused) {
3538 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003539}
3540
3541static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003542time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003543 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003544}
3545
3546/*
Tim Peters37f39822003-01-10 03:49:02 +00003547 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003548 */
3549
3550static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003551time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003552{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003553 const char *type_name = Py_TYPE(self)->tp_name;
3554 int h = TIME_GET_HOUR(self);
3555 int m = TIME_GET_MINUTE(self);
3556 int s = TIME_GET_SECOND(self);
3557 int us = TIME_GET_MICROSECOND(self);
3558 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003560 if (us)
3561 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3562 type_name, h, m, s, us);
3563 else if (s)
3564 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3565 type_name, h, m, s);
3566 else
3567 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3568 if (result != NULL && HASTZINFO(self))
3569 result = append_keyword_tzinfo(result, self->tzinfo);
3570 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003571}
3572
Tim Peters37f39822003-01-10 03:49:02 +00003573static PyObject *
3574time_str(PyDateTime_Time *self)
3575{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003576 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003577}
Tim Peters2a799bf2002-12-16 20:18:38 +00003578
3579static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003580time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003581{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003582 char buf[100];
3583 PyObject *result;
3584 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003586 if (us)
3587 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3588 TIME_GET_HOUR(self),
3589 TIME_GET_MINUTE(self),
3590 TIME_GET_SECOND(self),
3591 us);
3592 else
3593 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3594 TIME_GET_HOUR(self),
3595 TIME_GET_MINUTE(self),
3596 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003597
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003598 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003599 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003601 /* We need to append the UTC offset. */
3602 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3603 Py_None) < 0) {
3604 Py_DECREF(result);
3605 return NULL;
3606 }
3607 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3608 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003609}
3610
Tim Peters37f39822003-01-10 03:49:02 +00003611static PyObject *
3612time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003614 PyObject *result;
3615 PyObject *tuple;
3616 PyObject *format;
3617 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003619 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3620 &format))
3621 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003623 /* Python's strftime does insane things with the year part of the
3624 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003625 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003626 */
3627 tuple = Py_BuildValue("iiiiiiiii",
3628 1900, 1, 1, /* year, month, day */
3629 TIME_GET_HOUR(self),
3630 TIME_GET_MINUTE(self),
3631 TIME_GET_SECOND(self),
3632 0, 1, -1); /* weekday, daynum, dst */
3633 if (tuple == NULL)
3634 return NULL;
3635 assert(PyTuple_Size(tuple) == 9);
3636 result = wrap_strftime((PyObject *)self, format, tuple,
3637 Py_None);
3638 Py_DECREF(tuple);
3639 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003640}
Tim Peters2a799bf2002-12-16 20:18:38 +00003641
3642/*
3643 * Miscellaneous methods.
3644 */
3645
Tim Peters37f39822003-01-10 03:49:02 +00003646static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003647time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003648{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003649 PyObject *result = NULL;
3650 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003651 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003652
Brian Curtindfc80e32011-08-10 20:28:54 -05003653 if (! PyTime_Check(other))
3654 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003655
3656 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003657 diff = memcmp(((PyDateTime_Time *)self)->data,
3658 ((PyDateTime_Time *)other)->data,
3659 _PyDateTime_TIME_DATASIZE);
3660 return diff_to_bool(diff, op);
3661 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003662 offset1 = time_utcoffset(self, NULL);
3663 if (offset1 == NULL)
3664 return NULL;
3665 offset2 = time_utcoffset(other, NULL);
3666 if (offset2 == NULL)
3667 goto done;
3668 /* If they're both naive, or both aware and have the same offsets,
3669 * we get off cheap. Note that if they're both naive, offset1 ==
3670 * offset2 == Py_None at this point.
3671 */
3672 if ((offset1 == offset2) ||
3673 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3674 delta_cmp(offset1, offset2) == 0)) {
3675 diff = memcmp(((PyDateTime_Time *)self)->data,
3676 ((PyDateTime_Time *)other)->data,
3677 _PyDateTime_TIME_DATASIZE);
3678 result = diff_to_bool(diff, op);
3679 }
3680 /* The hard case: both aware with different UTC offsets */
3681 else if (offset1 != Py_None && offset2 != Py_None) {
3682 int offsecs1, offsecs2;
3683 assert(offset1 != offset2); /* else last "if" handled it */
3684 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3685 TIME_GET_MINUTE(self) * 60 +
3686 TIME_GET_SECOND(self) -
3687 GET_TD_DAYS(offset1) * 86400 -
3688 GET_TD_SECONDS(offset1);
3689 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3690 TIME_GET_MINUTE(other) * 60 +
3691 TIME_GET_SECOND(other) -
3692 GET_TD_DAYS(offset2) * 86400 -
3693 GET_TD_SECONDS(offset2);
3694 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003695 if (diff == 0)
3696 diff = TIME_GET_MICROSECOND(self) -
3697 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003698 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003699 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003700 else {
3701 PyErr_SetString(PyExc_TypeError,
3702 "can't compare offset-naive and "
3703 "offset-aware times");
3704 }
3705 done:
3706 Py_DECREF(offset1);
3707 Py_XDECREF(offset2);
3708 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003709}
3710
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003711static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003712time_hash(PyDateTime_Time *self)
3713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003714 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003715 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003716
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003717 offset = time_utcoffset((PyObject *)self, NULL);
3718
3719 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003720 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003721
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003722 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003723 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003724 self->hashcode = generic_hash(
3725 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003726 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003727 PyObject *temp1, *temp2;
3728 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003729 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003730 seconds = TIME_GET_HOUR(self) * 3600 +
3731 TIME_GET_MINUTE(self) * 60 +
3732 TIME_GET_SECOND(self);
3733 microseconds = TIME_GET_MICROSECOND(self);
3734 temp1 = new_delta(0, seconds, microseconds, 1);
3735 if (temp1 == NULL) {
3736 Py_DECREF(offset);
3737 return -1;
3738 }
3739 temp2 = delta_subtract(temp1, offset);
3740 Py_DECREF(temp1);
3741 if (temp2 == NULL) {
3742 Py_DECREF(offset);
3743 return -1;
3744 }
3745 self->hashcode = PyObject_Hash(temp2);
3746 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003747 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003748 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003749 }
3750 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003751}
Tim Peters2a799bf2002-12-16 20:18:38 +00003752
Tim Peters12bf3392002-12-24 05:41:27 +00003753static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003754time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003755{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003756 PyObject *clone;
3757 PyObject *tuple;
3758 int hh = TIME_GET_HOUR(self);
3759 int mm = TIME_GET_MINUTE(self);
3760 int ss = TIME_GET_SECOND(self);
3761 int us = TIME_GET_MICROSECOND(self);
3762 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003764 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3765 time_kws,
3766 &hh, &mm, &ss, &us, &tzinfo))
3767 return NULL;
3768 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3769 if (tuple == NULL)
3770 return NULL;
3771 clone = time_new(Py_TYPE(self), tuple, NULL);
3772 Py_DECREF(tuple);
3773 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003774}
3775
Tim Peters2a799bf2002-12-16 20:18:38 +00003776static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003777time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003778{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003779 PyObject *offset, *tzinfo;
3780 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003782 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3783 /* Since utcoffset is in whole minutes, nothing can
3784 * alter the conclusion that this is nonzero.
3785 */
3786 return 1;
3787 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003788 tzinfo = GET_TIME_TZINFO(self);
3789 if (tzinfo != Py_None) {
3790 offset = call_utcoffset(tzinfo, Py_None);
3791 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003792 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003793 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3794 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003795 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003796 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003797}
3798
Tim Peters371935f2003-02-01 01:52:50 +00003799/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003800
Tim Peters33e0f382003-01-10 02:05:14 +00003801/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003802 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3803 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003804 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003805 */
3806static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003807time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003809 PyObject *basestate;
3810 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003812 basestate = PyBytes_FromStringAndSize((char *)self->data,
3813 _PyDateTime_TIME_DATASIZE);
3814 if (basestate != NULL) {
3815 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3816 result = PyTuple_Pack(1, basestate);
3817 else
3818 result = PyTuple_Pack(2, basestate, self->tzinfo);
3819 Py_DECREF(basestate);
3820 }
3821 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003822}
3823
3824static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003825time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003827 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003828}
3829
Tim Peters37f39822003-01-10 03:49:02 +00003830static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003832 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3833 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3834 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003836 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3837 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003839 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3840 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003842 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3843 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003845 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3846 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003848 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3849 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003851 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3852 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003854 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3855 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003857 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003858};
3859
Tim Peters37f39822003-01-10 03:49:02 +00003860static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003861PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3862\n\
3863All arguments are optional. tzinfo may be None, or an instance of\n\
3864a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003865
Tim Peters37f39822003-01-10 03:49:02 +00003866static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003867 0, /* nb_add */
3868 0, /* nb_subtract */
3869 0, /* nb_multiply */
3870 0, /* nb_remainder */
3871 0, /* nb_divmod */
3872 0, /* nb_power */
3873 0, /* nb_negative */
3874 0, /* nb_positive */
3875 0, /* nb_absolute */
3876 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003877};
3878
Neal Norwitz227b5332006-03-22 09:28:35 +00003879static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003880 PyVarObject_HEAD_INIT(NULL, 0)
3881 "datetime.time", /* tp_name */
3882 sizeof(PyDateTime_Time), /* tp_basicsize */
3883 0, /* tp_itemsize */
3884 (destructor)time_dealloc, /* tp_dealloc */
3885 0, /* tp_print */
3886 0, /* tp_getattr */
3887 0, /* tp_setattr */
3888 0, /* tp_reserved */
3889 (reprfunc)time_repr, /* tp_repr */
3890 &time_as_number, /* tp_as_number */
3891 0, /* tp_as_sequence */
3892 0, /* tp_as_mapping */
3893 (hashfunc)time_hash, /* tp_hash */
3894 0, /* tp_call */
3895 (reprfunc)time_str, /* tp_str */
3896 PyObject_GenericGetAttr, /* tp_getattro */
3897 0, /* tp_setattro */
3898 0, /* tp_as_buffer */
3899 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3900 time_doc, /* tp_doc */
3901 0, /* tp_traverse */
3902 0, /* tp_clear */
3903 time_richcompare, /* tp_richcompare */
3904 0, /* tp_weaklistoffset */
3905 0, /* tp_iter */
3906 0, /* tp_iternext */
3907 time_methods, /* tp_methods */
3908 0, /* tp_members */
3909 time_getset, /* tp_getset */
3910 0, /* tp_base */
3911 0, /* tp_dict */
3912 0, /* tp_descr_get */
3913 0, /* tp_descr_set */
3914 0, /* tp_dictoffset */
3915 0, /* tp_init */
3916 time_alloc, /* tp_alloc */
3917 time_new, /* tp_new */
3918 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003919};
3920
3921/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003922 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003923 */
3924
Tim Petersa9bc1682003-01-11 03:39:11 +00003925/* Accessor properties. Properties for day, month, and year are inherited
3926 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003927 */
3928
3929static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003930datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003932 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003933}
3934
Tim Petersa9bc1682003-01-11 03:39:11 +00003935static PyObject *
3936datetime_minute(PyDateTime_DateTime *self, void *unused)
3937{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003938 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003939}
3940
3941static PyObject *
3942datetime_second(PyDateTime_DateTime *self, void *unused)
3943{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003944 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003945}
3946
3947static PyObject *
3948datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3949{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003950 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003951}
3952
3953static PyObject *
3954datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3955{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003956 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3957 Py_INCREF(result);
3958 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003959}
3960
3961static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003962 {"hour", (getter)datetime_hour},
3963 {"minute", (getter)datetime_minute},
3964 {"second", (getter)datetime_second},
3965 {"microsecond", (getter)datetime_microsecond},
3966 {"tzinfo", (getter)datetime_tzinfo},
3967 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003968};
3969
3970/*
3971 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003972 */
3973
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003974static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003975 "year", "month", "day", "hour", "minute", "second",
3976 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003977};
3978
Tim Peters2a799bf2002-12-16 20:18:38 +00003979static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003980datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003982 PyObject *self = NULL;
3983 PyObject *state;
3984 int year;
3985 int month;
3986 int day;
3987 int hour = 0;
3988 int minute = 0;
3989 int second = 0;
3990 int usecond = 0;
3991 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003993 /* Check for invocation from pickle with __getstate__ state */
3994 if (PyTuple_GET_SIZE(args) >= 1 &&
3995 PyTuple_GET_SIZE(args) <= 2 &&
3996 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3997 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3998 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
3999 {
4000 PyDateTime_DateTime *me;
4001 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004003 if (PyTuple_GET_SIZE(args) == 2) {
4004 tzinfo = PyTuple_GET_ITEM(args, 1);
4005 if (check_tzinfo_subclass(tzinfo) < 0) {
4006 PyErr_SetString(PyExc_TypeError, "bad "
4007 "tzinfo state arg");
4008 return NULL;
4009 }
4010 }
4011 aware = (char)(tzinfo != Py_None);
4012 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4013 if (me != NULL) {
4014 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004016 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4017 me->hashcode = -1;
4018 me->hastzinfo = aware;
4019 if (aware) {
4020 Py_INCREF(tzinfo);
4021 me->tzinfo = tzinfo;
4022 }
4023 }
4024 return (PyObject *)me;
4025 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004027 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4028 &year, &month, &day, &hour, &minute,
4029 &second, &usecond, &tzinfo)) {
4030 if (check_date_args(year, month, day) < 0)
4031 return NULL;
4032 if (check_time_args(hour, minute, second, usecond) < 0)
4033 return NULL;
4034 if (check_tzinfo_subclass(tzinfo) < 0)
4035 return NULL;
4036 self = new_datetime_ex(year, month, day,
4037 hour, minute, second, usecond,
4038 tzinfo, type);
4039 }
4040 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004041}
4042
Tim Petersa9bc1682003-01-11 03:39:11 +00004043/* TM_FUNC is the shared type of localtime() and gmtime(). */
4044typedef struct tm *(*TM_FUNC)(const time_t *timer);
4045
4046/* Internal helper.
4047 * Build datetime from a time_t and a distinct count of microseconds.
4048 * Pass localtime or gmtime for f, to control the interpretation of timet.
4049 */
4050static PyObject *
4051datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004052 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004053{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004054 struct tm *tm;
4055 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004057 tm = f(&timet);
4058 if (tm) {
4059 /* The platform localtime/gmtime may insert leap seconds,
4060 * indicated by tm->tm_sec > 59. We don't care about them,
4061 * except to the extent that passing them on to the datetime
4062 * constructor would raise ValueError for a reason that
4063 * made no sense to the user.
4064 */
4065 if (tm->tm_sec > 59)
4066 tm->tm_sec = 59;
4067 result = PyObject_CallFunction(cls, "iiiiiiiO",
4068 tm->tm_year + 1900,
4069 tm->tm_mon + 1,
4070 tm->tm_mday,
4071 tm->tm_hour,
4072 tm->tm_min,
4073 tm->tm_sec,
4074 us,
4075 tzinfo);
4076 }
4077 else
4078 PyErr_SetString(PyExc_ValueError,
4079 "timestamp out of range for "
4080 "platform localtime()/gmtime() function");
4081 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004082}
4083
4084/* Internal helper.
4085 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4086 * to control the interpretation of the timestamp. Since a double doesn't
4087 * have enough bits to cover a datetime's full range of precision, it's
4088 * better to call datetime_from_timet_and_us provided you have a way
4089 * to get that much precision (e.g., C time() isn't good enough).
4090 */
4091static PyObject *
4092datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004093 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004095 time_t timet;
4096 double fraction;
4097 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 timet = _PyTime_DoubleToTimet(timestamp);
4100 if (timet == (time_t)-1 && PyErr_Occurred())
4101 return NULL;
4102 fraction = timestamp - (double)timet;
4103 us = (int)round_to_long(fraction * 1e6);
4104 if (us < 0) {
4105 /* Truncation towards zero is not what we wanted
4106 for negative numbers (Python's mod semantics) */
4107 timet -= 1;
4108 us += 1000000;
4109 }
4110 /* If timestamp is less than one microsecond smaller than a
4111 * full second, round up. Otherwise, ValueErrors are raised
4112 * for some floats. */
4113 if (us == 1000000) {
4114 timet += 1;
4115 us = 0;
4116 }
4117 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004118}
4119
4120/* Internal helper.
4121 * Build most accurate possible datetime for current time. Pass localtime or
4122 * gmtime for f as appropriate.
4123 */
4124static PyObject *
4125datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4126{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004127 _PyTime_timeval t;
4128 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004129 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4130 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004131}
4132
Tim Peters2a799bf2002-12-16 20:18:38 +00004133/* Return best possible local time -- this isn't constrained by the
4134 * precision of a timestamp.
4135 */
4136static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004137datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004138{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004139 PyObject *self;
4140 PyObject *tzinfo = Py_None;
4141 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004143 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4144 &tzinfo))
4145 return NULL;
4146 if (check_tzinfo_subclass(tzinfo) < 0)
4147 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004149 self = datetime_best_possible(cls,
4150 tzinfo == Py_None ? localtime : gmtime,
4151 tzinfo);
4152 if (self != NULL && tzinfo != Py_None) {
4153 /* Convert UTC to tzinfo's zone. */
4154 PyObject *temp = self;
4155 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4156 Py_DECREF(temp);
4157 }
4158 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004159}
4160
Tim Petersa9bc1682003-01-11 03:39:11 +00004161/* Return best possible UTC time -- this isn't constrained by the
4162 * precision of a timestamp.
4163 */
4164static PyObject *
4165datetime_utcnow(PyObject *cls, PyObject *dummy)
4166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004167 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004168}
4169
Tim Peters2a799bf2002-12-16 20:18:38 +00004170/* Return new local datetime from timestamp (Python timestamp -- a double). */
4171static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004172datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004174 PyObject *self;
4175 double timestamp;
4176 PyObject *tzinfo = Py_None;
4177 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004179 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4180 keywords, &timestamp, &tzinfo))
4181 return NULL;
4182 if (check_tzinfo_subclass(tzinfo) < 0)
4183 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004185 self = datetime_from_timestamp(cls,
4186 tzinfo == Py_None ? localtime : gmtime,
4187 timestamp,
4188 tzinfo);
4189 if (self != NULL && tzinfo != Py_None) {
4190 /* Convert UTC to tzinfo's zone. */
4191 PyObject *temp = self;
4192 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4193 Py_DECREF(temp);
4194 }
4195 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004196}
4197
Tim Petersa9bc1682003-01-11 03:39:11 +00004198/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4199static PyObject *
4200datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004202 double timestamp;
4203 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004205 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4206 result = datetime_from_timestamp(cls, gmtime, timestamp,
4207 Py_None);
4208 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004209}
4210
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004211/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004212static PyObject *
4213datetime_strptime(PyObject *cls, PyObject *args)
4214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004215 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004216 PyObject *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004217
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004218 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004219 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004220
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004221 if (module == NULL) {
4222 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004223 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004224 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004225 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004226 return PyObject_CallMethod(module, "_strptime_datetime", "OOO",
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004227 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004228}
4229
Tim Petersa9bc1682003-01-11 03:39:11 +00004230/* Return new datetime from date/datetime and time arguments. */
4231static PyObject *
4232datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 static char *keywords[] = {"date", "time", NULL};
4235 PyObject *date;
4236 PyObject *time;
4237 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004239 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4240 &PyDateTime_DateType, &date,
4241 &PyDateTime_TimeType, &time)) {
4242 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004244 if (HASTZINFO(time))
4245 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4246 result = PyObject_CallFunction(cls, "iiiiiiiO",
4247 GET_YEAR(date),
4248 GET_MONTH(date),
4249 GET_DAY(date),
4250 TIME_GET_HOUR(time),
4251 TIME_GET_MINUTE(time),
4252 TIME_GET_SECOND(time),
4253 TIME_GET_MICROSECOND(time),
4254 tzinfo);
4255 }
4256 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004257}
Tim Peters2a799bf2002-12-16 20:18:38 +00004258
4259/*
4260 * Destructor.
4261 */
4262
4263static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004264datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004266 if (HASTZINFO(self)) {
4267 Py_XDECREF(self->tzinfo);
4268 }
4269 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004270}
4271
4272/*
4273 * Indirect access to tzinfo methods.
4274 */
4275
Tim Peters2a799bf2002-12-16 20:18:38 +00004276/* These are all METH_NOARGS, so don't need to check the arglist. */
4277static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004278datetime_utcoffset(PyObject *self, PyObject *unused) {
4279 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004280}
4281
4282static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004283datetime_dst(PyObject *self, PyObject *unused) {
4284 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004285}
4286
4287static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004288datetime_tzname(PyObject *self, PyObject *unused) {
4289 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004290}
4291
4292/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004293 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004294 */
4295
Tim Petersa9bc1682003-01-11 03:39:11 +00004296/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4297 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004298 */
4299static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004300add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004301 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 /* Note that the C-level additions can't overflow, because of
4304 * invariant bounds on the member values.
4305 */
4306 int year = GET_YEAR(date);
4307 int month = GET_MONTH(date);
4308 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4309 int hour = DATE_GET_HOUR(date);
4310 int minute = DATE_GET_MINUTE(date);
4311 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4312 int microsecond = DATE_GET_MICROSECOND(date) +
4313 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004315 assert(factor == 1 || factor == -1);
4316 if (normalize_datetime(&year, &month, &day,
4317 &hour, &minute, &second, &microsecond) < 0)
4318 return NULL;
4319 else
4320 return new_datetime(year, month, day,
4321 hour, minute, second, microsecond,
4322 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004323}
4324
4325static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004326datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004328 if (PyDateTime_Check(left)) {
4329 /* datetime + ??? */
4330 if (PyDelta_Check(right))
4331 /* datetime + delta */
4332 return add_datetime_timedelta(
4333 (PyDateTime_DateTime *)left,
4334 (PyDateTime_Delta *)right,
4335 1);
4336 }
4337 else if (PyDelta_Check(left)) {
4338 /* delta + datetime */
4339 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4340 (PyDateTime_Delta *) left,
4341 1);
4342 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004343 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004344}
4345
4346static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004347datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004349 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004351 if (PyDateTime_Check(left)) {
4352 /* datetime - ??? */
4353 if (PyDateTime_Check(right)) {
4354 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004355 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004356 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004357
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004358 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4359 offset2 = offset1 = Py_None;
4360 Py_INCREF(offset1);
4361 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004362 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004363 else {
4364 offset1 = datetime_utcoffset(left, NULL);
4365 if (offset1 == NULL)
4366 return NULL;
4367 offset2 = datetime_utcoffset(right, NULL);
4368 if (offset2 == NULL) {
4369 Py_DECREF(offset1);
4370 return NULL;
4371 }
4372 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4373 PyErr_SetString(PyExc_TypeError,
4374 "can't subtract offset-naive and "
4375 "offset-aware datetimes");
4376 Py_DECREF(offset1);
4377 Py_DECREF(offset2);
4378 return NULL;
4379 }
4380 }
4381 if ((offset1 != offset2) &&
4382 delta_cmp(offset1, offset2) != 0) {
4383 offdiff = delta_subtract(offset1, offset2);
4384 if (offdiff == NULL) {
4385 Py_DECREF(offset1);
4386 Py_DECREF(offset2);
4387 return NULL;
4388 }
4389 }
4390 Py_DECREF(offset1);
4391 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004392 delta_d = ymd_to_ord(GET_YEAR(left),
4393 GET_MONTH(left),
4394 GET_DAY(left)) -
4395 ymd_to_ord(GET_YEAR(right),
4396 GET_MONTH(right),
4397 GET_DAY(right));
4398 /* These can't overflow, since the values are
4399 * normalized. At most this gives the number of
4400 * seconds in one day.
4401 */
4402 delta_s = (DATE_GET_HOUR(left) -
4403 DATE_GET_HOUR(right)) * 3600 +
4404 (DATE_GET_MINUTE(left) -
4405 DATE_GET_MINUTE(right)) * 60 +
4406 (DATE_GET_SECOND(left) -
4407 DATE_GET_SECOND(right));
4408 delta_us = DATE_GET_MICROSECOND(left) -
4409 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004410 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004411 if (offdiff != NULL) {
4412 PyObject *temp = result;
4413 result = delta_subtract(result, offdiff);
4414 Py_DECREF(temp);
4415 Py_DECREF(offdiff);
4416 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004417 }
4418 else if (PyDelta_Check(right)) {
4419 /* datetime - delta */
4420 result = add_datetime_timedelta(
4421 (PyDateTime_DateTime *)left,
4422 (PyDateTime_Delta *)right,
4423 -1);
4424 }
4425 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004427 if (result == Py_NotImplemented)
4428 Py_INCREF(result);
4429 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004430}
4431
4432/* Various ways to turn a datetime into a string. */
4433
4434static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004435datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004437 const char *type_name = Py_TYPE(self)->tp_name;
4438 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004440 if (DATE_GET_MICROSECOND(self)) {
4441 baserepr = PyUnicode_FromFormat(
4442 "%s(%d, %d, %d, %d, %d, %d, %d)",
4443 type_name,
4444 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4445 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4446 DATE_GET_SECOND(self),
4447 DATE_GET_MICROSECOND(self));
4448 }
4449 else if (DATE_GET_SECOND(self)) {
4450 baserepr = PyUnicode_FromFormat(
4451 "%s(%d, %d, %d, %d, %d, %d)",
4452 type_name,
4453 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4454 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4455 DATE_GET_SECOND(self));
4456 }
4457 else {
4458 baserepr = PyUnicode_FromFormat(
4459 "%s(%d, %d, %d, %d, %d)",
4460 type_name,
4461 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4462 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4463 }
4464 if (baserepr == NULL || ! HASTZINFO(self))
4465 return baserepr;
4466 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004467}
4468
Tim Petersa9bc1682003-01-11 03:39:11 +00004469static PyObject *
4470datetime_str(PyDateTime_DateTime *self)
4471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004472 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004473}
Tim Peters2a799bf2002-12-16 20:18:38 +00004474
4475static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004476datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004478 int sep = 'T';
4479 static char *keywords[] = {"sep", NULL};
4480 char buffer[100];
4481 PyObject *result;
4482 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004484 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4485 return NULL;
4486 if (us)
4487 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4488 GET_YEAR(self), GET_MONTH(self),
4489 GET_DAY(self), (int)sep,
4490 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4491 DATE_GET_SECOND(self), us);
4492 else
4493 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4494 GET_YEAR(self), GET_MONTH(self),
4495 GET_DAY(self), (int)sep,
4496 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4497 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004499 if (!result || !HASTZINFO(self))
4500 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004502 /* We need to append the UTC offset. */
4503 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4504 (PyObject *)self) < 0) {
4505 Py_DECREF(result);
4506 return NULL;
4507 }
4508 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4509 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004510}
4511
Tim Petersa9bc1682003-01-11 03:39:11 +00004512static PyObject *
4513datetime_ctime(PyDateTime_DateTime *self)
4514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004515 return format_ctime((PyDateTime_Date *)self,
4516 DATE_GET_HOUR(self),
4517 DATE_GET_MINUTE(self),
4518 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004519}
4520
Tim Peters2a799bf2002-12-16 20:18:38 +00004521/* Miscellaneous methods. */
4522
Tim Petersa9bc1682003-01-11 03:39:11 +00004523static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004524datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004525{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004526 PyObject *result = NULL;
4527 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004528 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004530 if (! PyDateTime_Check(other)) {
4531 if (PyDate_Check(other)) {
4532 /* Prevent invocation of date_richcompare. We want to
4533 return NotImplemented here to give the other object
4534 a chance. But since DateTime is a subclass of
4535 Date, if the other object is a Date, it would
4536 compute an ordering based on the date part alone,
4537 and we don't want that. So force unequal or
4538 uncomparable here in that case. */
4539 if (op == Py_EQ)
4540 Py_RETURN_FALSE;
4541 if (op == Py_NE)
4542 Py_RETURN_TRUE;
4543 return cmperror(self, other);
4544 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004545 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004546 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004547
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004548 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004549 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4550 ((PyDateTime_DateTime *)other)->data,
4551 _PyDateTime_DATETIME_DATASIZE);
4552 return diff_to_bool(diff, op);
4553 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004554 offset1 = datetime_utcoffset(self, NULL);
4555 if (offset1 == NULL)
4556 return NULL;
4557 offset2 = datetime_utcoffset(other, NULL);
4558 if (offset2 == NULL)
4559 goto done;
4560 /* If they're both naive, or both aware and have the same offsets,
4561 * we get off cheap. Note that if they're both naive, offset1 ==
4562 * offset2 == Py_None at this point.
4563 */
4564 if ((offset1 == offset2) ||
4565 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4566 delta_cmp(offset1, offset2) == 0)) {
4567 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4568 ((PyDateTime_DateTime *)other)->data,
4569 _PyDateTime_DATETIME_DATASIZE);
4570 result = diff_to_bool(diff, op);
4571 }
4572 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004574
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004575 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004576 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4577 other);
4578 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004579 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004580 diff = GET_TD_DAYS(delta);
4581 if (diff == 0)
4582 diff = GET_TD_SECONDS(delta) |
4583 GET_TD_MICROSECONDS(delta);
4584 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004585 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004586 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004587 else {
4588 PyErr_SetString(PyExc_TypeError,
4589 "can't compare offset-naive and "
4590 "offset-aware datetimes");
4591 }
4592 done:
4593 Py_DECREF(offset1);
4594 Py_XDECREF(offset2);
4595 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004596}
4597
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004598static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004599datetime_hash(PyDateTime_DateTime *self)
4600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004601 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004602 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004603
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004604 offset = datetime_utcoffset((PyObject *)self, NULL);
4605
4606 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004607 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004609 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004610 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004611 self->hashcode = generic_hash(
4612 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004613 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004614 PyObject *temp1, *temp2;
4615 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004617 assert(HASTZINFO(self));
4618 days = ymd_to_ord(GET_YEAR(self),
4619 GET_MONTH(self),
4620 GET_DAY(self));
4621 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004622 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004623 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004624 temp1 = new_delta(days, seconds,
4625 DATE_GET_MICROSECOND(self),
4626 1);
4627 if (temp1 == NULL) {
4628 Py_DECREF(offset);
4629 return -1;
4630 }
4631 temp2 = delta_subtract(temp1, offset);
4632 Py_DECREF(temp1);
4633 if (temp2 == NULL) {
4634 Py_DECREF(offset);
4635 return -1;
4636 }
4637 self->hashcode = PyObject_Hash(temp2);
4638 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004640 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004641 }
4642 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004643}
Tim Peters2a799bf2002-12-16 20:18:38 +00004644
4645static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004646datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004647{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004648 PyObject *clone;
4649 PyObject *tuple;
4650 int y = GET_YEAR(self);
4651 int m = GET_MONTH(self);
4652 int d = GET_DAY(self);
4653 int hh = DATE_GET_HOUR(self);
4654 int mm = DATE_GET_MINUTE(self);
4655 int ss = DATE_GET_SECOND(self);
4656 int us = DATE_GET_MICROSECOND(self);
4657 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004659 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4660 datetime_kws,
4661 &y, &m, &d, &hh, &mm, &ss, &us,
4662 &tzinfo))
4663 return NULL;
4664 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4665 if (tuple == NULL)
4666 return NULL;
4667 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4668 Py_DECREF(tuple);
4669 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004670}
4671
4672static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004673datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004674{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004675 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004676 PyObject *offset;
4677 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004678 PyObject *tzinfo;
4679 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4682 &PyDateTime_TZInfoType, &tzinfo))
4683 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004685 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4686 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004688 /* Conversion to self's own time zone is a NOP. */
4689 if (self->tzinfo == tzinfo) {
4690 Py_INCREF(self);
4691 return (PyObject *)self;
4692 }
Tim Peters521fc152002-12-31 17:36:56 +00004693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004694 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004695 offset = datetime_utcoffset((PyObject *)self, NULL);
4696 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004697 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004698 if (offset == Py_None) {
4699 Py_DECREF(offset);
4700 NeedAware:
4701 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4702 "a naive datetime");
4703 return NULL;
4704 }
Tim Petersf3615152003-01-01 21:51:37 +00004705
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004706 /* result = self - offset */
4707 result = add_datetime_timedelta(self,
4708 (PyDateTime_Delta *)offset, -1);
4709 Py_DECREF(offset);
4710 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004711 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004713 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004714 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4715 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4716 Py_INCREF(tzinfo);
4717 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004718
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004719 temp = result;
4720 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4721 Py_DECREF(temp);
4722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004723 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004724}
4725
4726static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004727datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004729 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004731 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004732 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004733
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004734 dst = call_dst(self->tzinfo, (PyObject *)self);
4735 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004736 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004737
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004738 if (dst != Py_None)
4739 dstflag = delta_bool((PyDateTime_Delta *)dst);
4740 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004741 }
4742 return build_struct_time(GET_YEAR(self),
4743 GET_MONTH(self),
4744 GET_DAY(self),
4745 DATE_GET_HOUR(self),
4746 DATE_GET_MINUTE(self),
4747 DATE_GET_SECOND(self),
4748 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004749}
4750
4751static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004752datetime_getdate(PyDateTime_DateTime *self)
4753{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004754 return new_date(GET_YEAR(self),
4755 GET_MONTH(self),
4756 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004757}
4758
4759static PyObject *
4760datetime_gettime(PyDateTime_DateTime *self)
4761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004762 return new_time(DATE_GET_HOUR(self),
4763 DATE_GET_MINUTE(self),
4764 DATE_GET_SECOND(self),
4765 DATE_GET_MICROSECOND(self),
4766 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004767}
4768
4769static PyObject *
4770datetime_gettimetz(PyDateTime_DateTime *self)
4771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004772 return new_time(DATE_GET_HOUR(self),
4773 DATE_GET_MINUTE(self),
4774 DATE_GET_SECOND(self),
4775 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004776 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004777}
4778
4779static PyObject *
4780datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004781{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004782 int y, m, d, hh, mm, ss;
4783 PyObject *tzinfo;
4784 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004785
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004786 tzinfo = GET_DT_TZINFO(self);
4787 if (tzinfo == Py_None) {
4788 utcself = self;
4789 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004790 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004791 else {
4792 PyObject *offset;
4793 offset = call_utcoffset(tzinfo, (PyObject *)self);
4794 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004795 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004796 if (offset == Py_None) {
4797 Py_DECREF(offset);
4798 utcself = self;
4799 Py_INCREF(utcself);
4800 }
4801 else {
4802 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4803 (PyDateTime_Delta *)offset, -1);
4804 Py_DECREF(offset);
4805 if (utcself == NULL)
4806 return NULL;
4807 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004808 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004809 y = GET_YEAR(utcself);
4810 m = GET_MONTH(utcself);
4811 d = GET_DAY(utcself);
4812 hh = DATE_GET_HOUR(utcself);
4813 mm = DATE_GET_MINUTE(utcself);
4814 ss = DATE_GET_SECOND(utcself);
4815
4816 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004817 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004818}
4819
Tim Peters371935f2003-02-01 01:52:50 +00004820/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004821
Tim Petersa9bc1682003-01-11 03:39:11 +00004822/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004823 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4824 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004825 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004826 */
4827static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004828datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004830 PyObject *basestate;
4831 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004833 basestate = PyBytes_FromStringAndSize((char *)self->data,
4834 _PyDateTime_DATETIME_DATASIZE);
4835 if (basestate != NULL) {
4836 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4837 result = PyTuple_Pack(1, basestate);
4838 else
4839 result = PyTuple_Pack(2, basestate, self->tzinfo);
4840 Py_DECREF(basestate);
4841 }
4842 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004843}
4844
4845static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004846datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004848 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004849}
4850
Tim Petersa9bc1682003-01-11 03:39:11 +00004851static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004853 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004855 {"now", (PyCFunction)datetime_now,
4856 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4857 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004859 {"utcnow", (PyCFunction)datetime_utcnow,
4860 METH_NOARGS | METH_CLASS,
4861 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004863 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4864 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4865 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004867 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4868 METH_VARARGS | METH_CLASS,
4869 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4870 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004872 {"strptime", (PyCFunction)datetime_strptime,
4873 METH_VARARGS | METH_CLASS,
4874 PyDoc_STR("string, format -> new datetime parsed from a string "
4875 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004877 {"combine", (PyCFunction)datetime_combine,
4878 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4879 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004881 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004883 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4884 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004886 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4887 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004889 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4890 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004892 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4893 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004895 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4896 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004898 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4899 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004901 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4902 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4903 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4904 "sep is used to separate the year from the time, and "
4905 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004907 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4908 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004910 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4911 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004913 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4914 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004916 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4917 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004919 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4920 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004922 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4923 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004925 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004926};
4927
Tim Petersa9bc1682003-01-11 03:39:11 +00004928static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004929PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4930\n\
4931The year, month and day arguments are required. tzinfo may be None, or an\n\
4932instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004933
Tim Petersa9bc1682003-01-11 03:39:11 +00004934static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004935 datetime_add, /* nb_add */
4936 datetime_subtract, /* nb_subtract */
4937 0, /* nb_multiply */
4938 0, /* nb_remainder */
4939 0, /* nb_divmod */
4940 0, /* nb_power */
4941 0, /* nb_negative */
4942 0, /* nb_positive */
4943 0, /* nb_absolute */
4944 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004945};
4946
Neal Norwitz227b5332006-03-22 09:28:35 +00004947static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004948 PyVarObject_HEAD_INIT(NULL, 0)
4949 "datetime.datetime", /* tp_name */
4950 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4951 0, /* tp_itemsize */
4952 (destructor)datetime_dealloc, /* tp_dealloc */
4953 0, /* tp_print */
4954 0, /* tp_getattr */
4955 0, /* tp_setattr */
4956 0, /* tp_reserved */
4957 (reprfunc)datetime_repr, /* tp_repr */
4958 &datetime_as_number, /* tp_as_number */
4959 0, /* tp_as_sequence */
4960 0, /* tp_as_mapping */
4961 (hashfunc)datetime_hash, /* tp_hash */
4962 0, /* tp_call */
4963 (reprfunc)datetime_str, /* tp_str */
4964 PyObject_GenericGetAttr, /* tp_getattro */
4965 0, /* tp_setattro */
4966 0, /* tp_as_buffer */
4967 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4968 datetime_doc, /* tp_doc */
4969 0, /* tp_traverse */
4970 0, /* tp_clear */
4971 datetime_richcompare, /* tp_richcompare */
4972 0, /* tp_weaklistoffset */
4973 0, /* tp_iter */
4974 0, /* tp_iternext */
4975 datetime_methods, /* tp_methods */
4976 0, /* tp_members */
4977 datetime_getset, /* tp_getset */
4978 &PyDateTime_DateType, /* tp_base */
4979 0, /* tp_dict */
4980 0, /* tp_descr_get */
4981 0, /* tp_descr_set */
4982 0, /* tp_dictoffset */
4983 0, /* tp_init */
4984 datetime_alloc, /* tp_alloc */
4985 datetime_new, /* tp_new */
4986 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004987};
4988
4989/* ---------------------------------------------------------------------------
4990 * Module methods and initialization.
4991 */
4992
4993static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004994 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004995};
4996
Tim Peters9ddf40b2004-06-20 22:41:32 +00004997/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4998 * datetime.h.
4999 */
5000static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005001 &PyDateTime_DateType,
5002 &PyDateTime_DateTimeType,
5003 &PyDateTime_TimeType,
5004 &PyDateTime_DeltaType,
5005 &PyDateTime_TZInfoType,
5006 new_date_ex,
5007 new_datetime_ex,
5008 new_time_ex,
5009 new_delta_ex,
5010 datetime_fromtimestamp,
5011 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005012};
5013
5014
Martin v. Löwis1a214512008-06-11 05:26:20 +00005015
5016static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005017 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005018 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005019 "Fast implementation of the datetime type.",
5020 -1,
5021 module_methods,
5022 NULL,
5023 NULL,
5024 NULL,
5025 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005026};
5027
Tim Peters2a799bf2002-12-16 20:18:38 +00005028PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005029PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005030{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005031 PyObject *m; /* a module object */
5032 PyObject *d; /* its dict */
5033 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005034 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005036 m = PyModule_Create(&datetimemodule);
5037 if (m == NULL)
5038 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005040 if (PyType_Ready(&PyDateTime_DateType) < 0)
5041 return NULL;
5042 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5043 return NULL;
5044 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5045 return NULL;
5046 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5047 return NULL;
5048 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5049 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005050 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5051 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005053 /* timedelta values */
5054 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005056 x = new_delta(0, 0, 1, 0);
5057 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5058 return NULL;
5059 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005061 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5062 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5063 return NULL;
5064 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005066 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5067 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5068 return NULL;
5069 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005071 /* date values */
5072 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005074 x = new_date(1, 1, 1);
5075 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5076 return NULL;
5077 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005079 x = new_date(MAXYEAR, 12, 31);
5080 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5081 return NULL;
5082 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005084 x = new_delta(1, 0, 0, 0);
5085 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5086 return NULL;
5087 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005089 /* time values */
5090 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005092 x = new_time(0, 0, 0, 0, Py_None);
5093 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5094 return NULL;
5095 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005097 x = new_time(23, 59, 59, 999999, Py_None);
5098 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5099 return NULL;
5100 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005102 x = new_delta(0, 0, 1, 0);
5103 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5104 return NULL;
5105 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005107 /* datetime values */
5108 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005110 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5111 if (x == NULL || PyDict_SetItemString(d, "min", 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 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5116 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5117 return NULL;
5118 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005120 x = new_delta(0, 0, 1, 0);
5121 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5122 return NULL;
5123 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005124
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005125 /* timezone values */
5126 d = PyDateTime_TimeZoneType.tp_dict;
5127
5128 delta = new_delta(0, 0, 0, 0);
5129 if (delta == NULL)
5130 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005131 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005132 Py_DECREF(delta);
5133 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5134 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005135 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005136
5137 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5138 if (delta == NULL)
5139 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005140 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005141 Py_DECREF(delta);
5142 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5143 return NULL;
5144 Py_DECREF(x);
5145
5146 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5147 if (delta == NULL)
5148 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005149 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005150 Py_DECREF(delta);
5151 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5152 return NULL;
5153 Py_DECREF(x);
5154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005155 /* module initialization */
5156 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5157 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005159 Py_INCREF(&PyDateTime_DateType);
5160 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005162 Py_INCREF(&PyDateTime_DateTimeType);
5163 PyModule_AddObject(m, "datetime",
5164 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005166 Py_INCREF(&PyDateTime_TimeType);
5167 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005169 Py_INCREF(&PyDateTime_DeltaType);
5170 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005172 Py_INCREF(&PyDateTime_TZInfoType);
5173 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005174
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005175 Py_INCREF(&PyDateTime_TimeZoneType);
5176 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005178 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5179 if (x == NULL)
5180 return NULL;
5181 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005183 /* A 4-year cycle has an extra leap day over what we'd get from
5184 * pasting together 4 single years.
5185 */
5186 assert(DI4Y == 4 * 365 + 1);
5187 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005189 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5190 * get from pasting together 4 100-year cycles.
5191 */
5192 assert(DI400Y == 4 * DI100Y + 1);
5193 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005195 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5196 * pasting together 25 4-year cycles.
5197 */
5198 assert(DI100Y == 25 * DI4Y - 1);
5199 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005201 us_per_us = PyLong_FromLong(1);
5202 us_per_ms = PyLong_FromLong(1000);
5203 us_per_second = PyLong_FromLong(1000000);
5204 us_per_minute = PyLong_FromLong(60000000);
5205 seconds_per_day = PyLong_FromLong(24 * 3600);
5206 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5207 us_per_minute == NULL || seconds_per_day == NULL)
5208 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005210 /* The rest are too big for 32-bit ints, but even
5211 * us_per_week fits in 40 bits, so doubles should be exact.
5212 */
5213 us_per_hour = PyLong_FromDouble(3600000000.0);
5214 us_per_day = PyLong_FromDouble(86400000000.0);
5215 us_per_week = PyLong_FromDouble(604800000000.0);
5216 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5217 return NULL;
5218 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005219}
Tim Petersf3615152003-01-01 21:51:37 +00005220
5221/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005222Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005223 x.n = x stripped of its timezone -- its naive time.
5224 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005225 return None
Tim Petersf3615152003-01-01 21:51:37 +00005226 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005227 return None
Tim Petersf3615152003-01-01 21:51:37 +00005228 x.s = x's standard offset, x.o - x.d
5229
5230Now some derived rules, where k is a duration (timedelta).
5231
52321. x.o = x.s + x.d
5233 This follows from the definition of x.s.
5234
Tim Petersc5dc4da2003-01-02 17:55:03 +000052352. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005236 This is actually a requirement, an assumption we need to make about
5237 sane tzinfo classes.
5238
52393. The naive UTC time corresponding to x is x.n - x.o.
5240 This is again a requirement for a sane tzinfo class.
5241
52424. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005243 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005244
Tim Petersc5dc4da2003-01-02 17:55:03 +000052455. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005246 Again follows from how arithmetic is defined.
5247
Tim Peters8bb5ad22003-01-24 02:44:45 +00005248Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005249(meaning that the various tzinfo methods exist, and don't blow up or return
5250None when called).
5251
Tim Petersa9bc1682003-01-11 03:39:11 +00005252The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005253x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005254
5255By #3, we want
5256
Tim Peters8bb5ad22003-01-24 02:44:45 +00005257 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005258
5259The algorithm starts by attaching tz to x.n, and calling that y. So
5260x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5261becomes true; in effect, we want to solve [2] for k:
5262
Tim Peters8bb5ad22003-01-24 02:44:45 +00005263 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005264
5265By #1, this is the same as
5266
Tim Peters8bb5ad22003-01-24 02:44:45 +00005267 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005268
5269By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5270Substituting that into [3],
5271
Tim Peters8bb5ad22003-01-24 02:44:45 +00005272 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5273 k - (y+k).s - (y+k).d = 0; rearranging,
5274 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5275 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005276
Tim Peters8bb5ad22003-01-24 02:44:45 +00005277On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5278approximate k by ignoring the (y+k).d term at first. Note that k can't be
5279very large, since all offset-returning methods return a duration of magnitude
5280less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5281be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005282
5283In any case, the new value is
5284
Tim Peters8bb5ad22003-01-24 02:44:45 +00005285 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005286
Tim Peters8bb5ad22003-01-24 02:44:45 +00005287It's helpful to step back at look at [4] from a higher level: it's simply
5288mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005289
5290At this point, if
5291
Tim Peters8bb5ad22003-01-24 02:44:45 +00005292 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005293
5294we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005295at the start of daylight time. Picture US Eastern for concreteness. The wall
5296time 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 +00005297sense then. The docs ask that an Eastern tzinfo class consider such a time to
5298be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5299on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005300the only spelling that makes sense on the local wall clock.
5301
Tim Petersc5dc4da2003-01-02 17:55:03 +00005302In fact, if [5] holds at this point, we do have the standard-time spelling,
5303but that takes a bit of proof. We first prove a stronger result. What's the
5304difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005305
Tim Peters8bb5ad22003-01-24 02:44:45 +00005306 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005307
Tim Petersc5dc4da2003-01-02 17:55:03 +00005308Now
5309 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005310 (y + y.s).n = by #5
5311 y.n + y.s = since y.n = x.n
5312 x.n + y.s = since z and y are have the same tzinfo member,
5313 y.s = z.s by #2
5314 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005315
Tim Petersc5dc4da2003-01-02 17:55:03 +00005316Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005317
Tim Petersc5dc4da2003-01-02 17:55:03 +00005318 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005319 x.n - ((x.n + z.s) - z.o) = expanding
5320 x.n - x.n - z.s + z.o = cancelling
5321 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005322 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005323
Tim Petersc5dc4da2003-01-02 17:55:03 +00005324So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005325
Tim Petersc5dc4da2003-01-02 17:55:03 +00005326If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005327spelling we wanted in the endcase described above. We're done. Contrarily,
5328if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005329
Tim Petersc5dc4da2003-01-02 17:55:03 +00005330If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5331add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005332local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005333
Tim Petersc5dc4da2003-01-02 17:55:03 +00005334Let
Tim Petersf3615152003-01-01 21:51:37 +00005335
Tim Peters4fede1a2003-01-04 00:26:59 +00005336 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005337
Tim Peters4fede1a2003-01-04 00:26:59 +00005338and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005339
Tim Peters8bb5ad22003-01-24 02:44:45 +00005340 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005341
Tim Peters8bb5ad22003-01-24 02:44:45 +00005342If so, we're done. If not, the tzinfo class is insane, according to the
5343assumptions we've made. This also requires a bit of proof. As before, let's
5344compute the difference between the LHS and RHS of [8] (and skipping some of
5345the justifications for the kinds of substitutions we've done several times
5346already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005347
Tim Peters8bb5ad22003-01-24 02:44:45 +00005348 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005349 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5350 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5351 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5352 - z.n + z.n - z.o + z'.o = cancel z.n
5353 - z.o + z'.o = #1 twice
5354 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5355 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005356
5357So 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 +00005358we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5359return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005360
Tim Peters8bb5ad22003-01-24 02:44:45 +00005361How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5362a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5363would have to change the result dst() returns: we start in DST, and moving
5364a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005365
Tim Peters8bb5ad22003-01-24 02:44:45 +00005366There isn't a sane case where this can happen. The closest it gets is at
5367the end of DST, where there's an hour in UTC with no spelling in a hybrid
5368tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5369that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5370UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5371time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5372clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5373standard time. Since that's what the local clock *does*, we want to map both
5374UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005375in local time, but so it goes -- it's the way the local clock works.
5376
Tim Peters8bb5ad22003-01-24 02:44:45 +00005377When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5378so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5379z' = 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 +00005380(correctly) concludes that z' is not UTC-equivalent to x.
5381
5382Because we know z.d said z was in daylight time (else [5] would have held and
5383we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005384and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005385return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5386but the reasoning doesn't depend on the example -- it depends on there being
5387two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005388z' must be in standard time, and is the spelling we want in this case.
5389
5390Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5391concerned (because it takes z' as being in standard time rather than the
5392daylight time we intend here), but returning it gives the real-life "local
5393clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5394tz.
5395
5396When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5397the 1:MM standard time spelling we want.
5398
5399So how can this break? One of the assumptions must be violated. Two
5400possibilities:
5401
54021) [2] effectively says that y.s is invariant across all y belong to a given
5403 time zone. This isn't true if, for political reasons or continental drift,
5404 a region decides to change its base offset from UTC.
5405
54062) There may be versions of "double daylight" time where the tail end of
5407 the analysis gives up a step too early. I haven't thought about that
5408 enough to say.
5409
5410In any case, it's clear that the default fromutc() is strong enough to handle
5411"almost all" time zones: so long as the standard offset is invariant, it
5412doesn't matter if daylight time transition points change from year to year, or
5413if daylight time is skipped in some years; it doesn't matter how large or
5414small dst() may get within its bounds; and it doesn't even matter if some
5415perverse time zone returns a negative dst()). So a breaking case must be
5416pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005417--------------------------------------------------------------------------- */