blob: eb6998f0fa4a7647ce46e5eae70915c0633ba5de [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;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200949 _Py_identifier(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 assert(tzinfo != NULL);
952 assert(check_tzinfo_subclass(tzinfo) >= 0);
953 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000956 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000957
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200958 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000959
960 if (result == NULL || result == Py_None)
961 return result;
962
963 if (!PyUnicode_Check(result)) {
964 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
965 "return None or a string, not '%s'",
966 Py_TYPE(result)->tp_name);
967 Py_DECREF(result);
968 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000970
971 return result;
Tim Peters00237032002-12-27 02:21:51 +0000972}
973
Tim Peters2a799bf2002-12-16 20:18:38 +0000974/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
975 * stuff
976 * ", tzinfo=" + repr(tzinfo)
977 * before the closing ")".
978 */
979static PyObject *
980append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 assert(PyUnicode_Check(repr));
985 assert(tzinfo);
986 if (tzinfo == Py_None)
987 return repr;
988 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200989 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
990 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 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);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001082 _Py_identifier(replace);
1083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 if (Zreplacement == NULL)
1085 return NULL;
1086 if (tzinfo == Py_None || tzinfo == NULL)
1087 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 assert(tzinfoarg != NULL);
1090 temp = call_tzname(tzinfo, tzinfoarg);
1091 if (temp == NULL)
1092 goto Error;
1093 if (temp == Py_None) {
1094 Py_DECREF(temp);
1095 return Zreplacement;
1096 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 assert(PyUnicode_Check(temp));
1099 /* Since the tzname is getting stuffed into the
1100 * format, we have to double any % signs so that
1101 * strftime doesn't treat them as format codes.
1102 */
1103 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001104 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 Py_DECREF(temp);
1106 if (Zreplacement == NULL)
1107 return NULL;
1108 if (!PyUnicode_Check(Zreplacement)) {
1109 PyErr_SetString(PyExc_TypeError,
1110 "tzname.replace() did not return a string");
1111 goto Error;
1112 }
1113 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001114
1115 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 Py_DECREF(Zreplacement);
1117 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001118}
1119
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001120static PyObject *
1121make_freplacement(PyObject *object)
1122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 char freplacement[64];
1124 if (PyTime_Check(object))
1125 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1126 else if (PyDateTime_Check(object))
1127 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1128 else
1129 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001132}
1133
Tim Peters2a799bf2002-12-16 20:18:38 +00001134/* I sure don't want to reproduce the strftime code from the time module,
1135 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001136 * giving special meanings to the %z, %Z and %f format codes via a
1137 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001138 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1139 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001140 */
1141static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001142wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1148 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1149 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 const char *pin; /* pointer to next char in input format */
1152 Py_ssize_t flen; /* length of input format */
1153 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 PyObject *newfmt = NULL; /* py string, the output format */
1156 char *pnew; /* pointer to available byte in output format */
1157 size_t totalnew; /* number bytes total in output format buffer,
1158 exclusive of trailing \0 */
1159 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 const char *ptoappend; /* ptr to string to append to output buffer */
1162 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 assert(object && format && timetuple);
1165 assert(PyUnicode_Check(format));
1166 /* Convert the input format to a C string and size */
1167 pin = _PyUnicode_AsStringAndSize(format, &flen);
1168 if (!pin)
1169 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 /* Scan the input format, looking for %z/%Z/%f escapes, building
1172 * a new format. Since computing the replacements for those codes
1173 * is expensive, don't unless they're actually used.
1174 */
1175 if (flen > INT_MAX - 1) {
1176 PyErr_NoMemory();
1177 goto Done;
1178 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 totalnew = flen + 1; /* realistic if no %z/%Z */
1181 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1182 if (newfmt == NULL) goto Done;
1183 pnew = PyBytes_AsString(newfmt);
1184 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 while ((ch = *pin++) != '\0') {
1187 if (ch != '%') {
1188 ptoappend = pin - 1;
1189 ntoappend = 1;
1190 }
1191 else if ((ch = *pin++) == '\0') {
1192 /* There's a lone trailing %; doesn't make sense. */
1193 PyErr_SetString(PyExc_ValueError, "strftime format "
1194 "ends with raw %");
1195 goto Done;
1196 }
1197 /* A % has been seen and ch is the character after it. */
1198 else if (ch == 'z') {
1199 if (zreplacement == NULL) {
1200 /* format utcoffset */
1201 char buf[100];
1202 PyObject *tzinfo = get_tzinfo_member(object);
1203 zreplacement = PyBytes_FromStringAndSize("", 0);
1204 if (zreplacement == NULL) goto Done;
1205 if (tzinfo != Py_None && tzinfo != NULL) {
1206 assert(tzinfoarg != NULL);
1207 if (format_utcoffset(buf,
1208 sizeof(buf),
1209 "",
1210 tzinfo,
1211 tzinfoarg) < 0)
1212 goto Done;
1213 Py_DECREF(zreplacement);
1214 zreplacement =
1215 PyBytes_FromStringAndSize(buf,
1216 strlen(buf));
1217 if (zreplacement == NULL)
1218 goto Done;
1219 }
1220 }
1221 assert(zreplacement != NULL);
1222 ptoappend = PyBytes_AS_STRING(zreplacement);
1223 ntoappend = PyBytes_GET_SIZE(zreplacement);
1224 }
1225 else if (ch == 'Z') {
1226 /* format tzname */
1227 if (Zreplacement == NULL) {
1228 Zreplacement = make_Zreplacement(object,
1229 tzinfoarg);
1230 if (Zreplacement == NULL)
1231 goto Done;
1232 }
1233 assert(Zreplacement != NULL);
1234 assert(PyUnicode_Check(Zreplacement));
1235 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1236 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001237 if (ptoappend == NULL)
1238 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 }
1240 else if (ch == 'f') {
1241 /* format microseconds */
1242 if (freplacement == NULL) {
1243 freplacement = make_freplacement(object);
1244 if (freplacement == NULL)
1245 goto Done;
1246 }
1247 assert(freplacement != NULL);
1248 assert(PyBytes_Check(freplacement));
1249 ptoappend = PyBytes_AS_STRING(freplacement);
1250 ntoappend = PyBytes_GET_SIZE(freplacement);
1251 }
1252 else {
1253 /* percent followed by neither z nor Z */
1254 ptoappend = pin - 2;
1255 ntoappend = 2;
1256 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 /* Append the ntoappend chars starting at ptoappend to
1259 * the new format.
1260 */
1261 if (ntoappend == 0)
1262 continue;
1263 assert(ptoappend != NULL);
1264 assert(ntoappend > 0);
1265 while (usednew + ntoappend > totalnew) {
1266 size_t bigger = totalnew << 1;
1267 if ((bigger >> 1) != totalnew) { /* overflow */
1268 PyErr_NoMemory();
1269 goto Done;
1270 }
1271 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1272 goto Done;
1273 totalnew = bigger;
1274 pnew = PyBytes_AsString(newfmt) + usednew;
1275 }
1276 memcpy(pnew, ptoappend, ntoappend);
1277 pnew += ntoappend;
1278 usednew += ntoappend;
1279 assert(usednew <= totalnew);
1280 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1283 goto Done;
1284 {
1285 PyObject *format;
1286 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 if (time == NULL)
1289 goto Done;
1290 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1291 if (format != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001292 _Py_identifier(strftime);
1293
1294 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1295 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 Py_DECREF(format);
1297 }
1298 Py_DECREF(time);
1299 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001300 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 Py_XDECREF(freplacement);
1302 Py_XDECREF(zreplacement);
1303 Py_XDECREF(Zreplacement);
1304 Py_XDECREF(newfmt);
1305 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001306}
1307
Tim Peters2a799bf2002-12-16 20:18:38 +00001308/* ---------------------------------------------------------------------------
1309 * Wrap functions from the time module. These aren't directly available
1310 * from C. Perhaps they should be.
1311 */
1312
1313/* Call time.time() and return its result (a Python float). */
1314static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001315time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 PyObject *result = NULL;
1318 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 if (time != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001321 _Py_identifier(time);
1322
1323 result = _PyObject_CallMethodId(time, &PyId_time, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 Py_DECREF(time);
1325 }
1326 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001327}
1328
1329/* Build a time.struct_time. The weekday and day number are automatically
1330 * computed from the y,m,d args.
1331 */
1332static PyObject *
1333build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 PyObject *time;
1336 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 time = PyImport_ImportModuleNoBlock("time");
1339 if (time != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001340 _Py_identifier(struct_time);
1341
1342 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1343 "((iiiiiiiii))",
1344 y, m, d,
1345 hh, mm, ss,
1346 weekday(y, m, d),
1347 days_before_month(y, m) + d,
1348 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 Py_DECREF(time);
1350 }
1351 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001352}
1353
1354/* ---------------------------------------------------------------------------
1355 * Miscellaneous helpers.
1356 */
1357
Mark Dickinsone94c6792009-02-02 20:36:42 +00001358/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001359 * The comparisons here all most naturally compute a cmp()-like result.
1360 * This little helper turns that into a bool result for rich comparisons.
1361 */
1362static PyObject *
1363diff_to_bool(int diff, int op)
1364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 PyObject *result;
1366 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 switch (op) {
1369 case Py_EQ: istrue = diff == 0; break;
1370 case Py_NE: istrue = diff != 0; break;
1371 case Py_LE: istrue = diff <= 0; break;
1372 case Py_GE: istrue = diff >= 0; break;
1373 case Py_LT: istrue = diff < 0; break;
1374 case Py_GT: istrue = diff > 0; break;
1375 default:
1376 assert(! "op unknown");
1377 istrue = 0; /* To shut up compiler */
1378 }
1379 result = istrue ? Py_True : Py_False;
1380 Py_INCREF(result);
1381 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001382}
1383
Tim Peters07534a62003-02-07 22:50:28 +00001384/* Raises a "can't compare" TypeError and returns NULL. */
1385static PyObject *
1386cmperror(PyObject *a, PyObject *b)
1387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 PyErr_Format(PyExc_TypeError,
1389 "can't compare %s to %s",
1390 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1391 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001392}
1393
Tim Peters2a799bf2002-12-16 20:18:38 +00001394/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001395 * Cached Python objects; these are set by the module init function.
1396 */
1397
1398/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399static PyObject *us_per_us = NULL; /* 1 */
1400static PyObject *us_per_ms = NULL; /* 1000 */
1401static PyObject *us_per_second = NULL; /* 1000000 */
1402static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1403static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1404static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1405static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001406static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1407
Tim Peters2a799bf2002-12-16 20:18:38 +00001408/* ---------------------------------------------------------------------------
1409 * Class implementations.
1410 */
1411
1412/*
1413 * PyDateTime_Delta implementation.
1414 */
1415
1416/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001418 * as a Python int or long.
1419 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1420 * due to ubiquitous overflow possibilities.
1421 */
1422static PyObject *
1423delta_to_microseconds(PyDateTime_Delta *self)
1424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 PyObject *x1 = NULL;
1426 PyObject *x2 = NULL;
1427 PyObject *x3 = NULL;
1428 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1431 if (x1 == NULL)
1432 goto Done;
1433 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1434 if (x2 == NULL)
1435 goto Done;
1436 Py_DECREF(x1);
1437 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 /* x2 has days in seconds */
1440 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1441 if (x1 == NULL)
1442 goto Done;
1443 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1444 if (x3 == NULL)
1445 goto Done;
1446 Py_DECREF(x1);
1447 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001448 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 /* x3 has days+seconds in seconds */
1451 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1452 if (x1 == NULL)
1453 goto Done;
1454 Py_DECREF(x3);
1455 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 /* x1 has days+seconds in us */
1458 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1459 if (x2 == NULL)
1460 goto Done;
1461 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001462
1463Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 Py_XDECREF(x1);
1465 Py_XDECREF(x2);
1466 Py_XDECREF(x3);
1467 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001468}
1469
1470/* Convert a number of us (as a Python int or long) to a timedelta.
1471 */
1472static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001473microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 int us;
1476 int s;
1477 int d;
1478 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 PyObject *tuple = NULL;
1481 PyObject *num = NULL;
1482 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 tuple = PyNumber_Divmod(pyus, us_per_second);
1485 if (tuple == NULL)
1486 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 num = PyTuple_GetItem(tuple, 1); /* us */
1489 if (num == NULL)
1490 goto Done;
1491 temp = PyLong_AsLong(num);
1492 num = NULL;
1493 if (temp == -1 && PyErr_Occurred())
1494 goto Done;
1495 assert(0 <= temp && temp < 1000000);
1496 us = (int)temp;
1497 if (us < 0) {
1498 /* The divisor was positive, so this must be an error. */
1499 assert(PyErr_Occurred());
1500 goto Done;
1501 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1504 if (num == NULL)
1505 goto Done;
1506 Py_INCREF(num);
1507 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 tuple = PyNumber_Divmod(num, seconds_per_day);
1510 if (tuple == NULL)
1511 goto Done;
1512 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 num = PyTuple_GetItem(tuple, 1); /* seconds */
1515 if (num == NULL)
1516 goto Done;
1517 temp = PyLong_AsLong(num);
1518 num = NULL;
1519 if (temp == -1 && PyErr_Occurred())
1520 goto Done;
1521 assert(0 <= temp && temp < 24*3600);
1522 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 if (s < 0) {
1525 /* The divisor was positive, so this must be an error. */
1526 assert(PyErr_Occurred());
1527 goto Done;
1528 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1531 if (num == NULL)
1532 goto Done;
1533 Py_INCREF(num);
1534 temp = PyLong_AsLong(num);
1535 if (temp == -1 && PyErr_Occurred())
1536 goto Done;
1537 d = (int)temp;
1538 if ((long)d != temp) {
1539 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1540 "large to fit in a C int");
1541 goto Done;
1542 }
1543 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001544
1545Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 Py_XDECREF(tuple);
1547 Py_XDECREF(num);
1548 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001549}
1550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551#define microseconds_to_delta(pymicros) \
1552 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001553
Tim Peters2a799bf2002-12-16 20:18:38 +00001554static PyObject *
1555multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 PyObject *pyus_in;
1558 PyObject *pyus_out;
1559 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 pyus_in = delta_to_microseconds(delta);
1562 if (pyus_in == NULL)
1563 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1566 Py_DECREF(pyus_in);
1567 if (pyus_out == NULL)
1568 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 result = microseconds_to_delta(pyus_out);
1571 Py_DECREF(pyus_out);
1572 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001573}
1574
1575static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001576multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1577{
1578 PyObject *result = NULL;
1579 PyObject *pyus_in = NULL, *temp, *pyus_out;
1580 PyObject *ratio = NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001581 _Py_identifier(as_integer_ratio);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001582
1583 pyus_in = delta_to_microseconds(delta);
1584 if (pyus_in == NULL)
1585 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001586 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001587 if (ratio == NULL)
1588 goto error;
1589 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1590 Py_DECREF(pyus_in);
1591 pyus_in = NULL;
1592 if (temp == NULL)
1593 goto error;
1594 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1595 Py_DECREF(temp);
1596 if (pyus_out == NULL)
1597 goto error;
1598 result = microseconds_to_delta(pyus_out);
1599 Py_DECREF(pyus_out);
1600 error:
1601 Py_XDECREF(pyus_in);
1602 Py_XDECREF(ratio);
1603
1604 return result;
1605}
1606
1607static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001608divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 PyObject *pyus_in;
1611 PyObject *pyus_out;
1612 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 pyus_in = delta_to_microseconds(delta);
1615 if (pyus_in == NULL)
1616 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1619 Py_DECREF(pyus_in);
1620 if (pyus_out == NULL)
1621 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 result = microseconds_to_delta(pyus_out);
1624 Py_DECREF(pyus_out);
1625 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001626}
1627
1628static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001629divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 PyObject *pyus_left;
1632 PyObject *pyus_right;
1633 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 pyus_left = delta_to_microseconds(left);
1636 if (pyus_left == NULL)
1637 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 pyus_right = delta_to_microseconds(right);
1640 if (pyus_right == NULL) {
1641 Py_DECREF(pyus_left);
1642 return NULL;
1643 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1646 Py_DECREF(pyus_left);
1647 Py_DECREF(pyus_right);
1648 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001649}
1650
1651static PyObject *
1652truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 PyObject *pyus_left;
1655 PyObject *pyus_right;
1656 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 pyus_left = delta_to_microseconds(left);
1659 if (pyus_left == NULL)
1660 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 pyus_right = delta_to_microseconds(right);
1663 if (pyus_right == NULL) {
1664 Py_DECREF(pyus_left);
1665 return NULL;
1666 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1669 Py_DECREF(pyus_left);
1670 Py_DECREF(pyus_right);
1671 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001672}
1673
1674static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001675truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1676{
1677 PyObject *result = NULL;
1678 PyObject *pyus_in = NULL, *temp, *pyus_out;
1679 PyObject *ratio = NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001680 _Py_identifier(as_integer_ratio);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001681
1682 pyus_in = delta_to_microseconds(delta);
1683 if (pyus_in == NULL)
1684 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001685 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001686 if (ratio == NULL)
1687 goto error;
1688 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1689 Py_DECREF(pyus_in);
1690 pyus_in = NULL;
1691 if (temp == NULL)
1692 goto error;
1693 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1694 Py_DECREF(temp);
1695 if (pyus_out == NULL)
1696 goto error;
1697 result = microseconds_to_delta(pyus_out);
1698 Py_DECREF(pyus_out);
1699 error:
1700 Py_XDECREF(pyus_in);
1701 Py_XDECREF(ratio);
1702
1703 return result;
1704}
1705
1706static PyObject *
1707truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1708{
1709 PyObject *result;
1710 PyObject *pyus_in, *pyus_out;
1711 pyus_in = delta_to_microseconds(delta);
1712 if (pyus_in == NULL)
1713 return NULL;
1714 pyus_out = divide_nearest(pyus_in, i);
1715 Py_DECREF(pyus_in);
1716 if (pyus_out == NULL)
1717 return NULL;
1718 result = microseconds_to_delta(pyus_out);
1719 Py_DECREF(pyus_out);
1720
1721 return result;
1722}
1723
1724static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001725delta_add(PyObject *left, PyObject *right)
1726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1730 /* delta + delta */
1731 /* The C-level additions can't overflow because of the
1732 * invariant bounds.
1733 */
1734 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1735 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1736 int microseconds = GET_TD_MICROSECONDS(left) +
1737 GET_TD_MICROSECONDS(right);
1738 result = new_delta(days, seconds, microseconds, 1);
1739 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001741 if (result == Py_NotImplemented)
1742 Py_INCREF(result);
1743 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001744}
1745
1746static PyObject *
1747delta_negative(PyDateTime_Delta *self)
1748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 return new_delta(-GET_TD_DAYS(self),
1750 -GET_TD_SECONDS(self),
1751 -GET_TD_MICROSECONDS(self),
1752 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001753}
1754
1755static PyObject *
1756delta_positive(PyDateTime_Delta *self)
1757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 /* Could optimize this (by returning self) if this isn't a
1759 * subclass -- but who uses unary + ? Approximately nobody.
1760 */
1761 return new_delta(GET_TD_DAYS(self),
1762 GET_TD_SECONDS(self),
1763 GET_TD_MICROSECONDS(self),
1764 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001765}
1766
1767static PyObject *
1768delta_abs(PyDateTime_Delta *self)
1769{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 assert(GET_TD_MICROSECONDS(self) >= 0);
1773 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 if (GET_TD_DAYS(self) < 0)
1776 result = delta_negative(self);
1777 else
1778 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001781}
1782
1783static PyObject *
1784delta_subtract(PyObject *left, PyObject *right)
1785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1789 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001790 /* The C-level additions can't overflow because of the
1791 * invariant bounds.
1792 */
1793 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1794 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1795 int microseconds = GET_TD_MICROSECONDS(left) -
1796 GET_TD_MICROSECONDS(right);
1797 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 if (result == Py_NotImplemented)
1801 Py_INCREF(result);
1802 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001803}
1804
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001805static int
1806delta_cmp(PyObject *self, PyObject *other)
1807{
1808 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1809 if (diff == 0) {
1810 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1811 if (diff == 0)
1812 diff = GET_TD_MICROSECONDS(self) -
1813 GET_TD_MICROSECONDS(other);
1814 }
1815 return diff;
1816}
1817
Tim Peters2a799bf2002-12-16 20:18:38 +00001818static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001819delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001822 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 return diff_to_bool(diff, op);
1824 }
1825 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001826 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001828}
1829
1830static PyObject *delta_getstate(PyDateTime_Delta *self);
1831
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001832static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001833delta_hash(PyDateTime_Delta *self)
1834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 if (self->hashcode == -1) {
1836 PyObject *temp = delta_getstate(self);
1837 if (temp != NULL) {
1838 self->hashcode = PyObject_Hash(temp);
1839 Py_DECREF(temp);
1840 }
1841 }
1842 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001843}
1844
1845static PyObject *
1846delta_multiply(PyObject *left, PyObject *right)
1847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 if (PyDelta_Check(left)) {
1851 /* delta * ??? */
1852 if (PyLong_Check(right))
1853 result = multiply_int_timedelta(right,
1854 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001855 else if (PyFloat_Check(right))
1856 result = multiply_float_timedelta(right,
1857 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 }
1859 else if (PyLong_Check(left))
1860 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001861 (PyDateTime_Delta *) right);
1862 else if (PyFloat_Check(left))
1863 result = multiply_float_timedelta(left,
1864 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 if (result == Py_NotImplemented)
1867 Py_INCREF(result);
1868 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001869}
1870
1871static PyObject *
1872delta_divide(PyObject *left, PyObject *right)
1873{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 if (PyDelta_Check(left)) {
1877 /* delta * ??? */
1878 if (PyLong_Check(right))
1879 result = divide_timedelta_int(
1880 (PyDateTime_Delta *)left,
1881 right);
1882 else if (PyDelta_Check(right))
1883 result = divide_timedelta_timedelta(
1884 (PyDateTime_Delta *)left,
1885 (PyDateTime_Delta *)right);
1886 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 if (result == Py_NotImplemented)
1889 Py_INCREF(result);
1890 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001891}
1892
Mark Dickinson7c186e22010-04-20 22:32:49 +00001893static PyObject *
1894delta_truedivide(PyObject *left, PyObject *right)
1895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 if (PyDelta_Check(left)) {
1899 if (PyDelta_Check(right))
1900 result = truedivide_timedelta_timedelta(
1901 (PyDateTime_Delta *)left,
1902 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001903 else if (PyFloat_Check(right))
1904 result = truedivide_timedelta_float(
1905 (PyDateTime_Delta *)left, right);
1906 else if (PyLong_Check(right))
1907 result = truedivide_timedelta_int(
1908 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (result == Py_NotImplemented)
1912 Py_INCREF(result);
1913 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001914}
1915
1916static PyObject *
1917delta_remainder(PyObject *left, PyObject *right)
1918{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 PyObject *pyus_left;
1920 PyObject *pyus_right;
1921 PyObject *pyus_remainder;
1922 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001923
Brian Curtindfc80e32011-08-10 20:28:54 -05001924 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1925 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1928 if (pyus_left == NULL)
1929 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1932 if (pyus_right == NULL) {
1933 Py_DECREF(pyus_left);
1934 return NULL;
1935 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1938 Py_DECREF(pyus_left);
1939 Py_DECREF(pyus_right);
1940 if (pyus_remainder == NULL)
1941 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 remainder = microseconds_to_delta(pyus_remainder);
1944 Py_DECREF(pyus_remainder);
1945 if (remainder == NULL)
1946 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001949}
1950
1951static PyObject *
1952delta_divmod(PyObject *left, PyObject *right)
1953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 PyObject *pyus_left;
1955 PyObject *pyus_right;
1956 PyObject *divmod;
1957 PyObject *delta;
1958 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001959
Brian Curtindfc80e32011-08-10 20:28:54 -05001960 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1961 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001963 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1964 if (pyus_left == NULL)
1965 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1968 if (pyus_right == NULL) {
1969 Py_DECREF(pyus_left);
1970 return NULL;
1971 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1974 Py_DECREF(pyus_left);
1975 Py_DECREF(pyus_right);
1976 if (divmod == NULL)
1977 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 assert(PyTuple_Size(divmod) == 2);
1980 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1981 if (delta == NULL) {
1982 Py_DECREF(divmod);
1983 return NULL;
1984 }
1985 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1986 Py_DECREF(delta);
1987 Py_DECREF(divmod);
1988 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001989}
1990
Tim Peters2a799bf2002-12-16 20:18:38 +00001991/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1992 * timedelta constructor. sofar is the # of microseconds accounted for
1993 * so far, and there are factor microseconds per current unit, the number
1994 * of which is given by num. num * factor is added to sofar in a
1995 * numerically careful way, and that's the result. Any fractional
1996 * microseconds left over (this can happen if num is a float type) are
1997 * added into *leftover.
1998 * Note that there are many ways this can give an error (NULL) return.
1999 */
2000static PyObject *
2001accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2002 double *leftover)
2003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 PyObject *prod;
2005 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 if (PyLong_Check(num)) {
2010 prod = PyNumber_Multiply(num, factor);
2011 if (prod == NULL)
2012 return NULL;
2013 sum = PyNumber_Add(sofar, prod);
2014 Py_DECREF(prod);
2015 return sum;
2016 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 if (PyFloat_Check(num)) {
2019 double dnum;
2020 double fracpart;
2021 double intpart;
2022 PyObject *x;
2023 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 /* The Plan: decompose num into an integer part and a
2026 * fractional part, num = intpart + fracpart.
2027 * Then num * factor ==
2028 * intpart * factor + fracpart * factor
2029 * and the LHS can be computed exactly in long arithmetic.
2030 * The RHS is again broken into an int part and frac part.
2031 * and the frac part is added into *leftover.
2032 */
2033 dnum = PyFloat_AsDouble(num);
2034 if (dnum == -1.0 && PyErr_Occurred())
2035 return NULL;
2036 fracpart = modf(dnum, &intpart);
2037 x = PyLong_FromDouble(intpart);
2038 if (x == NULL)
2039 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 prod = PyNumber_Multiply(x, factor);
2042 Py_DECREF(x);
2043 if (prod == NULL)
2044 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002046 sum = PyNumber_Add(sofar, prod);
2047 Py_DECREF(prod);
2048 if (sum == NULL)
2049 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 if (fracpart == 0.0)
2052 return sum;
2053 /* So far we've lost no information. Dealing with the
2054 * fractional part requires float arithmetic, and may
2055 * lose a little info.
2056 */
2057 assert(PyLong_Check(factor));
2058 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002060 dnum *= fracpart;
2061 fracpart = modf(dnum, &intpart);
2062 x = PyLong_FromDouble(intpart);
2063 if (x == NULL) {
2064 Py_DECREF(sum);
2065 return NULL;
2066 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 y = PyNumber_Add(sum, x);
2069 Py_DECREF(sum);
2070 Py_DECREF(x);
2071 *leftover += fracpart;
2072 return y;
2073 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 PyErr_Format(PyExc_TypeError,
2076 "unsupported type for timedelta %s component: %s",
2077 tag, Py_TYPE(num)->tp_name);
2078 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002079}
2080
2081static PyObject *
2082delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 /* Argument objects. */
2087 PyObject *day = NULL;
2088 PyObject *second = NULL;
2089 PyObject *us = NULL;
2090 PyObject *ms = NULL;
2091 PyObject *minute = NULL;
2092 PyObject *hour = NULL;
2093 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 PyObject *x = NULL; /* running sum of microseconds */
2096 PyObject *y = NULL; /* temp sum of microseconds */
2097 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 static char *keywords[] = {
2100 "days", "seconds", "microseconds", "milliseconds",
2101 "minutes", "hours", "weeks", NULL
2102 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2105 keywords,
2106 &day, &second, &us,
2107 &ms, &minute, &hour, &week) == 0)
2108 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 x = PyLong_FromLong(0);
2111 if (x == NULL)
2112 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114#define CLEANUP \
2115 Py_DECREF(x); \
2116 x = y; \
2117 if (x == NULL) \
2118 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 if (us) {
2121 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2122 CLEANUP;
2123 }
2124 if (ms) {
2125 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2126 CLEANUP;
2127 }
2128 if (second) {
2129 y = accum("seconds", x, second, us_per_second, &leftover_us);
2130 CLEANUP;
2131 }
2132 if (minute) {
2133 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2134 CLEANUP;
2135 }
2136 if (hour) {
2137 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2138 CLEANUP;
2139 }
2140 if (day) {
2141 y = accum("days", x, day, us_per_day, &leftover_us);
2142 CLEANUP;
2143 }
2144 if (week) {
2145 y = accum("weeks", x, week, us_per_week, &leftover_us);
2146 CLEANUP;
2147 }
2148 if (leftover_us) {
2149 /* Round to nearest whole # of us, and add into x. */
2150 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2151 if (temp == NULL) {
2152 Py_DECREF(x);
2153 goto Done;
2154 }
2155 y = PyNumber_Add(x, temp);
2156 Py_DECREF(temp);
2157 CLEANUP;
2158 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 self = microseconds_to_delta_ex(x, type);
2161 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002162Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002164
2165#undef CLEANUP
2166}
2167
2168static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002169delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 return (GET_TD_DAYS(self) != 0
2172 || GET_TD_SECONDS(self) != 0
2173 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002174}
2175
2176static PyObject *
2177delta_repr(PyDateTime_Delta *self)
2178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 if (GET_TD_MICROSECONDS(self) != 0)
2180 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2181 Py_TYPE(self)->tp_name,
2182 GET_TD_DAYS(self),
2183 GET_TD_SECONDS(self),
2184 GET_TD_MICROSECONDS(self));
2185 if (GET_TD_SECONDS(self) != 0)
2186 return PyUnicode_FromFormat("%s(%d, %d)",
2187 Py_TYPE(self)->tp_name,
2188 GET_TD_DAYS(self),
2189 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 return PyUnicode_FromFormat("%s(%d)",
2192 Py_TYPE(self)->tp_name,
2193 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002194}
2195
2196static PyObject *
2197delta_str(PyDateTime_Delta *self)
2198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 int us = GET_TD_MICROSECONDS(self);
2200 int seconds = GET_TD_SECONDS(self);
2201 int minutes = divmod(seconds, 60, &seconds);
2202 int hours = divmod(minutes, 60, &minutes);
2203 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002205 if (days) {
2206 if (us)
2207 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2208 days, (days == 1 || days == -1) ? "" : "s",
2209 hours, minutes, seconds, us);
2210 else
2211 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2212 days, (days == 1 || days == -1) ? "" : "s",
2213 hours, minutes, seconds);
2214 } else {
2215 if (us)
2216 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2217 hours, minutes, seconds, us);
2218 else
2219 return PyUnicode_FromFormat("%d:%02d:%02d",
2220 hours, minutes, seconds);
2221 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002222
Tim Peters2a799bf2002-12-16 20:18:38 +00002223}
2224
Tim Peters371935f2003-02-01 01:52:50 +00002225/* Pickle support, a simple use of __reduce__. */
2226
Tim Petersb57f8f02003-02-01 02:54:15 +00002227/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002228static PyObject *
2229delta_getstate(PyDateTime_Delta *self)
2230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 return Py_BuildValue("iii", GET_TD_DAYS(self),
2232 GET_TD_SECONDS(self),
2233 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002234}
2235
Tim Peters2a799bf2002-12-16 20:18:38 +00002236static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002237delta_total_seconds(PyObject *self)
2238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 PyObject *total_seconds;
2240 PyObject *total_microseconds;
2241 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2244 if (total_microseconds == NULL)
2245 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 one_million = PyLong_FromLong(1000000L);
2248 if (one_million == NULL) {
2249 Py_DECREF(total_microseconds);
2250 return NULL;
2251 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 Py_DECREF(total_microseconds);
2256 Py_DECREF(one_million);
2257 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002258}
2259
2260static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002261delta_reduce(PyDateTime_Delta* self)
2262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002264}
2265
2266#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2267
2268static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 {"days", T_INT, OFFSET(days), READONLY,
2271 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 {"seconds", T_INT, OFFSET(seconds), READONLY,
2274 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2277 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2278 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002279};
2280
2281static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2283 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2286 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002289};
2290
2291static char delta_doc[] =
2292PyDoc_STR("Difference between two datetime values.");
2293
2294static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 delta_add, /* nb_add */
2296 delta_subtract, /* nb_subtract */
2297 delta_multiply, /* nb_multiply */
2298 delta_remainder, /* nb_remainder */
2299 delta_divmod, /* nb_divmod */
2300 0, /* nb_power */
2301 (unaryfunc)delta_negative, /* nb_negative */
2302 (unaryfunc)delta_positive, /* nb_positive */
2303 (unaryfunc)delta_abs, /* nb_absolute */
2304 (inquiry)delta_bool, /* nb_bool */
2305 0, /*nb_invert*/
2306 0, /*nb_lshift*/
2307 0, /*nb_rshift*/
2308 0, /*nb_and*/
2309 0, /*nb_xor*/
2310 0, /*nb_or*/
2311 0, /*nb_int*/
2312 0, /*nb_reserved*/
2313 0, /*nb_float*/
2314 0, /*nb_inplace_add*/
2315 0, /*nb_inplace_subtract*/
2316 0, /*nb_inplace_multiply*/
2317 0, /*nb_inplace_remainder*/
2318 0, /*nb_inplace_power*/
2319 0, /*nb_inplace_lshift*/
2320 0, /*nb_inplace_rshift*/
2321 0, /*nb_inplace_and*/
2322 0, /*nb_inplace_xor*/
2323 0, /*nb_inplace_or*/
2324 delta_divide, /* nb_floor_divide */
2325 delta_truedivide, /* nb_true_divide */
2326 0, /* nb_inplace_floor_divide */
2327 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002328};
2329
2330static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002331 PyVarObject_HEAD_INIT(NULL, 0)
2332 "datetime.timedelta", /* tp_name */
2333 sizeof(PyDateTime_Delta), /* tp_basicsize */
2334 0, /* tp_itemsize */
2335 0, /* tp_dealloc */
2336 0, /* tp_print */
2337 0, /* tp_getattr */
2338 0, /* tp_setattr */
2339 0, /* tp_reserved */
2340 (reprfunc)delta_repr, /* tp_repr */
2341 &delta_as_number, /* tp_as_number */
2342 0, /* tp_as_sequence */
2343 0, /* tp_as_mapping */
2344 (hashfunc)delta_hash, /* tp_hash */
2345 0, /* tp_call */
2346 (reprfunc)delta_str, /* tp_str */
2347 PyObject_GenericGetAttr, /* tp_getattro */
2348 0, /* tp_setattro */
2349 0, /* tp_as_buffer */
2350 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2351 delta_doc, /* tp_doc */
2352 0, /* tp_traverse */
2353 0, /* tp_clear */
2354 delta_richcompare, /* tp_richcompare */
2355 0, /* tp_weaklistoffset */
2356 0, /* tp_iter */
2357 0, /* tp_iternext */
2358 delta_methods, /* tp_methods */
2359 delta_members, /* tp_members */
2360 0, /* tp_getset */
2361 0, /* tp_base */
2362 0, /* tp_dict */
2363 0, /* tp_descr_get */
2364 0, /* tp_descr_set */
2365 0, /* tp_dictoffset */
2366 0, /* tp_init */
2367 0, /* tp_alloc */
2368 delta_new, /* tp_new */
2369 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002370};
2371
2372/*
2373 * PyDateTime_Date implementation.
2374 */
2375
2376/* Accessor properties. */
2377
2378static PyObject *
2379date_year(PyDateTime_Date *self, void *unused)
2380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002382}
2383
2384static PyObject *
2385date_month(PyDateTime_Date *self, void *unused)
2386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002388}
2389
2390static PyObject *
2391date_day(PyDateTime_Date *self, void *unused)
2392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002394}
2395
2396static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 {"year", (getter)date_year},
2398 {"month", (getter)date_month},
2399 {"day", (getter)date_day},
2400 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002401};
2402
2403/* Constructors. */
2404
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002405static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002406
Tim Peters2a799bf2002-12-16 20:18:38 +00002407static PyObject *
2408date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 PyObject *self = NULL;
2411 PyObject *state;
2412 int year;
2413 int month;
2414 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 /* Check for invocation from pickle with __getstate__ state */
2417 if (PyTuple_GET_SIZE(args) == 1 &&
2418 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2419 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2420 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2421 {
2422 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2425 if (me != NULL) {
2426 char *pdata = PyBytes_AS_STRING(state);
2427 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2428 me->hashcode = -1;
2429 }
2430 return (PyObject *)me;
2431 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2434 &year, &month, &day)) {
2435 if (check_date_args(year, month, day) < 0)
2436 return NULL;
2437 self = new_date_ex(year, month, day, type);
2438 }
2439 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002440}
2441
2442/* Return new date from localtime(t). */
2443static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002444date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 struct tm *tm;
2447 time_t t;
2448 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 t = _PyTime_DoubleToTimet(ts);
2451 if (t == (time_t)-1 && PyErr_Occurred())
2452 return NULL;
2453 tm = localtime(&t);
2454 if (tm)
2455 result = PyObject_CallFunction(cls, "iii",
2456 tm->tm_year + 1900,
2457 tm->tm_mon + 1,
2458 tm->tm_mday);
2459 else
2460 PyErr_SetString(PyExc_ValueError,
2461 "timestamp out of range for "
2462 "platform localtime() function");
2463 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002464}
2465
2466/* Return new date from current time.
2467 * We say this is equivalent to fromtimestamp(time.time()), and the
2468 * only way to be sure of that is to *call* time.time(). That's not
2469 * generally the same as calling C's time.
2470 */
2471static PyObject *
2472date_today(PyObject *cls, PyObject *dummy)
2473{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002474 PyObject *time;
2475 PyObject *result;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002476 _Py_identifier(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 time = time_time();
2479 if (time == NULL)
2480 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002482 /* Note well: today() is a class method, so this may not call
2483 * date.fromtimestamp. For example, it may call
2484 * datetime.fromtimestamp. That's why we need all the accuracy
2485 * time.time() delivers; if someone were gonzo about optimization,
2486 * date.today() could get away with plain C time().
2487 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002488 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 Py_DECREF(time);
2490 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002491}
2492
2493/* Return new date from given timestamp (Python timestamp -- a double). */
2494static PyObject *
2495date_fromtimestamp(PyObject *cls, PyObject *args)
2496{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002497 double timestamp;
2498 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2501 result = date_local_from_time_t(cls, timestamp);
2502 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002503}
2504
2505/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2506 * the ordinal is out of range.
2507 */
2508static PyObject *
2509date_fromordinal(PyObject *cls, PyObject *args)
2510{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 PyObject *result = NULL;
2512 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002514 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2515 int year;
2516 int month;
2517 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 if (ordinal < 1)
2520 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2521 ">= 1");
2522 else {
2523 ord_to_ymd(ordinal, &year, &month, &day);
2524 result = PyObject_CallFunction(cls, "iii",
2525 year, month, day);
2526 }
2527 }
2528 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002529}
2530
2531/*
2532 * Date arithmetic.
2533 */
2534
2535/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2536 * instead.
2537 */
2538static PyObject *
2539add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002541 PyObject *result = NULL;
2542 int year = GET_YEAR(date);
2543 int month = GET_MONTH(date);
2544 int deltadays = GET_TD_DAYS(delta);
2545 /* C-level overflow is impossible because |deltadays| < 1e9. */
2546 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002548 if (normalize_date(&year, &month, &day) >= 0)
2549 result = new_date(year, month, day);
2550 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002551}
2552
2553static PyObject *
2554date_add(PyObject *left, PyObject *right)
2555{
Brian Curtindfc80e32011-08-10 20:28:54 -05002556 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2557 Py_RETURN_NOTIMPLEMENTED;
2558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002559 if (PyDate_Check(left)) {
2560 /* date + ??? */
2561 if (PyDelta_Check(right))
2562 /* date + delta */
2563 return add_date_timedelta((PyDateTime_Date *) left,
2564 (PyDateTime_Delta *) right,
2565 0);
2566 }
2567 else {
2568 /* ??? + date
2569 * 'right' must be one of us, or we wouldn't have been called
2570 */
2571 if (PyDelta_Check(left))
2572 /* delta + date */
2573 return add_date_timedelta((PyDateTime_Date *) right,
2574 (PyDateTime_Delta *) left,
2575 0);
2576 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002577 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002578}
2579
2580static PyObject *
2581date_subtract(PyObject *left, PyObject *right)
2582{
Brian Curtindfc80e32011-08-10 20:28:54 -05002583 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2584 Py_RETURN_NOTIMPLEMENTED;
2585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 if (PyDate_Check(left)) {
2587 if (PyDate_Check(right)) {
2588 /* date - date */
2589 int left_ord = ymd_to_ord(GET_YEAR(left),
2590 GET_MONTH(left),
2591 GET_DAY(left));
2592 int right_ord = ymd_to_ord(GET_YEAR(right),
2593 GET_MONTH(right),
2594 GET_DAY(right));
2595 return new_delta(left_ord - right_ord, 0, 0, 0);
2596 }
2597 if (PyDelta_Check(right)) {
2598 /* date - delta */
2599 return add_date_timedelta((PyDateTime_Date *) left,
2600 (PyDateTime_Delta *) right,
2601 1);
2602 }
2603 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002604 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002605}
2606
2607
2608/* Various ways to turn a date into a string. */
2609
2610static PyObject *
2611date_repr(PyDateTime_Date *self)
2612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2614 Py_TYPE(self)->tp_name,
2615 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002616}
2617
2618static PyObject *
2619date_isoformat(PyDateTime_Date *self)
2620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 return PyUnicode_FromFormat("%04d-%02d-%02d",
2622 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002623}
2624
Tim Peterse2df5ff2003-05-02 18:39:55 +00002625/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002626static PyObject *
2627date_str(PyDateTime_Date *self)
2628{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002629 _Py_identifier(isoformat);
2630
2631 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002632}
2633
2634
2635static PyObject *
2636date_ctime(PyDateTime_Date *self)
2637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002638 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002639}
2640
2641static PyObject *
2642date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002644 /* This method can be inherited, and needs to call the
2645 * timetuple() method appropriate to self's class.
2646 */
2647 PyObject *result;
2648 PyObject *tuple;
2649 PyObject *format;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002650 _Py_identifier(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002651 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2654 &format))
2655 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002656
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002657 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 if (tuple == NULL)
2659 return NULL;
2660 result = wrap_strftime((PyObject *)self, format, tuple,
2661 (PyObject *)self);
2662 Py_DECREF(tuple);
2663 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002664}
2665
Eric Smith1ba31142007-09-11 18:06:02 +00002666static PyObject *
2667date_format(PyDateTime_Date *self, PyObject *args)
2668{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002669 PyObject *format;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002670 _Py_identifier(strftime);
Eric Smith1ba31142007-09-11 18:06:02 +00002671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002672 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2673 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002675 /* if the format is zero length, return str(self) */
2676 if (PyUnicode_GetSize(format) == 0)
2677 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002678
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002679 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002680}
2681
Tim Peters2a799bf2002-12-16 20:18:38 +00002682/* ISO methods. */
2683
2684static PyObject *
2685date_isoweekday(PyDateTime_Date *self)
2686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002687 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002689 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002690}
2691
2692static PyObject *
2693date_isocalendar(PyDateTime_Date *self)
2694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002695 int year = GET_YEAR(self);
2696 int week1_monday = iso_week1_monday(year);
2697 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2698 int week;
2699 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002701 week = divmod(today - week1_monday, 7, &day);
2702 if (week < 0) {
2703 --year;
2704 week1_monday = iso_week1_monday(year);
2705 week = divmod(today - week1_monday, 7, &day);
2706 }
2707 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2708 ++year;
2709 week = 0;
2710 }
2711 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002712}
2713
2714/* Miscellaneous methods. */
2715
Tim Peters2a799bf2002-12-16 20:18:38 +00002716static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002717date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002719 if (PyDate_Check(other)) {
2720 int diff = memcmp(((PyDateTime_Date *)self)->data,
2721 ((PyDateTime_Date *)other)->data,
2722 _PyDateTime_DATE_DATASIZE);
2723 return diff_to_bool(diff, op);
2724 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002725 else
2726 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002727}
2728
2729static PyObject *
2730date_timetuple(PyDateTime_Date *self)
2731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002732 return build_struct_time(GET_YEAR(self),
2733 GET_MONTH(self),
2734 GET_DAY(self),
2735 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002736}
2737
Tim Peters12bf3392002-12-24 05:41:27 +00002738static PyObject *
2739date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002741 PyObject *clone;
2742 PyObject *tuple;
2743 int year = GET_YEAR(self);
2744 int month = GET_MONTH(self);
2745 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002746
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002747 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2748 &year, &month, &day))
2749 return NULL;
2750 tuple = Py_BuildValue("iii", year, month, day);
2751 if (tuple == NULL)
2752 return NULL;
2753 clone = date_new(Py_TYPE(self), tuple, NULL);
2754 Py_DECREF(tuple);
2755 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002756}
2757
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002758/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002759 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002760*/
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002761static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002762generic_hash(unsigned char *data, int len)
2763{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002764 register unsigned char *p;
Mark Dickinsonc7d93b72011-09-25 15:34:32 +01002765 register Py_uhash_t x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002767 p = (unsigned char *) data;
Mark Dickinsonc7d93b72011-09-25 15:34:32 +01002768 x = (Py_uhash_t)*p << 7;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002769 while (--len >= 0)
Mark Dickinsonc7d93b72011-09-25 15:34:32 +01002770 x = (1000003U*x) ^ (Py_uhash_t)*p++;
2771 x ^= (Py_uhash_t)len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 if (x == -1)
2773 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002775 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002776}
2777
2778
2779static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002780
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002781static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002782date_hash(PyDateTime_Date *self)
2783{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002784 if (self->hashcode == -1)
2785 self->hashcode = generic_hash(
2786 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002788 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002789}
2790
2791static PyObject *
2792date_toordinal(PyDateTime_Date *self)
2793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002794 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2795 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002796}
2797
2798static PyObject *
2799date_weekday(PyDateTime_Date *self)
2800{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002801 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002803 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002804}
2805
Tim Peters371935f2003-02-01 01:52:50 +00002806/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002807
Tim Petersb57f8f02003-02-01 02:54:15 +00002808/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002809static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002810date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002811{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002812 PyObject* field;
2813 field = PyBytes_FromStringAndSize((char*)self->data,
2814 _PyDateTime_DATE_DATASIZE);
2815 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002816}
2817
2818static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002819date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002821 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002822}
2823
2824static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002826 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002828 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2829 METH_CLASS,
2830 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2831 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002833 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2834 METH_CLASS,
2835 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2836 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002838 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2839 PyDoc_STR("Current date or datetime: same as "
2840 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002842 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2845 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2848 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2851 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2854 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2857 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2858 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002860 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2861 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002863 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2864 PyDoc_STR("Return the day of the week represented by the date.\n"
2865 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002867 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2868 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2869 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002871 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2872 PyDoc_STR("Return the day of the week represented by the date.\n"
2873 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2876 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2879 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002881 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002882};
2883
2884static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002885PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002886
2887static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002888 date_add, /* nb_add */
2889 date_subtract, /* nb_subtract */
2890 0, /* nb_multiply */
2891 0, /* nb_remainder */
2892 0, /* nb_divmod */
2893 0, /* nb_power */
2894 0, /* nb_negative */
2895 0, /* nb_positive */
2896 0, /* nb_absolute */
2897 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002898};
2899
2900static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002901 PyVarObject_HEAD_INIT(NULL, 0)
2902 "datetime.date", /* tp_name */
2903 sizeof(PyDateTime_Date), /* tp_basicsize */
2904 0, /* tp_itemsize */
2905 0, /* tp_dealloc */
2906 0, /* tp_print */
2907 0, /* tp_getattr */
2908 0, /* tp_setattr */
2909 0, /* tp_reserved */
2910 (reprfunc)date_repr, /* tp_repr */
2911 &date_as_number, /* tp_as_number */
2912 0, /* tp_as_sequence */
2913 0, /* tp_as_mapping */
2914 (hashfunc)date_hash, /* tp_hash */
2915 0, /* tp_call */
2916 (reprfunc)date_str, /* tp_str */
2917 PyObject_GenericGetAttr, /* tp_getattro */
2918 0, /* tp_setattro */
2919 0, /* tp_as_buffer */
2920 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2921 date_doc, /* tp_doc */
2922 0, /* tp_traverse */
2923 0, /* tp_clear */
2924 date_richcompare, /* tp_richcompare */
2925 0, /* tp_weaklistoffset */
2926 0, /* tp_iter */
2927 0, /* tp_iternext */
2928 date_methods, /* tp_methods */
2929 0, /* tp_members */
2930 date_getset, /* tp_getset */
2931 0, /* tp_base */
2932 0, /* tp_dict */
2933 0, /* tp_descr_get */
2934 0, /* tp_descr_set */
2935 0, /* tp_dictoffset */
2936 0, /* tp_init */
2937 0, /* tp_alloc */
2938 date_new, /* tp_new */
2939 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002940};
2941
2942/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002943 * PyDateTime_TZInfo implementation.
2944 */
2945
2946/* This is a pure abstract base class, so doesn't do anything beyond
2947 * raising NotImplemented exceptions. Real tzinfo classes need
2948 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002949 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002950 * be subclasses of this tzinfo class, which is easy and quick to check).
2951 *
2952 * Note: For reasons having to do with pickling of subclasses, we have
2953 * to allow tzinfo objects to be instantiated. This wasn't an issue
2954 * in the Python implementation (__init__() could raise NotImplementedError
2955 * there without ill effect), but doing so in the C implementation hit a
2956 * brick wall.
2957 */
2958
2959static PyObject *
2960tzinfo_nogo(const char* methodname)
2961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002962 PyErr_Format(PyExc_NotImplementedError,
2963 "a tzinfo subclass must implement %s()",
2964 methodname);
2965 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002966}
2967
2968/* Methods. A subclass must implement these. */
2969
Tim Peters52dcce22003-01-23 16:36:11 +00002970static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002971tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2972{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002973 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002974}
2975
Tim Peters52dcce22003-01-23 16:36:11 +00002976static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002977tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2978{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002979 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002980}
2981
Tim Peters52dcce22003-01-23 16:36:11 +00002982static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002983tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2984{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002985 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002986}
2987
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002988
2989static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2990 PyDateTime_Delta *delta,
2991 int factor);
2992static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2993static PyObject *datetime_dst(PyObject *self, PyObject *);
2994
Tim Peters52dcce22003-01-23 16:36:11 +00002995static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002996tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002997{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002998 PyObject *result = NULL;
2999 PyObject *off = NULL, *dst = NULL;
3000 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003001
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003002 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003003 PyErr_SetString(PyExc_TypeError,
3004 "fromutc: argument must be a datetime");
3005 return NULL;
3006 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003007 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003008 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3009 "is not self");
3010 return NULL;
3011 }
Tim Peters52dcce22003-01-23 16:36:11 +00003012
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003013 off = datetime_utcoffset(dt, NULL);
3014 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003016 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003017 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3018 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003019 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003020 }
Tim Peters52dcce22003-01-23 16:36:11 +00003021
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003022 dst = datetime_dst(dt, NULL);
3023 if (dst == NULL)
3024 goto Fail;
3025 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003026 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3027 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003028 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003029 }
Tim Peters52dcce22003-01-23 16:36:11 +00003030
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003031 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3032 if (delta == NULL)
3033 goto Fail;
3034 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003035 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003036 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003037
3038 Py_DECREF(dst);
3039 dst = call_dst(GET_DT_TZINFO(dt), result);
3040 if (dst == NULL)
3041 goto Fail;
3042 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003043 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003044 if (delta_bool(delta) != 0) {
3045 PyObject *temp = result;
3046 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3047 (PyDateTime_Delta *)dst, 1);
3048 Py_DECREF(temp);
3049 if (result == NULL)
3050 goto Fail;
3051 }
3052 Py_DECREF(delta);
3053 Py_DECREF(dst);
3054 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003055 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003056
3057Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003058 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3059 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003061 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003062Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003063 Py_XDECREF(off);
3064 Py_XDECREF(dst);
3065 Py_XDECREF(delta);
3066 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003067 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003068}
3069
Tim Peters2a799bf2002-12-16 20:18:38 +00003070/*
3071 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003072 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003073 */
3074
Guido van Rossum177e41a2003-01-30 22:06:23 +00003075static PyObject *
3076tzinfo_reduce(PyObject *self)
3077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003078 PyObject *args, *state, *tmp;
3079 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003081 tmp = PyTuple_New(0);
3082 if (tmp == NULL)
3083 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003085 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3086 if (getinitargs != NULL) {
3087 args = PyObject_CallObject(getinitargs, tmp);
3088 Py_DECREF(getinitargs);
3089 if (args == NULL) {
3090 Py_DECREF(tmp);
3091 return NULL;
3092 }
3093 }
3094 else {
3095 PyErr_Clear();
3096 args = tmp;
3097 Py_INCREF(args);
3098 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003100 getstate = PyObject_GetAttrString(self, "__getstate__");
3101 if (getstate != NULL) {
3102 state = PyObject_CallObject(getstate, tmp);
3103 Py_DECREF(getstate);
3104 if (state == NULL) {
3105 Py_DECREF(args);
3106 Py_DECREF(tmp);
3107 return NULL;
3108 }
3109 }
3110 else {
3111 PyObject **dictptr;
3112 PyErr_Clear();
3113 state = Py_None;
3114 dictptr = _PyObject_GetDictPtr(self);
3115 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3116 state = *dictptr;
3117 Py_INCREF(state);
3118 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003120 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 if (state == Py_None) {
3123 Py_DECREF(state);
3124 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3125 }
3126 else
3127 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003128}
Tim Peters2a799bf2002-12-16 20:18:38 +00003129
3130static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003132 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3133 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003135 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003136 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3137 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3140 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003142 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003143 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003145 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3146 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003148 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003149};
3150
3151static char tzinfo_doc[] =
3152PyDoc_STR("Abstract base class for time zone info objects.");
3153
Neal Norwitz227b5332006-03-22 09:28:35 +00003154static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003155 PyVarObject_HEAD_INIT(NULL, 0)
3156 "datetime.tzinfo", /* tp_name */
3157 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3158 0, /* tp_itemsize */
3159 0, /* tp_dealloc */
3160 0, /* tp_print */
3161 0, /* tp_getattr */
3162 0, /* tp_setattr */
3163 0, /* tp_reserved */
3164 0, /* tp_repr */
3165 0, /* tp_as_number */
3166 0, /* tp_as_sequence */
3167 0, /* tp_as_mapping */
3168 0, /* tp_hash */
3169 0, /* tp_call */
3170 0, /* tp_str */
3171 PyObject_GenericGetAttr, /* tp_getattro */
3172 0, /* tp_setattro */
3173 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003174 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003175 tzinfo_doc, /* tp_doc */
3176 0, /* tp_traverse */
3177 0, /* tp_clear */
3178 0, /* tp_richcompare */
3179 0, /* tp_weaklistoffset */
3180 0, /* tp_iter */
3181 0, /* tp_iternext */
3182 tzinfo_methods, /* tp_methods */
3183 0, /* tp_members */
3184 0, /* tp_getset */
3185 0, /* tp_base */
3186 0, /* tp_dict */
3187 0, /* tp_descr_get */
3188 0, /* tp_descr_set */
3189 0, /* tp_dictoffset */
3190 0, /* tp_init */
3191 0, /* tp_alloc */
3192 PyType_GenericNew, /* tp_new */
3193 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003194};
3195
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003196static char *timezone_kws[] = {"offset", "name", NULL};
3197
3198static PyObject *
3199timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3200{
3201 PyObject *offset;
3202 PyObject *name = NULL;
3203 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3204 &PyDateTime_DeltaType, &offset,
3205 &PyUnicode_Type, &name))
3206 return new_timezone(offset, name);
3207
3208 return NULL;
3209}
3210
3211static void
3212timezone_dealloc(PyDateTime_TimeZone *self)
3213{
3214 Py_CLEAR(self->offset);
3215 Py_CLEAR(self->name);
3216 Py_TYPE(self)->tp_free((PyObject *)self);
3217}
3218
3219static PyObject *
3220timezone_richcompare(PyDateTime_TimeZone *self,
3221 PyDateTime_TimeZone *other, int op)
3222{
Brian Curtindfc80e32011-08-10 20:28:54 -05003223 if (op != Py_EQ && op != Py_NE)
3224 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003225 return delta_richcompare(self->offset, other->offset, op);
3226}
3227
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003228static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003229timezone_hash(PyDateTime_TimeZone *self)
3230{
3231 return delta_hash((PyDateTime_Delta *)self->offset);
3232}
3233
3234/* Check argument type passed to tzname, utcoffset, or dst methods.
3235 Returns 0 for good argument. Returns -1 and sets exception info
3236 otherwise.
3237 */
3238static int
3239_timezone_check_argument(PyObject *dt, const char *meth)
3240{
3241 if (dt == Py_None || PyDateTime_Check(dt))
3242 return 0;
3243 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3244 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3245 return -1;
3246}
3247
3248static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003249timezone_repr(PyDateTime_TimeZone *self)
3250{
3251 /* Note that although timezone is not subclassable, it is convenient
3252 to use Py_TYPE(self)->tp_name here. */
3253 const char *type_name = Py_TYPE(self)->tp_name;
3254
3255 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3256 return PyUnicode_FromFormat("%s.utc", type_name);
3257
3258 if (self->name == NULL)
3259 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3260
3261 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3262 self->name);
3263}
3264
3265
3266static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003267timezone_str(PyDateTime_TimeZone *self)
3268{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003269 int hours, minutes, seconds;
3270 PyObject *offset;
3271 char sign;
3272
3273 if (self->name != NULL) {
3274 Py_INCREF(self->name);
3275 return self->name;
3276 }
3277 /* Offset is normalized, so it is negative if days < 0 */
3278 if (GET_TD_DAYS(self->offset) < 0) {
3279 sign = '-';
3280 offset = delta_negative((PyDateTime_Delta *)self->offset);
3281 if (offset == NULL)
3282 return NULL;
3283 }
3284 else {
3285 sign = '+';
3286 offset = self->offset;
3287 Py_INCREF(offset);
3288 }
3289 /* Offset is not negative here. */
3290 seconds = GET_TD_SECONDS(offset);
3291 Py_DECREF(offset);
3292 minutes = divmod(seconds, 60, &seconds);
3293 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003294 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003295 assert(seconds == 0);
3296 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003297}
3298
3299static PyObject *
3300timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3301{
3302 if (_timezone_check_argument(dt, "tzname") == -1)
3303 return NULL;
3304
3305 return timezone_str(self);
3306}
3307
3308static PyObject *
3309timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3310{
3311 if (_timezone_check_argument(dt, "utcoffset") == -1)
3312 return NULL;
3313
3314 Py_INCREF(self->offset);
3315 return self->offset;
3316}
3317
3318static PyObject *
3319timezone_dst(PyObject *self, PyObject *dt)
3320{
3321 if (_timezone_check_argument(dt, "dst") == -1)
3322 return NULL;
3323
3324 Py_RETURN_NONE;
3325}
3326
3327static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003328timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3329{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003330 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003331 PyErr_SetString(PyExc_TypeError,
3332 "fromutc: argument must be a datetime");
3333 return NULL;
3334 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003335 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003336 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3337 "is not self");
3338 return NULL;
3339 }
3340
3341 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3342}
3343
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003344static PyObject *
3345timezone_getinitargs(PyDateTime_TimeZone *self)
3346{
3347 if (self->name == NULL)
3348 return Py_BuildValue("(O)", self->offset);
3349 return Py_BuildValue("(OO)", self->offset, self->name);
3350}
3351
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003352static PyMethodDef timezone_methods[] = {
3353 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3354 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003355 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003356
3357 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003358 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003359
3360 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003361 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003362
3363 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3364 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3365
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003366 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3367 PyDoc_STR("pickle support")},
3368
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003369 {NULL, NULL}
3370};
3371
3372static char timezone_doc[] =
3373PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3374
3375static PyTypeObject PyDateTime_TimeZoneType = {
3376 PyVarObject_HEAD_INIT(NULL, 0)
3377 "datetime.timezone", /* tp_name */
3378 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3379 0, /* tp_itemsize */
3380 (destructor)timezone_dealloc, /* tp_dealloc */
3381 0, /* tp_print */
3382 0, /* tp_getattr */
3383 0, /* tp_setattr */
3384 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003385 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003386 0, /* tp_as_number */
3387 0, /* tp_as_sequence */
3388 0, /* tp_as_mapping */
3389 (hashfunc)timezone_hash, /* tp_hash */
3390 0, /* tp_call */
3391 (reprfunc)timezone_str, /* tp_str */
3392 0, /* tp_getattro */
3393 0, /* tp_setattro */
3394 0, /* tp_as_buffer */
3395 Py_TPFLAGS_DEFAULT, /* tp_flags */
3396 timezone_doc, /* tp_doc */
3397 0, /* tp_traverse */
3398 0, /* tp_clear */
3399 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3400 0, /* tp_weaklistoffset */
3401 0, /* tp_iter */
3402 0, /* tp_iternext */
3403 timezone_methods, /* tp_methods */
3404 0, /* tp_members */
3405 0, /* tp_getset */
3406 &PyDateTime_TZInfoType, /* tp_base */
3407 0, /* tp_dict */
3408 0, /* tp_descr_get */
3409 0, /* tp_descr_set */
3410 0, /* tp_dictoffset */
3411 0, /* tp_init */
3412 0, /* tp_alloc */
3413 timezone_new, /* tp_new */
3414};
3415
Tim Peters2a799bf2002-12-16 20:18:38 +00003416/*
Tim Peters37f39822003-01-10 03:49:02 +00003417 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003418 */
3419
Tim Peters37f39822003-01-10 03:49:02 +00003420/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003421 */
3422
3423static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003424time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003426 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003427}
3428
Tim Peters37f39822003-01-10 03:49:02 +00003429static PyObject *
3430time_minute(PyDateTime_Time *self, void *unused)
3431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003432 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003433}
3434
3435/* The name time_second conflicted with some platform header file. */
3436static PyObject *
3437py_time_second(PyDateTime_Time *self, void *unused)
3438{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003439 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003440}
3441
3442static PyObject *
3443time_microsecond(PyDateTime_Time *self, void *unused)
3444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003445 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003446}
3447
3448static PyObject *
3449time_tzinfo(PyDateTime_Time *self, void *unused)
3450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003451 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3452 Py_INCREF(result);
3453 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003454}
3455
3456static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003457 {"hour", (getter)time_hour},
3458 {"minute", (getter)time_minute},
3459 {"second", (getter)py_time_second},
3460 {"microsecond", (getter)time_microsecond},
3461 {"tzinfo", (getter)time_tzinfo},
3462 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003463};
3464
3465/*
3466 * Constructors.
3467 */
3468
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003469static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003470 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003471
Tim Peters2a799bf2002-12-16 20:18:38 +00003472static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003473time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003475 PyObject *self = NULL;
3476 PyObject *state;
3477 int hour = 0;
3478 int minute = 0;
3479 int second = 0;
3480 int usecond = 0;
3481 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003483 /* Check for invocation from pickle with __getstate__ state */
3484 if (PyTuple_GET_SIZE(args) >= 1 &&
3485 PyTuple_GET_SIZE(args) <= 2 &&
3486 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3487 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3488 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3489 {
3490 PyDateTime_Time *me;
3491 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003493 if (PyTuple_GET_SIZE(args) == 2) {
3494 tzinfo = PyTuple_GET_ITEM(args, 1);
3495 if (check_tzinfo_subclass(tzinfo) < 0) {
3496 PyErr_SetString(PyExc_TypeError, "bad "
3497 "tzinfo state arg");
3498 return NULL;
3499 }
3500 }
3501 aware = (char)(tzinfo != Py_None);
3502 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3503 if (me != NULL) {
3504 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003506 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3507 me->hashcode = -1;
3508 me->hastzinfo = aware;
3509 if (aware) {
3510 Py_INCREF(tzinfo);
3511 me->tzinfo = tzinfo;
3512 }
3513 }
3514 return (PyObject *)me;
3515 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003517 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3518 &hour, &minute, &second, &usecond,
3519 &tzinfo)) {
3520 if (check_time_args(hour, minute, second, usecond) < 0)
3521 return NULL;
3522 if (check_tzinfo_subclass(tzinfo) < 0)
3523 return NULL;
3524 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3525 type);
3526 }
3527 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003528}
3529
3530/*
3531 * Destructor.
3532 */
3533
3534static void
Tim Peters37f39822003-01-10 03:49:02 +00003535time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003536{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003537 if (HASTZINFO(self)) {
3538 Py_XDECREF(self->tzinfo);
3539 }
3540 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003541}
3542
3543/*
Tim Peters855fe882002-12-22 03:43:39 +00003544 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003545 */
3546
Tim Peters2a799bf2002-12-16 20:18:38 +00003547/* These are all METH_NOARGS, so don't need to check the arglist. */
3548static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003549time_utcoffset(PyObject *self, PyObject *unused) {
3550 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003551}
3552
3553static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003554time_dst(PyObject *self, PyObject *unused) {
3555 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003556}
3557
3558static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003559time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003560 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003561}
3562
3563/*
Tim Peters37f39822003-01-10 03:49:02 +00003564 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003565 */
3566
3567static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003568time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003569{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003570 const char *type_name = Py_TYPE(self)->tp_name;
3571 int h = TIME_GET_HOUR(self);
3572 int m = TIME_GET_MINUTE(self);
3573 int s = TIME_GET_SECOND(self);
3574 int us = TIME_GET_MICROSECOND(self);
3575 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003577 if (us)
3578 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3579 type_name, h, m, s, us);
3580 else if (s)
3581 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3582 type_name, h, m, s);
3583 else
3584 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3585 if (result != NULL && HASTZINFO(self))
3586 result = append_keyword_tzinfo(result, self->tzinfo);
3587 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003588}
3589
Tim Peters37f39822003-01-10 03:49:02 +00003590static PyObject *
3591time_str(PyDateTime_Time *self)
3592{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003593 _Py_identifier(isoformat);
3594
3595 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003596}
Tim Peters2a799bf2002-12-16 20:18:38 +00003597
3598static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003599time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003601 char buf[100];
3602 PyObject *result;
3603 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003605 if (us)
3606 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3607 TIME_GET_HOUR(self),
3608 TIME_GET_MINUTE(self),
3609 TIME_GET_SECOND(self),
3610 us);
3611 else
3612 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3613 TIME_GET_HOUR(self),
3614 TIME_GET_MINUTE(self),
3615 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003616
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003617 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003618 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003620 /* We need to append the UTC offset. */
3621 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3622 Py_None) < 0) {
3623 Py_DECREF(result);
3624 return NULL;
3625 }
3626 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3627 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003628}
3629
Tim Peters37f39822003-01-10 03:49:02 +00003630static PyObject *
3631time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003633 PyObject *result;
3634 PyObject *tuple;
3635 PyObject *format;
3636 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003638 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3639 &format))
3640 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003642 /* Python's strftime does insane things with the year part of the
3643 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003644 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003645 */
3646 tuple = Py_BuildValue("iiiiiiiii",
3647 1900, 1, 1, /* year, month, day */
3648 TIME_GET_HOUR(self),
3649 TIME_GET_MINUTE(self),
3650 TIME_GET_SECOND(self),
3651 0, 1, -1); /* weekday, daynum, dst */
3652 if (tuple == NULL)
3653 return NULL;
3654 assert(PyTuple_Size(tuple) == 9);
3655 result = wrap_strftime((PyObject *)self, format, tuple,
3656 Py_None);
3657 Py_DECREF(tuple);
3658 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003659}
Tim Peters2a799bf2002-12-16 20:18:38 +00003660
3661/*
3662 * Miscellaneous methods.
3663 */
3664
Tim Peters37f39822003-01-10 03:49:02 +00003665static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003666time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003667{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003668 PyObject *result = NULL;
3669 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003670 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003671
Brian Curtindfc80e32011-08-10 20:28:54 -05003672 if (! PyTime_Check(other))
3673 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003674
3675 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003676 diff = memcmp(((PyDateTime_Time *)self)->data,
3677 ((PyDateTime_Time *)other)->data,
3678 _PyDateTime_TIME_DATASIZE);
3679 return diff_to_bool(diff, op);
3680 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003681 offset1 = time_utcoffset(self, NULL);
3682 if (offset1 == NULL)
3683 return NULL;
3684 offset2 = time_utcoffset(other, NULL);
3685 if (offset2 == NULL)
3686 goto done;
3687 /* If they're both naive, or both aware and have the same offsets,
3688 * we get off cheap. Note that if they're both naive, offset1 ==
3689 * offset2 == Py_None at this point.
3690 */
3691 if ((offset1 == offset2) ||
3692 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3693 delta_cmp(offset1, offset2) == 0)) {
3694 diff = memcmp(((PyDateTime_Time *)self)->data,
3695 ((PyDateTime_Time *)other)->data,
3696 _PyDateTime_TIME_DATASIZE);
3697 result = diff_to_bool(diff, op);
3698 }
3699 /* The hard case: both aware with different UTC offsets */
3700 else if (offset1 != Py_None && offset2 != Py_None) {
3701 int offsecs1, offsecs2;
3702 assert(offset1 != offset2); /* else last "if" handled it */
3703 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3704 TIME_GET_MINUTE(self) * 60 +
3705 TIME_GET_SECOND(self) -
3706 GET_TD_DAYS(offset1) * 86400 -
3707 GET_TD_SECONDS(offset1);
3708 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3709 TIME_GET_MINUTE(other) * 60 +
3710 TIME_GET_SECOND(other) -
3711 GET_TD_DAYS(offset2) * 86400 -
3712 GET_TD_SECONDS(offset2);
3713 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003714 if (diff == 0)
3715 diff = TIME_GET_MICROSECOND(self) -
3716 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003717 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003718 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003719 else {
3720 PyErr_SetString(PyExc_TypeError,
3721 "can't compare offset-naive and "
3722 "offset-aware times");
3723 }
3724 done:
3725 Py_DECREF(offset1);
3726 Py_XDECREF(offset2);
3727 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003728}
3729
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003730static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003731time_hash(PyDateTime_Time *self)
3732{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003733 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003734 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003735
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003736 offset = time_utcoffset((PyObject *)self, NULL);
3737
3738 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003739 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003741 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003742 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003743 self->hashcode = generic_hash(
3744 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003745 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003746 PyObject *temp1, *temp2;
3747 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003748 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003749 seconds = TIME_GET_HOUR(self) * 3600 +
3750 TIME_GET_MINUTE(self) * 60 +
3751 TIME_GET_SECOND(self);
3752 microseconds = TIME_GET_MICROSECOND(self);
3753 temp1 = new_delta(0, seconds, microseconds, 1);
3754 if (temp1 == NULL) {
3755 Py_DECREF(offset);
3756 return -1;
3757 }
3758 temp2 = delta_subtract(temp1, offset);
3759 Py_DECREF(temp1);
3760 if (temp2 == NULL) {
3761 Py_DECREF(offset);
3762 return -1;
3763 }
3764 self->hashcode = PyObject_Hash(temp2);
3765 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003766 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003767 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003768 }
3769 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003770}
Tim Peters2a799bf2002-12-16 20:18:38 +00003771
Tim Peters12bf3392002-12-24 05:41:27 +00003772static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003773time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003775 PyObject *clone;
3776 PyObject *tuple;
3777 int hh = TIME_GET_HOUR(self);
3778 int mm = TIME_GET_MINUTE(self);
3779 int ss = TIME_GET_SECOND(self);
3780 int us = TIME_GET_MICROSECOND(self);
3781 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003783 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3784 time_kws,
3785 &hh, &mm, &ss, &us, &tzinfo))
3786 return NULL;
3787 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3788 if (tuple == NULL)
3789 return NULL;
3790 clone = time_new(Py_TYPE(self), tuple, NULL);
3791 Py_DECREF(tuple);
3792 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003793}
3794
Tim Peters2a799bf2002-12-16 20:18:38 +00003795static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003796time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003797{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003798 PyObject *offset, *tzinfo;
3799 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003801 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3802 /* Since utcoffset is in whole minutes, nothing can
3803 * alter the conclusion that this is nonzero.
3804 */
3805 return 1;
3806 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003807 tzinfo = GET_TIME_TZINFO(self);
3808 if (tzinfo != Py_None) {
3809 offset = call_utcoffset(tzinfo, Py_None);
3810 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003811 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003812 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3813 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003814 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003815 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003816}
3817
Tim Peters371935f2003-02-01 01:52:50 +00003818/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003819
Tim Peters33e0f382003-01-10 02:05:14 +00003820/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003821 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3822 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003823 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003824 */
3825static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003826time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003827{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003828 PyObject *basestate;
3829 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003831 basestate = PyBytes_FromStringAndSize((char *)self->data,
3832 _PyDateTime_TIME_DATASIZE);
3833 if (basestate != NULL) {
3834 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3835 result = PyTuple_Pack(1, basestate);
3836 else
3837 result = PyTuple_Pack(2, basestate, self->tzinfo);
3838 Py_DECREF(basestate);
3839 }
3840 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003841}
3842
3843static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003844time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003846 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003847}
3848
Tim Peters37f39822003-01-10 03:49:02 +00003849static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003851 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3852 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3853 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003855 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3856 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3859 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003861 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3862 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003864 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3865 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003867 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3868 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003870 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3871 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003873 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3874 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003876 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003877};
3878
Tim Peters37f39822003-01-10 03:49:02 +00003879static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003880PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3881\n\
3882All arguments are optional. tzinfo may be None, or an instance of\n\
3883a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003884
Tim Peters37f39822003-01-10 03:49:02 +00003885static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003886 0, /* nb_add */
3887 0, /* nb_subtract */
3888 0, /* nb_multiply */
3889 0, /* nb_remainder */
3890 0, /* nb_divmod */
3891 0, /* nb_power */
3892 0, /* nb_negative */
3893 0, /* nb_positive */
3894 0, /* nb_absolute */
3895 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003896};
3897
Neal Norwitz227b5332006-03-22 09:28:35 +00003898static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003899 PyVarObject_HEAD_INIT(NULL, 0)
3900 "datetime.time", /* tp_name */
3901 sizeof(PyDateTime_Time), /* tp_basicsize */
3902 0, /* tp_itemsize */
3903 (destructor)time_dealloc, /* tp_dealloc */
3904 0, /* tp_print */
3905 0, /* tp_getattr */
3906 0, /* tp_setattr */
3907 0, /* tp_reserved */
3908 (reprfunc)time_repr, /* tp_repr */
3909 &time_as_number, /* tp_as_number */
3910 0, /* tp_as_sequence */
3911 0, /* tp_as_mapping */
3912 (hashfunc)time_hash, /* tp_hash */
3913 0, /* tp_call */
3914 (reprfunc)time_str, /* tp_str */
3915 PyObject_GenericGetAttr, /* tp_getattro */
3916 0, /* tp_setattro */
3917 0, /* tp_as_buffer */
3918 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3919 time_doc, /* tp_doc */
3920 0, /* tp_traverse */
3921 0, /* tp_clear */
3922 time_richcompare, /* tp_richcompare */
3923 0, /* tp_weaklistoffset */
3924 0, /* tp_iter */
3925 0, /* tp_iternext */
3926 time_methods, /* tp_methods */
3927 0, /* tp_members */
3928 time_getset, /* tp_getset */
3929 0, /* tp_base */
3930 0, /* tp_dict */
3931 0, /* tp_descr_get */
3932 0, /* tp_descr_set */
3933 0, /* tp_dictoffset */
3934 0, /* tp_init */
3935 time_alloc, /* tp_alloc */
3936 time_new, /* tp_new */
3937 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003938};
3939
3940/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003941 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003942 */
3943
Tim Petersa9bc1682003-01-11 03:39:11 +00003944/* Accessor properties. Properties for day, month, and year are inherited
3945 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003946 */
3947
3948static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003949datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003951 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003952}
3953
Tim Petersa9bc1682003-01-11 03:39:11 +00003954static PyObject *
3955datetime_minute(PyDateTime_DateTime *self, void *unused)
3956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003957 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003958}
3959
3960static PyObject *
3961datetime_second(PyDateTime_DateTime *self, void *unused)
3962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003963 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003964}
3965
3966static PyObject *
3967datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003969 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003970}
3971
3972static PyObject *
3973datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3974{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003975 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3976 Py_INCREF(result);
3977 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003978}
3979
3980static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003981 {"hour", (getter)datetime_hour},
3982 {"minute", (getter)datetime_minute},
3983 {"second", (getter)datetime_second},
3984 {"microsecond", (getter)datetime_microsecond},
3985 {"tzinfo", (getter)datetime_tzinfo},
3986 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003987};
3988
3989/*
3990 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003991 */
3992
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003993static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003994 "year", "month", "day", "hour", "minute", "second",
3995 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003996};
3997
Tim Peters2a799bf2002-12-16 20:18:38 +00003998static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003999datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004000{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 PyObject *self = NULL;
4002 PyObject *state;
4003 int year;
4004 int month;
4005 int day;
4006 int hour = 0;
4007 int minute = 0;
4008 int second = 0;
4009 int usecond = 0;
4010 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004012 /* Check for invocation from pickle with __getstate__ state */
4013 if (PyTuple_GET_SIZE(args) >= 1 &&
4014 PyTuple_GET_SIZE(args) <= 2 &&
4015 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4016 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4017 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4018 {
4019 PyDateTime_DateTime *me;
4020 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004022 if (PyTuple_GET_SIZE(args) == 2) {
4023 tzinfo = PyTuple_GET_ITEM(args, 1);
4024 if (check_tzinfo_subclass(tzinfo) < 0) {
4025 PyErr_SetString(PyExc_TypeError, "bad "
4026 "tzinfo state arg");
4027 return NULL;
4028 }
4029 }
4030 aware = (char)(tzinfo != Py_None);
4031 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4032 if (me != NULL) {
4033 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004035 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4036 me->hashcode = -1;
4037 me->hastzinfo = aware;
4038 if (aware) {
4039 Py_INCREF(tzinfo);
4040 me->tzinfo = tzinfo;
4041 }
4042 }
4043 return (PyObject *)me;
4044 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004046 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4047 &year, &month, &day, &hour, &minute,
4048 &second, &usecond, &tzinfo)) {
4049 if (check_date_args(year, month, day) < 0)
4050 return NULL;
4051 if (check_time_args(hour, minute, second, usecond) < 0)
4052 return NULL;
4053 if (check_tzinfo_subclass(tzinfo) < 0)
4054 return NULL;
4055 self = new_datetime_ex(year, month, day,
4056 hour, minute, second, usecond,
4057 tzinfo, type);
4058 }
4059 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004060}
4061
Tim Petersa9bc1682003-01-11 03:39:11 +00004062/* TM_FUNC is the shared type of localtime() and gmtime(). */
4063typedef struct tm *(*TM_FUNC)(const time_t *timer);
4064
4065/* Internal helper.
4066 * Build datetime from a time_t and a distinct count of microseconds.
4067 * Pass localtime or gmtime for f, to control the interpretation of timet.
4068 */
4069static PyObject *
4070datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004071 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004073 struct tm *tm;
4074 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004076 tm = f(&timet);
4077 if (tm) {
4078 /* The platform localtime/gmtime may insert leap seconds,
4079 * indicated by tm->tm_sec > 59. We don't care about them,
4080 * except to the extent that passing them on to the datetime
4081 * constructor would raise ValueError for a reason that
4082 * made no sense to the user.
4083 */
4084 if (tm->tm_sec > 59)
4085 tm->tm_sec = 59;
4086 result = PyObject_CallFunction(cls, "iiiiiiiO",
4087 tm->tm_year + 1900,
4088 tm->tm_mon + 1,
4089 tm->tm_mday,
4090 tm->tm_hour,
4091 tm->tm_min,
4092 tm->tm_sec,
4093 us,
4094 tzinfo);
4095 }
4096 else
4097 PyErr_SetString(PyExc_ValueError,
4098 "timestamp out of range for "
4099 "platform localtime()/gmtime() function");
4100 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004101}
4102
4103/* Internal helper.
4104 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4105 * to control the interpretation of the timestamp. Since a double doesn't
4106 * have enough bits to cover a datetime's full range of precision, it's
4107 * better to call datetime_from_timet_and_us provided you have a way
4108 * to get that much precision (e.g., C time() isn't good enough).
4109 */
4110static PyObject *
4111datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004112 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004113{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004114 time_t timet;
4115 double fraction;
4116 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004118 timet = _PyTime_DoubleToTimet(timestamp);
4119 if (timet == (time_t)-1 && PyErr_Occurred())
4120 return NULL;
4121 fraction = timestamp - (double)timet;
4122 us = (int)round_to_long(fraction * 1e6);
4123 if (us < 0) {
4124 /* Truncation towards zero is not what we wanted
4125 for negative numbers (Python's mod semantics) */
4126 timet -= 1;
4127 us += 1000000;
4128 }
4129 /* If timestamp is less than one microsecond smaller than a
4130 * full second, round up. Otherwise, ValueErrors are raised
4131 * for some floats. */
4132 if (us == 1000000) {
4133 timet += 1;
4134 us = 0;
4135 }
4136 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004137}
4138
4139/* Internal helper.
4140 * Build most accurate possible datetime for current time. Pass localtime or
4141 * gmtime for f as appropriate.
4142 */
4143static PyObject *
4144datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4145{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004146 _PyTime_timeval t;
4147 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004148 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4149 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004150}
4151
Tim Peters2a799bf2002-12-16 20:18:38 +00004152/* Return best possible local time -- this isn't constrained by the
4153 * precision of a timestamp.
4154 */
4155static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004156datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004158 PyObject *self;
4159 PyObject *tzinfo = Py_None;
4160 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004162 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4163 &tzinfo))
4164 return NULL;
4165 if (check_tzinfo_subclass(tzinfo) < 0)
4166 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004168 self = datetime_best_possible(cls,
4169 tzinfo == Py_None ? localtime : gmtime,
4170 tzinfo);
4171 if (self != NULL && tzinfo != Py_None) {
4172 /* Convert UTC to tzinfo's zone. */
4173 PyObject *temp = self;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004174 _Py_identifier(fromutc);
4175
4176 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 Py_DECREF(temp);
4178 }
4179 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004180}
4181
Tim Petersa9bc1682003-01-11 03:39:11 +00004182/* Return best possible UTC time -- this isn't constrained by the
4183 * precision of a timestamp.
4184 */
4185static PyObject *
4186datetime_utcnow(PyObject *cls, PyObject *dummy)
4187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004188 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004189}
4190
Tim Peters2a799bf2002-12-16 20:18:38 +00004191/* Return new local datetime from timestamp (Python timestamp -- a double). */
4192static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004193datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004194{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004195 PyObject *self;
4196 double timestamp;
4197 PyObject *tzinfo = Py_None;
4198 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004200 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4201 keywords, &timestamp, &tzinfo))
4202 return NULL;
4203 if (check_tzinfo_subclass(tzinfo) < 0)
4204 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004206 self = datetime_from_timestamp(cls,
4207 tzinfo == Py_None ? localtime : gmtime,
4208 timestamp,
4209 tzinfo);
4210 if (self != NULL && tzinfo != Py_None) {
4211 /* Convert UTC to tzinfo's zone. */
4212 PyObject *temp = self;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004213 _Py_identifier(fromutc);
4214
4215 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004216 Py_DECREF(temp);
4217 }
4218 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004219}
4220
Tim Petersa9bc1682003-01-11 03:39:11 +00004221/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4222static PyObject *
4223datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004225 double timestamp;
4226 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004228 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4229 result = datetime_from_timestamp(cls, gmtime, timestamp,
4230 Py_None);
4231 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004232}
4233
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004234/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004235static PyObject *
4236datetime_strptime(PyObject *cls, PyObject *args)
4237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004238 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004239 PyObject *string, *format;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004240 _Py_identifier(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004241
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004242 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004243 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004244
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004245 if (module == NULL) {
4246 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004247 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004248 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004249 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004250 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4251 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004252}
4253
Tim Petersa9bc1682003-01-11 03:39:11 +00004254/* Return new datetime from date/datetime and time arguments. */
4255static PyObject *
4256datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004258 static char *keywords[] = {"date", "time", NULL};
4259 PyObject *date;
4260 PyObject *time;
4261 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004263 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4264 &PyDateTime_DateType, &date,
4265 &PyDateTime_TimeType, &time)) {
4266 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004268 if (HASTZINFO(time))
4269 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4270 result = PyObject_CallFunction(cls, "iiiiiiiO",
4271 GET_YEAR(date),
4272 GET_MONTH(date),
4273 GET_DAY(date),
4274 TIME_GET_HOUR(time),
4275 TIME_GET_MINUTE(time),
4276 TIME_GET_SECOND(time),
4277 TIME_GET_MICROSECOND(time),
4278 tzinfo);
4279 }
4280 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004281}
Tim Peters2a799bf2002-12-16 20:18:38 +00004282
4283/*
4284 * Destructor.
4285 */
4286
4287static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004288datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004290 if (HASTZINFO(self)) {
4291 Py_XDECREF(self->tzinfo);
4292 }
4293 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004294}
4295
4296/*
4297 * Indirect access to tzinfo methods.
4298 */
4299
Tim Peters2a799bf2002-12-16 20:18:38 +00004300/* These are all METH_NOARGS, so don't need to check the arglist. */
4301static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004302datetime_utcoffset(PyObject *self, PyObject *unused) {
4303 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004304}
4305
4306static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004307datetime_dst(PyObject *self, PyObject *unused) {
4308 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004309}
4310
4311static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004312datetime_tzname(PyObject *self, PyObject *unused) {
4313 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004314}
4315
4316/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004317 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004318 */
4319
Tim Petersa9bc1682003-01-11 03:39:11 +00004320/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4321 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004322 */
4323static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004324add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004325 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004327 /* Note that the C-level additions can't overflow, because of
4328 * invariant bounds on the member values.
4329 */
4330 int year = GET_YEAR(date);
4331 int month = GET_MONTH(date);
4332 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4333 int hour = DATE_GET_HOUR(date);
4334 int minute = DATE_GET_MINUTE(date);
4335 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4336 int microsecond = DATE_GET_MICROSECOND(date) +
4337 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004339 assert(factor == 1 || factor == -1);
4340 if (normalize_datetime(&year, &month, &day,
4341 &hour, &minute, &second, &microsecond) < 0)
4342 return NULL;
4343 else
4344 return new_datetime(year, month, day,
4345 hour, minute, second, microsecond,
4346 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004347}
4348
4349static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004350datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004352 if (PyDateTime_Check(left)) {
4353 /* datetime + ??? */
4354 if (PyDelta_Check(right))
4355 /* datetime + delta */
4356 return add_datetime_timedelta(
4357 (PyDateTime_DateTime *)left,
4358 (PyDateTime_Delta *)right,
4359 1);
4360 }
4361 else if (PyDelta_Check(left)) {
4362 /* delta + datetime */
4363 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4364 (PyDateTime_Delta *) left,
4365 1);
4366 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004367 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004368}
4369
4370static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004371datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004373 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004375 if (PyDateTime_Check(left)) {
4376 /* datetime - ??? */
4377 if (PyDateTime_Check(right)) {
4378 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004379 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004380 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004381
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004382 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4383 offset2 = offset1 = Py_None;
4384 Py_INCREF(offset1);
4385 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004386 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004387 else {
4388 offset1 = datetime_utcoffset(left, NULL);
4389 if (offset1 == NULL)
4390 return NULL;
4391 offset2 = datetime_utcoffset(right, NULL);
4392 if (offset2 == NULL) {
4393 Py_DECREF(offset1);
4394 return NULL;
4395 }
4396 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4397 PyErr_SetString(PyExc_TypeError,
4398 "can't subtract offset-naive and "
4399 "offset-aware datetimes");
4400 Py_DECREF(offset1);
4401 Py_DECREF(offset2);
4402 return NULL;
4403 }
4404 }
4405 if ((offset1 != offset2) &&
4406 delta_cmp(offset1, offset2) != 0) {
4407 offdiff = delta_subtract(offset1, offset2);
4408 if (offdiff == NULL) {
4409 Py_DECREF(offset1);
4410 Py_DECREF(offset2);
4411 return NULL;
4412 }
4413 }
4414 Py_DECREF(offset1);
4415 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004416 delta_d = ymd_to_ord(GET_YEAR(left),
4417 GET_MONTH(left),
4418 GET_DAY(left)) -
4419 ymd_to_ord(GET_YEAR(right),
4420 GET_MONTH(right),
4421 GET_DAY(right));
4422 /* These can't overflow, since the values are
4423 * normalized. At most this gives the number of
4424 * seconds in one day.
4425 */
4426 delta_s = (DATE_GET_HOUR(left) -
4427 DATE_GET_HOUR(right)) * 3600 +
4428 (DATE_GET_MINUTE(left) -
4429 DATE_GET_MINUTE(right)) * 60 +
4430 (DATE_GET_SECOND(left) -
4431 DATE_GET_SECOND(right));
4432 delta_us = DATE_GET_MICROSECOND(left) -
4433 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004434 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004435 if (offdiff != NULL) {
4436 PyObject *temp = result;
4437 result = delta_subtract(result, offdiff);
4438 Py_DECREF(temp);
4439 Py_DECREF(offdiff);
4440 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004441 }
4442 else if (PyDelta_Check(right)) {
4443 /* datetime - delta */
4444 result = add_datetime_timedelta(
4445 (PyDateTime_DateTime *)left,
4446 (PyDateTime_Delta *)right,
4447 -1);
4448 }
4449 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004451 if (result == Py_NotImplemented)
4452 Py_INCREF(result);
4453 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004454}
4455
4456/* Various ways to turn a datetime into a string. */
4457
4458static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004459datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004461 const char *type_name = Py_TYPE(self)->tp_name;
4462 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004464 if (DATE_GET_MICROSECOND(self)) {
4465 baserepr = PyUnicode_FromFormat(
4466 "%s(%d, %d, %d, %d, %d, %d, %d)",
4467 type_name,
4468 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4469 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4470 DATE_GET_SECOND(self),
4471 DATE_GET_MICROSECOND(self));
4472 }
4473 else if (DATE_GET_SECOND(self)) {
4474 baserepr = PyUnicode_FromFormat(
4475 "%s(%d, %d, %d, %d, %d, %d)",
4476 type_name,
4477 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4478 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4479 DATE_GET_SECOND(self));
4480 }
4481 else {
4482 baserepr = PyUnicode_FromFormat(
4483 "%s(%d, %d, %d, %d, %d)",
4484 type_name,
4485 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4486 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4487 }
4488 if (baserepr == NULL || ! HASTZINFO(self))
4489 return baserepr;
4490 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004491}
4492
Tim Petersa9bc1682003-01-11 03:39:11 +00004493static PyObject *
4494datetime_str(PyDateTime_DateTime *self)
4495{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004496 _Py_identifier(isoformat);
4497
4498 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004499}
Tim Peters2a799bf2002-12-16 20:18:38 +00004500
4501static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004502datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004504 int sep = 'T';
4505 static char *keywords[] = {"sep", NULL};
4506 char buffer[100];
4507 PyObject *result;
4508 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004510 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4511 return NULL;
4512 if (us)
4513 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4514 GET_YEAR(self), GET_MONTH(self),
4515 GET_DAY(self), (int)sep,
4516 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4517 DATE_GET_SECOND(self), us);
4518 else
4519 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4520 GET_YEAR(self), GET_MONTH(self),
4521 GET_DAY(self), (int)sep,
4522 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4523 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004525 if (!result || !HASTZINFO(self))
4526 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004528 /* We need to append the UTC offset. */
4529 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4530 (PyObject *)self) < 0) {
4531 Py_DECREF(result);
4532 return NULL;
4533 }
4534 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4535 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004536}
4537
Tim Petersa9bc1682003-01-11 03:39:11 +00004538static PyObject *
4539datetime_ctime(PyDateTime_DateTime *self)
4540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004541 return format_ctime((PyDateTime_Date *)self,
4542 DATE_GET_HOUR(self),
4543 DATE_GET_MINUTE(self),
4544 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004545}
4546
Tim Peters2a799bf2002-12-16 20:18:38 +00004547/* Miscellaneous methods. */
4548
Tim Petersa9bc1682003-01-11 03:39:11 +00004549static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004550datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004551{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004552 PyObject *result = NULL;
4553 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004554 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004556 if (! PyDateTime_Check(other)) {
4557 if (PyDate_Check(other)) {
4558 /* Prevent invocation of date_richcompare. We want to
4559 return NotImplemented here to give the other object
4560 a chance. But since DateTime is a subclass of
4561 Date, if the other object is a Date, it would
4562 compute an ordering based on the date part alone,
4563 and we don't want that. So force unequal or
4564 uncomparable here in that case. */
4565 if (op == Py_EQ)
4566 Py_RETURN_FALSE;
4567 if (op == Py_NE)
4568 Py_RETURN_TRUE;
4569 return cmperror(self, other);
4570 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004571 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004572 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004573
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004574 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004575 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4576 ((PyDateTime_DateTime *)other)->data,
4577 _PyDateTime_DATETIME_DATASIZE);
4578 return diff_to_bool(diff, op);
4579 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004580 offset1 = datetime_utcoffset(self, NULL);
4581 if (offset1 == NULL)
4582 return NULL;
4583 offset2 = datetime_utcoffset(other, NULL);
4584 if (offset2 == NULL)
4585 goto done;
4586 /* If they're both naive, or both aware and have the same offsets,
4587 * we get off cheap. Note that if they're both naive, offset1 ==
4588 * offset2 == Py_None at this point.
4589 */
4590 if ((offset1 == offset2) ||
4591 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4592 delta_cmp(offset1, offset2) == 0)) {
4593 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4594 ((PyDateTime_DateTime *)other)->data,
4595 _PyDateTime_DATETIME_DATASIZE);
4596 result = diff_to_bool(diff, op);
4597 }
4598 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004599 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004600
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004601 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004602 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4603 other);
4604 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004605 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004606 diff = GET_TD_DAYS(delta);
4607 if (diff == 0)
4608 diff = GET_TD_SECONDS(delta) |
4609 GET_TD_MICROSECONDS(delta);
4610 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004611 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004612 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004613 else {
4614 PyErr_SetString(PyExc_TypeError,
4615 "can't compare offset-naive and "
4616 "offset-aware datetimes");
4617 }
4618 done:
4619 Py_DECREF(offset1);
4620 Py_XDECREF(offset2);
4621 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004622}
4623
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004624static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004625datetime_hash(PyDateTime_DateTime *self)
4626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004627 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004628 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004629
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004630 offset = datetime_utcoffset((PyObject *)self, NULL);
4631
4632 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004633 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004635 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004636 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004637 self->hashcode = generic_hash(
4638 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004640 PyObject *temp1, *temp2;
4641 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004643 assert(HASTZINFO(self));
4644 days = ymd_to_ord(GET_YEAR(self),
4645 GET_MONTH(self),
4646 GET_DAY(self));
4647 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004648 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004649 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004650 temp1 = new_delta(days, seconds,
4651 DATE_GET_MICROSECOND(self),
4652 1);
4653 if (temp1 == NULL) {
4654 Py_DECREF(offset);
4655 return -1;
4656 }
4657 temp2 = delta_subtract(temp1, offset);
4658 Py_DECREF(temp1);
4659 if (temp2 == NULL) {
4660 Py_DECREF(offset);
4661 return -1;
4662 }
4663 self->hashcode = PyObject_Hash(temp2);
4664 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004665 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004666 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004667 }
4668 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004669}
Tim Peters2a799bf2002-12-16 20:18:38 +00004670
4671static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004672datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004674 PyObject *clone;
4675 PyObject *tuple;
4676 int y = GET_YEAR(self);
4677 int m = GET_MONTH(self);
4678 int d = GET_DAY(self);
4679 int hh = DATE_GET_HOUR(self);
4680 int mm = DATE_GET_MINUTE(self);
4681 int ss = DATE_GET_SECOND(self);
4682 int us = DATE_GET_MICROSECOND(self);
4683 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004685 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4686 datetime_kws,
4687 &y, &m, &d, &hh, &mm, &ss, &us,
4688 &tzinfo))
4689 return NULL;
4690 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4691 if (tuple == NULL)
4692 return NULL;
4693 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4694 Py_DECREF(tuple);
4695 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004696}
4697
4698static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004699datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004700{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004701 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004702 PyObject *offset;
4703 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004704 PyObject *tzinfo;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004705 _Py_identifier(fromutc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004706 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004708 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4709 &PyDateTime_TZInfoType, &tzinfo))
4710 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004712 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4713 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004714
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004715 /* Conversion to self's own time zone is a NOP. */
4716 if (self->tzinfo == tzinfo) {
4717 Py_INCREF(self);
4718 return (PyObject *)self;
4719 }
Tim Peters521fc152002-12-31 17:36:56 +00004720
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004721 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004722 offset = datetime_utcoffset((PyObject *)self, NULL);
4723 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004724 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004725 if (offset == Py_None) {
4726 Py_DECREF(offset);
4727 NeedAware:
4728 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4729 "a naive datetime");
4730 return NULL;
4731 }
Tim Petersf3615152003-01-01 21:51:37 +00004732
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004733 /* result = self - offset */
4734 result = add_datetime_timedelta(self,
4735 (PyDateTime_Delta *)offset, -1);
4736 Py_DECREF(offset);
4737 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004738 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004740 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004741 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4742 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4743 Py_INCREF(tzinfo);
4744 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004745
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004746 temp = result;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004747 result = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004748 Py_DECREF(temp);
4749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004750 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004751}
4752
4753static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004754datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004755{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004756 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004758 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004759 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004760
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004761 dst = call_dst(self->tzinfo, (PyObject *)self);
4762 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004763 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004764
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004765 if (dst != Py_None)
4766 dstflag = delta_bool((PyDateTime_Delta *)dst);
4767 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004768 }
4769 return build_struct_time(GET_YEAR(self),
4770 GET_MONTH(self),
4771 GET_DAY(self),
4772 DATE_GET_HOUR(self),
4773 DATE_GET_MINUTE(self),
4774 DATE_GET_SECOND(self),
4775 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004776}
4777
4778static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004779datetime_getdate(PyDateTime_DateTime *self)
4780{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004781 return new_date(GET_YEAR(self),
4782 GET_MONTH(self),
4783 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004784}
4785
4786static PyObject *
4787datetime_gettime(PyDateTime_DateTime *self)
4788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004789 return new_time(DATE_GET_HOUR(self),
4790 DATE_GET_MINUTE(self),
4791 DATE_GET_SECOND(self),
4792 DATE_GET_MICROSECOND(self),
4793 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004794}
4795
4796static PyObject *
4797datetime_gettimetz(PyDateTime_DateTime *self)
4798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004799 return new_time(DATE_GET_HOUR(self),
4800 DATE_GET_MINUTE(self),
4801 DATE_GET_SECOND(self),
4802 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004803 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004804}
4805
4806static PyObject *
4807datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004808{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004809 int y, m, d, hh, mm, ss;
4810 PyObject *tzinfo;
4811 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004812
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004813 tzinfo = GET_DT_TZINFO(self);
4814 if (tzinfo == Py_None) {
4815 utcself = self;
4816 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004817 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004818 else {
4819 PyObject *offset;
4820 offset = call_utcoffset(tzinfo, (PyObject *)self);
4821 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004822 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004823 if (offset == Py_None) {
4824 Py_DECREF(offset);
4825 utcself = self;
4826 Py_INCREF(utcself);
4827 }
4828 else {
4829 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4830 (PyDateTime_Delta *)offset, -1);
4831 Py_DECREF(offset);
4832 if (utcself == NULL)
4833 return NULL;
4834 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004835 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004836 y = GET_YEAR(utcself);
4837 m = GET_MONTH(utcself);
4838 d = GET_DAY(utcself);
4839 hh = DATE_GET_HOUR(utcself);
4840 mm = DATE_GET_MINUTE(utcself);
4841 ss = DATE_GET_SECOND(utcself);
4842
4843 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004844 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004845}
4846
Tim Peters371935f2003-02-01 01:52:50 +00004847/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004848
Tim Petersa9bc1682003-01-11 03:39:11 +00004849/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004850 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4851 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004852 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004853 */
4854static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004855datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004857 PyObject *basestate;
4858 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004860 basestate = PyBytes_FromStringAndSize((char *)self->data,
4861 _PyDateTime_DATETIME_DATASIZE);
4862 if (basestate != NULL) {
4863 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4864 result = PyTuple_Pack(1, basestate);
4865 else
4866 result = PyTuple_Pack(2, basestate, self->tzinfo);
4867 Py_DECREF(basestate);
4868 }
4869 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004870}
4871
4872static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004873datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004875 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004876}
4877
Tim Petersa9bc1682003-01-11 03:39:11 +00004878static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004880 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 {"now", (PyCFunction)datetime_now,
4883 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4884 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004886 {"utcnow", (PyCFunction)datetime_utcnow,
4887 METH_NOARGS | METH_CLASS,
4888 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4891 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4892 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004894 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4895 METH_VARARGS | METH_CLASS,
4896 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4897 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004899 {"strptime", (PyCFunction)datetime_strptime,
4900 METH_VARARGS | METH_CLASS,
4901 PyDoc_STR("string, format -> new datetime parsed from a string "
4902 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004904 {"combine", (PyCFunction)datetime_combine,
4905 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4906 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004908 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004910 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4911 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004913 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4914 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004916 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4917 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004919 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4920 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004922 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4923 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004925 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4926 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004928 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4929 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4930 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4931 "sep is used to separate the year from the time, and "
4932 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4935 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004937 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4938 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004940 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4941 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004943 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4944 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004946 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4947 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004949 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4950 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004952 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004953};
4954
Tim Petersa9bc1682003-01-11 03:39:11 +00004955static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004956PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4957\n\
4958The year, month and day arguments are required. tzinfo may be None, or an\n\
4959instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004960
Tim Petersa9bc1682003-01-11 03:39:11 +00004961static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004962 datetime_add, /* nb_add */
4963 datetime_subtract, /* nb_subtract */
4964 0, /* nb_multiply */
4965 0, /* nb_remainder */
4966 0, /* nb_divmod */
4967 0, /* nb_power */
4968 0, /* nb_negative */
4969 0, /* nb_positive */
4970 0, /* nb_absolute */
4971 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004972};
4973
Neal Norwitz227b5332006-03-22 09:28:35 +00004974static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004975 PyVarObject_HEAD_INIT(NULL, 0)
4976 "datetime.datetime", /* tp_name */
4977 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4978 0, /* tp_itemsize */
4979 (destructor)datetime_dealloc, /* tp_dealloc */
4980 0, /* tp_print */
4981 0, /* tp_getattr */
4982 0, /* tp_setattr */
4983 0, /* tp_reserved */
4984 (reprfunc)datetime_repr, /* tp_repr */
4985 &datetime_as_number, /* tp_as_number */
4986 0, /* tp_as_sequence */
4987 0, /* tp_as_mapping */
4988 (hashfunc)datetime_hash, /* tp_hash */
4989 0, /* tp_call */
4990 (reprfunc)datetime_str, /* tp_str */
4991 PyObject_GenericGetAttr, /* tp_getattro */
4992 0, /* tp_setattro */
4993 0, /* tp_as_buffer */
4994 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4995 datetime_doc, /* tp_doc */
4996 0, /* tp_traverse */
4997 0, /* tp_clear */
4998 datetime_richcompare, /* tp_richcompare */
4999 0, /* tp_weaklistoffset */
5000 0, /* tp_iter */
5001 0, /* tp_iternext */
5002 datetime_methods, /* tp_methods */
5003 0, /* tp_members */
5004 datetime_getset, /* tp_getset */
5005 &PyDateTime_DateType, /* tp_base */
5006 0, /* tp_dict */
5007 0, /* tp_descr_get */
5008 0, /* tp_descr_set */
5009 0, /* tp_dictoffset */
5010 0, /* tp_init */
5011 datetime_alloc, /* tp_alloc */
5012 datetime_new, /* tp_new */
5013 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005014};
5015
5016/* ---------------------------------------------------------------------------
5017 * Module methods and initialization.
5018 */
5019
5020static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005021 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005022};
5023
Tim Peters9ddf40b2004-06-20 22:41:32 +00005024/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5025 * datetime.h.
5026 */
5027static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005028 &PyDateTime_DateType,
5029 &PyDateTime_DateTimeType,
5030 &PyDateTime_TimeType,
5031 &PyDateTime_DeltaType,
5032 &PyDateTime_TZInfoType,
5033 new_date_ex,
5034 new_datetime_ex,
5035 new_time_ex,
5036 new_delta_ex,
5037 datetime_fromtimestamp,
5038 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005039};
5040
5041
Martin v. Löwis1a214512008-06-11 05:26:20 +00005042
5043static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005044 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005045 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005046 "Fast implementation of the datetime type.",
5047 -1,
5048 module_methods,
5049 NULL,
5050 NULL,
5051 NULL,
5052 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005053};
5054
Tim Peters2a799bf2002-12-16 20:18:38 +00005055PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005056PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005058 PyObject *m; /* a module object */
5059 PyObject *d; /* its dict */
5060 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005061 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005063 m = PyModule_Create(&datetimemodule);
5064 if (m == NULL)
5065 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005067 if (PyType_Ready(&PyDateTime_DateType) < 0)
5068 return NULL;
5069 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5070 return NULL;
5071 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5072 return NULL;
5073 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5074 return NULL;
5075 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5076 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005077 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5078 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005080 /* timedelta values */
5081 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005083 x = new_delta(0, 0, 1, 0);
5084 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5085 return NULL;
5086 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005088 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5089 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5090 return NULL;
5091 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005093 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5094 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5095 return NULL;
5096 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005098 /* date values */
5099 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005101 x = new_date(1, 1, 1);
5102 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5103 return NULL;
5104 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005106 x = new_date(MAXYEAR, 12, 31);
5107 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5108 return NULL;
5109 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005111 x = new_delta(1, 0, 0, 0);
5112 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5113 return NULL;
5114 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005116 /* time values */
5117 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005119 x = new_time(0, 0, 0, 0, Py_None);
5120 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5121 return NULL;
5122 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005124 x = new_time(23, 59, 59, 999999, Py_None);
5125 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5126 return NULL;
5127 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005129 x = new_delta(0, 0, 1, 0);
5130 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5131 return NULL;
5132 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005134 /* datetime values */
5135 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005137 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5138 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5139 return NULL;
5140 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005142 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5143 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5144 return NULL;
5145 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005147 x = new_delta(0, 0, 1, 0);
5148 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5149 return NULL;
5150 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005151
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005152 /* timezone values */
5153 d = PyDateTime_TimeZoneType.tp_dict;
5154
5155 delta = new_delta(0, 0, 0, 0);
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, "utc", x) < 0)
5161 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005162 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005163
5164 delta = new_delta(-1, 60, 0, 1); /* -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, "min", x) < 0)
5170 return NULL;
5171 Py_DECREF(x);
5172
5173 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5174 if (delta == NULL)
5175 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005176 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005177 Py_DECREF(delta);
5178 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5179 return NULL;
5180 Py_DECREF(x);
5181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005182 /* module initialization */
5183 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5184 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005186 Py_INCREF(&PyDateTime_DateType);
5187 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005189 Py_INCREF(&PyDateTime_DateTimeType);
5190 PyModule_AddObject(m, "datetime",
5191 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005193 Py_INCREF(&PyDateTime_TimeType);
5194 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005196 Py_INCREF(&PyDateTime_DeltaType);
5197 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005199 Py_INCREF(&PyDateTime_TZInfoType);
5200 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005201
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005202 Py_INCREF(&PyDateTime_TimeZoneType);
5203 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005205 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5206 if (x == NULL)
5207 return NULL;
5208 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005210 /* A 4-year cycle has an extra leap day over what we'd get from
5211 * pasting together 4 single years.
5212 */
5213 assert(DI4Y == 4 * 365 + 1);
5214 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005216 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5217 * get from pasting together 4 100-year cycles.
5218 */
5219 assert(DI400Y == 4 * DI100Y + 1);
5220 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005222 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5223 * pasting together 25 4-year cycles.
5224 */
5225 assert(DI100Y == 25 * DI4Y - 1);
5226 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005228 us_per_us = PyLong_FromLong(1);
5229 us_per_ms = PyLong_FromLong(1000);
5230 us_per_second = PyLong_FromLong(1000000);
5231 us_per_minute = PyLong_FromLong(60000000);
5232 seconds_per_day = PyLong_FromLong(24 * 3600);
5233 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5234 us_per_minute == NULL || seconds_per_day == NULL)
5235 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005237 /* The rest are too big for 32-bit ints, but even
5238 * us_per_week fits in 40 bits, so doubles should be exact.
5239 */
5240 us_per_hour = PyLong_FromDouble(3600000000.0);
5241 us_per_day = PyLong_FromDouble(86400000000.0);
5242 us_per_week = PyLong_FromDouble(604800000000.0);
5243 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5244 return NULL;
5245 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005246}
Tim Petersf3615152003-01-01 21:51:37 +00005247
5248/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005249Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005250 x.n = x stripped of its timezone -- its naive time.
5251 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005252 return None
Tim Petersf3615152003-01-01 21:51:37 +00005253 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005254 return None
Tim Petersf3615152003-01-01 21:51:37 +00005255 x.s = x's standard offset, x.o - x.d
5256
5257Now some derived rules, where k is a duration (timedelta).
5258
52591. x.o = x.s + x.d
5260 This follows from the definition of x.s.
5261
Tim Petersc5dc4da2003-01-02 17:55:03 +000052622. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005263 This is actually a requirement, an assumption we need to make about
5264 sane tzinfo classes.
5265
52663. The naive UTC time corresponding to x is x.n - x.o.
5267 This is again a requirement for a sane tzinfo class.
5268
52694. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005270 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005271
Tim Petersc5dc4da2003-01-02 17:55:03 +000052725. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005273 Again follows from how arithmetic is defined.
5274
Tim Peters8bb5ad22003-01-24 02:44:45 +00005275Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005276(meaning that the various tzinfo methods exist, and don't blow up or return
5277None when called).
5278
Tim Petersa9bc1682003-01-11 03:39:11 +00005279The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005280x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005281
5282By #3, we want
5283
Tim Peters8bb5ad22003-01-24 02:44:45 +00005284 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005285
5286The algorithm starts by attaching tz to x.n, and calling that y. So
5287x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5288becomes true; in effect, we want to solve [2] for k:
5289
Tim Peters8bb5ad22003-01-24 02:44:45 +00005290 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005291
5292By #1, this is the same as
5293
Tim Peters8bb5ad22003-01-24 02:44:45 +00005294 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005295
5296By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5297Substituting that into [3],
5298
Tim Peters8bb5ad22003-01-24 02:44:45 +00005299 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5300 k - (y+k).s - (y+k).d = 0; rearranging,
5301 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5302 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005303
Tim Peters8bb5ad22003-01-24 02:44:45 +00005304On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5305approximate k by ignoring the (y+k).d term at first. Note that k can't be
5306very large, since all offset-returning methods return a duration of magnitude
5307less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5308be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005309
5310In any case, the new value is
5311
Tim Peters8bb5ad22003-01-24 02:44:45 +00005312 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005313
Tim Peters8bb5ad22003-01-24 02:44:45 +00005314It's helpful to step back at look at [4] from a higher level: it's simply
5315mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005316
5317At this point, if
5318
Tim Peters8bb5ad22003-01-24 02:44:45 +00005319 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005320
5321we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005322at the start of daylight time. Picture US Eastern for concreteness. The wall
5323time 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 +00005324sense then. The docs ask that an Eastern tzinfo class consider such a time to
5325be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5326on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005327the only spelling that makes sense on the local wall clock.
5328
Tim Petersc5dc4da2003-01-02 17:55:03 +00005329In fact, if [5] holds at this point, we do have the standard-time spelling,
5330but that takes a bit of proof. We first prove a stronger result. What's the
5331difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005332
Tim Peters8bb5ad22003-01-24 02:44:45 +00005333 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005334
Tim Petersc5dc4da2003-01-02 17:55:03 +00005335Now
5336 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005337 (y + y.s).n = by #5
5338 y.n + y.s = since y.n = x.n
5339 x.n + y.s = since z and y are have the same tzinfo member,
5340 y.s = z.s by #2
5341 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005342
Tim Petersc5dc4da2003-01-02 17:55:03 +00005343Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005344
Tim Petersc5dc4da2003-01-02 17:55:03 +00005345 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005346 x.n - ((x.n + z.s) - z.o) = expanding
5347 x.n - x.n - z.s + z.o = cancelling
5348 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005349 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005350
Tim Petersc5dc4da2003-01-02 17:55:03 +00005351So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005352
Tim Petersc5dc4da2003-01-02 17:55:03 +00005353If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005354spelling we wanted in the endcase described above. We're done. Contrarily,
5355if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005356
Tim Petersc5dc4da2003-01-02 17:55:03 +00005357If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5358add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005359local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005360
Tim Petersc5dc4da2003-01-02 17:55:03 +00005361Let
Tim Petersf3615152003-01-01 21:51:37 +00005362
Tim Peters4fede1a2003-01-04 00:26:59 +00005363 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005364
Tim Peters4fede1a2003-01-04 00:26:59 +00005365and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005366
Tim Peters8bb5ad22003-01-24 02:44:45 +00005367 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005368
Tim Peters8bb5ad22003-01-24 02:44:45 +00005369If so, we're done. If not, the tzinfo class is insane, according to the
5370assumptions we've made. This also requires a bit of proof. As before, let's
5371compute the difference between the LHS and RHS of [8] (and skipping some of
5372the justifications for the kinds of substitutions we've done several times
5373already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005374
Tim Peters8bb5ad22003-01-24 02:44:45 +00005375 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005376 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5377 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5378 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5379 - z.n + z.n - z.o + z'.o = cancel z.n
5380 - z.o + z'.o = #1 twice
5381 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5382 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005383
5384So 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 +00005385we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5386return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005387
Tim Peters8bb5ad22003-01-24 02:44:45 +00005388How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5389a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5390would have to change the result dst() returns: we start in DST, and moving
5391a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005392
Tim Peters8bb5ad22003-01-24 02:44:45 +00005393There isn't a sane case where this can happen. The closest it gets is at
5394the end of DST, where there's an hour in UTC with no spelling in a hybrid
5395tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5396that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5397UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5398time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5399clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5400standard time. Since that's what the local clock *does*, we want to map both
5401UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005402in local time, but so it goes -- it's the way the local clock works.
5403
Tim Peters8bb5ad22003-01-24 02:44:45 +00005404When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5405so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5406z' = 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 +00005407(correctly) concludes that z' is not UTC-equivalent to x.
5408
5409Because we know z.d said z was in daylight time (else [5] would have held and
5410we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005411and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005412return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5413but the reasoning doesn't depend on the example -- it depends on there being
5414two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005415z' must be in standard time, and is the spelling we want in this case.
5416
5417Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5418concerned (because it takes z' as being in standard time rather than the
5419daylight time we intend here), but returning it gives the real-life "local
5420clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5421tz.
5422
5423When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5424the 1:MM standard time spelling we want.
5425
5426So how can this break? One of the assumptions must be violated. Two
5427possibilities:
5428
54291) [2] effectively says that y.s is invariant across all y belong to a given
5430 time zone. This isn't true if, for political reasons or continental drift,
5431 a region decides to change its base offset from UTC.
5432
54332) There may be versions of "double daylight" time where the tail end of
5434 the analysis gives up a step too early. I haven't thought about that
5435 enough to say.
5436
5437In any case, it's clear that the default fromutc() is strong enough to handle
5438"almost all" time zones: so long as the standard offset is invariant, it
5439doesn't matter if daylight time transition points change from year to year, or
5440if daylight time is skipped in some years; it doesn't matter how large or
5441small dst() may get within its bounds; and it doesn't even matter if some
5442perverse time zone returns a negative dst()). So a breaking case must be
5443pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005444--------------------------------------------------------------------------- */