blob: 747be45246c9152f4c126bcc0390afba8fa7b733 [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 ')'. */
988 assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
989 temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
990 PyUnicode_GET_SIZE(repr) - 1);
991 Py_DECREF(repr);
992 if (temp == NULL)
993 return NULL;
994 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
995 Py_DECREF(temp);
996 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +0000997}
998
999/* ---------------------------------------------------------------------------
1000 * String format helpers.
1001 */
1002
1003static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001004format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 static const char *DayNames[] = {
1007 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1008 };
1009 static const char *MonthNames[] = {
1010 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1011 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1012 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1017 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1018 GET_DAY(date), hours, minutes, seconds,
1019 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001020}
1021
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001022static PyObject *delta_negative(PyDateTime_Delta *self);
1023
Tim Peters2a799bf2002-12-16 20:18:38 +00001024/* Add an hours & minutes UTC offset string to buf. buf has no more than
1025 * buflen bytes remaining. The UTC offset is gotten by calling
1026 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1027 * *buf, and that's all. Else the returned value is checked for sanity (an
1028 * integer in range), and if that's OK it's converted to an hours & minutes
1029 * string of the form
1030 * sign HH sep MM
1031 * Returns 0 if everything is OK. If the return value from utcoffset() is
1032 * bogus, an appropriate exception is set and -1 is returned.
1033 */
1034static int
Tim Peters328fff72002-12-20 01:31:27 +00001035format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001037{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001038 PyObject *offset;
1039 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001043
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001044 offset = call_utcoffset(tzinfo, tzinfoarg);
1045 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001047 if (offset == Py_None) {
1048 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 *buf = '\0';
1050 return 0;
1051 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001052 /* Offset is normalized, so it is negative if days < 0 */
1053 if (GET_TD_DAYS(offset) < 0) {
1054 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001056 offset = delta_negative((PyDateTime_Delta *)offset);
1057 Py_DECREF(temp);
1058 if (offset == NULL)
1059 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001061 else {
1062 sign = '+';
1063 }
1064 /* Offset is not negative here. */
1065 seconds = GET_TD_SECONDS(offset);
1066 Py_DECREF(offset);
1067 minutes = divmod(seconds, 60, &seconds);
1068 hours = divmod(minutes, 60, &minutes);
1069 assert(seconds == 0);
1070 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001074}
1075
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001076static PyObject *
1077make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 PyObject *temp;
1080 PyObject *tzinfo = get_tzinfo_member(object);
1081 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1082 if (Zreplacement == NULL)
1083 return NULL;
1084 if (tzinfo == Py_None || tzinfo == NULL)
1085 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 assert(tzinfoarg != NULL);
1088 temp = call_tzname(tzinfo, tzinfoarg);
1089 if (temp == NULL)
1090 goto Error;
1091 if (temp == Py_None) {
1092 Py_DECREF(temp);
1093 return Zreplacement;
1094 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 assert(PyUnicode_Check(temp));
1097 /* Since the tzname is getting stuffed into the
1098 * format, we have to double any % signs so that
1099 * strftime doesn't treat them as format codes.
1100 */
1101 Py_DECREF(Zreplacement);
1102 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1103 Py_DECREF(temp);
1104 if (Zreplacement == NULL)
1105 return NULL;
1106 if (!PyUnicode_Check(Zreplacement)) {
1107 PyErr_SetString(PyExc_TypeError,
1108 "tzname.replace() did not return a string");
1109 goto Error;
1110 }
1111 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001112
1113 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 Py_DECREF(Zreplacement);
1115 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001116}
1117
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001118static PyObject *
1119make_freplacement(PyObject *object)
1120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 char freplacement[64];
1122 if (PyTime_Check(object))
1123 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1124 else if (PyDateTime_Check(object))
1125 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1126 else
1127 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001130}
1131
Tim Peters2a799bf2002-12-16 20:18:38 +00001132/* I sure don't want to reproduce the strftime code from the time module,
1133 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001134 * giving special meanings to the %z, %Z and %f format codes via a
1135 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001136 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1137 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001138 */
1139static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001140wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1146 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1147 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 const char *pin; /* pointer to next char in input format */
1150 Py_ssize_t flen; /* length of input format */
1151 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 PyObject *newfmt = NULL; /* py string, the output format */
1154 char *pnew; /* pointer to available byte in output format */
1155 size_t totalnew; /* number bytes total in output format buffer,
1156 exclusive of trailing \0 */
1157 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 const char *ptoappend; /* ptr to string to append to output buffer */
1160 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 assert(object && format && timetuple);
1163 assert(PyUnicode_Check(format));
1164 /* Convert the input format to a C string and size */
1165 pin = _PyUnicode_AsStringAndSize(format, &flen);
1166 if (!pin)
1167 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 /* Scan the input format, looking for %z/%Z/%f escapes, building
1170 * a new format. Since computing the replacements for those codes
1171 * is expensive, don't unless they're actually used.
1172 */
1173 if (flen > INT_MAX - 1) {
1174 PyErr_NoMemory();
1175 goto Done;
1176 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 totalnew = flen + 1; /* realistic if no %z/%Z */
1179 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1180 if (newfmt == NULL) goto Done;
1181 pnew = PyBytes_AsString(newfmt);
1182 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 while ((ch = *pin++) != '\0') {
1185 if (ch != '%') {
1186 ptoappend = pin - 1;
1187 ntoappend = 1;
1188 }
1189 else if ((ch = *pin++) == '\0') {
1190 /* There's a lone trailing %; doesn't make sense. */
1191 PyErr_SetString(PyExc_ValueError, "strftime format "
1192 "ends with raw %");
1193 goto Done;
1194 }
1195 /* A % has been seen and ch is the character after it. */
1196 else if (ch == 'z') {
1197 if (zreplacement == NULL) {
1198 /* format utcoffset */
1199 char buf[100];
1200 PyObject *tzinfo = get_tzinfo_member(object);
1201 zreplacement = PyBytes_FromStringAndSize("", 0);
1202 if (zreplacement == NULL) goto Done;
1203 if (tzinfo != Py_None && tzinfo != NULL) {
1204 assert(tzinfoarg != NULL);
1205 if (format_utcoffset(buf,
1206 sizeof(buf),
1207 "",
1208 tzinfo,
1209 tzinfoarg) < 0)
1210 goto Done;
1211 Py_DECREF(zreplacement);
1212 zreplacement =
1213 PyBytes_FromStringAndSize(buf,
1214 strlen(buf));
1215 if (zreplacement == NULL)
1216 goto Done;
1217 }
1218 }
1219 assert(zreplacement != NULL);
1220 ptoappend = PyBytes_AS_STRING(zreplacement);
1221 ntoappend = PyBytes_GET_SIZE(zreplacement);
1222 }
1223 else if (ch == 'Z') {
1224 /* format tzname */
1225 if (Zreplacement == NULL) {
1226 Zreplacement = make_Zreplacement(object,
1227 tzinfoarg);
1228 if (Zreplacement == NULL)
1229 goto Done;
1230 }
1231 assert(Zreplacement != NULL);
1232 assert(PyUnicode_Check(Zreplacement));
1233 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1234 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001235 if (ptoappend == NULL)
1236 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 }
1238 else if (ch == 'f') {
1239 /* format microseconds */
1240 if (freplacement == NULL) {
1241 freplacement = make_freplacement(object);
1242 if (freplacement == NULL)
1243 goto Done;
1244 }
1245 assert(freplacement != NULL);
1246 assert(PyBytes_Check(freplacement));
1247 ptoappend = PyBytes_AS_STRING(freplacement);
1248 ntoappend = PyBytes_GET_SIZE(freplacement);
1249 }
1250 else {
1251 /* percent followed by neither z nor Z */
1252 ptoappend = pin - 2;
1253 ntoappend = 2;
1254 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 /* Append the ntoappend chars starting at ptoappend to
1257 * the new format.
1258 */
1259 if (ntoappend == 0)
1260 continue;
1261 assert(ptoappend != NULL);
1262 assert(ntoappend > 0);
1263 while (usednew + ntoappend > totalnew) {
1264 size_t bigger = totalnew << 1;
1265 if ((bigger >> 1) != totalnew) { /* overflow */
1266 PyErr_NoMemory();
1267 goto Done;
1268 }
1269 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1270 goto Done;
1271 totalnew = bigger;
1272 pnew = PyBytes_AsString(newfmt) + usednew;
1273 }
1274 memcpy(pnew, ptoappend, ntoappend);
1275 pnew += ntoappend;
1276 usednew += ntoappend;
1277 assert(usednew <= totalnew);
1278 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1281 goto Done;
1282 {
1283 PyObject *format;
1284 PyObject *time = PyImport_ImportModuleNoBlock("time");
1285 if (time == NULL)
1286 goto Done;
1287 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1288 if (format != NULL) {
1289 result = PyObject_CallMethod(time, "strftime", "OO",
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001290 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 Py_DECREF(format);
1292 }
1293 Py_DECREF(time);
1294 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001295 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 Py_XDECREF(freplacement);
1297 Py_XDECREF(zreplacement);
1298 Py_XDECREF(Zreplacement);
1299 Py_XDECREF(newfmt);
1300 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001301}
1302
Tim Peters2a799bf2002-12-16 20:18:38 +00001303/* ---------------------------------------------------------------------------
1304 * Wrap functions from the time module. These aren't directly available
1305 * from C. Perhaps they should be.
1306 */
1307
1308/* Call time.time() and return its result (a Python float). */
1309static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001310time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 PyObject *result = NULL;
1313 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 if (time != NULL) {
1316 result = PyObject_CallMethod(time, "time", "()");
1317 Py_DECREF(time);
1318 }
1319 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001320}
1321
1322/* Build a time.struct_time. The weekday and day number are automatically
1323 * computed from the y,m,d args.
1324 */
1325static PyObject *
1326build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 PyObject *time;
1329 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 time = PyImport_ImportModuleNoBlock("time");
1332 if (time != NULL) {
1333 result = PyObject_CallMethod(time, "struct_time",
1334 "((iiiiiiiii))",
1335 y, m, d,
1336 hh, mm, ss,
1337 weekday(y, m, d),
1338 days_before_month(y, m) + d,
1339 dstflag);
1340 Py_DECREF(time);
1341 }
1342 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001343}
1344
1345/* ---------------------------------------------------------------------------
1346 * Miscellaneous helpers.
1347 */
1348
Mark Dickinsone94c6792009-02-02 20:36:42 +00001349/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001350 * The comparisons here all most naturally compute a cmp()-like result.
1351 * This little helper turns that into a bool result for rich comparisons.
1352 */
1353static PyObject *
1354diff_to_bool(int diff, int op)
1355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 PyObject *result;
1357 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 switch (op) {
1360 case Py_EQ: istrue = diff == 0; break;
1361 case Py_NE: istrue = diff != 0; break;
1362 case Py_LE: istrue = diff <= 0; break;
1363 case Py_GE: istrue = diff >= 0; break;
1364 case Py_LT: istrue = diff < 0; break;
1365 case Py_GT: istrue = diff > 0; break;
1366 default:
1367 assert(! "op unknown");
1368 istrue = 0; /* To shut up compiler */
1369 }
1370 result = istrue ? Py_True : Py_False;
1371 Py_INCREF(result);
1372 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001373}
1374
Tim Peters07534a62003-02-07 22:50:28 +00001375/* Raises a "can't compare" TypeError and returns NULL. */
1376static PyObject *
1377cmperror(PyObject *a, PyObject *b)
1378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 PyErr_Format(PyExc_TypeError,
1380 "can't compare %s to %s",
1381 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1382 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001383}
1384
Tim Peters2a799bf2002-12-16 20:18:38 +00001385/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001386 * Cached Python objects; these are set by the module init function.
1387 */
1388
1389/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390static PyObject *us_per_us = NULL; /* 1 */
1391static PyObject *us_per_ms = NULL; /* 1000 */
1392static PyObject *us_per_second = NULL; /* 1000000 */
1393static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1394static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1395static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1396static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001397static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1398
Tim Peters2a799bf2002-12-16 20:18:38 +00001399/* ---------------------------------------------------------------------------
1400 * Class implementations.
1401 */
1402
1403/*
1404 * PyDateTime_Delta implementation.
1405 */
1406
1407/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001409 * as a Python int or long.
1410 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1411 * due to ubiquitous overflow possibilities.
1412 */
1413static PyObject *
1414delta_to_microseconds(PyDateTime_Delta *self)
1415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 PyObject *x1 = NULL;
1417 PyObject *x2 = NULL;
1418 PyObject *x3 = NULL;
1419 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1422 if (x1 == NULL)
1423 goto Done;
1424 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1425 if (x2 == NULL)
1426 goto Done;
1427 Py_DECREF(x1);
1428 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 /* x2 has days in seconds */
1431 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1432 if (x1 == NULL)
1433 goto Done;
1434 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1435 if (x3 == NULL)
1436 goto Done;
1437 Py_DECREF(x1);
1438 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001439 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 /* x3 has days+seconds in seconds */
1442 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1443 if (x1 == NULL)
1444 goto Done;
1445 Py_DECREF(x3);
1446 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 /* x1 has days+seconds in us */
1449 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1450 if (x2 == NULL)
1451 goto Done;
1452 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001453
1454Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 Py_XDECREF(x1);
1456 Py_XDECREF(x2);
1457 Py_XDECREF(x3);
1458 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001459}
1460
1461/* Convert a number of us (as a Python int or long) to a timedelta.
1462 */
1463static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001464microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 int us;
1467 int s;
1468 int d;
1469 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 PyObject *tuple = NULL;
1472 PyObject *num = NULL;
1473 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 tuple = PyNumber_Divmod(pyus, us_per_second);
1476 if (tuple == NULL)
1477 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 num = PyTuple_GetItem(tuple, 1); /* us */
1480 if (num == NULL)
1481 goto Done;
1482 temp = PyLong_AsLong(num);
1483 num = NULL;
1484 if (temp == -1 && PyErr_Occurred())
1485 goto Done;
1486 assert(0 <= temp && temp < 1000000);
1487 us = (int)temp;
1488 if (us < 0) {
1489 /* The divisor was positive, so this must be an error. */
1490 assert(PyErr_Occurred());
1491 goto Done;
1492 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1495 if (num == NULL)
1496 goto Done;
1497 Py_INCREF(num);
1498 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 tuple = PyNumber_Divmod(num, seconds_per_day);
1501 if (tuple == NULL)
1502 goto Done;
1503 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 num = PyTuple_GetItem(tuple, 1); /* seconds */
1506 if (num == NULL)
1507 goto Done;
1508 temp = PyLong_AsLong(num);
1509 num = NULL;
1510 if (temp == -1 && PyErr_Occurred())
1511 goto Done;
1512 assert(0 <= temp && temp < 24*3600);
1513 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 if (s < 0) {
1516 /* The divisor was positive, so this must be an error. */
1517 assert(PyErr_Occurred());
1518 goto Done;
1519 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1522 if (num == NULL)
1523 goto Done;
1524 Py_INCREF(num);
1525 temp = PyLong_AsLong(num);
1526 if (temp == -1 && PyErr_Occurred())
1527 goto Done;
1528 d = (int)temp;
1529 if ((long)d != temp) {
1530 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1531 "large to fit in a C int");
1532 goto Done;
1533 }
1534 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001535
1536Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 Py_XDECREF(tuple);
1538 Py_XDECREF(num);
1539 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001540}
1541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542#define microseconds_to_delta(pymicros) \
1543 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001544
Tim Peters2a799bf2002-12-16 20:18:38 +00001545static PyObject *
1546multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 PyObject *pyus_in;
1549 PyObject *pyus_out;
1550 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 pyus_in = delta_to_microseconds(delta);
1553 if (pyus_in == NULL)
1554 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1557 Py_DECREF(pyus_in);
1558 if (pyus_out == NULL)
1559 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 result = microseconds_to_delta(pyus_out);
1562 Py_DECREF(pyus_out);
1563 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001564}
1565
1566static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001567multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1568{
1569 PyObject *result = NULL;
1570 PyObject *pyus_in = NULL, *temp, *pyus_out;
1571 PyObject *ratio = NULL;
1572
1573 pyus_in = delta_to_microseconds(delta);
1574 if (pyus_in == NULL)
1575 return NULL;
1576 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1577 if (ratio == NULL)
1578 goto error;
1579 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1580 Py_DECREF(pyus_in);
1581 pyus_in = NULL;
1582 if (temp == NULL)
1583 goto error;
1584 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1585 Py_DECREF(temp);
1586 if (pyus_out == NULL)
1587 goto error;
1588 result = microseconds_to_delta(pyus_out);
1589 Py_DECREF(pyus_out);
1590 error:
1591 Py_XDECREF(pyus_in);
1592 Py_XDECREF(ratio);
1593
1594 return result;
1595}
1596
1597static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001598divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 PyObject *pyus_in;
1601 PyObject *pyus_out;
1602 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 pyus_in = delta_to_microseconds(delta);
1605 if (pyus_in == NULL)
1606 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1609 Py_DECREF(pyus_in);
1610 if (pyus_out == NULL)
1611 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 result = microseconds_to_delta(pyus_out);
1614 Py_DECREF(pyus_out);
1615 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001616}
1617
1618static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001619divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyObject *pyus_left;
1622 PyObject *pyus_right;
1623 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 pyus_left = delta_to_microseconds(left);
1626 if (pyus_left == NULL)
1627 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 pyus_right = delta_to_microseconds(right);
1630 if (pyus_right == NULL) {
1631 Py_DECREF(pyus_left);
1632 return NULL;
1633 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1636 Py_DECREF(pyus_left);
1637 Py_DECREF(pyus_right);
1638 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001639}
1640
1641static PyObject *
1642truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 PyObject *pyus_left;
1645 PyObject *pyus_right;
1646 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 pyus_left = delta_to_microseconds(left);
1649 if (pyus_left == NULL)
1650 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 pyus_right = delta_to_microseconds(right);
1653 if (pyus_right == NULL) {
1654 Py_DECREF(pyus_left);
1655 return NULL;
1656 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1659 Py_DECREF(pyus_left);
1660 Py_DECREF(pyus_right);
1661 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001662}
1663
1664static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001665truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1666{
1667 PyObject *result = NULL;
1668 PyObject *pyus_in = NULL, *temp, *pyus_out;
1669 PyObject *ratio = NULL;
1670
1671 pyus_in = delta_to_microseconds(delta);
1672 if (pyus_in == NULL)
1673 return NULL;
1674 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1675 if (ratio == NULL)
1676 goto error;
1677 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1678 Py_DECREF(pyus_in);
1679 pyus_in = NULL;
1680 if (temp == NULL)
1681 goto error;
1682 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1683 Py_DECREF(temp);
1684 if (pyus_out == NULL)
1685 goto error;
1686 result = microseconds_to_delta(pyus_out);
1687 Py_DECREF(pyus_out);
1688 error:
1689 Py_XDECREF(pyus_in);
1690 Py_XDECREF(ratio);
1691
1692 return result;
1693}
1694
1695static PyObject *
1696truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1697{
1698 PyObject *result;
1699 PyObject *pyus_in, *pyus_out;
1700 pyus_in = delta_to_microseconds(delta);
1701 if (pyus_in == NULL)
1702 return NULL;
1703 pyus_out = divide_nearest(pyus_in, i);
1704 Py_DECREF(pyus_in);
1705 if (pyus_out == NULL)
1706 return NULL;
1707 result = microseconds_to_delta(pyus_out);
1708 Py_DECREF(pyus_out);
1709
1710 return result;
1711}
1712
1713static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001714delta_add(PyObject *left, PyObject *right)
1715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1719 /* delta + delta */
1720 /* The C-level additions can't overflow because of the
1721 * invariant bounds.
1722 */
1723 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1724 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1725 int microseconds = GET_TD_MICROSECONDS(left) +
1726 GET_TD_MICROSECONDS(right);
1727 result = new_delta(days, seconds, microseconds, 1);
1728 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 if (result == Py_NotImplemented)
1731 Py_INCREF(result);
1732 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001733}
1734
1735static PyObject *
1736delta_negative(PyDateTime_Delta *self)
1737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 return new_delta(-GET_TD_DAYS(self),
1739 -GET_TD_SECONDS(self),
1740 -GET_TD_MICROSECONDS(self),
1741 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001742}
1743
1744static PyObject *
1745delta_positive(PyDateTime_Delta *self)
1746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 /* Could optimize this (by returning self) if this isn't a
1748 * subclass -- but who uses unary + ? Approximately nobody.
1749 */
1750 return new_delta(GET_TD_DAYS(self),
1751 GET_TD_SECONDS(self),
1752 GET_TD_MICROSECONDS(self),
1753 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001754}
1755
1756static PyObject *
1757delta_abs(PyDateTime_Delta *self)
1758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 assert(GET_TD_MICROSECONDS(self) >= 0);
1762 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 if (GET_TD_DAYS(self) < 0)
1765 result = delta_negative(self);
1766 else
1767 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001770}
1771
1772static PyObject *
1773delta_subtract(PyObject *left, PyObject *right)
1774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1778 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001779 /* The C-level additions can't overflow because of the
1780 * invariant bounds.
1781 */
1782 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1783 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1784 int microseconds = GET_TD_MICROSECONDS(left) -
1785 GET_TD_MICROSECONDS(right);
1786 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 if (result == Py_NotImplemented)
1790 Py_INCREF(result);
1791 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001792}
1793
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001794static int
1795delta_cmp(PyObject *self, PyObject *other)
1796{
1797 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1798 if (diff == 0) {
1799 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1800 if (diff == 0)
1801 diff = GET_TD_MICROSECONDS(self) -
1802 GET_TD_MICROSECONDS(other);
1803 }
1804 return diff;
1805}
1806
Tim Peters2a799bf2002-12-16 20:18:38 +00001807static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001808delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001811 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 return diff_to_bool(diff, op);
1813 }
1814 else {
1815 Py_INCREF(Py_NotImplemented);
1816 return Py_NotImplemented;
1817 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001818}
1819
1820static PyObject *delta_getstate(PyDateTime_Delta *self);
1821
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001822static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001823delta_hash(PyDateTime_Delta *self)
1824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 if (self->hashcode == -1) {
1826 PyObject *temp = delta_getstate(self);
1827 if (temp != NULL) {
1828 self->hashcode = PyObject_Hash(temp);
1829 Py_DECREF(temp);
1830 }
1831 }
1832 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001833}
1834
1835static PyObject *
1836delta_multiply(PyObject *left, PyObject *right)
1837{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 if (PyDelta_Check(left)) {
1841 /* delta * ??? */
1842 if (PyLong_Check(right))
1843 result = multiply_int_timedelta(right,
1844 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001845 else if (PyFloat_Check(right))
1846 result = multiply_float_timedelta(right,
1847 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 }
1849 else if (PyLong_Check(left))
1850 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001851 (PyDateTime_Delta *) right);
1852 else if (PyFloat_Check(left))
1853 result = multiply_float_timedelta(left,
1854 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 if (result == Py_NotImplemented)
1857 Py_INCREF(result);
1858 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001859}
1860
1861static PyObject *
1862delta_divide(PyObject *left, PyObject *right)
1863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 if (PyDelta_Check(left)) {
1867 /* delta * ??? */
1868 if (PyLong_Check(right))
1869 result = divide_timedelta_int(
1870 (PyDateTime_Delta *)left,
1871 right);
1872 else if (PyDelta_Check(right))
1873 result = divide_timedelta_timedelta(
1874 (PyDateTime_Delta *)left,
1875 (PyDateTime_Delta *)right);
1876 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 if (result == Py_NotImplemented)
1879 Py_INCREF(result);
1880 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001881}
1882
Mark Dickinson7c186e22010-04-20 22:32:49 +00001883static PyObject *
1884delta_truedivide(PyObject *left, PyObject *right)
1885{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 if (PyDelta_Check(left)) {
1889 if (PyDelta_Check(right))
1890 result = truedivide_timedelta_timedelta(
1891 (PyDateTime_Delta *)left,
1892 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001893 else if (PyFloat_Check(right))
1894 result = truedivide_timedelta_float(
1895 (PyDateTime_Delta *)left, right);
1896 else if (PyLong_Check(right))
1897 result = truedivide_timedelta_int(
1898 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 if (result == Py_NotImplemented)
1902 Py_INCREF(result);
1903 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001904}
1905
1906static PyObject *
1907delta_remainder(PyObject *left, PyObject *right)
1908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 PyObject *pyus_left;
1910 PyObject *pyus_right;
1911 PyObject *pyus_remainder;
1912 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
1915 Py_INCREF(Py_NotImplemented);
1916 return Py_NotImplemented;
1917 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1920 if (pyus_left == NULL)
1921 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1924 if (pyus_right == NULL) {
1925 Py_DECREF(pyus_left);
1926 return NULL;
1927 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1930 Py_DECREF(pyus_left);
1931 Py_DECREF(pyus_right);
1932 if (pyus_remainder == NULL)
1933 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 remainder = microseconds_to_delta(pyus_remainder);
1936 Py_DECREF(pyus_remainder);
1937 if (remainder == NULL)
1938 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001941}
1942
1943static PyObject *
1944delta_divmod(PyObject *left, PyObject *right)
1945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 PyObject *pyus_left;
1947 PyObject *pyus_right;
1948 PyObject *divmod;
1949 PyObject *delta;
1950 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
1953 Py_INCREF(Py_NotImplemented);
1954 return Py_NotImplemented;
1955 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1958 if (pyus_left == NULL)
1959 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1962 if (pyus_right == NULL) {
1963 Py_DECREF(pyus_left);
1964 return NULL;
1965 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1968 Py_DECREF(pyus_left);
1969 Py_DECREF(pyus_right);
1970 if (divmod == NULL)
1971 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 assert(PyTuple_Size(divmod) == 2);
1974 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1975 if (delta == NULL) {
1976 Py_DECREF(divmod);
1977 return NULL;
1978 }
1979 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1980 Py_DECREF(delta);
1981 Py_DECREF(divmod);
1982 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001983}
1984
Tim Peters2a799bf2002-12-16 20:18:38 +00001985/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1986 * timedelta constructor. sofar is the # of microseconds accounted for
1987 * so far, and there are factor microseconds per current unit, the number
1988 * of which is given by num. num * factor is added to sofar in a
1989 * numerically careful way, and that's the result. Any fractional
1990 * microseconds left over (this can happen if num is a float type) are
1991 * added into *leftover.
1992 * Note that there are many ways this can give an error (NULL) return.
1993 */
1994static PyObject *
1995accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1996 double *leftover)
1997{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 PyObject *prod;
1999 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 if (PyLong_Check(num)) {
2004 prod = PyNumber_Multiply(num, factor);
2005 if (prod == NULL)
2006 return NULL;
2007 sum = PyNumber_Add(sofar, prod);
2008 Py_DECREF(prod);
2009 return sum;
2010 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 if (PyFloat_Check(num)) {
2013 double dnum;
2014 double fracpart;
2015 double intpart;
2016 PyObject *x;
2017 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 /* The Plan: decompose num into an integer part and a
2020 * fractional part, num = intpart + fracpart.
2021 * Then num * factor ==
2022 * intpart * factor + fracpart * factor
2023 * and the LHS can be computed exactly in long arithmetic.
2024 * The RHS is again broken into an int part and frac part.
2025 * and the frac part is added into *leftover.
2026 */
2027 dnum = PyFloat_AsDouble(num);
2028 if (dnum == -1.0 && PyErr_Occurred())
2029 return NULL;
2030 fracpart = modf(dnum, &intpart);
2031 x = PyLong_FromDouble(intpart);
2032 if (x == NULL)
2033 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 prod = PyNumber_Multiply(x, factor);
2036 Py_DECREF(x);
2037 if (prod == NULL)
2038 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 sum = PyNumber_Add(sofar, prod);
2041 Py_DECREF(prod);
2042 if (sum == NULL)
2043 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 if (fracpart == 0.0)
2046 return sum;
2047 /* So far we've lost no information. Dealing with the
2048 * fractional part requires float arithmetic, and may
2049 * lose a little info.
2050 */
2051 assert(PyLong_Check(factor));
2052 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002054 dnum *= fracpart;
2055 fracpart = modf(dnum, &intpart);
2056 x = PyLong_FromDouble(intpart);
2057 if (x == NULL) {
2058 Py_DECREF(sum);
2059 return NULL;
2060 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002062 y = PyNumber_Add(sum, x);
2063 Py_DECREF(sum);
2064 Py_DECREF(x);
2065 *leftover += fracpart;
2066 return y;
2067 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 PyErr_Format(PyExc_TypeError,
2070 "unsupported type for timedelta %s component: %s",
2071 tag, Py_TYPE(num)->tp_name);
2072 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002073}
2074
2075static PyObject *
2076delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002080 /* Argument objects. */
2081 PyObject *day = NULL;
2082 PyObject *second = NULL;
2083 PyObject *us = NULL;
2084 PyObject *ms = NULL;
2085 PyObject *minute = NULL;
2086 PyObject *hour = NULL;
2087 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 PyObject *x = NULL; /* running sum of microseconds */
2090 PyObject *y = NULL; /* temp sum of microseconds */
2091 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 static char *keywords[] = {
2094 "days", "seconds", "microseconds", "milliseconds",
2095 "minutes", "hours", "weeks", NULL
2096 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2099 keywords,
2100 &day, &second, &us,
2101 &ms, &minute, &hour, &week) == 0)
2102 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 x = PyLong_FromLong(0);
2105 if (x == NULL)
2106 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108#define CLEANUP \
2109 Py_DECREF(x); \
2110 x = y; \
2111 if (x == NULL) \
2112 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 if (us) {
2115 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2116 CLEANUP;
2117 }
2118 if (ms) {
2119 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2120 CLEANUP;
2121 }
2122 if (second) {
2123 y = accum("seconds", x, second, us_per_second, &leftover_us);
2124 CLEANUP;
2125 }
2126 if (minute) {
2127 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2128 CLEANUP;
2129 }
2130 if (hour) {
2131 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2132 CLEANUP;
2133 }
2134 if (day) {
2135 y = accum("days", x, day, us_per_day, &leftover_us);
2136 CLEANUP;
2137 }
2138 if (week) {
2139 y = accum("weeks", x, week, us_per_week, &leftover_us);
2140 CLEANUP;
2141 }
2142 if (leftover_us) {
2143 /* Round to nearest whole # of us, and add into x. */
2144 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2145 if (temp == NULL) {
2146 Py_DECREF(x);
2147 goto Done;
2148 }
2149 y = PyNumber_Add(x, temp);
2150 Py_DECREF(temp);
2151 CLEANUP;
2152 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002154 self = microseconds_to_delta_ex(x, type);
2155 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002156Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002158
2159#undef CLEANUP
2160}
2161
2162static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002163delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 return (GET_TD_DAYS(self) != 0
2166 || GET_TD_SECONDS(self) != 0
2167 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002168}
2169
2170static PyObject *
2171delta_repr(PyDateTime_Delta *self)
2172{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 if (GET_TD_MICROSECONDS(self) != 0)
2174 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2175 Py_TYPE(self)->tp_name,
2176 GET_TD_DAYS(self),
2177 GET_TD_SECONDS(self),
2178 GET_TD_MICROSECONDS(self));
2179 if (GET_TD_SECONDS(self) != 0)
2180 return PyUnicode_FromFormat("%s(%d, %d)",
2181 Py_TYPE(self)->tp_name,
2182 GET_TD_DAYS(self),
2183 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 return PyUnicode_FromFormat("%s(%d)",
2186 Py_TYPE(self)->tp_name,
2187 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002188}
2189
2190static PyObject *
2191delta_str(PyDateTime_Delta *self)
2192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 int us = GET_TD_MICROSECONDS(self);
2194 int seconds = GET_TD_SECONDS(self);
2195 int minutes = divmod(seconds, 60, &seconds);
2196 int hours = divmod(minutes, 60, &minutes);
2197 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 if (days) {
2200 if (us)
2201 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2202 days, (days == 1 || days == -1) ? "" : "s",
2203 hours, minutes, seconds, us);
2204 else
2205 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2206 days, (days == 1 || days == -1) ? "" : "s",
2207 hours, minutes, seconds);
2208 } else {
2209 if (us)
2210 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2211 hours, minutes, seconds, us);
2212 else
2213 return PyUnicode_FromFormat("%d:%02d:%02d",
2214 hours, minutes, seconds);
2215 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002216
Tim Peters2a799bf2002-12-16 20:18:38 +00002217}
2218
Tim Peters371935f2003-02-01 01:52:50 +00002219/* Pickle support, a simple use of __reduce__. */
2220
Tim Petersb57f8f02003-02-01 02:54:15 +00002221/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002222static PyObject *
2223delta_getstate(PyDateTime_Delta *self)
2224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 return Py_BuildValue("iii", GET_TD_DAYS(self),
2226 GET_TD_SECONDS(self),
2227 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002228}
2229
Tim Peters2a799bf2002-12-16 20:18:38 +00002230static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002231delta_total_seconds(PyObject *self)
2232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 PyObject *total_seconds;
2234 PyObject *total_microseconds;
2235 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2238 if (total_microseconds == NULL)
2239 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 one_million = PyLong_FromLong(1000000L);
2242 if (one_million == NULL) {
2243 Py_DECREF(total_microseconds);
2244 return NULL;
2245 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 Py_DECREF(total_microseconds);
2250 Py_DECREF(one_million);
2251 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002252}
2253
2254static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002255delta_reduce(PyDateTime_Delta* self)
2256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002258}
2259
2260#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2261
2262static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 {"days", T_INT, OFFSET(days), READONLY,
2265 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 {"seconds", T_INT, OFFSET(seconds), READONLY,
2268 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2271 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2272 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002273};
2274
2275static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2277 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2280 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002283};
2284
2285static char delta_doc[] =
2286PyDoc_STR("Difference between two datetime values.");
2287
2288static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 delta_add, /* nb_add */
2290 delta_subtract, /* nb_subtract */
2291 delta_multiply, /* nb_multiply */
2292 delta_remainder, /* nb_remainder */
2293 delta_divmod, /* nb_divmod */
2294 0, /* nb_power */
2295 (unaryfunc)delta_negative, /* nb_negative */
2296 (unaryfunc)delta_positive, /* nb_positive */
2297 (unaryfunc)delta_abs, /* nb_absolute */
2298 (inquiry)delta_bool, /* nb_bool */
2299 0, /*nb_invert*/
2300 0, /*nb_lshift*/
2301 0, /*nb_rshift*/
2302 0, /*nb_and*/
2303 0, /*nb_xor*/
2304 0, /*nb_or*/
2305 0, /*nb_int*/
2306 0, /*nb_reserved*/
2307 0, /*nb_float*/
2308 0, /*nb_inplace_add*/
2309 0, /*nb_inplace_subtract*/
2310 0, /*nb_inplace_multiply*/
2311 0, /*nb_inplace_remainder*/
2312 0, /*nb_inplace_power*/
2313 0, /*nb_inplace_lshift*/
2314 0, /*nb_inplace_rshift*/
2315 0, /*nb_inplace_and*/
2316 0, /*nb_inplace_xor*/
2317 0, /*nb_inplace_or*/
2318 delta_divide, /* nb_floor_divide */
2319 delta_truedivide, /* nb_true_divide */
2320 0, /* nb_inplace_floor_divide */
2321 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002322};
2323
2324static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 PyVarObject_HEAD_INIT(NULL, 0)
2326 "datetime.timedelta", /* tp_name */
2327 sizeof(PyDateTime_Delta), /* tp_basicsize */
2328 0, /* tp_itemsize */
2329 0, /* tp_dealloc */
2330 0, /* tp_print */
2331 0, /* tp_getattr */
2332 0, /* tp_setattr */
2333 0, /* tp_reserved */
2334 (reprfunc)delta_repr, /* tp_repr */
2335 &delta_as_number, /* tp_as_number */
2336 0, /* tp_as_sequence */
2337 0, /* tp_as_mapping */
2338 (hashfunc)delta_hash, /* tp_hash */
2339 0, /* tp_call */
2340 (reprfunc)delta_str, /* tp_str */
2341 PyObject_GenericGetAttr, /* tp_getattro */
2342 0, /* tp_setattro */
2343 0, /* tp_as_buffer */
2344 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2345 delta_doc, /* tp_doc */
2346 0, /* tp_traverse */
2347 0, /* tp_clear */
2348 delta_richcompare, /* tp_richcompare */
2349 0, /* tp_weaklistoffset */
2350 0, /* tp_iter */
2351 0, /* tp_iternext */
2352 delta_methods, /* tp_methods */
2353 delta_members, /* tp_members */
2354 0, /* tp_getset */
2355 0, /* tp_base */
2356 0, /* tp_dict */
2357 0, /* tp_descr_get */
2358 0, /* tp_descr_set */
2359 0, /* tp_dictoffset */
2360 0, /* tp_init */
2361 0, /* tp_alloc */
2362 delta_new, /* tp_new */
2363 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002364};
2365
2366/*
2367 * PyDateTime_Date implementation.
2368 */
2369
2370/* Accessor properties. */
2371
2372static PyObject *
2373date_year(PyDateTime_Date *self, void *unused)
2374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002376}
2377
2378static PyObject *
2379date_month(PyDateTime_Date *self, void *unused)
2380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002382}
2383
2384static PyObject *
2385date_day(PyDateTime_Date *self, void *unused)
2386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002388}
2389
2390static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 {"year", (getter)date_year},
2392 {"month", (getter)date_month},
2393 {"day", (getter)date_day},
2394 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002395};
2396
2397/* Constructors. */
2398
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002399static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002400
Tim Peters2a799bf2002-12-16 20:18:38 +00002401static PyObject *
2402date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 PyObject *self = NULL;
2405 PyObject *state;
2406 int year;
2407 int month;
2408 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 /* Check for invocation from pickle with __getstate__ state */
2411 if (PyTuple_GET_SIZE(args) == 1 &&
2412 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2413 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2414 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2415 {
2416 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2419 if (me != NULL) {
2420 char *pdata = PyBytes_AS_STRING(state);
2421 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2422 me->hashcode = -1;
2423 }
2424 return (PyObject *)me;
2425 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2428 &year, &month, &day)) {
2429 if (check_date_args(year, month, day) < 0)
2430 return NULL;
2431 self = new_date_ex(year, month, day, type);
2432 }
2433 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002434}
2435
2436/* Return new date from localtime(t). */
2437static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002438date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002440 struct tm *tm;
2441 time_t t;
2442 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 t = _PyTime_DoubleToTimet(ts);
2445 if (t == (time_t)-1 && PyErr_Occurred())
2446 return NULL;
2447 tm = localtime(&t);
2448 if (tm)
2449 result = PyObject_CallFunction(cls, "iii",
2450 tm->tm_year + 1900,
2451 tm->tm_mon + 1,
2452 tm->tm_mday);
2453 else
2454 PyErr_SetString(PyExc_ValueError,
2455 "timestamp out of range for "
2456 "platform localtime() function");
2457 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002458}
2459
2460/* Return new date from current time.
2461 * We say this is equivalent to fromtimestamp(time.time()), and the
2462 * only way to be sure of that is to *call* time.time(). That's not
2463 * generally the same as calling C's time.
2464 */
2465static PyObject *
2466date_today(PyObject *cls, PyObject *dummy)
2467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002468 PyObject *time;
2469 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 time = time_time();
2472 if (time == NULL)
2473 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 /* Note well: today() is a class method, so this may not call
2476 * date.fromtimestamp. For example, it may call
2477 * datetime.fromtimestamp. That's why we need all the accuracy
2478 * time.time() delivers; if someone were gonzo about optimization,
2479 * date.today() could get away with plain C time().
2480 */
2481 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2482 Py_DECREF(time);
2483 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002484}
2485
2486/* Return new date from given timestamp (Python timestamp -- a double). */
2487static PyObject *
2488date_fromtimestamp(PyObject *cls, PyObject *args)
2489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 double timestamp;
2491 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2494 result = date_local_from_time_t(cls, timestamp);
2495 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002496}
2497
2498/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2499 * the ordinal is out of range.
2500 */
2501static PyObject *
2502date_fromordinal(PyObject *cls, PyObject *args)
2503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 PyObject *result = NULL;
2505 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002507 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2508 int year;
2509 int month;
2510 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 if (ordinal < 1)
2513 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2514 ">= 1");
2515 else {
2516 ord_to_ymd(ordinal, &year, &month, &day);
2517 result = PyObject_CallFunction(cls, "iii",
2518 year, month, day);
2519 }
2520 }
2521 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002522}
2523
2524/*
2525 * Date arithmetic.
2526 */
2527
2528/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2529 * instead.
2530 */
2531static PyObject *
2532add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2533{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002534 PyObject *result = NULL;
2535 int year = GET_YEAR(date);
2536 int month = GET_MONTH(date);
2537 int deltadays = GET_TD_DAYS(delta);
2538 /* C-level overflow is impossible because |deltadays| < 1e9. */
2539 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002541 if (normalize_date(&year, &month, &day) >= 0)
2542 result = new_date(year, month, day);
2543 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002544}
2545
2546static PyObject *
2547date_add(PyObject *left, PyObject *right)
2548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002549 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2550 Py_INCREF(Py_NotImplemented);
2551 return Py_NotImplemented;
2552 }
2553 if (PyDate_Check(left)) {
2554 /* date + ??? */
2555 if (PyDelta_Check(right))
2556 /* date + delta */
2557 return add_date_timedelta((PyDateTime_Date *) left,
2558 (PyDateTime_Delta *) right,
2559 0);
2560 }
2561 else {
2562 /* ??? + date
2563 * 'right' must be one of us, or we wouldn't have been called
2564 */
2565 if (PyDelta_Check(left))
2566 /* delta + date */
2567 return add_date_timedelta((PyDateTime_Date *) right,
2568 (PyDateTime_Delta *) left,
2569 0);
2570 }
2571 Py_INCREF(Py_NotImplemented);
2572 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002573}
2574
2575static PyObject *
2576date_subtract(PyObject *left, PyObject *right)
2577{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2579 Py_INCREF(Py_NotImplemented);
2580 return Py_NotImplemented;
2581 }
2582 if (PyDate_Check(left)) {
2583 if (PyDate_Check(right)) {
2584 /* date - date */
2585 int left_ord = ymd_to_ord(GET_YEAR(left),
2586 GET_MONTH(left),
2587 GET_DAY(left));
2588 int right_ord = ymd_to_ord(GET_YEAR(right),
2589 GET_MONTH(right),
2590 GET_DAY(right));
2591 return new_delta(left_ord - right_ord, 0, 0, 0);
2592 }
2593 if (PyDelta_Check(right)) {
2594 /* date - delta */
2595 return add_date_timedelta((PyDateTime_Date *) left,
2596 (PyDateTime_Delta *) right,
2597 1);
2598 }
2599 }
2600 Py_INCREF(Py_NotImplemented);
2601 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002602}
2603
2604
2605/* Various ways to turn a date into a string. */
2606
2607static PyObject *
2608date_repr(PyDateTime_Date *self)
2609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002610 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2611 Py_TYPE(self)->tp_name,
2612 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002613}
2614
2615static PyObject *
2616date_isoformat(PyDateTime_Date *self)
2617{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002618 return PyUnicode_FromFormat("%04d-%02d-%02d",
2619 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002620}
2621
Tim Peterse2df5ff2003-05-02 18:39:55 +00002622/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002623static PyObject *
2624date_str(PyDateTime_Date *self)
2625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002626 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002627}
2628
2629
2630static PyObject *
2631date_ctime(PyDateTime_Date *self)
2632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002634}
2635
2636static PyObject *
2637date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 /* This method can be inherited, and needs to call the
2640 * timetuple() method appropriate to self's class.
2641 */
2642 PyObject *result;
2643 PyObject *tuple;
2644 PyObject *format;
2645 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002647 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2648 &format))
2649 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002651 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2652 if (tuple == NULL)
2653 return NULL;
2654 result = wrap_strftime((PyObject *)self, format, tuple,
2655 (PyObject *)self);
2656 Py_DECREF(tuple);
2657 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002658}
2659
Eric Smith1ba31142007-09-11 18:06:02 +00002660static PyObject *
2661date_format(PyDateTime_Date *self, PyObject *args)
2662{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002663 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002665 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2666 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002668 /* if the format is zero length, return str(self) */
2669 if (PyUnicode_GetSize(format) == 0)
2670 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002672 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002673}
2674
Tim Peters2a799bf2002-12-16 20:18:38 +00002675/* ISO methods. */
2676
2677static PyObject *
2678date_isoweekday(PyDateTime_Date *self)
2679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002680 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002682 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002683}
2684
2685static PyObject *
2686date_isocalendar(PyDateTime_Date *self)
2687{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002688 int year = GET_YEAR(self);
2689 int week1_monday = iso_week1_monday(year);
2690 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2691 int week;
2692 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002694 week = divmod(today - week1_monday, 7, &day);
2695 if (week < 0) {
2696 --year;
2697 week1_monday = iso_week1_monday(year);
2698 week = divmod(today - week1_monday, 7, &day);
2699 }
2700 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2701 ++year;
2702 week = 0;
2703 }
2704 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002705}
2706
2707/* Miscellaneous methods. */
2708
Tim Peters2a799bf2002-12-16 20:18:38 +00002709static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002710date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002711{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002712 if (PyDate_Check(other)) {
2713 int diff = memcmp(((PyDateTime_Date *)self)->data,
2714 ((PyDateTime_Date *)other)->data,
2715 _PyDateTime_DATE_DATASIZE);
2716 return diff_to_bool(diff, op);
2717 }
2718 else {
2719 Py_INCREF(Py_NotImplemented);
2720 return Py_NotImplemented;
2721 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002722}
2723
2724static PyObject *
2725date_timetuple(PyDateTime_Date *self)
2726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002727 return build_struct_time(GET_YEAR(self),
2728 GET_MONTH(self),
2729 GET_DAY(self),
2730 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002731}
2732
Tim Peters12bf3392002-12-24 05:41:27 +00002733static PyObject *
2734date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002736 PyObject *clone;
2737 PyObject *tuple;
2738 int year = GET_YEAR(self);
2739 int month = GET_MONTH(self);
2740 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002742 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2743 &year, &month, &day))
2744 return NULL;
2745 tuple = Py_BuildValue("iii", year, month, day);
2746 if (tuple == NULL)
2747 return NULL;
2748 clone = date_new(Py_TYPE(self), tuple, NULL);
2749 Py_DECREF(tuple);
2750 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002751}
2752
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002753/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002754 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002755*/
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002756static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002757generic_hash(unsigned char *data, int len)
2758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002759 register unsigned char *p;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002760 register Py_hash_t x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002762 p = (unsigned char *) data;
2763 x = *p << 7;
2764 while (--len >= 0)
2765 x = (1000003*x) ^ *p++;
2766 x ^= len;
2767 if (x == -1)
2768 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002770 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002771}
2772
2773
2774static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002775
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002776static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002777date_hash(PyDateTime_Date *self)
2778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002779 if (self->hashcode == -1)
2780 self->hashcode = generic_hash(
2781 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002783 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002784}
2785
2786static PyObject *
2787date_toordinal(PyDateTime_Date *self)
2788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002789 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2790 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002791}
2792
2793static PyObject *
2794date_weekday(PyDateTime_Date *self)
2795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002798 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002799}
2800
Tim Peters371935f2003-02-01 01:52:50 +00002801/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002802
Tim Petersb57f8f02003-02-01 02:54:15 +00002803/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002804static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002805date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002806{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002807 PyObject* field;
2808 field = PyBytes_FromStringAndSize((char*)self->data,
2809 _PyDateTime_DATE_DATASIZE);
2810 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002811}
2812
2813static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002814date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002815{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002816 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002817}
2818
2819static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002821 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002822
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002823 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2824 METH_CLASS,
2825 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2826 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002828 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2829 METH_CLASS,
2830 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2831 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002833 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2834 PyDoc_STR("Current date or datetime: same as "
2835 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002839 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2840 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002842 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2843 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2846 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002848 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2849 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2852 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2853 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002855 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2856 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002858 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2859 PyDoc_STR("Return the day of the week represented by the date.\n"
2860 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2863 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2864 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002866 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2867 PyDoc_STR("Return the day of the week represented by the date.\n"
2868 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002870 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2871 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002873 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2874 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002876 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002877};
2878
2879static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002880PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002881
2882static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002883 date_add, /* nb_add */
2884 date_subtract, /* nb_subtract */
2885 0, /* nb_multiply */
2886 0, /* nb_remainder */
2887 0, /* nb_divmod */
2888 0, /* nb_power */
2889 0, /* nb_negative */
2890 0, /* nb_positive */
2891 0, /* nb_absolute */
2892 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002893};
2894
2895static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002896 PyVarObject_HEAD_INIT(NULL, 0)
2897 "datetime.date", /* tp_name */
2898 sizeof(PyDateTime_Date), /* tp_basicsize */
2899 0, /* tp_itemsize */
2900 0, /* tp_dealloc */
2901 0, /* tp_print */
2902 0, /* tp_getattr */
2903 0, /* tp_setattr */
2904 0, /* tp_reserved */
2905 (reprfunc)date_repr, /* tp_repr */
2906 &date_as_number, /* tp_as_number */
2907 0, /* tp_as_sequence */
2908 0, /* tp_as_mapping */
2909 (hashfunc)date_hash, /* tp_hash */
2910 0, /* tp_call */
2911 (reprfunc)date_str, /* tp_str */
2912 PyObject_GenericGetAttr, /* tp_getattro */
2913 0, /* tp_setattro */
2914 0, /* tp_as_buffer */
2915 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2916 date_doc, /* tp_doc */
2917 0, /* tp_traverse */
2918 0, /* tp_clear */
2919 date_richcompare, /* tp_richcompare */
2920 0, /* tp_weaklistoffset */
2921 0, /* tp_iter */
2922 0, /* tp_iternext */
2923 date_methods, /* tp_methods */
2924 0, /* tp_members */
2925 date_getset, /* tp_getset */
2926 0, /* tp_base */
2927 0, /* tp_dict */
2928 0, /* tp_descr_get */
2929 0, /* tp_descr_set */
2930 0, /* tp_dictoffset */
2931 0, /* tp_init */
2932 0, /* tp_alloc */
2933 date_new, /* tp_new */
2934 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002935};
2936
2937/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002938 * PyDateTime_TZInfo implementation.
2939 */
2940
2941/* This is a pure abstract base class, so doesn't do anything beyond
2942 * raising NotImplemented exceptions. Real tzinfo classes need
2943 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002944 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002945 * be subclasses of this tzinfo class, which is easy and quick to check).
2946 *
2947 * Note: For reasons having to do with pickling of subclasses, we have
2948 * to allow tzinfo objects to be instantiated. This wasn't an issue
2949 * in the Python implementation (__init__() could raise NotImplementedError
2950 * there without ill effect), but doing so in the C implementation hit a
2951 * brick wall.
2952 */
2953
2954static PyObject *
2955tzinfo_nogo(const char* methodname)
2956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002957 PyErr_Format(PyExc_NotImplementedError,
2958 "a tzinfo subclass must implement %s()",
2959 methodname);
2960 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002961}
2962
2963/* Methods. A subclass must implement these. */
2964
Tim Peters52dcce22003-01-23 16:36:11 +00002965static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002966tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002968 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002969}
2970
Tim Peters52dcce22003-01-23 16:36:11 +00002971static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002972tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002974 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002975}
2976
Tim Peters52dcce22003-01-23 16:36:11 +00002977static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002978tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002980 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002981}
2982
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002983
2984static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2985 PyDateTime_Delta *delta,
2986 int factor);
2987static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2988static PyObject *datetime_dst(PyObject *self, PyObject *);
2989
Tim Peters52dcce22003-01-23 16:36:11 +00002990static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002991tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002992{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002993 PyObject *result = NULL;
2994 PyObject *off = NULL, *dst = NULL;
2995 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002996
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002997 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002998 PyErr_SetString(PyExc_TypeError,
2999 "fromutc: argument must be a datetime");
3000 return NULL;
3001 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003002 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003003 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3004 "is not self");
3005 return NULL;
3006 }
Tim Peters52dcce22003-01-23 16:36:11 +00003007
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003008 off = datetime_utcoffset(dt, NULL);
3009 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003010 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003011 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003012 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3013 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003014 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 }
Tim Peters52dcce22003-01-23 16:36:11 +00003016
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003017 dst = datetime_dst(dt, NULL);
3018 if (dst == NULL)
3019 goto Fail;
3020 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003021 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3022 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003023 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003024 }
Tim Peters52dcce22003-01-23 16:36:11 +00003025
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003026 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3027 if (delta == NULL)
3028 goto Fail;
3029 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003030 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003031 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003032
3033 Py_DECREF(dst);
3034 dst = call_dst(GET_DT_TZINFO(dt), result);
3035 if (dst == NULL)
3036 goto Fail;
3037 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003039 if (delta_bool(delta) != 0) {
3040 PyObject *temp = result;
3041 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3042 (PyDateTime_Delta *)dst, 1);
3043 Py_DECREF(temp);
3044 if (result == NULL)
3045 goto Fail;
3046 }
3047 Py_DECREF(delta);
3048 Py_DECREF(dst);
3049 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003050 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003051
3052Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003053 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3054 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003056 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003057Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003058 Py_XDECREF(off);
3059 Py_XDECREF(dst);
3060 Py_XDECREF(delta);
3061 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003063}
3064
Tim Peters2a799bf2002-12-16 20:18:38 +00003065/*
3066 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003067 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003068 */
3069
Guido van Rossum177e41a2003-01-30 22:06:23 +00003070static PyObject *
3071tzinfo_reduce(PyObject *self)
3072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003073 PyObject *args, *state, *tmp;
3074 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003076 tmp = PyTuple_New(0);
3077 if (tmp == NULL)
3078 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003080 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3081 if (getinitargs != NULL) {
3082 args = PyObject_CallObject(getinitargs, tmp);
3083 Py_DECREF(getinitargs);
3084 if (args == NULL) {
3085 Py_DECREF(tmp);
3086 return NULL;
3087 }
3088 }
3089 else {
3090 PyErr_Clear();
3091 args = tmp;
3092 Py_INCREF(args);
3093 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003095 getstate = PyObject_GetAttrString(self, "__getstate__");
3096 if (getstate != NULL) {
3097 state = PyObject_CallObject(getstate, tmp);
3098 Py_DECREF(getstate);
3099 if (state == NULL) {
3100 Py_DECREF(args);
3101 Py_DECREF(tmp);
3102 return NULL;
3103 }
3104 }
3105 else {
3106 PyObject **dictptr;
3107 PyErr_Clear();
3108 state = Py_None;
3109 dictptr = _PyObject_GetDictPtr(self);
3110 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3111 state = *dictptr;
3112 Py_INCREF(state);
3113 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003115 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003117 if (state == Py_None) {
3118 Py_DECREF(state);
3119 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3120 }
3121 else
3122 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003123}
Tim Peters2a799bf2002-12-16 20:18:38 +00003124
3125static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003127 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3128 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003130 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003131 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3132 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003134 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3135 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003137 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003138 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003140 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3141 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003144};
3145
3146static char tzinfo_doc[] =
3147PyDoc_STR("Abstract base class for time zone info objects.");
3148
Neal Norwitz227b5332006-03-22 09:28:35 +00003149static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003150 PyVarObject_HEAD_INIT(NULL, 0)
3151 "datetime.tzinfo", /* tp_name */
3152 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3153 0, /* tp_itemsize */
3154 0, /* tp_dealloc */
3155 0, /* tp_print */
3156 0, /* tp_getattr */
3157 0, /* tp_setattr */
3158 0, /* tp_reserved */
3159 0, /* tp_repr */
3160 0, /* tp_as_number */
3161 0, /* tp_as_sequence */
3162 0, /* tp_as_mapping */
3163 0, /* tp_hash */
3164 0, /* tp_call */
3165 0, /* tp_str */
3166 PyObject_GenericGetAttr, /* tp_getattro */
3167 0, /* tp_setattro */
3168 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003169 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003170 tzinfo_doc, /* tp_doc */
3171 0, /* tp_traverse */
3172 0, /* tp_clear */
3173 0, /* tp_richcompare */
3174 0, /* tp_weaklistoffset */
3175 0, /* tp_iter */
3176 0, /* tp_iternext */
3177 tzinfo_methods, /* tp_methods */
3178 0, /* tp_members */
3179 0, /* tp_getset */
3180 0, /* tp_base */
3181 0, /* tp_dict */
3182 0, /* tp_descr_get */
3183 0, /* tp_descr_set */
3184 0, /* tp_dictoffset */
3185 0, /* tp_init */
3186 0, /* tp_alloc */
3187 PyType_GenericNew, /* tp_new */
3188 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003189};
3190
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003191static char *timezone_kws[] = {"offset", "name", NULL};
3192
3193static PyObject *
3194timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3195{
3196 PyObject *offset;
3197 PyObject *name = NULL;
3198 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3199 &PyDateTime_DeltaType, &offset,
3200 &PyUnicode_Type, &name))
3201 return new_timezone(offset, name);
3202
3203 return NULL;
3204}
3205
3206static void
3207timezone_dealloc(PyDateTime_TimeZone *self)
3208{
3209 Py_CLEAR(self->offset);
3210 Py_CLEAR(self->name);
3211 Py_TYPE(self)->tp_free((PyObject *)self);
3212}
3213
3214static PyObject *
3215timezone_richcompare(PyDateTime_TimeZone *self,
3216 PyDateTime_TimeZone *other, int op)
3217{
3218 if (op != Py_EQ && op != Py_NE) {
3219 Py_INCREF(Py_NotImplemented);
3220 return Py_NotImplemented;
3221 }
3222 return delta_richcompare(self->offset, other->offset, op);
3223}
3224
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003225static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003226timezone_hash(PyDateTime_TimeZone *self)
3227{
3228 return delta_hash((PyDateTime_Delta *)self->offset);
3229}
3230
3231/* Check argument type passed to tzname, utcoffset, or dst methods.
3232 Returns 0 for good argument. Returns -1 and sets exception info
3233 otherwise.
3234 */
3235static int
3236_timezone_check_argument(PyObject *dt, const char *meth)
3237{
3238 if (dt == Py_None || PyDateTime_Check(dt))
3239 return 0;
3240 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3241 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3242 return -1;
3243}
3244
3245static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003246timezone_repr(PyDateTime_TimeZone *self)
3247{
3248 /* Note that although timezone is not subclassable, it is convenient
3249 to use Py_TYPE(self)->tp_name here. */
3250 const char *type_name = Py_TYPE(self)->tp_name;
3251
3252 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3253 return PyUnicode_FromFormat("%s.utc", type_name);
3254
3255 if (self->name == NULL)
3256 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3257
3258 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3259 self->name);
3260}
3261
3262
3263static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003264timezone_str(PyDateTime_TimeZone *self)
3265{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003266 int hours, minutes, seconds;
3267 PyObject *offset;
3268 char sign;
3269
3270 if (self->name != NULL) {
3271 Py_INCREF(self->name);
3272 return self->name;
3273 }
3274 /* Offset is normalized, so it is negative if days < 0 */
3275 if (GET_TD_DAYS(self->offset) < 0) {
3276 sign = '-';
3277 offset = delta_negative((PyDateTime_Delta *)self->offset);
3278 if (offset == NULL)
3279 return NULL;
3280 }
3281 else {
3282 sign = '+';
3283 offset = self->offset;
3284 Py_INCREF(offset);
3285 }
3286 /* Offset is not negative here. */
3287 seconds = GET_TD_SECONDS(offset);
3288 Py_DECREF(offset);
3289 minutes = divmod(seconds, 60, &seconds);
3290 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003291 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003292 assert(seconds == 0);
3293 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003294}
3295
3296static PyObject *
3297timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3298{
3299 if (_timezone_check_argument(dt, "tzname") == -1)
3300 return NULL;
3301
3302 return timezone_str(self);
3303}
3304
3305static PyObject *
3306timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3307{
3308 if (_timezone_check_argument(dt, "utcoffset") == -1)
3309 return NULL;
3310
3311 Py_INCREF(self->offset);
3312 return self->offset;
3313}
3314
3315static PyObject *
3316timezone_dst(PyObject *self, PyObject *dt)
3317{
3318 if (_timezone_check_argument(dt, "dst") == -1)
3319 return NULL;
3320
3321 Py_RETURN_NONE;
3322}
3323
3324static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003325timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3326{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003327 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003328 PyErr_SetString(PyExc_TypeError,
3329 "fromutc: argument must be a datetime");
3330 return NULL;
3331 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003332 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003333 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3334 "is not self");
3335 return NULL;
3336 }
3337
3338 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3339}
3340
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003341static PyObject *
3342timezone_getinitargs(PyDateTime_TimeZone *self)
3343{
3344 if (self->name == NULL)
3345 return Py_BuildValue("(O)", self->offset);
3346 return Py_BuildValue("(OO)", self->offset, self->name);
3347}
3348
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003349static PyMethodDef timezone_methods[] = {
3350 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3351 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003352 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003353
3354 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003355 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003356
3357 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003358 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003359
3360 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3361 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3362
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003363 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3364 PyDoc_STR("pickle support")},
3365
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003366 {NULL, NULL}
3367};
3368
3369static char timezone_doc[] =
3370PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3371
3372static PyTypeObject PyDateTime_TimeZoneType = {
3373 PyVarObject_HEAD_INIT(NULL, 0)
3374 "datetime.timezone", /* tp_name */
3375 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3376 0, /* tp_itemsize */
3377 (destructor)timezone_dealloc, /* tp_dealloc */
3378 0, /* tp_print */
3379 0, /* tp_getattr */
3380 0, /* tp_setattr */
3381 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003382 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003383 0, /* tp_as_number */
3384 0, /* tp_as_sequence */
3385 0, /* tp_as_mapping */
3386 (hashfunc)timezone_hash, /* tp_hash */
3387 0, /* tp_call */
3388 (reprfunc)timezone_str, /* tp_str */
3389 0, /* tp_getattro */
3390 0, /* tp_setattro */
3391 0, /* tp_as_buffer */
3392 Py_TPFLAGS_DEFAULT, /* tp_flags */
3393 timezone_doc, /* tp_doc */
3394 0, /* tp_traverse */
3395 0, /* tp_clear */
3396 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3397 0, /* tp_weaklistoffset */
3398 0, /* tp_iter */
3399 0, /* tp_iternext */
3400 timezone_methods, /* tp_methods */
3401 0, /* tp_members */
3402 0, /* tp_getset */
3403 &PyDateTime_TZInfoType, /* tp_base */
3404 0, /* tp_dict */
3405 0, /* tp_descr_get */
3406 0, /* tp_descr_set */
3407 0, /* tp_dictoffset */
3408 0, /* tp_init */
3409 0, /* tp_alloc */
3410 timezone_new, /* tp_new */
3411};
3412
Tim Peters2a799bf2002-12-16 20:18:38 +00003413/*
Tim Peters37f39822003-01-10 03:49:02 +00003414 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003415 */
3416
Tim Peters37f39822003-01-10 03:49:02 +00003417/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003418 */
3419
3420static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003421time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003423 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003424}
3425
Tim Peters37f39822003-01-10 03:49:02 +00003426static PyObject *
3427time_minute(PyDateTime_Time *self, void *unused)
3428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003429 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003430}
3431
3432/* The name time_second conflicted with some platform header file. */
3433static PyObject *
3434py_time_second(PyDateTime_Time *self, void *unused)
3435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003436 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003437}
3438
3439static PyObject *
3440time_microsecond(PyDateTime_Time *self, void *unused)
3441{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003442 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003443}
3444
3445static PyObject *
3446time_tzinfo(PyDateTime_Time *self, void *unused)
3447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003448 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3449 Py_INCREF(result);
3450 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003451}
3452
3453static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003454 {"hour", (getter)time_hour},
3455 {"minute", (getter)time_minute},
3456 {"second", (getter)py_time_second},
3457 {"microsecond", (getter)time_microsecond},
3458 {"tzinfo", (getter)time_tzinfo},
3459 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003460};
3461
3462/*
3463 * Constructors.
3464 */
3465
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003466static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003467 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003468
Tim Peters2a799bf2002-12-16 20:18:38 +00003469static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003470time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003472 PyObject *self = NULL;
3473 PyObject *state;
3474 int hour = 0;
3475 int minute = 0;
3476 int second = 0;
3477 int usecond = 0;
3478 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003480 /* Check for invocation from pickle with __getstate__ state */
3481 if (PyTuple_GET_SIZE(args) >= 1 &&
3482 PyTuple_GET_SIZE(args) <= 2 &&
3483 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3484 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3485 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3486 {
3487 PyDateTime_Time *me;
3488 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003490 if (PyTuple_GET_SIZE(args) == 2) {
3491 tzinfo = PyTuple_GET_ITEM(args, 1);
3492 if (check_tzinfo_subclass(tzinfo) < 0) {
3493 PyErr_SetString(PyExc_TypeError, "bad "
3494 "tzinfo state arg");
3495 return NULL;
3496 }
3497 }
3498 aware = (char)(tzinfo != Py_None);
3499 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3500 if (me != NULL) {
3501 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003503 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3504 me->hashcode = -1;
3505 me->hastzinfo = aware;
3506 if (aware) {
3507 Py_INCREF(tzinfo);
3508 me->tzinfo = tzinfo;
3509 }
3510 }
3511 return (PyObject *)me;
3512 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003514 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3515 &hour, &minute, &second, &usecond,
3516 &tzinfo)) {
3517 if (check_time_args(hour, minute, second, usecond) < 0)
3518 return NULL;
3519 if (check_tzinfo_subclass(tzinfo) < 0)
3520 return NULL;
3521 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3522 type);
3523 }
3524 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003525}
3526
3527/*
3528 * Destructor.
3529 */
3530
3531static void
Tim Peters37f39822003-01-10 03:49:02 +00003532time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003533{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003534 if (HASTZINFO(self)) {
3535 Py_XDECREF(self->tzinfo);
3536 }
3537 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003538}
3539
3540/*
Tim Peters855fe882002-12-22 03:43:39 +00003541 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003542 */
3543
Tim Peters2a799bf2002-12-16 20:18:38 +00003544/* These are all METH_NOARGS, so don't need to check the arglist. */
3545static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003546time_utcoffset(PyObject *self, PyObject *unused) {
3547 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003548}
3549
3550static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003551time_dst(PyObject *self, PyObject *unused) {
3552 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003553}
3554
3555static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003556time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003557 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003558}
3559
3560/*
Tim Peters37f39822003-01-10 03:49:02 +00003561 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003562 */
3563
3564static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003565time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003566{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003567 const char *type_name = Py_TYPE(self)->tp_name;
3568 int h = TIME_GET_HOUR(self);
3569 int m = TIME_GET_MINUTE(self);
3570 int s = TIME_GET_SECOND(self);
3571 int us = TIME_GET_MICROSECOND(self);
3572 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003574 if (us)
3575 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3576 type_name, h, m, s, us);
3577 else if (s)
3578 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3579 type_name, h, m, s);
3580 else
3581 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3582 if (result != NULL && HASTZINFO(self))
3583 result = append_keyword_tzinfo(result, self->tzinfo);
3584 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003585}
3586
Tim Peters37f39822003-01-10 03:49:02 +00003587static PyObject *
3588time_str(PyDateTime_Time *self)
3589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003590 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003591}
Tim Peters2a799bf2002-12-16 20:18:38 +00003592
3593static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003594time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003595{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003596 char buf[100];
3597 PyObject *result;
3598 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003600 if (us)
3601 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3602 TIME_GET_HOUR(self),
3603 TIME_GET_MINUTE(self),
3604 TIME_GET_SECOND(self),
3605 us);
3606 else
3607 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3608 TIME_GET_HOUR(self),
3609 TIME_GET_MINUTE(self),
3610 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003611
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003612 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003613 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003615 /* We need to append the UTC offset. */
3616 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3617 Py_None) < 0) {
3618 Py_DECREF(result);
3619 return NULL;
3620 }
3621 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3622 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003623}
3624
Tim Peters37f39822003-01-10 03:49:02 +00003625static PyObject *
3626time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003628 PyObject *result;
3629 PyObject *tuple;
3630 PyObject *format;
3631 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003633 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3634 &format))
3635 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003637 /* Python's strftime does insane things with the year part of the
3638 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003639 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003640 */
3641 tuple = Py_BuildValue("iiiiiiiii",
3642 1900, 1, 1, /* year, month, day */
3643 TIME_GET_HOUR(self),
3644 TIME_GET_MINUTE(self),
3645 TIME_GET_SECOND(self),
3646 0, 1, -1); /* weekday, daynum, dst */
3647 if (tuple == NULL)
3648 return NULL;
3649 assert(PyTuple_Size(tuple) == 9);
3650 result = wrap_strftime((PyObject *)self, format, tuple,
3651 Py_None);
3652 Py_DECREF(tuple);
3653 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003654}
Tim Peters2a799bf2002-12-16 20:18:38 +00003655
3656/*
3657 * Miscellaneous methods.
3658 */
3659
Tim Peters37f39822003-01-10 03:49:02 +00003660static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003661time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003662{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003663 PyObject *result = NULL;
3664 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003665 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003667 if (! PyTime_Check(other)) {
3668 Py_INCREF(Py_NotImplemented);
3669 return Py_NotImplemented;
3670 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003671
3672 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003673 diff = memcmp(((PyDateTime_Time *)self)->data,
3674 ((PyDateTime_Time *)other)->data,
3675 _PyDateTime_TIME_DATASIZE);
3676 return diff_to_bool(diff, op);
3677 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003678 offset1 = time_utcoffset(self, NULL);
3679 if (offset1 == NULL)
3680 return NULL;
3681 offset2 = time_utcoffset(other, NULL);
3682 if (offset2 == NULL)
3683 goto done;
3684 /* If they're both naive, or both aware and have the same offsets,
3685 * we get off cheap. Note that if they're both naive, offset1 ==
3686 * offset2 == Py_None at this point.
3687 */
3688 if ((offset1 == offset2) ||
3689 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3690 delta_cmp(offset1, offset2) == 0)) {
3691 diff = memcmp(((PyDateTime_Time *)self)->data,
3692 ((PyDateTime_Time *)other)->data,
3693 _PyDateTime_TIME_DATASIZE);
3694 result = diff_to_bool(diff, op);
3695 }
3696 /* The hard case: both aware with different UTC offsets */
3697 else if (offset1 != Py_None && offset2 != Py_None) {
3698 int offsecs1, offsecs2;
3699 assert(offset1 != offset2); /* else last "if" handled it */
3700 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3701 TIME_GET_MINUTE(self) * 60 +
3702 TIME_GET_SECOND(self) -
3703 GET_TD_DAYS(offset1) * 86400 -
3704 GET_TD_SECONDS(offset1);
3705 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3706 TIME_GET_MINUTE(other) * 60 +
3707 TIME_GET_SECOND(other) -
3708 GET_TD_DAYS(offset2) * 86400 -
3709 GET_TD_SECONDS(offset2);
3710 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003711 if (diff == 0)
3712 diff = TIME_GET_MICROSECOND(self) -
3713 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003714 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003715 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003716 else {
3717 PyErr_SetString(PyExc_TypeError,
3718 "can't compare offset-naive and "
3719 "offset-aware times");
3720 }
3721 done:
3722 Py_DECREF(offset1);
3723 Py_XDECREF(offset2);
3724 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003725}
3726
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003727static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003728time_hash(PyDateTime_Time *self)
3729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003730 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003731 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003732
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003733 offset = time_utcoffset((PyObject *)self, NULL);
3734
3735 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003736 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003738 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003739 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003740 self->hashcode = generic_hash(
3741 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003742 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003743 PyObject *temp1, *temp2;
3744 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003745 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003746 seconds = TIME_GET_HOUR(self) * 3600 +
3747 TIME_GET_MINUTE(self) * 60 +
3748 TIME_GET_SECOND(self);
3749 microseconds = TIME_GET_MICROSECOND(self);
3750 temp1 = new_delta(0, seconds, microseconds, 1);
3751 if (temp1 == NULL) {
3752 Py_DECREF(offset);
3753 return -1;
3754 }
3755 temp2 = delta_subtract(temp1, offset);
3756 Py_DECREF(temp1);
3757 if (temp2 == NULL) {
3758 Py_DECREF(offset);
3759 return -1;
3760 }
3761 self->hashcode = PyObject_Hash(temp2);
3762 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003763 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003764 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003765 }
3766 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003767}
Tim Peters2a799bf2002-12-16 20:18:38 +00003768
Tim Peters12bf3392002-12-24 05:41:27 +00003769static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003770time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003772 PyObject *clone;
3773 PyObject *tuple;
3774 int hh = TIME_GET_HOUR(self);
3775 int mm = TIME_GET_MINUTE(self);
3776 int ss = TIME_GET_SECOND(self);
3777 int us = TIME_GET_MICROSECOND(self);
3778 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003780 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3781 time_kws,
3782 &hh, &mm, &ss, &us, &tzinfo))
3783 return NULL;
3784 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3785 if (tuple == NULL)
3786 return NULL;
3787 clone = time_new(Py_TYPE(self), tuple, NULL);
3788 Py_DECREF(tuple);
3789 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003790}
3791
Tim Peters2a799bf2002-12-16 20:18:38 +00003792static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003793time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003794{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003795 PyObject *offset, *tzinfo;
3796 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003798 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3799 /* Since utcoffset is in whole minutes, nothing can
3800 * alter the conclusion that this is nonzero.
3801 */
3802 return 1;
3803 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003804 tzinfo = GET_TIME_TZINFO(self);
3805 if (tzinfo != Py_None) {
3806 offset = call_utcoffset(tzinfo, Py_None);
3807 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003808 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003809 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3810 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003811 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003812 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003813}
3814
Tim Peters371935f2003-02-01 01:52:50 +00003815/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003816
Tim Peters33e0f382003-01-10 02:05:14 +00003817/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003818 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3819 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003820 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003821 */
3822static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003823time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003825 PyObject *basestate;
3826 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003828 basestate = PyBytes_FromStringAndSize((char *)self->data,
3829 _PyDateTime_TIME_DATASIZE);
3830 if (basestate != NULL) {
3831 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3832 result = PyTuple_Pack(1, basestate);
3833 else
3834 result = PyTuple_Pack(2, basestate, self->tzinfo);
3835 Py_DECREF(basestate);
3836 }
3837 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003838}
3839
3840static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003841time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003842{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003843 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003844}
3845
Tim Peters37f39822003-01-10 03:49:02 +00003846static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003848 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3849 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3850 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003852 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3853 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003855 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3856 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3859 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003861 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3862 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003864 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3865 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003867 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3868 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003870 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3871 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003873 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003874};
3875
Tim Peters37f39822003-01-10 03:49:02 +00003876static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003877PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3878\n\
3879All arguments are optional. tzinfo may be None, or an instance of\n\
3880a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003881
Tim Peters37f39822003-01-10 03:49:02 +00003882static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 0, /* nb_add */
3884 0, /* nb_subtract */
3885 0, /* nb_multiply */
3886 0, /* nb_remainder */
3887 0, /* nb_divmod */
3888 0, /* nb_power */
3889 0, /* nb_negative */
3890 0, /* nb_positive */
3891 0, /* nb_absolute */
3892 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003893};
3894
Neal Norwitz227b5332006-03-22 09:28:35 +00003895static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003896 PyVarObject_HEAD_INIT(NULL, 0)
3897 "datetime.time", /* tp_name */
3898 sizeof(PyDateTime_Time), /* tp_basicsize */
3899 0, /* tp_itemsize */
3900 (destructor)time_dealloc, /* tp_dealloc */
3901 0, /* tp_print */
3902 0, /* tp_getattr */
3903 0, /* tp_setattr */
3904 0, /* tp_reserved */
3905 (reprfunc)time_repr, /* tp_repr */
3906 &time_as_number, /* tp_as_number */
3907 0, /* tp_as_sequence */
3908 0, /* tp_as_mapping */
3909 (hashfunc)time_hash, /* tp_hash */
3910 0, /* tp_call */
3911 (reprfunc)time_str, /* tp_str */
3912 PyObject_GenericGetAttr, /* tp_getattro */
3913 0, /* tp_setattro */
3914 0, /* tp_as_buffer */
3915 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3916 time_doc, /* tp_doc */
3917 0, /* tp_traverse */
3918 0, /* tp_clear */
3919 time_richcompare, /* tp_richcompare */
3920 0, /* tp_weaklistoffset */
3921 0, /* tp_iter */
3922 0, /* tp_iternext */
3923 time_methods, /* tp_methods */
3924 0, /* tp_members */
3925 time_getset, /* tp_getset */
3926 0, /* tp_base */
3927 0, /* tp_dict */
3928 0, /* tp_descr_get */
3929 0, /* tp_descr_set */
3930 0, /* tp_dictoffset */
3931 0, /* tp_init */
3932 time_alloc, /* tp_alloc */
3933 time_new, /* tp_new */
3934 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003935};
3936
3937/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003938 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003939 */
3940
Tim Petersa9bc1682003-01-11 03:39:11 +00003941/* Accessor properties. Properties for day, month, and year are inherited
3942 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003943 */
3944
3945static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003946datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003948 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003949}
3950
Tim Petersa9bc1682003-01-11 03:39:11 +00003951static PyObject *
3952datetime_minute(PyDateTime_DateTime *self, void *unused)
3953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003954 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003955}
3956
3957static PyObject *
3958datetime_second(PyDateTime_DateTime *self, void *unused)
3959{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003960 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003961}
3962
3963static PyObject *
3964datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3965{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003966 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003967}
3968
3969static PyObject *
3970datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003972 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3973 Py_INCREF(result);
3974 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003975}
3976
3977static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 {"hour", (getter)datetime_hour},
3979 {"minute", (getter)datetime_minute},
3980 {"second", (getter)datetime_second},
3981 {"microsecond", (getter)datetime_microsecond},
3982 {"tzinfo", (getter)datetime_tzinfo},
3983 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003984};
3985
3986/*
3987 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003988 */
3989
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003990static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003991 "year", "month", "day", "hour", "minute", "second",
3992 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003993};
3994
Tim Peters2a799bf2002-12-16 20:18:38 +00003995static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003996datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003997{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003998 PyObject *self = NULL;
3999 PyObject *state;
4000 int year;
4001 int month;
4002 int day;
4003 int hour = 0;
4004 int minute = 0;
4005 int second = 0;
4006 int usecond = 0;
4007 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004009 /* Check for invocation from pickle with __getstate__ state */
4010 if (PyTuple_GET_SIZE(args) >= 1 &&
4011 PyTuple_GET_SIZE(args) <= 2 &&
4012 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4013 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4014 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4015 {
4016 PyDateTime_DateTime *me;
4017 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004019 if (PyTuple_GET_SIZE(args) == 2) {
4020 tzinfo = PyTuple_GET_ITEM(args, 1);
4021 if (check_tzinfo_subclass(tzinfo) < 0) {
4022 PyErr_SetString(PyExc_TypeError, "bad "
4023 "tzinfo state arg");
4024 return NULL;
4025 }
4026 }
4027 aware = (char)(tzinfo != Py_None);
4028 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4029 if (me != NULL) {
4030 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004032 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4033 me->hashcode = -1;
4034 me->hastzinfo = aware;
4035 if (aware) {
4036 Py_INCREF(tzinfo);
4037 me->tzinfo = tzinfo;
4038 }
4039 }
4040 return (PyObject *)me;
4041 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004043 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4044 &year, &month, &day, &hour, &minute,
4045 &second, &usecond, &tzinfo)) {
4046 if (check_date_args(year, month, day) < 0)
4047 return NULL;
4048 if (check_time_args(hour, minute, second, usecond) < 0)
4049 return NULL;
4050 if (check_tzinfo_subclass(tzinfo) < 0)
4051 return NULL;
4052 self = new_datetime_ex(year, month, day,
4053 hour, minute, second, usecond,
4054 tzinfo, type);
4055 }
4056 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004057}
4058
Tim Petersa9bc1682003-01-11 03:39:11 +00004059/* TM_FUNC is the shared type of localtime() and gmtime(). */
4060typedef struct tm *(*TM_FUNC)(const time_t *timer);
4061
4062/* Internal helper.
4063 * Build datetime from a time_t and a distinct count of microseconds.
4064 * Pass localtime or gmtime for f, to control the interpretation of timet.
4065 */
4066static PyObject *
4067datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004068 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004069{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004070 struct tm *tm;
4071 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004073 tm = f(&timet);
4074 if (tm) {
4075 /* The platform localtime/gmtime may insert leap seconds,
4076 * indicated by tm->tm_sec > 59. We don't care about them,
4077 * except to the extent that passing them on to the datetime
4078 * constructor would raise ValueError for a reason that
4079 * made no sense to the user.
4080 */
4081 if (tm->tm_sec > 59)
4082 tm->tm_sec = 59;
4083 result = PyObject_CallFunction(cls, "iiiiiiiO",
4084 tm->tm_year + 1900,
4085 tm->tm_mon + 1,
4086 tm->tm_mday,
4087 tm->tm_hour,
4088 tm->tm_min,
4089 tm->tm_sec,
4090 us,
4091 tzinfo);
4092 }
4093 else
4094 PyErr_SetString(PyExc_ValueError,
4095 "timestamp out of range for "
4096 "platform localtime()/gmtime() function");
4097 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004098}
4099
4100/* Internal helper.
4101 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4102 * to control the interpretation of the timestamp. Since a double doesn't
4103 * have enough bits to cover a datetime's full range of precision, it's
4104 * better to call datetime_from_timet_and_us provided you have a way
4105 * to get that much precision (e.g., C time() isn't good enough).
4106 */
4107static PyObject *
4108datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004109 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004110{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004111 time_t timet;
4112 double fraction;
4113 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004115 timet = _PyTime_DoubleToTimet(timestamp);
4116 if (timet == (time_t)-1 && PyErr_Occurred())
4117 return NULL;
4118 fraction = timestamp - (double)timet;
4119 us = (int)round_to_long(fraction * 1e6);
4120 if (us < 0) {
4121 /* Truncation towards zero is not what we wanted
4122 for negative numbers (Python's mod semantics) */
4123 timet -= 1;
4124 us += 1000000;
4125 }
4126 /* If timestamp is less than one microsecond smaller than a
4127 * full second, round up. Otherwise, ValueErrors are raised
4128 * for some floats. */
4129 if (us == 1000000) {
4130 timet += 1;
4131 us = 0;
4132 }
4133 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004134}
4135
4136/* Internal helper.
4137 * Build most accurate possible datetime for current time. Pass localtime or
4138 * gmtime for f as appropriate.
4139 */
4140static PyObject *
4141datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4142{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004143 _PyTime_timeval t;
4144 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004145 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4146 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004147}
4148
Tim Peters2a799bf2002-12-16 20:18:38 +00004149/* Return best possible local time -- this isn't constrained by the
4150 * precision of a timestamp.
4151 */
4152static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004153datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004154{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004155 PyObject *self;
4156 PyObject *tzinfo = Py_None;
4157 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004159 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4160 &tzinfo))
4161 return NULL;
4162 if (check_tzinfo_subclass(tzinfo) < 0)
4163 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004165 self = datetime_best_possible(cls,
4166 tzinfo == Py_None ? localtime : gmtime,
4167 tzinfo);
4168 if (self != NULL && tzinfo != Py_None) {
4169 /* Convert UTC to tzinfo's zone. */
4170 PyObject *temp = self;
4171 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4172 Py_DECREF(temp);
4173 }
4174 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004175}
4176
Tim Petersa9bc1682003-01-11 03:39:11 +00004177/* Return best possible UTC time -- this isn't constrained by the
4178 * precision of a timestamp.
4179 */
4180static PyObject *
4181datetime_utcnow(PyObject *cls, PyObject *dummy)
4182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004184}
4185
Tim Peters2a799bf2002-12-16 20:18:38 +00004186/* Return new local datetime from timestamp (Python timestamp -- a double). */
4187static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004188datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004190 PyObject *self;
4191 double timestamp;
4192 PyObject *tzinfo = Py_None;
4193 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004195 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4196 keywords, &timestamp, &tzinfo))
4197 return NULL;
4198 if (check_tzinfo_subclass(tzinfo) < 0)
4199 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004201 self = datetime_from_timestamp(cls,
4202 tzinfo == Py_None ? localtime : gmtime,
4203 timestamp,
4204 tzinfo);
4205 if (self != NULL && tzinfo != Py_None) {
4206 /* Convert UTC to tzinfo's zone. */
4207 PyObject *temp = self;
4208 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4209 Py_DECREF(temp);
4210 }
4211 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004212}
4213
Tim Petersa9bc1682003-01-11 03:39:11 +00004214/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4215static PyObject *
4216datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004218 double timestamp;
4219 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004221 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4222 result = datetime_from_timestamp(cls, gmtime, timestamp,
4223 Py_None);
4224 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004225}
4226
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004227/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004228static PyObject *
4229datetime_strptime(PyObject *cls, PyObject *args)
4230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004231 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4235 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004236
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004237 if (module == NULL) {
4238 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004239 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004240 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004241 }
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004242 return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4243 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004244}
4245
Tim Petersa9bc1682003-01-11 03:39:11 +00004246/* Return new datetime from date/datetime and time arguments. */
4247static PyObject *
4248datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004250 static char *keywords[] = {"date", "time", NULL};
4251 PyObject *date;
4252 PyObject *time;
4253 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004255 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4256 &PyDateTime_DateType, &date,
4257 &PyDateTime_TimeType, &time)) {
4258 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004260 if (HASTZINFO(time))
4261 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4262 result = PyObject_CallFunction(cls, "iiiiiiiO",
4263 GET_YEAR(date),
4264 GET_MONTH(date),
4265 GET_DAY(date),
4266 TIME_GET_HOUR(time),
4267 TIME_GET_MINUTE(time),
4268 TIME_GET_SECOND(time),
4269 TIME_GET_MICROSECOND(time),
4270 tzinfo);
4271 }
4272 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004273}
Tim Peters2a799bf2002-12-16 20:18:38 +00004274
4275/*
4276 * Destructor.
4277 */
4278
4279static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004280datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004282 if (HASTZINFO(self)) {
4283 Py_XDECREF(self->tzinfo);
4284 }
4285 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004286}
4287
4288/*
4289 * Indirect access to tzinfo methods.
4290 */
4291
Tim Peters2a799bf2002-12-16 20:18:38 +00004292/* These are all METH_NOARGS, so don't need to check the arglist. */
4293static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004294datetime_utcoffset(PyObject *self, PyObject *unused) {
4295 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004296}
4297
4298static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004299datetime_dst(PyObject *self, PyObject *unused) {
4300 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004301}
4302
4303static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004304datetime_tzname(PyObject *self, PyObject *unused) {
4305 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004306}
4307
4308/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004309 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004310 */
4311
Tim Petersa9bc1682003-01-11 03:39:11 +00004312/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4313 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004314 */
4315static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004316add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004317 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004319 /* Note that the C-level additions can't overflow, because of
4320 * invariant bounds on the member values.
4321 */
4322 int year = GET_YEAR(date);
4323 int month = GET_MONTH(date);
4324 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4325 int hour = DATE_GET_HOUR(date);
4326 int minute = DATE_GET_MINUTE(date);
4327 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4328 int microsecond = DATE_GET_MICROSECOND(date) +
4329 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004331 assert(factor == 1 || factor == -1);
4332 if (normalize_datetime(&year, &month, &day,
4333 &hour, &minute, &second, &microsecond) < 0)
4334 return NULL;
4335 else
4336 return new_datetime(year, month, day,
4337 hour, minute, second, microsecond,
4338 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004339}
4340
4341static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004342datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004344 if (PyDateTime_Check(left)) {
4345 /* datetime + ??? */
4346 if (PyDelta_Check(right))
4347 /* datetime + delta */
4348 return add_datetime_timedelta(
4349 (PyDateTime_DateTime *)left,
4350 (PyDateTime_Delta *)right,
4351 1);
4352 }
4353 else if (PyDelta_Check(left)) {
4354 /* delta + datetime */
4355 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4356 (PyDateTime_Delta *) left,
4357 1);
4358 }
4359 Py_INCREF(Py_NotImplemented);
4360 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004361}
4362
4363static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004364datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004366 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004368 if (PyDateTime_Check(left)) {
4369 /* datetime - ??? */
4370 if (PyDateTime_Check(right)) {
4371 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004372 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004373 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004374
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004375 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4376 offset2 = offset1 = Py_None;
4377 Py_INCREF(offset1);
4378 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004379 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004380 else {
4381 offset1 = datetime_utcoffset(left, NULL);
4382 if (offset1 == NULL)
4383 return NULL;
4384 offset2 = datetime_utcoffset(right, NULL);
4385 if (offset2 == NULL) {
4386 Py_DECREF(offset1);
4387 return NULL;
4388 }
4389 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4390 PyErr_SetString(PyExc_TypeError,
4391 "can't subtract offset-naive and "
4392 "offset-aware datetimes");
4393 Py_DECREF(offset1);
4394 Py_DECREF(offset2);
4395 return NULL;
4396 }
4397 }
4398 if ((offset1 != offset2) &&
4399 delta_cmp(offset1, offset2) != 0) {
4400 offdiff = delta_subtract(offset1, offset2);
4401 if (offdiff == NULL) {
4402 Py_DECREF(offset1);
4403 Py_DECREF(offset2);
4404 return NULL;
4405 }
4406 }
4407 Py_DECREF(offset1);
4408 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004409 delta_d = ymd_to_ord(GET_YEAR(left),
4410 GET_MONTH(left),
4411 GET_DAY(left)) -
4412 ymd_to_ord(GET_YEAR(right),
4413 GET_MONTH(right),
4414 GET_DAY(right));
4415 /* These can't overflow, since the values are
4416 * normalized. At most this gives the number of
4417 * seconds in one day.
4418 */
4419 delta_s = (DATE_GET_HOUR(left) -
4420 DATE_GET_HOUR(right)) * 3600 +
4421 (DATE_GET_MINUTE(left) -
4422 DATE_GET_MINUTE(right)) * 60 +
4423 (DATE_GET_SECOND(left) -
4424 DATE_GET_SECOND(right));
4425 delta_us = DATE_GET_MICROSECOND(left) -
4426 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004427 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004428 if (offdiff != NULL) {
4429 PyObject *temp = result;
4430 result = delta_subtract(result, offdiff);
4431 Py_DECREF(temp);
4432 Py_DECREF(offdiff);
4433 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004434 }
4435 else if (PyDelta_Check(right)) {
4436 /* datetime - delta */
4437 result = add_datetime_timedelta(
4438 (PyDateTime_DateTime *)left,
4439 (PyDateTime_Delta *)right,
4440 -1);
4441 }
4442 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004444 if (result == Py_NotImplemented)
4445 Py_INCREF(result);
4446 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004447}
4448
4449/* Various ways to turn a datetime into a string. */
4450
4451static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004452datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004454 const char *type_name = Py_TYPE(self)->tp_name;
4455 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004457 if (DATE_GET_MICROSECOND(self)) {
4458 baserepr = PyUnicode_FromFormat(
4459 "%s(%d, %d, %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 DATE_GET_SECOND(self),
4464 DATE_GET_MICROSECOND(self));
4465 }
4466 else if (DATE_GET_SECOND(self)) {
4467 baserepr = PyUnicode_FromFormat(
4468 "%s(%d, %d, %d, %d, %d, %d)",
4469 type_name,
4470 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4471 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4472 DATE_GET_SECOND(self));
4473 }
4474 else {
4475 baserepr = PyUnicode_FromFormat(
4476 "%s(%d, %d, %d, %d, %d)",
4477 type_name,
4478 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4479 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4480 }
4481 if (baserepr == NULL || ! HASTZINFO(self))
4482 return baserepr;
4483 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004484}
4485
Tim Petersa9bc1682003-01-11 03:39:11 +00004486static PyObject *
4487datetime_str(PyDateTime_DateTime *self)
4488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004489 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004490}
Tim Peters2a799bf2002-12-16 20:18:38 +00004491
4492static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004493datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004495 int sep = 'T';
4496 static char *keywords[] = {"sep", NULL};
4497 char buffer[100];
4498 PyObject *result;
4499 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004501 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4502 return NULL;
4503 if (us)
4504 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4505 GET_YEAR(self), GET_MONTH(self),
4506 GET_DAY(self), (int)sep,
4507 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4508 DATE_GET_SECOND(self), us);
4509 else
4510 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4511 GET_YEAR(self), GET_MONTH(self),
4512 GET_DAY(self), (int)sep,
4513 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4514 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004516 if (!result || !HASTZINFO(self))
4517 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004519 /* We need to append the UTC offset. */
4520 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4521 (PyObject *)self) < 0) {
4522 Py_DECREF(result);
4523 return NULL;
4524 }
4525 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4526 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004527}
4528
Tim Petersa9bc1682003-01-11 03:39:11 +00004529static PyObject *
4530datetime_ctime(PyDateTime_DateTime *self)
4531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004532 return format_ctime((PyDateTime_Date *)self,
4533 DATE_GET_HOUR(self),
4534 DATE_GET_MINUTE(self),
4535 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004536}
4537
Tim Peters2a799bf2002-12-16 20:18:38 +00004538/* Miscellaneous methods. */
4539
Tim Petersa9bc1682003-01-11 03:39:11 +00004540static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004541datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004542{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004543 PyObject *result = NULL;
4544 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004545 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004547 if (! PyDateTime_Check(other)) {
4548 if (PyDate_Check(other)) {
4549 /* Prevent invocation of date_richcompare. We want to
4550 return NotImplemented here to give the other object
4551 a chance. But since DateTime is a subclass of
4552 Date, if the other object is a Date, it would
4553 compute an ordering based on the date part alone,
4554 and we don't want that. So force unequal or
4555 uncomparable here in that case. */
4556 if (op == Py_EQ)
4557 Py_RETURN_FALSE;
4558 if (op == Py_NE)
4559 Py_RETURN_TRUE;
4560 return cmperror(self, other);
4561 }
4562 Py_INCREF(Py_NotImplemented);
4563 return Py_NotImplemented;
4564 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004565
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004566 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004567 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4568 ((PyDateTime_DateTime *)other)->data,
4569 _PyDateTime_DATETIME_DATASIZE);
4570 return diff_to_bool(diff, op);
4571 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004572 offset1 = datetime_utcoffset(self, NULL);
4573 if (offset1 == NULL)
4574 return NULL;
4575 offset2 = datetime_utcoffset(other, NULL);
4576 if (offset2 == NULL)
4577 goto done;
4578 /* If they're both naive, or both aware and have the same offsets,
4579 * we get off cheap. Note that if they're both naive, offset1 ==
4580 * offset2 == Py_None at this point.
4581 */
4582 if ((offset1 == offset2) ||
4583 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4584 delta_cmp(offset1, offset2) == 0)) {
4585 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4586 ((PyDateTime_DateTime *)other)->data,
4587 _PyDateTime_DATETIME_DATASIZE);
4588 result = diff_to_bool(diff, op);
4589 }
4590 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004591 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004592
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004593 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004594 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4595 other);
4596 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004597 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004598 diff = GET_TD_DAYS(delta);
4599 if (diff == 0)
4600 diff = GET_TD_SECONDS(delta) |
4601 GET_TD_MICROSECONDS(delta);
4602 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004603 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004604 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004605 else {
4606 PyErr_SetString(PyExc_TypeError,
4607 "can't compare offset-naive and "
4608 "offset-aware datetimes");
4609 }
4610 done:
4611 Py_DECREF(offset1);
4612 Py_XDECREF(offset2);
4613 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004614}
4615
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004616static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004617datetime_hash(PyDateTime_DateTime *self)
4618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004619 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004620 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004621
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004622 offset = datetime_utcoffset((PyObject *)self, NULL);
4623
4624 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004625 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004627 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004628 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004629 self->hashcode = generic_hash(
4630 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004632 PyObject *temp1, *temp2;
4633 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004635 assert(HASTZINFO(self));
4636 days = ymd_to_ord(GET_YEAR(self),
4637 GET_MONTH(self),
4638 GET_DAY(self));
4639 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004640 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004641 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004642 temp1 = new_delta(days, seconds,
4643 DATE_GET_MICROSECOND(self),
4644 1);
4645 if (temp1 == NULL) {
4646 Py_DECREF(offset);
4647 return -1;
4648 }
4649 temp2 = delta_subtract(temp1, offset);
4650 Py_DECREF(temp1);
4651 if (temp2 == NULL) {
4652 Py_DECREF(offset);
4653 return -1;
4654 }
4655 self->hashcode = PyObject_Hash(temp2);
4656 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004657 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004658 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004659 }
4660 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004661}
Tim Peters2a799bf2002-12-16 20:18:38 +00004662
4663static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004664datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004665{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004666 PyObject *clone;
4667 PyObject *tuple;
4668 int y = GET_YEAR(self);
4669 int m = GET_MONTH(self);
4670 int d = GET_DAY(self);
4671 int hh = DATE_GET_HOUR(self);
4672 int mm = DATE_GET_MINUTE(self);
4673 int ss = DATE_GET_SECOND(self);
4674 int us = DATE_GET_MICROSECOND(self);
4675 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004677 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4678 datetime_kws,
4679 &y, &m, &d, &hh, &mm, &ss, &us,
4680 &tzinfo))
4681 return NULL;
4682 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4683 if (tuple == NULL)
4684 return NULL;
4685 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4686 Py_DECREF(tuple);
4687 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004688}
4689
4690static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004691datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004692{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004693 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004694 PyObject *offset;
4695 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004696 PyObject *tzinfo;
4697 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004699 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4700 &PyDateTime_TZInfoType, &tzinfo))
4701 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004703 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4704 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004706 /* Conversion to self's own time zone is a NOP. */
4707 if (self->tzinfo == tzinfo) {
4708 Py_INCREF(self);
4709 return (PyObject *)self;
4710 }
Tim Peters521fc152002-12-31 17:36:56 +00004711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004712 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004713 offset = datetime_utcoffset((PyObject *)self, NULL);
4714 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004715 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004716 if (offset == Py_None) {
4717 Py_DECREF(offset);
4718 NeedAware:
4719 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4720 "a naive datetime");
4721 return NULL;
4722 }
Tim Petersf3615152003-01-01 21:51:37 +00004723
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004724 /* result = self - offset */
4725 result = add_datetime_timedelta(self,
4726 (PyDateTime_Delta *)offset, -1);
4727 Py_DECREF(offset);
4728 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004729 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004731 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004732 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4733 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4734 Py_INCREF(tzinfo);
4735 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004736
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004737 temp = result;
4738 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4739 Py_DECREF(temp);
4740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004741 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004742}
4743
4744static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004745datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004747 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004749 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004750 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004751
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004752 dst = call_dst(self->tzinfo, (PyObject *)self);
4753 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004754 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004755
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004756 if (dst != Py_None)
4757 dstflag = delta_bool((PyDateTime_Delta *)dst);
4758 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004759 }
4760 return build_struct_time(GET_YEAR(self),
4761 GET_MONTH(self),
4762 GET_DAY(self),
4763 DATE_GET_HOUR(self),
4764 DATE_GET_MINUTE(self),
4765 DATE_GET_SECOND(self),
4766 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004767}
4768
4769static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004770datetime_getdate(PyDateTime_DateTime *self)
4771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004772 return new_date(GET_YEAR(self),
4773 GET_MONTH(self),
4774 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004775}
4776
4777static PyObject *
4778datetime_gettime(PyDateTime_DateTime *self)
4779{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004780 return new_time(DATE_GET_HOUR(self),
4781 DATE_GET_MINUTE(self),
4782 DATE_GET_SECOND(self),
4783 DATE_GET_MICROSECOND(self),
4784 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004785}
4786
4787static PyObject *
4788datetime_gettimetz(PyDateTime_DateTime *self)
4789{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004790 return new_time(DATE_GET_HOUR(self),
4791 DATE_GET_MINUTE(self),
4792 DATE_GET_SECOND(self),
4793 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004794 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004795}
4796
4797static PyObject *
4798datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004799{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004800 int y, m, d, hh, mm, ss;
4801 PyObject *tzinfo;
4802 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004803
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004804 tzinfo = GET_DT_TZINFO(self);
4805 if (tzinfo == Py_None) {
4806 utcself = self;
4807 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004808 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004809 else {
4810 PyObject *offset;
4811 offset = call_utcoffset(tzinfo, (PyObject *)self);
4812 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004813 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004814 if (offset == Py_None) {
4815 Py_DECREF(offset);
4816 utcself = self;
4817 Py_INCREF(utcself);
4818 }
4819 else {
4820 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4821 (PyDateTime_Delta *)offset, -1);
4822 Py_DECREF(offset);
4823 if (utcself == NULL)
4824 return NULL;
4825 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004826 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004827 y = GET_YEAR(utcself);
4828 m = GET_MONTH(utcself);
4829 d = GET_DAY(utcself);
4830 hh = DATE_GET_HOUR(utcself);
4831 mm = DATE_GET_MINUTE(utcself);
4832 ss = DATE_GET_SECOND(utcself);
4833
4834 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004835 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004836}
4837
Tim Peters371935f2003-02-01 01:52:50 +00004838/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004839
Tim Petersa9bc1682003-01-11 03:39:11 +00004840/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004841 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4842 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004843 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004844 */
4845static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004846datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004848 PyObject *basestate;
4849 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004851 basestate = PyBytes_FromStringAndSize((char *)self->data,
4852 _PyDateTime_DATETIME_DATASIZE);
4853 if (basestate != NULL) {
4854 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4855 result = PyTuple_Pack(1, basestate);
4856 else
4857 result = PyTuple_Pack(2, basestate, self->tzinfo);
4858 Py_DECREF(basestate);
4859 }
4860 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004861}
4862
4863static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004864datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004866 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004867}
4868
Tim Petersa9bc1682003-01-11 03:39:11 +00004869static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004871 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004873 {"now", (PyCFunction)datetime_now,
4874 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4875 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004877 {"utcnow", (PyCFunction)datetime_utcnow,
4878 METH_NOARGS | METH_CLASS,
4879 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004881 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4882 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4883 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004885 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4886 METH_VARARGS | METH_CLASS,
4887 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4888 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 {"strptime", (PyCFunction)datetime_strptime,
4891 METH_VARARGS | METH_CLASS,
4892 PyDoc_STR("string, format -> new datetime parsed from a string "
4893 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004895 {"combine", (PyCFunction)datetime_combine,
4896 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4897 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004899 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004901 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4902 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004904 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4905 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004907 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4908 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004910 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4911 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004913 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4914 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004916 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4917 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004919 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4920 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4921 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4922 "sep is used to separate the year from the time, and "
4923 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004925 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4926 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004928 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4929 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004931 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4932 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4935 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004937 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4938 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004940 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4941 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004943 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004944};
4945
Tim Petersa9bc1682003-01-11 03:39:11 +00004946static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004947PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4948\n\
4949The year, month and day arguments are required. tzinfo may be None, or an\n\
4950instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004951
Tim Petersa9bc1682003-01-11 03:39:11 +00004952static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004953 datetime_add, /* nb_add */
4954 datetime_subtract, /* nb_subtract */
4955 0, /* nb_multiply */
4956 0, /* nb_remainder */
4957 0, /* nb_divmod */
4958 0, /* nb_power */
4959 0, /* nb_negative */
4960 0, /* nb_positive */
4961 0, /* nb_absolute */
4962 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004963};
4964
Neal Norwitz227b5332006-03-22 09:28:35 +00004965static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004966 PyVarObject_HEAD_INIT(NULL, 0)
4967 "datetime.datetime", /* tp_name */
4968 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4969 0, /* tp_itemsize */
4970 (destructor)datetime_dealloc, /* tp_dealloc */
4971 0, /* tp_print */
4972 0, /* tp_getattr */
4973 0, /* tp_setattr */
4974 0, /* tp_reserved */
4975 (reprfunc)datetime_repr, /* tp_repr */
4976 &datetime_as_number, /* tp_as_number */
4977 0, /* tp_as_sequence */
4978 0, /* tp_as_mapping */
4979 (hashfunc)datetime_hash, /* tp_hash */
4980 0, /* tp_call */
4981 (reprfunc)datetime_str, /* tp_str */
4982 PyObject_GenericGetAttr, /* tp_getattro */
4983 0, /* tp_setattro */
4984 0, /* tp_as_buffer */
4985 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4986 datetime_doc, /* tp_doc */
4987 0, /* tp_traverse */
4988 0, /* tp_clear */
4989 datetime_richcompare, /* tp_richcompare */
4990 0, /* tp_weaklistoffset */
4991 0, /* tp_iter */
4992 0, /* tp_iternext */
4993 datetime_methods, /* tp_methods */
4994 0, /* tp_members */
4995 datetime_getset, /* tp_getset */
4996 &PyDateTime_DateType, /* tp_base */
4997 0, /* tp_dict */
4998 0, /* tp_descr_get */
4999 0, /* tp_descr_set */
5000 0, /* tp_dictoffset */
5001 0, /* tp_init */
5002 datetime_alloc, /* tp_alloc */
5003 datetime_new, /* tp_new */
5004 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005005};
5006
5007/* ---------------------------------------------------------------------------
5008 * Module methods and initialization.
5009 */
5010
5011static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005012 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005013};
5014
Tim Peters9ddf40b2004-06-20 22:41:32 +00005015/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5016 * datetime.h.
5017 */
5018static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005019 &PyDateTime_DateType,
5020 &PyDateTime_DateTimeType,
5021 &PyDateTime_TimeType,
5022 &PyDateTime_DeltaType,
5023 &PyDateTime_TZInfoType,
5024 new_date_ex,
5025 new_datetime_ex,
5026 new_time_ex,
5027 new_delta_ex,
5028 datetime_fromtimestamp,
5029 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005030};
5031
5032
Martin v. Löwis1a214512008-06-11 05:26:20 +00005033
5034static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005036 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005037 "Fast implementation of the datetime type.",
5038 -1,
5039 module_methods,
5040 NULL,
5041 NULL,
5042 NULL,
5043 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005044};
5045
Tim Peters2a799bf2002-12-16 20:18:38 +00005046PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005047PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005048{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005049 PyObject *m; /* a module object */
5050 PyObject *d; /* its dict */
5051 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005052 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005054 m = PyModule_Create(&datetimemodule);
5055 if (m == NULL)
5056 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005058 if (PyType_Ready(&PyDateTime_DateType) < 0)
5059 return NULL;
5060 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5061 return NULL;
5062 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5063 return NULL;
5064 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5065 return NULL;
5066 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5067 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005068 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5069 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005071 /* timedelta values */
5072 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005074 x = new_delta(0, 0, 1, 0);
5075 if (x == NULL || PyDict_SetItemString(d, "resolution", 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_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5080 if (x == NULL || PyDict_SetItemString(d, "min", 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(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5085 if (x == NULL || PyDict_SetItemString(d, "max", 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 /* date values */
5090 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005092 x = new_date(1, 1, 1);
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_date(MAXYEAR, 12, 31);
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(1, 0, 0, 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 /* time values */
5108 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005110 x = new_time(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_time(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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005125 /* datetime values */
5126 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005128 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5129 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5130 return NULL;
5131 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005133 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5134 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5135 return NULL;
5136 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005138 x = new_delta(0, 0, 1, 0);
5139 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5140 return NULL;
5141 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005142
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005143 /* timezone values */
5144 d = PyDateTime_TimeZoneType.tp_dict;
5145
5146 delta = new_delta(0, 0, 0, 0);
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, "utc", x) < 0)
5152 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005153 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005154
5155 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5156 if (delta == NULL)
5157 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005158 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005159 Py_DECREF(delta);
5160 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5161 return NULL;
5162 Py_DECREF(x);
5163
5164 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5165 if (delta == NULL)
5166 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005167 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005168 Py_DECREF(delta);
5169 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5170 return NULL;
5171 Py_DECREF(x);
5172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005173 /* module initialization */
5174 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5175 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005177 Py_INCREF(&PyDateTime_DateType);
5178 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005180 Py_INCREF(&PyDateTime_DateTimeType);
5181 PyModule_AddObject(m, "datetime",
5182 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005184 Py_INCREF(&PyDateTime_TimeType);
5185 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005187 Py_INCREF(&PyDateTime_DeltaType);
5188 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005190 Py_INCREF(&PyDateTime_TZInfoType);
5191 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005192
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005193 Py_INCREF(&PyDateTime_TimeZoneType);
5194 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005196 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5197 if (x == NULL)
5198 return NULL;
5199 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005201 /* A 4-year cycle has an extra leap day over what we'd get from
5202 * pasting together 4 single years.
5203 */
5204 assert(DI4Y == 4 * 365 + 1);
5205 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005207 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5208 * get from pasting together 4 100-year cycles.
5209 */
5210 assert(DI400Y == 4 * DI100Y + 1);
5211 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005213 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5214 * pasting together 25 4-year cycles.
5215 */
5216 assert(DI100Y == 25 * DI4Y - 1);
5217 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005219 us_per_us = PyLong_FromLong(1);
5220 us_per_ms = PyLong_FromLong(1000);
5221 us_per_second = PyLong_FromLong(1000000);
5222 us_per_minute = PyLong_FromLong(60000000);
5223 seconds_per_day = PyLong_FromLong(24 * 3600);
5224 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5225 us_per_minute == NULL || seconds_per_day == NULL)
5226 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005228 /* The rest are too big for 32-bit ints, but even
5229 * us_per_week fits in 40 bits, so doubles should be exact.
5230 */
5231 us_per_hour = PyLong_FromDouble(3600000000.0);
5232 us_per_day = PyLong_FromDouble(86400000000.0);
5233 us_per_week = PyLong_FromDouble(604800000000.0);
5234 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5235 return NULL;
5236 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005237}
Tim Petersf3615152003-01-01 21:51:37 +00005238
5239/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005240Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005241 x.n = x stripped of its timezone -- its naive time.
5242 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 return None
Tim Petersf3615152003-01-01 21:51:37 +00005244 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005245 return None
Tim Petersf3615152003-01-01 21:51:37 +00005246 x.s = x's standard offset, x.o - x.d
5247
5248Now some derived rules, where k is a duration (timedelta).
5249
52501. x.o = x.s + x.d
5251 This follows from the definition of x.s.
5252
Tim Petersc5dc4da2003-01-02 17:55:03 +000052532. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005254 This is actually a requirement, an assumption we need to make about
5255 sane tzinfo classes.
5256
52573. The naive UTC time corresponding to x is x.n - x.o.
5258 This is again a requirement for a sane tzinfo class.
5259
52604. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005261 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005262
Tim Petersc5dc4da2003-01-02 17:55:03 +000052635. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005264 Again follows from how arithmetic is defined.
5265
Tim Peters8bb5ad22003-01-24 02:44:45 +00005266Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005267(meaning that the various tzinfo methods exist, and don't blow up or return
5268None when called).
5269
Tim Petersa9bc1682003-01-11 03:39:11 +00005270The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005271x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005272
5273By #3, we want
5274
Tim Peters8bb5ad22003-01-24 02:44:45 +00005275 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005276
5277The algorithm starts by attaching tz to x.n, and calling that y. So
5278x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5279becomes true; in effect, we want to solve [2] for k:
5280
Tim Peters8bb5ad22003-01-24 02:44:45 +00005281 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005282
5283By #1, this is the same as
5284
Tim Peters8bb5ad22003-01-24 02:44:45 +00005285 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005286
5287By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5288Substituting that into [3],
5289
Tim Peters8bb5ad22003-01-24 02:44:45 +00005290 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5291 k - (y+k).s - (y+k).d = 0; rearranging,
5292 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5293 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005294
Tim Peters8bb5ad22003-01-24 02:44:45 +00005295On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5296approximate k by ignoring the (y+k).d term at first. Note that k can't be
5297very large, since all offset-returning methods return a duration of magnitude
5298less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5299be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005300
5301In any case, the new value is
5302
Tim Peters8bb5ad22003-01-24 02:44:45 +00005303 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005304
Tim Peters8bb5ad22003-01-24 02:44:45 +00005305It's helpful to step back at look at [4] from a higher level: it's simply
5306mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005307
5308At this point, if
5309
Tim Peters8bb5ad22003-01-24 02:44:45 +00005310 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005311
5312we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005313at the start of daylight time. Picture US Eastern for concreteness. The wall
5314time 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 +00005315sense then. The docs ask that an Eastern tzinfo class consider such a time to
5316be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5317on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005318the only spelling that makes sense on the local wall clock.
5319
Tim Petersc5dc4da2003-01-02 17:55:03 +00005320In fact, if [5] holds at this point, we do have the standard-time spelling,
5321but that takes a bit of proof. We first prove a stronger result. What's the
5322difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005323
Tim Peters8bb5ad22003-01-24 02:44:45 +00005324 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005325
Tim Petersc5dc4da2003-01-02 17:55:03 +00005326Now
5327 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005328 (y + y.s).n = by #5
5329 y.n + y.s = since y.n = x.n
5330 x.n + y.s = since z and y are have the same tzinfo member,
5331 y.s = z.s by #2
5332 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005333
Tim Petersc5dc4da2003-01-02 17:55:03 +00005334Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005335
Tim Petersc5dc4da2003-01-02 17:55:03 +00005336 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005337 x.n - ((x.n + z.s) - z.o) = expanding
5338 x.n - x.n - z.s + z.o = cancelling
5339 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005340 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005341
Tim Petersc5dc4da2003-01-02 17:55:03 +00005342So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005343
Tim Petersc5dc4da2003-01-02 17:55:03 +00005344If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005345spelling we wanted in the endcase described above. We're done. Contrarily,
5346if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005347
Tim Petersc5dc4da2003-01-02 17:55:03 +00005348If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5349add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005350local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005351
Tim Petersc5dc4da2003-01-02 17:55:03 +00005352Let
Tim Petersf3615152003-01-01 21:51:37 +00005353
Tim Peters4fede1a2003-01-04 00:26:59 +00005354 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005355
Tim Peters4fede1a2003-01-04 00:26:59 +00005356and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005357
Tim Peters8bb5ad22003-01-24 02:44:45 +00005358 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005359
Tim Peters8bb5ad22003-01-24 02:44:45 +00005360If so, we're done. If not, the tzinfo class is insane, according to the
5361assumptions we've made. This also requires a bit of proof. As before, let's
5362compute the difference between the LHS and RHS of [8] (and skipping some of
5363the justifications for the kinds of substitutions we've done several times
5364already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005365
Tim Peters8bb5ad22003-01-24 02:44:45 +00005366 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005367 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5368 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5369 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5370 - z.n + z.n - z.o + z'.o = cancel z.n
5371 - z.o + z'.o = #1 twice
5372 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5373 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005374
5375So 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 +00005376we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5377return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005378
Tim Peters8bb5ad22003-01-24 02:44:45 +00005379How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5380a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5381would have to change the result dst() returns: we start in DST, and moving
5382a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005383
Tim Peters8bb5ad22003-01-24 02:44:45 +00005384There isn't a sane case where this can happen. The closest it gets is at
5385the end of DST, where there's an hour in UTC with no spelling in a hybrid
5386tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5387that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5388UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5389time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5390clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5391standard time. Since that's what the local clock *does*, we want to map both
5392UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005393in local time, but so it goes -- it's the way the local clock works.
5394
Tim Peters8bb5ad22003-01-24 02:44:45 +00005395When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5396so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5397z' = 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 +00005398(correctly) concludes that z' is not UTC-equivalent to x.
5399
5400Because we know z.d said z was in daylight time (else [5] would have held and
5401we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005402and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005403return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5404but the reasoning doesn't depend on the example -- it depends on there being
5405two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005406z' must be in standard time, and is the spelling we want in this case.
5407
5408Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5409concerned (because it takes z' as being in standard time rather than the
5410daylight time we intend here), but returning it gives the real-life "local
5411clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5412tz.
5413
5414When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5415the 1:MM standard time spelling we want.
5416
5417So how can this break? One of the assumptions must be violated. Two
5418possibilities:
5419
54201) [2] effectively says that y.s is invariant across all y belong to a given
5421 time zone. This isn't true if, for political reasons or continental drift,
5422 a region decides to change its base offset from UTC.
5423
54242) There may be versions of "double daylight" time where the tail end of
5425 the analysis gives up a step too early. I haven't thought about that
5426 enough to say.
5427
5428In any case, it's clear that the default fromutc() is strong enough to handle
5429"almost all" time zones: so long as the standard offset is invariant, it
5430doesn't matter if daylight time transition points change from year to year, or
5431if daylight time is skipped in some years; it doesn't matter how large or
5432small dst() may get within its bounds; and it doesn't even matter if some
5433perverse time zone returns a negative dst()). So a breaking case must be
5434pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005435--------------------------------------------------------------------------- */