blob: 718dfe2d03a60fb9dc36957798f99078d48110c3 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
Tim Peters2a799bf2002-12-16 20:18:38 +00006#include "structmember.h"
7
8#include <time.h>
9
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000010#include "_time.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000011
12/* Differentiate between building the core module and building extension
13 * modules.
14 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000015#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000016#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000017#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000018#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000019#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000020
21/* We require that C int be at least 32 bits, and use int virtually
22 * everywhere. In just a few cases we use a temp long, where a Python
23 * API returns a C long. In such cases, we have to ensure that the
24 * final result fits in a C int (this can be an issue on 64-bit boxes).
25 */
26#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000027# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000028#endif
29
30#define MINYEAR 1
31#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000032#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000033
34/* Nine decimal digits is easy to communicate, and leaves enough room
35 * so that two delta days can be added w/o fear of overflowing a signed
36 * 32-bit int, and with plenty of room left over to absorb any possible
37 * carries from adding seconds.
38 */
39#define MAX_DELTA_DAYS 999999999
40
41/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042#define GET_YEAR PyDateTime_GET_YEAR
43#define GET_MONTH PyDateTime_GET_MONTH
44#define GET_DAY PyDateTime_GET_DAY
45#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
46#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
47#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
48#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000049
50/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
52 ((o)->data[1] = ((v) & 0x00ff)))
53#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
54#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000055
56/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000057#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
58#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
59#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
60#define DATE_SET_MICROSECOND(o, v) \
61 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
62 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
63 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000064
65/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
67#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
68#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
69#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
70#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
71#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
72#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
73#define TIME_SET_MICROSECOND(o, v) \
74 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
75 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
76 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000077
78/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
80#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
81#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083#define SET_TD_DAYS(o, v) ((o)->days = (v))
84#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000085#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
86
Tim Petersa032d2e2003-01-11 00:15:54 +000087/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
88 * p->hastzinfo.
89 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +000090#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
91#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
92 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
93#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
94 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +000095/* M is a char or int claiming to be a valid month. The macro is equivalent
96 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +000098 */
99#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
100
Tim Peters2a799bf2002-12-16 20:18:38 +0000101/* Forward declarations. */
102static PyTypeObject PyDateTime_DateType;
103static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000104static PyTypeObject PyDateTime_DeltaType;
105static PyTypeObject PyDateTime_TimeType;
106static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000107static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000108
109/* ---------------------------------------------------------------------------
110 * Math utilities.
111 */
112
113/* k = i+j overflows iff k differs in sign from both inputs,
114 * iff k^i has sign bit set and k^j has sign bit set,
115 * iff (k^i)&(k^j) has sign bit set.
116 */
117#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000119
120/* Compute Python divmod(x, y), returning the quotient and storing the
121 * remainder into *r. The quotient is the floor of x/y, and that's
122 * the real point of this. C will probably truncate instead (C99
123 * requires truncation; C89 left it implementation-defined).
124 * Simplification: we *require* that y > 0 here. That's appropriate
125 * for all the uses made of it. This simplifies the code and makes
126 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
127 * overflow case).
128 */
129static int
130divmod(int x, int y, int *r)
131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 assert(y > 0);
135 quo = x / y;
136 *r = x - quo * y;
137 if (*r < 0) {
138 --quo;
139 *r += y;
140 }
141 assert(0 <= *r && *r < y);
142 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000143}
144
Tim Peters5d644dd2003-01-02 16:32:54 +0000145/* Round a double to the nearest long. |x| must be small enough to fit
146 * in a C long; this is not checked.
147 */
148static long
149round_to_long(double x)
150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 if (x >= 0.0)
152 x = floor(x + 0.5);
153 else
154 x = ceil(x - 0.5);
155 return (long)x;
Tim Peters5d644dd2003-01-02 16:32:54 +0000156}
157
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000158/* Nearest integer to m / n for integers m and n. Half-integer results
159 * are rounded to even.
160 */
161static PyObject *
162divide_nearest(PyObject *m, PyObject *n)
163{
164 PyObject *result;
165 PyObject *temp;
166
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000167 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000168 if (temp == NULL)
169 return NULL;
170 result = PyTuple_GET_ITEM(temp, 0);
171 Py_INCREF(result);
172 Py_DECREF(temp);
173
174 return result;
175}
176
Tim Peters2a799bf2002-12-16 20:18:38 +0000177/* ---------------------------------------------------------------------------
178 * General calendrical helper functions
179 */
180
181/* For each month ordinal in 1..12, the number of days in that month,
182 * and the number of days before that month in the same year. These
183 * are correct for non-leap years only.
184 */
185static int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 0, /* unused; this vector uses 1-based indexing */
187 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000188};
189
190static int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 0, /* unused; this vector uses 1-based indexing */
192 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000193};
194
195/* year -> 1 if leap year, else 0. */
196static int
197is_leap(int year)
198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 /* Cast year to unsigned. The result is the same either way, but
200 * C can generate faster code for unsigned mod than for signed
201 * mod (especially for % 4 -- a good compiler should just grab
202 * the last 2 bits when the LHS is unsigned).
203 */
204 const unsigned int ayear = (unsigned int)year;
205 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000206}
207
208/* year, month -> number of days in that month in that year */
209static int
210days_in_month(int year, int month)
211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 assert(month >= 1);
213 assert(month <= 12);
214 if (month == 2 && is_leap(year))
215 return 29;
216 else
217 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000218}
219
220/* year, month -> number of days in year preceeding first day of month */
221static int
222days_before_month(int year, int month)
223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 assert(month >= 1);
227 assert(month <= 12);
228 days = _days_before_month[month];
229 if (month > 2 && is_leap(year))
230 ++days;
231 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000232}
233
234/* year -> number of days before January 1st of year. Remember that we
235 * start with year 1, so days_before_year(1) == 0.
236 */
237static int
238days_before_year(int year)
239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 int y = year - 1;
241 /* This is incorrect if year <= 0; we really want the floor
242 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000243 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000245 assert (year >= 1);
246 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000247}
248
249/* Number of days in 4, 100, and 400 year cycles. That these have
250 * the correct values is asserted in the module init function.
251 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252#define DI4Y 1461 /* days_before_year(5); days in 4 years */
253#define DI100Y 36524 /* days_before_year(101); days in 100 years */
254#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000255
256/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
257static void
258ord_to_ymd(int ordinal, int *year, int *month, int *day)
259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
263 * leap years repeats exactly every 400 years. The basic strategy is
264 * to find the closest 400-year boundary at or before ordinal, then
265 * work with the offset from that boundary to ordinal. Life is much
266 * clearer if we subtract 1 from ordinal first -- then the values
267 * of ordinal at 400-year boundaries are exactly those divisible
268 * by DI400Y:
269 *
270 * D M Y n n-1
271 * -- --- ---- ---------- ----------------
272 * 31 Dec -400 -DI400Y -DI400Y -1
273 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
274 * ...
275 * 30 Dec 000 -1 -2
276 * 31 Dec 000 0 -1
277 * 1 Jan 001 1 0 400-year boundary
278 * 2 Jan 001 2 1
279 * 3 Jan 001 3 2
280 * ...
281 * 31 Dec 400 DI400Y DI400Y -1
282 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
283 */
284 assert(ordinal >= 1);
285 --ordinal;
286 n400 = ordinal / DI400Y;
287 n = ordinal % DI400Y;
288 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 /* Now n is the (non-negative) offset, in days, from January 1 of
291 * year, to the desired date. Now compute how many 100-year cycles
292 * precede n.
293 * Note that it's possible for n100 to equal 4! In that case 4 full
294 * 100-year cycles precede the desired day, which implies the
295 * desired day is December 31 at the end of a 400-year cycle.
296 */
297 n100 = n / DI100Y;
298 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 /* Now compute how many 4-year cycles precede it. */
301 n4 = n / DI4Y;
302 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 /* And now how many single years. Again n1 can be 4, and again
305 * meaning that the desired day is December 31 at the end of the
306 * 4-year cycle.
307 */
308 n1 = n / 365;
309 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 *year += n100 * 100 + n4 * 4 + n1;
312 if (n1 == 4 || n100 == 4) {
313 assert(n == 0);
314 *year -= 1;
315 *month = 12;
316 *day = 31;
317 return;
318 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 /* Now the year is correct, and n is the offset from January 1. We
321 * find the month via an estimate that's either exact or one too
322 * large.
323 */
324 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
325 assert(leapyear == is_leap(*year));
326 *month = (n + 50) >> 5;
327 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
328 if (preceding > n) {
329 /* estimate is too large */
330 *month -= 1;
331 preceding -= days_in_month(*year, *month);
332 }
333 n -= preceding;
334 assert(0 <= n);
335 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000338}
339
340/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
341static int
342ymd_to_ord(int year, int month, int day)
343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000345}
346
347/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
348static int
349weekday(int year, int month, int day)
350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000352}
353
354/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
355 * first calendar week containing a Thursday.
356 */
357static int
358iso_week1_monday(int year)
359{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
361 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
362 int first_weekday = (first_day + 6) % 7;
363 /* ordinal of closest Monday at or before 1/1 */
364 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
367 week1_monday += 7;
368 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000369}
370
371/* ---------------------------------------------------------------------------
372 * Range checkers.
373 */
374
375/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
376 * If not, raise OverflowError and return -1.
377 */
378static int
379check_delta_day_range(int days)
380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
382 return 0;
383 PyErr_Format(PyExc_OverflowError,
384 "days=%d; must have magnitude <= %d",
385 days, MAX_DELTA_DAYS);
386 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000387}
388
389/* Check that date arguments are in range. Return 0 if they are. If they
390 * aren't, raise ValueError and return -1.
391 */
392static int
393check_date_args(int year, int month, int day)
394{
395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 if (year < MINYEAR || year > MAXYEAR) {
397 PyErr_SetString(PyExc_ValueError,
398 "year is out of range");
399 return -1;
400 }
401 if (month < 1 || month > 12) {
402 PyErr_SetString(PyExc_ValueError,
403 "month must be in 1..12");
404 return -1;
405 }
406 if (day < 1 || day > days_in_month(year, month)) {
407 PyErr_SetString(PyExc_ValueError,
408 "day is out of range for month");
409 return -1;
410 }
411 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000412}
413
414/* Check that time arguments are in range. Return 0 if they are. If they
415 * aren't, raise ValueError and return -1.
416 */
417static int
418check_time_args(int h, int m, int s, int us)
419{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 if (h < 0 || h > 23) {
421 PyErr_SetString(PyExc_ValueError,
422 "hour must be in 0..23");
423 return -1;
424 }
425 if (m < 0 || m > 59) {
426 PyErr_SetString(PyExc_ValueError,
427 "minute must be in 0..59");
428 return -1;
429 }
430 if (s < 0 || s > 59) {
431 PyErr_SetString(PyExc_ValueError,
432 "second must be in 0..59");
433 return -1;
434 }
435 if (us < 0 || us > 999999) {
436 PyErr_SetString(PyExc_ValueError,
437 "microsecond must be in 0..999999");
438 return -1;
439 }
440 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000441}
442
443/* ---------------------------------------------------------------------------
444 * Normalization utilities.
445 */
446
447/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
448 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
449 * at least factor, enough of *lo is converted into "hi" units so that
450 * 0 <= *lo < factor. The input values must be such that int overflow
451 * is impossible.
452 */
453static void
454normalize_pair(int *hi, int *lo, int factor)
455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 assert(factor > 0);
457 assert(lo != hi);
458 if (*lo < 0 || *lo >= factor) {
459 const int num_hi = divmod(*lo, factor, lo);
460 const int new_hi = *hi + num_hi;
461 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
462 *hi = new_hi;
463 }
464 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000465}
466
467/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 * 0 <= *s < 24*3600
469 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000470 * The input values must be such that the internals don't overflow.
471 * The way this routine is used, we don't get close.
472 */
473static void
474normalize_d_s_us(int *d, int *s, int *us)
475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 if (*us < 0 || *us >= 1000000) {
477 normalize_pair(s, us, 1000000);
478 /* |s| can't be bigger than about
479 * |original s| + |original us|/1000000 now.
480 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 }
483 if (*s < 0 || *s >= 24*3600) {
484 normalize_pair(d, s, 24*3600);
485 /* |d| can't be bigger than about
486 * |original d| +
487 * (|original s| + |original us|/1000000) / (24*3600) now.
488 */
489 }
490 assert(0 <= *s && *s < 24*3600);
491 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000492}
493
494/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 * 1 <= *m <= 12
496 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000497 * The input values must be such that the internals don't overflow.
498 * The way this routine is used, we don't get close.
499 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000500static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000501normalize_y_m_d(int *y, int *m, int *d)
502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000504
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000505 /* In actual use, m is always the month component extracted from a
506 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 /* Now only day can be out of bounds (year may also be out of bounds
512 * for a datetime object, but we don't care about that here).
513 * If day is out of bounds, what to do is arguable, but at least the
514 * method here is principled and explainable.
515 */
516 dim = days_in_month(*y, *m);
517 if (*d < 1 || *d > dim) {
518 /* Move day-1 days from the first of the month. First try to
519 * get off cheap if we're only one day out of range
520 * (adjustments for timezone alone can't be worse than that).
521 */
522 if (*d == 0) {
523 --*m;
524 if (*m > 0)
525 *d = days_in_month(*y, *m);
526 else {
527 --*y;
528 *m = 12;
529 *d = 31;
530 }
531 }
532 else if (*d == dim + 1) {
533 /* move forward a day */
534 ++*m;
535 *d = 1;
536 if (*m > 12) {
537 *m = 1;
538 ++*y;
539 }
540 }
541 else {
542 int ordinal = ymd_to_ord(*y, *m, 1) +
543 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000544 if (ordinal < 1 || ordinal > MAXORDINAL) {
545 goto error;
546 } else {
547 ord_to_ymd(ordinal, y, m, d);
548 return 0;
549 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 }
551 }
552 assert(*m > 0);
553 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000554 if (MINYEAR <= *y && *y <= MAXYEAR)
555 return 0;
556 error:
557 PyErr_SetString(PyExc_OverflowError,
558 "date value out of range");
559 return -1;
560
Tim Peters2a799bf2002-12-16 20:18:38 +0000561}
562
563/* Fiddle out-of-bounds months and days so that the result makes some kind
564 * of sense. The parameters are both inputs and outputs. Returns < 0 on
565 * failure, where failure means the adjusted year is out of bounds.
566 */
567static int
568normalize_date(int *year, int *month, int *day)
569{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000570 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000571}
572
573/* Force all the datetime fields into range. The parameters are both
574 * inputs and outputs. Returns < 0 on error.
575 */
576static int
577normalize_datetime(int *year, int *month, int *day,
578 int *hour, int *minute, int *second,
579 int *microsecond)
580{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 normalize_pair(second, microsecond, 1000000);
582 normalize_pair(minute, second, 60);
583 normalize_pair(hour, minute, 60);
584 normalize_pair(day, hour, 24);
585 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000586}
587
588/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000589 * Basic object allocation: tp_alloc implementations. These allocate
590 * Python objects of the right size and type, and do the Python object-
591 * initialization bit. If there's not enough memory, they return NULL after
592 * setting MemoryError. All data members remain uninitialized trash.
593 *
594 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000595 * member is needed. This is ugly, imprecise, and possibly insecure.
596 * tp_basicsize for the time and datetime types is set to the size of the
597 * struct that has room for the tzinfo member, so subclasses in Python will
598 * allocate enough space for a tzinfo member whether or not one is actually
599 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
600 * part is that PyType_GenericAlloc() (which subclasses in Python end up
601 * using) just happens today to effectively ignore the nitems argument
602 * when tp_itemsize is 0, which it is for these type objects. If that
603 * changes, perhaps the callers of tp_alloc slots in this file should
604 * be changed to force a 0 nitems argument unless the type being allocated
605 * is a base type implemented in this file (so that tp_alloc is time_alloc
606 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000607 */
608
609static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000610time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 self = (PyObject *)
615 PyObject_MALLOC(aware ?
616 sizeof(PyDateTime_Time) :
617 sizeof(_PyDateTime_BaseTime));
618 if (self == NULL)
619 return (PyObject *)PyErr_NoMemory();
620 PyObject_INIT(self, type);
621 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000622}
623
624static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000625datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 self = (PyObject *)
630 PyObject_MALLOC(aware ?
631 sizeof(PyDateTime_DateTime) :
632 sizeof(_PyDateTime_BaseDateTime));
633 if (self == NULL)
634 return (PyObject *)PyErr_NoMemory();
635 PyObject_INIT(self, type);
636 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000637}
638
639/* ---------------------------------------------------------------------------
640 * Helpers for setting object fields. These work on pointers to the
641 * appropriate base class.
642 */
643
644/* For date and datetime. */
645static void
646set_date_fields(PyDateTime_Date *self, int y, int m, int d)
647{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 self->hashcode = -1;
649 SET_YEAR(self, y);
650 SET_MONTH(self, m);
651 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000652}
653
654/* ---------------------------------------------------------------------------
655 * Create various objects, mostly without range checking.
656 */
657
658/* Create a date instance with no range checking. */
659static PyObject *
660new_date_ex(int year, int month, int day, PyTypeObject *type)
661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
665 if (self != NULL)
666 set_date_fields(self, year, month, day);
667 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000668}
669
670#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000671 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000672
673/* Create a datetime instance with no range checking. */
674static PyObject *
675new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 PyDateTime_DateTime *self;
679 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000681 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
682 if (self != NULL) {
683 self->hastzinfo = aware;
684 set_date_fields((PyDateTime_Date *)self, year, month, day);
685 DATE_SET_HOUR(self, hour);
686 DATE_SET_MINUTE(self, minute);
687 DATE_SET_SECOND(self, second);
688 DATE_SET_MICROSECOND(self, usecond);
689 if (aware) {
690 Py_INCREF(tzinfo);
691 self->tzinfo = tzinfo;
692 }
693 }
694 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000695}
696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
698 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
699 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000700
701/* Create a time instance with no range checking. */
702static PyObject *
703new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000705{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 PyDateTime_Time *self;
707 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
710 if (self != NULL) {
711 self->hastzinfo = aware;
712 self->hashcode = -1;
713 TIME_SET_HOUR(self, hour);
714 TIME_SET_MINUTE(self, minute);
715 TIME_SET_SECOND(self, second);
716 TIME_SET_MICROSECOND(self, usecond);
717 if (aware) {
718 Py_INCREF(tzinfo);
719 self->tzinfo = tzinfo;
720 }
721 }
722 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000723}
724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725#define new_time(hh, mm, ss, us, tzinfo) \
726 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000727
728/* Create a timedelta instance. Normalize the members iff normalize is
729 * true. Passing false is a speed optimization, if you know for sure
730 * that seconds and microseconds are already in their proper ranges. In any
731 * case, raises OverflowError and returns NULL if the normalized days is out
732 * of range).
733 */
734static PyObject *
735new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 if (normalize)
741 normalize_d_s_us(&days, &seconds, &microseconds);
742 assert(0 <= seconds && seconds < 24*3600);
743 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 if (check_delta_day_range(days) < 0)
746 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
749 if (self != NULL) {
750 self->hashcode = -1;
751 SET_TD_DAYS(self, days);
752 SET_TD_SECONDS(self, seconds);
753 SET_TD_MICROSECONDS(self, microseconds);
754 }
755 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000756}
757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758#define new_delta(d, s, us, normalize) \
759 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000760
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000761
762typedef struct
763{
764 PyObject_HEAD
765 PyObject *offset;
766 PyObject *name;
767} PyDateTime_TimeZone;
768
Victor Stinner6ced7c42011-03-21 18:15:42 +0100769/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000770static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000771
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000772/* Create new timezone instance checking offset range. This
773 function does not check the name argument. Caller must assure
774 that offset is a timedelta instance and name is either NULL
775 or a unicode object. */
776static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000777create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000778{
779 PyDateTime_TimeZone *self;
780 PyTypeObject *type = &PyDateTime_TimeZoneType;
781
782 assert(offset != NULL);
783 assert(PyDelta_Check(offset));
784 assert(name == NULL || PyUnicode_Check(name));
785
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000786 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
787 if (self == NULL) {
788 return NULL;
789 }
790 Py_INCREF(offset);
791 self->offset = offset;
792 Py_XINCREF(name);
793 self->name = name;
794 return (PyObject *)self;
795}
796
797static int delta_bool(PyDateTime_Delta *self);
798
799static PyObject *
800new_timezone(PyObject *offset, PyObject *name)
801{
802 assert(offset != NULL);
803 assert(PyDelta_Check(offset));
804 assert(name == NULL || PyUnicode_Check(name));
805
806 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
807 Py_INCREF(PyDateTime_TimeZone_UTC);
808 return PyDateTime_TimeZone_UTC;
809 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000810 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
811 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
812 " representing a whole number of minutes");
813 return NULL;
814 }
815 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
816 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
817 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
818 " strictly between -timedelta(hours=24) and"
819 " timedelta(hours=24).");
820 return NULL;
821 }
822
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000823 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000824}
825
Tim Petersb0c854d2003-05-17 15:57:00 +0000826/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000827 * tzinfo helpers.
828 */
829
Tim Peters855fe882002-12-22 03:43:39 +0000830/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
831 * raise TypeError and return -1.
832 */
833static int
834check_tzinfo_subclass(PyObject *p)
835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 if (p == Py_None || PyTZInfo_Check(p))
837 return 0;
838 PyErr_Format(PyExc_TypeError,
839 "tzinfo argument must be None or of a tzinfo subclass, "
840 "not type '%s'",
841 Py_TYPE(p)->tp_name);
842 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000843}
844
Tim Peters2a799bf2002-12-16 20:18:38 +0000845/* If self has a tzinfo member, return a BORROWED reference to it. Else
846 * return NULL, which is NOT AN ERROR. There are no error returns here,
847 * and the caller must not decref the result.
848 */
849static PyObject *
850get_tzinfo_member(PyObject *self)
851{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 if (PyDateTime_Check(self) && HASTZINFO(self))
855 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
856 else if (PyTime_Check(self) && HASTZINFO(self))
857 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000860}
861
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000862/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
863 * be an instance of the tzinfo class. If the method returns None, this
864 * returns None. If the method doesn't return None or timedelta, TypeError is
865 * raised and this returns NULL. If it returns a timedelta and the value is
866 * out of range or isn't a whole number of minutes, ValueError is raised and
867 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000868 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000869static PyObject *
870call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000871{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000872 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000875 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000877
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000878 if (tzinfo == Py_None)
879 Py_RETURN_NONE;
880 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
881 if (offset == Py_None || offset == NULL)
882 return offset;
883 if (PyDelta_Check(offset)) {
884 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
885 Py_DECREF(offset);
886 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
887 " representing a whole number of minutes");
888 return NULL;
889 }
890 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
891 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
892 Py_DECREF(offset);
893 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
894 " strictly between -timedelta(hours=24) and"
895 " timedelta(hours=24).");
896 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 }
898 }
899 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000900 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 PyErr_Format(PyExc_TypeError,
902 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000903 "timedelta, not '%.200s'",
904 name, Py_TYPE(offset)->tp_name);
905 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000907
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000908 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000909}
910
911/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
912 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
913 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000914 * doesn't return None or timedelta, TypeError is raised and this returns -1.
915 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
916 * # of minutes), ValueError is raised and this returns -1. Else *none is
917 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000918 */
Tim Peters855fe882002-12-22 03:43:39 +0000919static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000920call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
921{
922 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000923}
924
Tim Peters2a799bf2002-12-16 20:18:38 +0000925/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
926 * result. tzinfo must be an instance of the tzinfo class. If dst()
927 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000928 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000929 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000930 * ValueError is raised and this returns -1. Else *none is set to 0 and
931 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000932 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000933static PyObject *
934call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000935{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000936 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000937}
938
Tim Petersbad8ff02002-12-30 20:52:32 +0000939/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000940 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000941 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000942 * returns NULL. If the result is a string, we ensure it is a Unicode
943 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000944 */
945static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000946call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 assert(tzinfo != NULL);
951 assert(check_tzinfo_subclass(tzinfo) >= 0);
952 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000955 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000956
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000957 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
958
959 if (result == NULL || result == Py_None)
960 return result;
961
962 if (!PyUnicode_Check(result)) {
963 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
964 "return None or a string, not '%s'",
965 Py_TYPE(result)->tp_name);
966 Py_DECREF(result);
967 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000969
970 return result;
Tim Peters00237032002-12-27 02:21:51 +0000971}
972
Tim Peters2a799bf2002-12-16 20:18:38 +0000973/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
974 * stuff
975 * ", tzinfo=" + repr(tzinfo)
976 * before the closing ")".
977 */
978static PyObject *
979append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 assert(PyUnicode_Check(repr));
984 assert(tzinfo);
985 if (tzinfo == Py_None)
986 return repr;
987 /* Get rid of the trailing ')'. */
988 assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
989 temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
990 PyUnicode_GET_SIZE(repr) - 1);
991 Py_DECREF(repr);
992 if (temp == NULL)
993 return NULL;
994 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
995 Py_DECREF(temp);
996 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +0000997}
998
999/* ---------------------------------------------------------------------------
1000 * String format helpers.
1001 */
1002
1003static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001004format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 static const char *DayNames[] = {
1007 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1008 };
1009 static const char *MonthNames[] = {
1010 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1011 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1012 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1017 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1018 GET_DAY(date), hours, minutes, seconds,
1019 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001020}
1021
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001022static PyObject *delta_negative(PyDateTime_Delta *self);
1023
Tim Peters2a799bf2002-12-16 20:18:38 +00001024/* Add an hours & minutes UTC offset string to buf. buf has no more than
1025 * buflen bytes remaining. The UTC offset is gotten by calling
1026 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1027 * *buf, and that's all. Else the returned value is checked for sanity (an
1028 * integer in range), and if that's OK it's converted to an hours & minutes
1029 * string of the form
1030 * sign HH sep MM
1031 * Returns 0 if everything is OK. If the return value from utcoffset() is
1032 * bogus, an appropriate exception is set and -1 is returned.
1033 */
1034static int
Tim Peters328fff72002-12-20 01:31:27 +00001035format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001037{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001038 PyObject *offset;
1039 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001043
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001044 offset = call_utcoffset(tzinfo, tzinfoarg);
1045 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001047 if (offset == Py_None) {
1048 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 *buf = '\0';
1050 return 0;
1051 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001052 /* Offset is normalized, so it is negative if days < 0 */
1053 if (GET_TD_DAYS(offset) < 0) {
1054 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001056 offset = delta_negative((PyDateTime_Delta *)offset);
1057 Py_DECREF(temp);
1058 if (offset == NULL)
1059 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001061 else {
1062 sign = '+';
1063 }
1064 /* Offset is not negative here. */
1065 seconds = GET_TD_SECONDS(offset);
1066 Py_DECREF(offset);
1067 minutes = divmod(seconds, 60, &seconds);
1068 hours = divmod(minutes, 60, &minutes);
1069 assert(seconds == 0);
1070 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001074}
1075
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001076static PyObject *
1077make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 PyObject *temp;
1080 PyObject *tzinfo = get_tzinfo_member(object);
1081 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1082 if (Zreplacement == NULL)
1083 return NULL;
1084 if (tzinfo == Py_None || tzinfo == NULL)
1085 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 assert(tzinfoarg != NULL);
1088 temp = call_tzname(tzinfo, tzinfoarg);
1089 if (temp == NULL)
1090 goto Error;
1091 if (temp == Py_None) {
1092 Py_DECREF(temp);
1093 return Zreplacement;
1094 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 assert(PyUnicode_Check(temp));
1097 /* Since the tzname is getting stuffed into the
1098 * format, we have to double any % signs so that
1099 * strftime doesn't treat them as format codes.
1100 */
1101 Py_DECREF(Zreplacement);
1102 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1103 Py_DECREF(temp);
1104 if (Zreplacement == NULL)
1105 return NULL;
1106 if (!PyUnicode_Check(Zreplacement)) {
1107 PyErr_SetString(PyExc_TypeError,
1108 "tzname.replace() did not return a string");
1109 goto Error;
1110 }
1111 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001112
1113 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 Py_DECREF(Zreplacement);
1115 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001116}
1117
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001118static PyObject *
1119make_freplacement(PyObject *object)
1120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 char freplacement[64];
1122 if (PyTime_Check(object))
1123 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1124 else if (PyDateTime_Check(object))
1125 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1126 else
1127 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001130}
1131
Tim Peters2a799bf2002-12-16 20:18:38 +00001132/* I sure don't want to reproduce the strftime code from the time module,
1133 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001134 * giving special meanings to the %z, %Z and %f format codes via a
1135 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001136 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1137 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001138 */
1139static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001140wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1146 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1147 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 const char *pin; /* pointer to next char in input format */
1150 Py_ssize_t flen; /* length of input format */
1151 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 PyObject *newfmt = NULL; /* py string, the output format */
1154 char *pnew; /* pointer to available byte in output format */
1155 size_t totalnew; /* number bytes total in output format buffer,
1156 exclusive of trailing \0 */
1157 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 const char *ptoappend; /* ptr to string to append to output buffer */
1160 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 assert(object && format && timetuple);
1163 assert(PyUnicode_Check(format));
1164 /* Convert the input format to a C string and size */
1165 pin = _PyUnicode_AsStringAndSize(format, &flen);
1166 if (!pin)
1167 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 /* Scan the input format, looking for %z/%Z/%f escapes, building
1170 * a new format. Since computing the replacements for those codes
1171 * is expensive, don't unless they're actually used.
1172 */
1173 if (flen > INT_MAX - 1) {
1174 PyErr_NoMemory();
1175 goto Done;
1176 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 totalnew = flen + 1; /* realistic if no %z/%Z */
1179 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1180 if (newfmt == NULL) goto Done;
1181 pnew = PyBytes_AsString(newfmt);
1182 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 while ((ch = *pin++) != '\0') {
1185 if (ch != '%') {
1186 ptoappend = pin - 1;
1187 ntoappend = 1;
1188 }
1189 else if ((ch = *pin++) == '\0') {
1190 /* There's a lone trailing %; doesn't make sense. */
1191 PyErr_SetString(PyExc_ValueError, "strftime format "
1192 "ends with raw %");
1193 goto Done;
1194 }
1195 /* A % has been seen and ch is the character after it. */
1196 else if (ch == 'z') {
1197 if (zreplacement == NULL) {
1198 /* format utcoffset */
1199 char buf[100];
1200 PyObject *tzinfo = get_tzinfo_member(object);
1201 zreplacement = PyBytes_FromStringAndSize("", 0);
1202 if (zreplacement == NULL) goto Done;
1203 if (tzinfo != Py_None && tzinfo != NULL) {
1204 assert(tzinfoarg != NULL);
1205 if (format_utcoffset(buf,
1206 sizeof(buf),
1207 "",
1208 tzinfo,
1209 tzinfoarg) < 0)
1210 goto Done;
1211 Py_DECREF(zreplacement);
1212 zreplacement =
1213 PyBytes_FromStringAndSize(buf,
1214 strlen(buf));
1215 if (zreplacement == NULL)
1216 goto Done;
1217 }
1218 }
1219 assert(zreplacement != NULL);
1220 ptoappend = PyBytes_AS_STRING(zreplacement);
1221 ntoappend = PyBytes_GET_SIZE(zreplacement);
1222 }
1223 else if (ch == 'Z') {
1224 /* format tzname */
1225 if (Zreplacement == NULL) {
1226 Zreplacement = make_Zreplacement(object,
1227 tzinfoarg);
1228 if (Zreplacement == NULL)
1229 goto Done;
1230 }
1231 assert(Zreplacement != NULL);
1232 assert(PyUnicode_Check(Zreplacement));
1233 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1234 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001235 if (ptoappend == NULL)
1236 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 }
1238 else if (ch == 'f') {
1239 /* format microseconds */
1240 if (freplacement == NULL) {
1241 freplacement = make_freplacement(object);
1242 if (freplacement == NULL)
1243 goto Done;
1244 }
1245 assert(freplacement != NULL);
1246 assert(PyBytes_Check(freplacement));
1247 ptoappend = PyBytes_AS_STRING(freplacement);
1248 ntoappend = PyBytes_GET_SIZE(freplacement);
1249 }
1250 else {
1251 /* percent followed by neither z nor Z */
1252 ptoappend = pin - 2;
1253 ntoappend = 2;
1254 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 /* Append the ntoappend chars starting at ptoappend to
1257 * the new format.
1258 */
1259 if (ntoappend == 0)
1260 continue;
1261 assert(ptoappend != NULL);
1262 assert(ntoappend > 0);
1263 while (usednew + ntoappend > totalnew) {
1264 size_t bigger = totalnew << 1;
1265 if ((bigger >> 1) != totalnew) { /* overflow */
1266 PyErr_NoMemory();
1267 goto Done;
1268 }
1269 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1270 goto Done;
1271 totalnew = bigger;
1272 pnew = PyBytes_AsString(newfmt) + usednew;
1273 }
1274 memcpy(pnew, ptoappend, ntoappend);
1275 pnew += ntoappend;
1276 usednew += ntoappend;
1277 assert(usednew <= totalnew);
1278 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1281 goto Done;
1282 {
1283 PyObject *format;
1284 PyObject *time = PyImport_ImportModuleNoBlock("time");
1285 if (time == NULL)
1286 goto Done;
1287 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1288 if (format != NULL) {
1289 result = PyObject_CallMethod(time, "strftime", "OO",
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001290 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 Py_DECREF(format);
1292 }
1293 Py_DECREF(time);
1294 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001295 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 Py_XDECREF(freplacement);
1297 Py_XDECREF(zreplacement);
1298 Py_XDECREF(Zreplacement);
1299 Py_XDECREF(newfmt);
1300 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001301}
1302
Tim Peters2a799bf2002-12-16 20:18:38 +00001303/* ---------------------------------------------------------------------------
1304 * Wrap functions from the time module. These aren't directly available
1305 * from C. Perhaps they should be.
1306 */
1307
1308/* Call time.time() and return its result (a Python float). */
1309static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001310time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 PyObject *result = NULL;
1313 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 if (time != NULL) {
1316 result = PyObject_CallMethod(time, "time", "()");
1317 Py_DECREF(time);
1318 }
1319 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001320}
1321
1322/* Build a time.struct_time. The weekday and day number are automatically
1323 * computed from the y,m,d args.
1324 */
1325static PyObject *
1326build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 PyObject *time;
1329 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 time = PyImport_ImportModuleNoBlock("time");
1332 if (time != NULL) {
1333 result = PyObject_CallMethod(time, "struct_time",
1334 "((iiiiiiiii))",
1335 y, m, d,
1336 hh, mm, ss,
1337 weekday(y, m, d),
1338 days_before_month(y, m) + d,
1339 dstflag);
1340 Py_DECREF(time);
1341 }
1342 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001343}
1344
1345/* ---------------------------------------------------------------------------
1346 * Miscellaneous helpers.
1347 */
1348
Mark Dickinsone94c6792009-02-02 20:36:42 +00001349/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001350 * The comparisons here all most naturally compute a cmp()-like result.
1351 * This little helper turns that into a bool result for rich comparisons.
1352 */
1353static PyObject *
1354diff_to_bool(int diff, int op)
1355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 PyObject *result;
1357 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 switch (op) {
1360 case Py_EQ: istrue = diff == 0; break;
1361 case Py_NE: istrue = diff != 0; break;
1362 case Py_LE: istrue = diff <= 0; break;
1363 case Py_GE: istrue = diff >= 0; break;
1364 case Py_LT: istrue = diff < 0; break;
1365 case Py_GT: istrue = diff > 0; break;
1366 default:
1367 assert(! "op unknown");
1368 istrue = 0; /* To shut up compiler */
1369 }
1370 result = istrue ? Py_True : Py_False;
1371 Py_INCREF(result);
1372 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001373}
1374
Tim Peters07534a62003-02-07 22:50:28 +00001375/* Raises a "can't compare" TypeError and returns NULL. */
1376static PyObject *
1377cmperror(PyObject *a, PyObject *b)
1378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 PyErr_Format(PyExc_TypeError,
1380 "can't compare %s to %s",
1381 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1382 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001383}
1384
Tim Peters2a799bf2002-12-16 20:18:38 +00001385/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001386 * Cached Python objects; these are set by the module init function.
1387 */
1388
1389/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390static PyObject *us_per_us = NULL; /* 1 */
1391static PyObject *us_per_ms = NULL; /* 1000 */
1392static PyObject *us_per_second = NULL; /* 1000000 */
1393static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1394static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1395static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1396static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001397static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1398
Tim Peters2a799bf2002-12-16 20:18:38 +00001399/* ---------------------------------------------------------------------------
1400 * Class implementations.
1401 */
1402
1403/*
1404 * PyDateTime_Delta implementation.
1405 */
1406
1407/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001409 * as a Python int or long.
1410 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1411 * due to ubiquitous overflow possibilities.
1412 */
1413static PyObject *
1414delta_to_microseconds(PyDateTime_Delta *self)
1415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 PyObject *x1 = NULL;
1417 PyObject *x2 = NULL;
1418 PyObject *x3 = NULL;
1419 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1422 if (x1 == NULL)
1423 goto Done;
1424 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1425 if (x2 == NULL)
1426 goto Done;
1427 Py_DECREF(x1);
1428 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 /* x2 has days in seconds */
1431 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1432 if (x1 == NULL)
1433 goto Done;
1434 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1435 if (x3 == NULL)
1436 goto Done;
1437 Py_DECREF(x1);
1438 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001439 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 /* x3 has days+seconds in seconds */
1442 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1443 if (x1 == NULL)
1444 goto Done;
1445 Py_DECREF(x3);
1446 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 /* x1 has days+seconds in us */
1449 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1450 if (x2 == NULL)
1451 goto Done;
1452 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001453
1454Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 Py_XDECREF(x1);
1456 Py_XDECREF(x2);
1457 Py_XDECREF(x3);
1458 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001459}
1460
1461/* Convert a number of us (as a Python int or long) to a timedelta.
1462 */
1463static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001464microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 int us;
1467 int s;
1468 int d;
1469 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 PyObject *tuple = NULL;
1472 PyObject *num = NULL;
1473 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 tuple = PyNumber_Divmod(pyus, us_per_second);
1476 if (tuple == NULL)
1477 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 num = PyTuple_GetItem(tuple, 1); /* us */
1480 if (num == NULL)
1481 goto Done;
1482 temp = PyLong_AsLong(num);
1483 num = NULL;
1484 if (temp == -1 && PyErr_Occurred())
1485 goto Done;
1486 assert(0 <= temp && temp < 1000000);
1487 us = (int)temp;
1488 if (us < 0) {
1489 /* The divisor was positive, so this must be an error. */
1490 assert(PyErr_Occurred());
1491 goto Done;
1492 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1495 if (num == NULL)
1496 goto Done;
1497 Py_INCREF(num);
1498 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 tuple = PyNumber_Divmod(num, seconds_per_day);
1501 if (tuple == NULL)
1502 goto Done;
1503 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 num = PyTuple_GetItem(tuple, 1); /* seconds */
1506 if (num == NULL)
1507 goto Done;
1508 temp = PyLong_AsLong(num);
1509 num = NULL;
1510 if (temp == -1 && PyErr_Occurred())
1511 goto Done;
1512 assert(0 <= temp && temp < 24*3600);
1513 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 if (s < 0) {
1516 /* The divisor was positive, so this must be an error. */
1517 assert(PyErr_Occurred());
1518 goto Done;
1519 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1522 if (num == NULL)
1523 goto Done;
1524 Py_INCREF(num);
1525 temp = PyLong_AsLong(num);
1526 if (temp == -1 && PyErr_Occurred())
1527 goto Done;
1528 d = (int)temp;
1529 if ((long)d != temp) {
1530 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1531 "large to fit in a C int");
1532 goto Done;
1533 }
1534 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001535
1536Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 Py_XDECREF(tuple);
1538 Py_XDECREF(num);
1539 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001540}
1541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542#define microseconds_to_delta(pymicros) \
1543 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001544
Tim Peters2a799bf2002-12-16 20:18:38 +00001545static PyObject *
1546multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 PyObject *pyus_in;
1549 PyObject *pyus_out;
1550 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 pyus_in = delta_to_microseconds(delta);
1553 if (pyus_in == NULL)
1554 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1557 Py_DECREF(pyus_in);
1558 if (pyus_out == NULL)
1559 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 result = microseconds_to_delta(pyus_out);
1562 Py_DECREF(pyus_out);
1563 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001564}
1565
1566static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001567multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1568{
1569 PyObject *result = NULL;
1570 PyObject *pyus_in = NULL, *temp, *pyus_out;
1571 PyObject *ratio = NULL;
1572
1573 pyus_in = delta_to_microseconds(delta);
1574 if (pyus_in == NULL)
1575 return NULL;
1576 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1577 if (ratio == NULL)
1578 goto error;
1579 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1580 Py_DECREF(pyus_in);
1581 pyus_in = NULL;
1582 if (temp == NULL)
1583 goto error;
1584 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1585 Py_DECREF(temp);
1586 if (pyus_out == NULL)
1587 goto error;
1588 result = microseconds_to_delta(pyus_out);
1589 Py_DECREF(pyus_out);
1590 error:
1591 Py_XDECREF(pyus_in);
1592 Py_XDECREF(ratio);
1593
1594 return result;
1595}
1596
1597static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001598divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 PyObject *pyus_in;
1601 PyObject *pyus_out;
1602 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 pyus_in = delta_to_microseconds(delta);
1605 if (pyus_in == NULL)
1606 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1609 Py_DECREF(pyus_in);
1610 if (pyus_out == NULL)
1611 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 result = microseconds_to_delta(pyus_out);
1614 Py_DECREF(pyus_out);
1615 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001616}
1617
1618static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001619divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyObject *pyus_left;
1622 PyObject *pyus_right;
1623 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 pyus_left = delta_to_microseconds(left);
1626 if (pyus_left == NULL)
1627 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 pyus_right = delta_to_microseconds(right);
1630 if (pyus_right == NULL) {
1631 Py_DECREF(pyus_left);
1632 return NULL;
1633 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1636 Py_DECREF(pyus_left);
1637 Py_DECREF(pyus_right);
1638 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001639}
1640
1641static PyObject *
1642truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 PyObject *pyus_left;
1645 PyObject *pyus_right;
1646 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001648 pyus_left = delta_to_microseconds(left);
1649 if (pyus_left == NULL)
1650 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 pyus_right = delta_to_microseconds(right);
1653 if (pyus_right == NULL) {
1654 Py_DECREF(pyus_left);
1655 return NULL;
1656 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1659 Py_DECREF(pyus_left);
1660 Py_DECREF(pyus_right);
1661 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001662}
1663
1664static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001665truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1666{
1667 PyObject *result = NULL;
1668 PyObject *pyus_in = NULL, *temp, *pyus_out;
1669 PyObject *ratio = NULL;
1670
1671 pyus_in = delta_to_microseconds(delta);
1672 if (pyus_in == NULL)
1673 return NULL;
1674 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1675 if (ratio == NULL)
1676 goto error;
1677 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1678 Py_DECREF(pyus_in);
1679 pyus_in = NULL;
1680 if (temp == NULL)
1681 goto error;
1682 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1683 Py_DECREF(temp);
1684 if (pyus_out == NULL)
1685 goto error;
1686 result = microseconds_to_delta(pyus_out);
1687 Py_DECREF(pyus_out);
1688 error:
1689 Py_XDECREF(pyus_in);
1690 Py_XDECREF(ratio);
1691
1692 return result;
1693}
1694
1695static PyObject *
1696truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1697{
1698 PyObject *result;
1699 PyObject *pyus_in, *pyus_out;
1700 pyus_in = delta_to_microseconds(delta);
1701 if (pyus_in == NULL)
1702 return NULL;
1703 pyus_out = divide_nearest(pyus_in, i);
1704 Py_DECREF(pyus_in);
1705 if (pyus_out == NULL)
1706 return NULL;
1707 result = microseconds_to_delta(pyus_out);
1708 Py_DECREF(pyus_out);
1709
1710 return result;
1711}
1712
1713static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001714delta_add(PyObject *left, PyObject *right)
1715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1719 /* delta + delta */
1720 /* The C-level additions can't overflow because of the
1721 * invariant bounds.
1722 */
1723 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1724 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1725 int microseconds = GET_TD_MICROSECONDS(left) +
1726 GET_TD_MICROSECONDS(right);
1727 result = new_delta(days, seconds, microseconds, 1);
1728 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 if (result == Py_NotImplemented)
1731 Py_INCREF(result);
1732 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001733}
1734
1735static PyObject *
1736delta_negative(PyDateTime_Delta *self)
1737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 return new_delta(-GET_TD_DAYS(self),
1739 -GET_TD_SECONDS(self),
1740 -GET_TD_MICROSECONDS(self),
1741 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001742}
1743
1744static PyObject *
1745delta_positive(PyDateTime_Delta *self)
1746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 /* Could optimize this (by returning self) if this isn't a
1748 * subclass -- but who uses unary + ? Approximately nobody.
1749 */
1750 return new_delta(GET_TD_DAYS(self),
1751 GET_TD_SECONDS(self),
1752 GET_TD_MICROSECONDS(self),
1753 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001754}
1755
1756static PyObject *
1757delta_abs(PyDateTime_Delta *self)
1758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 assert(GET_TD_MICROSECONDS(self) >= 0);
1762 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 if (GET_TD_DAYS(self) < 0)
1765 result = delta_negative(self);
1766 else
1767 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001770}
1771
1772static PyObject *
1773delta_subtract(PyObject *left, PyObject *right)
1774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1778 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001779 /* The C-level additions can't overflow because of the
1780 * invariant bounds.
1781 */
1782 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1783 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1784 int microseconds = GET_TD_MICROSECONDS(left) -
1785 GET_TD_MICROSECONDS(right);
1786 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 if (result == Py_NotImplemented)
1790 Py_INCREF(result);
1791 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001792}
1793
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001794static int
1795delta_cmp(PyObject *self, PyObject *other)
1796{
1797 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1798 if (diff == 0) {
1799 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1800 if (diff == 0)
1801 diff = GET_TD_MICROSECONDS(self) -
1802 GET_TD_MICROSECONDS(other);
1803 }
1804 return diff;
1805}
1806
Tim Peters2a799bf2002-12-16 20:18:38 +00001807static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001808delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001811 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 return diff_to_bool(diff, op);
1813 }
1814 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001815 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001817}
1818
1819static PyObject *delta_getstate(PyDateTime_Delta *self);
1820
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001821static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001822delta_hash(PyDateTime_Delta *self)
1823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 if (self->hashcode == -1) {
1825 PyObject *temp = delta_getstate(self);
1826 if (temp != NULL) {
1827 self->hashcode = PyObject_Hash(temp);
1828 Py_DECREF(temp);
1829 }
1830 }
1831 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001832}
1833
1834static PyObject *
1835delta_multiply(PyObject *left, PyObject *right)
1836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 if (PyDelta_Check(left)) {
1840 /* delta * ??? */
1841 if (PyLong_Check(right))
1842 result = multiply_int_timedelta(right,
1843 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001844 else if (PyFloat_Check(right))
1845 result = multiply_float_timedelta(right,
1846 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 }
1848 else if (PyLong_Check(left))
1849 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001850 (PyDateTime_Delta *) right);
1851 else if (PyFloat_Check(left))
1852 result = multiply_float_timedelta(left,
1853 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 if (result == Py_NotImplemented)
1856 Py_INCREF(result);
1857 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001858}
1859
1860static PyObject *
1861delta_divide(PyObject *left, PyObject *right)
1862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 if (PyDelta_Check(left)) {
1866 /* delta * ??? */
1867 if (PyLong_Check(right))
1868 result = divide_timedelta_int(
1869 (PyDateTime_Delta *)left,
1870 right);
1871 else if (PyDelta_Check(right))
1872 result = divide_timedelta_timedelta(
1873 (PyDateTime_Delta *)left,
1874 (PyDateTime_Delta *)right);
1875 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 if (result == Py_NotImplemented)
1878 Py_INCREF(result);
1879 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001880}
1881
Mark Dickinson7c186e22010-04-20 22:32:49 +00001882static PyObject *
1883delta_truedivide(PyObject *left, PyObject *right)
1884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 if (PyDelta_Check(left)) {
1888 if (PyDelta_Check(right))
1889 result = truedivide_timedelta_timedelta(
1890 (PyDateTime_Delta *)left,
1891 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001892 else if (PyFloat_Check(right))
1893 result = truedivide_timedelta_float(
1894 (PyDateTime_Delta *)left, right);
1895 else if (PyLong_Check(right))
1896 result = truedivide_timedelta_int(
1897 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 if (result == Py_NotImplemented)
1901 Py_INCREF(result);
1902 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001903}
1904
1905static PyObject *
1906delta_remainder(PyObject *left, PyObject *right)
1907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 PyObject *pyus_left;
1909 PyObject *pyus_right;
1910 PyObject *pyus_remainder;
1911 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001912
Brian Curtindfc80e32011-08-10 20:28:54 -05001913 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1914 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1917 if (pyus_left == NULL)
1918 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1921 if (pyus_right == NULL) {
1922 Py_DECREF(pyus_left);
1923 return NULL;
1924 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1927 Py_DECREF(pyus_left);
1928 Py_DECREF(pyus_right);
1929 if (pyus_remainder == NULL)
1930 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 remainder = microseconds_to_delta(pyus_remainder);
1933 Py_DECREF(pyus_remainder);
1934 if (remainder == NULL)
1935 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001938}
1939
1940static PyObject *
1941delta_divmod(PyObject *left, PyObject *right)
1942{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 PyObject *pyus_left;
1944 PyObject *pyus_right;
1945 PyObject *divmod;
1946 PyObject *delta;
1947 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001948
Brian Curtindfc80e32011-08-10 20:28:54 -05001949 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1950 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1953 if (pyus_left == NULL)
1954 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1957 if (pyus_right == NULL) {
1958 Py_DECREF(pyus_left);
1959 return NULL;
1960 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1963 Py_DECREF(pyus_left);
1964 Py_DECREF(pyus_right);
1965 if (divmod == NULL)
1966 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 assert(PyTuple_Size(divmod) == 2);
1969 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1970 if (delta == NULL) {
1971 Py_DECREF(divmod);
1972 return NULL;
1973 }
1974 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1975 Py_DECREF(delta);
1976 Py_DECREF(divmod);
1977 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001978}
1979
Tim Peters2a799bf2002-12-16 20:18:38 +00001980/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1981 * timedelta constructor. sofar is the # of microseconds accounted for
1982 * so far, and there are factor microseconds per current unit, the number
1983 * of which is given by num. num * factor is added to sofar in a
1984 * numerically careful way, and that's the result. Any fractional
1985 * microseconds left over (this can happen if num is a float type) are
1986 * added into *leftover.
1987 * Note that there are many ways this can give an error (NULL) return.
1988 */
1989static PyObject *
1990accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1991 double *leftover)
1992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 PyObject *prod;
1994 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00001995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 if (PyLong_Check(num)) {
1999 prod = PyNumber_Multiply(num, factor);
2000 if (prod == NULL)
2001 return NULL;
2002 sum = PyNumber_Add(sofar, prod);
2003 Py_DECREF(prod);
2004 return sum;
2005 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 if (PyFloat_Check(num)) {
2008 double dnum;
2009 double fracpart;
2010 double intpart;
2011 PyObject *x;
2012 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 /* The Plan: decompose num into an integer part and a
2015 * fractional part, num = intpart + fracpart.
2016 * Then num * factor ==
2017 * intpart * factor + fracpart * factor
2018 * and the LHS can be computed exactly in long arithmetic.
2019 * The RHS is again broken into an int part and frac part.
2020 * and the frac part is added into *leftover.
2021 */
2022 dnum = PyFloat_AsDouble(num);
2023 if (dnum == -1.0 && PyErr_Occurred())
2024 return NULL;
2025 fracpart = modf(dnum, &intpart);
2026 x = PyLong_FromDouble(intpart);
2027 if (x == NULL)
2028 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 prod = PyNumber_Multiply(x, factor);
2031 Py_DECREF(x);
2032 if (prod == NULL)
2033 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 sum = PyNumber_Add(sofar, prod);
2036 Py_DECREF(prod);
2037 if (sum == NULL)
2038 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 if (fracpart == 0.0)
2041 return sum;
2042 /* So far we've lost no information. Dealing with the
2043 * fractional part requires float arithmetic, and may
2044 * lose a little info.
2045 */
2046 assert(PyLong_Check(factor));
2047 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 dnum *= fracpart;
2050 fracpart = modf(dnum, &intpart);
2051 x = PyLong_FromDouble(intpart);
2052 if (x == NULL) {
2053 Py_DECREF(sum);
2054 return NULL;
2055 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002057 y = PyNumber_Add(sum, x);
2058 Py_DECREF(sum);
2059 Py_DECREF(x);
2060 *leftover += fracpart;
2061 return y;
2062 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 PyErr_Format(PyExc_TypeError,
2065 "unsupported type for timedelta %s component: %s",
2066 tag, Py_TYPE(num)->tp_name);
2067 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002068}
2069
2070static PyObject *
2071delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 /* Argument objects. */
2076 PyObject *day = NULL;
2077 PyObject *second = NULL;
2078 PyObject *us = NULL;
2079 PyObject *ms = NULL;
2080 PyObject *minute = NULL;
2081 PyObject *hour = NULL;
2082 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 PyObject *x = NULL; /* running sum of microseconds */
2085 PyObject *y = NULL; /* temp sum of microseconds */
2086 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 static char *keywords[] = {
2089 "days", "seconds", "microseconds", "milliseconds",
2090 "minutes", "hours", "weeks", NULL
2091 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2094 keywords,
2095 &day, &second, &us,
2096 &ms, &minute, &hour, &week) == 0)
2097 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 x = PyLong_FromLong(0);
2100 if (x == NULL)
2101 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103#define CLEANUP \
2104 Py_DECREF(x); \
2105 x = y; \
2106 if (x == NULL) \
2107 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 if (us) {
2110 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2111 CLEANUP;
2112 }
2113 if (ms) {
2114 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2115 CLEANUP;
2116 }
2117 if (second) {
2118 y = accum("seconds", x, second, us_per_second, &leftover_us);
2119 CLEANUP;
2120 }
2121 if (minute) {
2122 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2123 CLEANUP;
2124 }
2125 if (hour) {
2126 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2127 CLEANUP;
2128 }
2129 if (day) {
2130 y = accum("days", x, day, us_per_day, &leftover_us);
2131 CLEANUP;
2132 }
2133 if (week) {
2134 y = accum("weeks", x, week, us_per_week, &leftover_us);
2135 CLEANUP;
2136 }
2137 if (leftover_us) {
2138 /* Round to nearest whole # of us, and add into x. */
2139 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2140 if (temp == NULL) {
2141 Py_DECREF(x);
2142 goto Done;
2143 }
2144 y = PyNumber_Add(x, temp);
2145 Py_DECREF(temp);
2146 CLEANUP;
2147 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 self = microseconds_to_delta_ex(x, type);
2150 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002151Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002152 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002153
2154#undef CLEANUP
2155}
2156
2157static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002158delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 return (GET_TD_DAYS(self) != 0
2161 || GET_TD_SECONDS(self) != 0
2162 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002163}
2164
2165static PyObject *
2166delta_repr(PyDateTime_Delta *self)
2167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 if (GET_TD_MICROSECONDS(self) != 0)
2169 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2170 Py_TYPE(self)->tp_name,
2171 GET_TD_DAYS(self),
2172 GET_TD_SECONDS(self),
2173 GET_TD_MICROSECONDS(self));
2174 if (GET_TD_SECONDS(self) != 0)
2175 return PyUnicode_FromFormat("%s(%d, %d)",
2176 Py_TYPE(self)->tp_name,
2177 GET_TD_DAYS(self),
2178 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 return PyUnicode_FromFormat("%s(%d)",
2181 Py_TYPE(self)->tp_name,
2182 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002183}
2184
2185static PyObject *
2186delta_str(PyDateTime_Delta *self)
2187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 int us = GET_TD_MICROSECONDS(self);
2189 int seconds = GET_TD_SECONDS(self);
2190 int minutes = divmod(seconds, 60, &seconds);
2191 int hours = divmod(minutes, 60, &minutes);
2192 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 if (days) {
2195 if (us)
2196 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2197 days, (days == 1 || days == -1) ? "" : "s",
2198 hours, minutes, seconds, us);
2199 else
2200 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2201 days, (days == 1 || days == -1) ? "" : "s",
2202 hours, minutes, seconds);
2203 } else {
2204 if (us)
2205 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2206 hours, minutes, seconds, us);
2207 else
2208 return PyUnicode_FromFormat("%d:%02d:%02d",
2209 hours, minutes, seconds);
2210 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002211
Tim Peters2a799bf2002-12-16 20:18:38 +00002212}
2213
Tim Peters371935f2003-02-01 01:52:50 +00002214/* Pickle support, a simple use of __reduce__. */
2215
Tim Petersb57f8f02003-02-01 02:54:15 +00002216/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002217static PyObject *
2218delta_getstate(PyDateTime_Delta *self)
2219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 return Py_BuildValue("iii", GET_TD_DAYS(self),
2221 GET_TD_SECONDS(self),
2222 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002223}
2224
Tim Peters2a799bf2002-12-16 20:18:38 +00002225static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002226delta_total_seconds(PyObject *self)
2227{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 PyObject *total_seconds;
2229 PyObject *total_microseconds;
2230 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2233 if (total_microseconds == NULL)
2234 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002236 one_million = PyLong_FromLong(1000000L);
2237 if (one_million == NULL) {
2238 Py_DECREF(total_microseconds);
2239 return NULL;
2240 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002242 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 Py_DECREF(total_microseconds);
2245 Py_DECREF(one_million);
2246 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002247}
2248
2249static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002250delta_reduce(PyDateTime_Delta* self)
2251{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002252 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002253}
2254
2255#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2256
2257static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002259 {"days", T_INT, OFFSET(days), READONLY,
2260 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 {"seconds", T_INT, OFFSET(seconds), READONLY,
2263 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2266 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2267 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002268};
2269
2270static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2272 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2275 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002278};
2279
2280static char delta_doc[] =
2281PyDoc_STR("Difference between two datetime values.");
2282
2283static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 delta_add, /* nb_add */
2285 delta_subtract, /* nb_subtract */
2286 delta_multiply, /* nb_multiply */
2287 delta_remainder, /* nb_remainder */
2288 delta_divmod, /* nb_divmod */
2289 0, /* nb_power */
2290 (unaryfunc)delta_negative, /* nb_negative */
2291 (unaryfunc)delta_positive, /* nb_positive */
2292 (unaryfunc)delta_abs, /* nb_absolute */
2293 (inquiry)delta_bool, /* nb_bool */
2294 0, /*nb_invert*/
2295 0, /*nb_lshift*/
2296 0, /*nb_rshift*/
2297 0, /*nb_and*/
2298 0, /*nb_xor*/
2299 0, /*nb_or*/
2300 0, /*nb_int*/
2301 0, /*nb_reserved*/
2302 0, /*nb_float*/
2303 0, /*nb_inplace_add*/
2304 0, /*nb_inplace_subtract*/
2305 0, /*nb_inplace_multiply*/
2306 0, /*nb_inplace_remainder*/
2307 0, /*nb_inplace_power*/
2308 0, /*nb_inplace_lshift*/
2309 0, /*nb_inplace_rshift*/
2310 0, /*nb_inplace_and*/
2311 0, /*nb_inplace_xor*/
2312 0, /*nb_inplace_or*/
2313 delta_divide, /* nb_floor_divide */
2314 delta_truedivide, /* nb_true_divide */
2315 0, /* nb_inplace_floor_divide */
2316 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002317};
2318
2319static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002320 PyVarObject_HEAD_INIT(NULL, 0)
2321 "datetime.timedelta", /* tp_name */
2322 sizeof(PyDateTime_Delta), /* tp_basicsize */
2323 0, /* tp_itemsize */
2324 0, /* tp_dealloc */
2325 0, /* tp_print */
2326 0, /* tp_getattr */
2327 0, /* tp_setattr */
2328 0, /* tp_reserved */
2329 (reprfunc)delta_repr, /* tp_repr */
2330 &delta_as_number, /* tp_as_number */
2331 0, /* tp_as_sequence */
2332 0, /* tp_as_mapping */
2333 (hashfunc)delta_hash, /* tp_hash */
2334 0, /* tp_call */
2335 (reprfunc)delta_str, /* tp_str */
2336 PyObject_GenericGetAttr, /* tp_getattro */
2337 0, /* tp_setattro */
2338 0, /* tp_as_buffer */
2339 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2340 delta_doc, /* tp_doc */
2341 0, /* tp_traverse */
2342 0, /* tp_clear */
2343 delta_richcompare, /* tp_richcompare */
2344 0, /* tp_weaklistoffset */
2345 0, /* tp_iter */
2346 0, /* tp_iternext */
2347 delta_methods, /* tp_methods */
2348 delta_members, /* tp_members */
2349 0, /* tp_getset */
2350 0, /* tp_base */
2351 0, /* tp_dict */
2352 0, /* tp_descr_get */
2353 0, /* tp_descr_set */
2354 0, /* tp_dictoffset */
2355 0, /* tp_init */
2356 0, /* tp_alloc */
2357 delta_new, /* tp_new */
2358 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002359};
2360
2361/*
2362 * PyDateTime_Date implementation.
2363 */
2364
2365/* Accessor properties. */
2366
2367static PyObject *
2368date_year(PyDateTime_Date *self, void *unused)
2369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002371}
2372
2373static PyObject *
2374date_month(PyDateTime_Date *self, void *unused)
2375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002377}
2378
2379static PyObject *
2380date_day(PyDateTime_Date *self, void *unused)
2381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002383}
2384
2385static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 {"year", (getter)date_year},
2387 {"month", (getter)date_month},
2388 {"day", (getter)date_day},
2389 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002390};
2391
2392/* Constructors. */
2393
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002394static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002395
Tim Peters2a799bf2002-12-16 20:18:38 +00002396static PyObject *
2397date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 PyObject *self = NULL;
2400 PyObject *state;
2401 int year;
2402 int month;
2403 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 /* Check for invocation from pickle with __getstate__ state */
2406 if (PyTuple_GET_SIZE(args) == 1 &&
2407 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2408 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2409 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2410 {
2411 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2414 if (me != NULL) {
2415 char *pdata = PyBytes_AS_STRING(state);
2416 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2417 me->hashcode = -1;
2418 }
2419 return (PyObject *)me;
2420 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2423 &year, &month, &day)) {
2424 if (check_date_args(year, month, day) < 0)
2425 return NULL;
2426 self = new_date_ex(year, month, day, type);
2427 }
2428 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002429}
2430
2431/* Return new date from localtime(t). */
2432static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002433date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 struct tm *tm;
2436 time_t t;
2437 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 t = _PyTime_DoubleToTimet(ts);
2440 if (t == (time_t)-1 && PyErr_Occurred())
2441 return NULL;
2442 tm = localtime(&t);
2443 if (tm)
2444 result = PyObject_CallFunction(cls, "iii",
2445 tm->tm_year + 1900,
2446 tm->tm_mon + 1,
2447 tm->tm_mday);
2448 else
2449 PyErr_SetString(PyExc_ValueError,
2450 "timestamp out of range for "
2451 "platform localtime() function");
2452 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002453}
2454
2455/* Return new date from current time.
2456 * We say this is equivalent to fromtimestamp(time.time()), and the
2457 * only way to be sure of that is to *call* time.time(). That's not
2458 * generally the same as calling C's time.
2459 */
2460static PyObject *
2461date_today(PyObject *cls, PyObject *dummy)
2462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 PyObject *time;
2464 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 time = time_time();
2467 if (time == NULL)
2468 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002470 /* Note well: today() is a class method, so this may not call
2471 * date.fromtimestamp. For example, it may call
2472 * datetime.fromtimestamp. That's why we need all the accuracy
2473 * time.time() delivers; if someone were gonzo about optimization,
2474 * date.today() could get away with plain C time().
2475 */
2476 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2477 Py_DECREF(time);
2478 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002479}
2480
2481/* Return new date from given timestamp (Python timestamp -- a double). */
2482static PyObject *
2483date_fromtimestamp(PyObject *cls, PyObject *args)
2484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 double timestamp;
2486 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002488 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2489 result = date_local_from_time_t(cls, timestamp);
2490 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002491}
2492
2493/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2494 * the ordinal is out of range.
2495 */
2496static PyObject *
2497date_fromordinal(PyObject *cls, PyObject *args)
2498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 PyObject *result = NULL;
2500 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2503 int year;
2504 int month;
2505 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002507 if (ordinal < 1)
2508 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2509 ">= 1");
2510 else {
2511 ord_to_ymd(ordinal, &year, &month, &day);
2512 result = PyObject_CallFunction(cls, "iii",
2513 year, month, day);
2514 }
2515 }
2516 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002517}
2518
2519/*
2520 * Date arithmetic.
2521 */
2522
2523/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2524 * instead.
2525 */
2526static PyObject *
2527add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 PyObject *result = NULL;
2530 int year = GET_YEAR(date);
2531 int month = GET_MONTH(date);
2532 int deltadays = GET_TD_DAYS(delta);
2533 /* C-level overflow is impossible because |deltadays| < 1e9. */
2534 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 if (normalize_date(&year, &month, &day) >= 0)
2537 result = new_date(year, month, day);
2538 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002539}
2540
2541static PyObject *
2542date_add(PyObject *left, PyObject *right)
2543{
Brian Curtindfc80e32011-08-10 20:28:54 -05002544 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2545 Py_RETURN_NOTIMPLEMENTED;
2546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002547 if (PyDate_Check(left)) {
2548 /* date + ??? */
2549 if (PyDelta_Check(right))
2550 /* date + delta */
2551 return add_date_timedelta((PyDateTime_Date *) left,
2552 (PyDateTime_Delta *) right,
2553 0);
2554 }
2555 else {
2556 /* ??? + date
2557 * 'right' must be one of us, or we wouldn't have been called
2558 */
2559 if (PyDelta_Check(left))
2560 /* delta + date */
2561 return add_date_timedelta((PyDateTime_Date *) right,
2562 (PyDateTime_Delta *) left,
2563 0);
2564 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002565 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002566}
2567
2568static PyObject *
2569date_subtract(PyObject *left, PyObject *right)
2570{
Brian Curtindfc80e32011-08-10 20:28:54 -05002571 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2572 Py_RETURN_NOTIMPLEMENTED;
2573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002574 if (PyDate_Check(left)) {
2575 if (PyDate_Check(right)) {
2576 /* date - date */
2577 int left_ord = ymd_to_ord(GET_YEAR(left),
2578 GET_MONTH(left),
2579 GET_DAY(left));
2580 int right_ord = ymd_to_ord(GET_YEAR(right),
2581 GET_MONTH(right),
2582 GET_DAY(right));
2583 return new_delta(left_ord - right_ord, 0, 0, 0);
2584 }
2585 if (PyDelta_Check(right)) {
2586 /* date - delta */
2587 return add_date_timedelta((PyDateTime_Date *) left,
2588 (PyDateTime_Delta *) right,
2589 1);
2590 }
2591 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002592 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002593}
2594
2595
2596/* Various ways to turn a date into a string. */
2597
2598static PyObject *
2599date_repr(PyDateTime_Date *self)
2600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2602 Py_TYPE(self)->tp_name,
2603 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002604}
2605
2606static PyObject *
2607date_isoformat(PyDateTime_Date *self)
2608{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002609 return PyUnicode_FromFormat("%04d-%02d-%02d",
2610 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002611}
2612
Tim Peterse2df5ff2003-05-02 18:39:55 +00002613/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002614static PyObject *
2615date_str(PyDateTime_Date *self)
2616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002618}
2619
2620
2621static PyObject *
2622date_ctime(PyDateTime_Date *self)
2623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002625}
2626
2627static PyObject *
2628date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 /* This method can be inherited, and needs to call the
2631 * timetuple() method appropriate to self's class.
2632 */
2633 PyObject *result;
2634 PyObject *tuple;
2635 PyObject *format;
2636 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002638 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2639 &format))
2640 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2643 if (tuple == NULL)
2644 return NULL;
2645 result = wrap_strftime((PyObject *)self, format, tuple,
2646 (PyObject *)self);
2647 Py_DECREF(tuple);
2648 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002649}
2650
Eric Smith1ba31142007-09-11 18:06:02 +00002651static PyObject *
2652date_format(PyDateTime_Date *self, PyObject *args)
2653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002656 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2657 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 /* if the format is zero length, return str(self) */
2660 if (PyUnicode_GetSize(format) == 0)
2661 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002663 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002664}
2665
Tim Peters2a799bf2002-12-16 20:18:38 +00002666/* ISO methods. */
2667
2668static PyObject *
2669date_isoweekday(PyDateTime_Date *self)
2670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002673 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002674}
2675
2676static PyObject *
2677date_isocalendar(PyDateTime_Date *self)
2678{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002679 int year = GET_YEAR(self);
2680 int week1_monday = iso_week1_monday(year);
2681 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2682 int week;
2683 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002685 week = divmod(today - week1_monday, 7, &day);
2686 if (week < 0) {
2687 --year;
2688 week1_monday = iso_week1_monday(year);
2689 week = divmod(today - week1_monday, 7, &day);
2690 }
2691 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2692 ++year;
2693 week = 0;
2694 }
2695 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002696}
2697
2698/* Miscellaneous methods. */
2699
Tim Peters2a799bf2002-12-16 20:18:38 +00002700static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002701date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002702{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002703 if (PyDate_Check(other)) {
2704 int diff = memcmp(((PyDateTime_Date *)self)->data,
2705 ((PyDateTime_Date *)other)->data,
2706 _PyDateTime_DATE_DATASIZE);
2707 return diff_to_bool(diff, op);
2708 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002709 else
2710 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002711}
2712
2713static PyObject *
2714date_timetuple(PyDateTime_Date *self)
2715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002716 return build_struct_time(GET_YEAR(self),
2717 GET_MONTH(self),
2718 GET_DAY(self),
2719 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002720}
2721
Tim Peters12bf3392002-12-24 05:41:27 +00002722static PyObject *
2723date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002725 PyObject *clone;
2726 PyObject *tuple;
2727 int year = GET_YEAR(self);
2728 int month = GET_MONTH(self);
2729 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002731 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2732 &year, &month, &day))
2733 return NULL;
2734 tuple = Py_BuildValue("iii", year, month, day);
2735 if (tuple == NULL)
2736 return NULL;
2737 clone = date_new(Py_TYPE(self), tuple, NULL);
2738 Py_DECREF(tuple);
2739 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002740}
2741
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002742/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002743 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002744*/
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002745static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002746generic_hash(unsigned char *data, int len)
2747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002748 register unsigned char *p;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002749 register Py_hash_t x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002751 p = (unsigned char *) data;
2752 x = *p << 7;
2753 while (--len >= 0)
2754 x = (1000003*x) ^ *p++;
2755 x ^= len;
2756 if (x == -1)
2757 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002759 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002760}
2761
2762
2763static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002764
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002765static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002766date_hash(PyDateTime_Date *self)
2767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002768 if (self->hashcode == -1)
2769 self->hashcode = generic_hash(
2770 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002773}
2774
2775static PyObject *
2776date_toordinal(PyDateTime_Date *self)
2777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002778 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2779 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002780}
2781
2782static PyObject *
2783date_weekday(PyDateTime_Date *self)
2784{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002785 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002787 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002788}
2789
Tim Peters371935f2003-02-01 01:52:50 +00002790/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002791
Tim Petersb57f8f02003-02-01 02:54:15 +00002792/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002793static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002794date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 PyObject* field;
2797 field = PyBytes_FromStringAndSize((char*)self->data,
2798 _PyDateTime_DATE_DATASIZE);
2799 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002800}
2801
2802static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002803date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002806}
2807
2808static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002812 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2813 METH_CLASS,
2814 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2815 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002817 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2818 METH_CLASS,
2819 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2820 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2823 PyDoc_STR("Current date or datetime: same as "
2824 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002826 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002828 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2829 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2832 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002834 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2835 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2838 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002840 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2841 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2842 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2845 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2848 PyDoc_STR("Return the day of the week represented by the date.\n"
2849 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2852 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2853 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002855 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2856 PyDoc_STR("Return the day of the week represented by the date.\n"
2857 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002859 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2860 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2863 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002865 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002866};
2867
2868static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002869PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002870
2871static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002872 date_add, /* nb_add */
2873 date_subtract, /* nb_subtract */
2874 0, /* nb_multiply */
2875 0, /* nb_remainder */
2876 0, /* nb_divmod */
2877 0, /* nb_power */
2878 0, /* nb_negative */
2879 0, /* nb_positive */
2880 0, /* nb_absolute */
2881 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002882};
2883
2884static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002885 PyVarObject_HEAD_INIT(NULL, 0)
2886 "datetime.date", /* tp_name */
2887 sizeof(PyDateTime_Date), /* tp_basicsize */
2888 0, /* tp_itemsize */
2889 0, /* tp_dealloc */
2890 0, /* tp_print */
2891 0, /* tp_getattr */
2892 0, /* tp_setattr */
2893 0, /* tp_reserved */
2894 (reprfunc)date_repr, /* tp_repr */
2895 &date_as_number, /* tp_as_number */
2896 0, /* tp_as_sequence */
2897 0, /* tp_as_mapping */
2898 (hashfunc)date_hash, /* tp_hash */
2899 0, /* tp_call */
2900 (reprfunc)date_str, /* tp_str */
2901 PyObject_GenericGetAttr, /* tp_getattro */
2902 0, /* tp_setattro */
2903 0, /* tp_as_buffer */
2904 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2905 date_doc, /* tp_doc */
2906 0, /* tp_traverse */
2907 0, /* tp_clear */
2908 date_richcompare, /* tp_richcompare */
2909 0, /* tp_weaklistoffset */
2910 0, /* tp_iter */
2911 0, /* tp_iternext */
2912 date_methods, /* tp_methods */
2913 0, /* tp_members */
2914 date_getset, /* tp_getset */
2915 0, /* tp_base */
2916 0, /* tp_dict */
2917 0, /* tp_descr_get */
2918 0, /* tp_descr_set */
2919 0, /* tp_dictoffset */
2920 0, /* tp_init */
2921 0, /* tp_alloc */
2922 date_new, /* tp_new */
2923 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002924};
2925
2926/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002927 * PyDateTime_TZInfo implementation.
2928 */
2929
2930/* This is a pure abstract base class, so doesn't do anything beyond
2931 * raising NotImplemented exceptions. Real tzinfo classes need
2932 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002933 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002934 * be subclasses of this tzinfo class, which is easy and quick to check).
2935 *
2936 * Note: For reasons having to do with pickling of subclasses, we have
2937 * to allow tzinfo objects to be instantiated. This wasn't an issue
2938 * in the Python implementation (__init__() could raise NotImplementedError
2939 * there without ill effect), but doing so in the C implementation hit a
2940 * brick wall.
2941 */
2942
2943static PyObject *
2944tzinfo_nogo(const char* methodname)
2945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002946 PyErr_Format(PyExc_NotImplementedError,
2947 "a tzinfo subclass must implement %s()",
2948 methodname);
2949 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002950}
2951
2952/* Methods. A subclass must implement these. */
2953
Tim Peters52dcce22003-01-23 16:36:11 +00002954static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002955tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002957 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002958}
2959
Tim Peters52dcce22003-01-23 16:36:11 +00002960static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002961tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002963 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002964}
2965
Tim Peters52dcce22003-01-23 16:36:11 +00002966static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002967tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002969 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002970}
2971
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002972
2973static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2974 PyDateTime_Delta *delta,
2975 int factor);
2976static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2977static PyObject *datetime_dst(PyObject *self, PyObject *);
2978
Tim Peters52dcce22003-01-23 16:36:11 +00002979static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002980tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002981{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002982 PyObject *result = NULL;
2983 PyObject *off = NULL, *dst = NULL;
2984 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002985
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002986 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002987 PyErr_SetString(PyExc_TypeError,
2988 "fromutc: argument must be a datetime");
2989 return NULL;
2990 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002991 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002992 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2993 "is not self");
2994 return NULL;
2995 }
Tim Peters52dcce22003-01-23 16:36:11 +00002996
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002997 off = datetime_utcoffset(dt, NULL);
2998 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002999 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003000 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003001 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3002 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003003 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003004 }
Tim Peters52dcce22003-01-23 16:36:11 +00003005
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003006 dst = datetime_dst(dt, NULL);
3007 if (dst == NULL)
3008 goto Fail;
3009 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003010 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3011 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003012 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003013 }
Tim Peters52dcce22003-01-23 16:36:11 +00003014
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003015 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3016 if (delta == NULL)
3017 goto Fail;
3018 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003019 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003020 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003021
3022 Py_DECREF(dst);
3023 dst = call_dst(GET_DT_TZINFO(dt), result);
3024 if (dst == NULL)
3025 goto Fail;
3026 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003027 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003028 if (delta_bool(delta) != 0) {
3029 PyObject *temp = result;
3030 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3031 (PyDateTime_Delta *)dst, 1);
3032 Py_DECREF(temp);
3033 if (result == NULL)
3034 goto Fail;
3035 }
3036 Py_DECREF(delta);
3037 Py_DECREF(dst);
3038 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003039 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003040
3041Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003042 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3043 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003045 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003046Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003047 Py_XDECREF(off);
3048 Py_XDECREF(dst);
3049 Py_XDECREF(delta);
3050 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003051 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003052}
3053
Tim Peters2a799bf2002-12-16 20:18:38 +00003054/*
3055 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003056 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003057 */
3058
Guido van Rossum177e41a2003-01-30 22:06:23 +00003059static PyObject *
3060tzinfo_reduce(PyObject *self)
3061{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 PyObject *args, *state, *tmp;
3063 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003065 tmp = PyTuple_New(0);
3066 if (tmp == NULL)
3067 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003069 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3070 if (getinitargs != NULL) {
3071 args = PyObject_CallObject(getinitargs, tmp);
3072 Py_DECREF(getinitargs);
3073 if (args == NULL) {
3074 Py_DECREF(tmp);
3075 return NULL;
3076 }
3077 }
3078 else {
3079 PyErr_Clear();
3080 args = tmp;
3081 Py_INCREF(args);
3082 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003084 getstate = PyObject_GetAttrString(self, "__getstate__");
3085 if (getstate != NULL) {
3086 state = PyObject_CallObject(getstate, tmp);
3087 Py_DECREF(getstate);
3088 if (state == NULL) {
3089 Py_DECREF(args);
3090 Py_DECREF(tmp);
3091 return NULL;
3092 }
3093 }
3094 else {
3095 PyObject **dictptr;
3096 PyErr_Clear();
3097 state = Py_None;
3098 dictptr = _PyObject_GetDictPtr(self);
3099 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3100 state = *dictptr;
3101 Py_INCREF(state);
3102 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003104 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003106 if (state == Py_None) {
3107 Py_DECREF(state);
3108 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3109 }
3110 else
3111 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003112}
Tim Peters2a799bf2002-12-16 20:18:38 +00003113
3114static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003116 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3117 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003119 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003120 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3121 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003123 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3124 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003126 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003127 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003129 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3130 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003132 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003133};
3134
3135static char tzinfo_doc[] =
3136PyDoc_STR("Abstract base class for time zone info objects.");
3137
Neal Norwitz227b5332006-03-22 09:28:35 +00003138static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 PyVarObject_HEAD_INIT(NULL, 0)
3140 "datetime.tzinfo", /* tp_name */
3141 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3142 0, /* tp_itemsize */
3143 0, /* tp_dealloc */
3144 0, /* tp_print */
3145 0, /* tp_getattr */
3146 0, /* tp_setattr */
3147 0, /* tp_reserved */
3148 0, /* tp_repr */
3149 0, /* tp_as_number */
3150 0, /* tp_as_sequence */
3151 0, /* tp_as_mapping */
3152 0, /* tp_hash */
3153 0, /* tp_call */
3154 0, /* tp_str */
3155 PyObject_GenericGetAttr, /* tp_getattro */
3156 0, /* tp_setattro */
3157 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003158 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003159 tzinfo_doc, /* tp_doc */
3160 0, /* tp_traverse */
3161 0, /* tp_clear */
3162 0, /* tp_richcompare */
3163 0, /* tp_weaklistoffset */
3164 0, /* tp_iter */
3165 0, /* tp_iternext */
3166 tzinfo_methods, /* tp_methods */
3167 0, /* tp_members */
3168 0, /* tp_getset */
3169 0, /* tp_base */
3170 0, /* tp_dict */
3171 0, /* tp_descr_get */
3172 0, /* tp_descr_set */
3173 0, /* tp_dictoffset */
3174 0, /* tp_init */
3175 0, /* tp_alloc */
3176 PyType_GenericNew, /* tp_new */
3177 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003178};
3179
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003180static char *timezone_kws[] = {"offset", "name", NULL};
3181
3182static PyObject *
3183timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3184{
3185 PyObject *offset;
3186 PyObject *name = NULL;
3187 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3188 &PyDateTime_DeltaType, &offset,
3189 &PyUnicode_Type, &name))
3190 return new_timezone(offset, name);
3191
3192 return NULL;
3193}
3194
3195static void
3196timezone_dealloc(PyDateTime_TimeZone *self)
3197{
3198 Py_CLEAR(self->offset);
3199 Py_CLEAR(self->name);
3200 Py_TYPE(self)->tp_free((PyObject *)self);
3201}
3202
3203static PyObject *
3204timezone_richcompare(PyDateTime_TimeZone *self,
3205 PyDateTime_TimeZone *other, int op)
3206{
Brian Curtindfc80e32011-08-10 20:28:54 -05003207 if (op != Py_EQ && op != Py_NE)
3208 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003209 return delta_richcompare(self->offset, other->offset, op);
3210}
3211
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003212static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003213timezone_hash(PyDateTime_TimeZone *self)
3214{
3215 return delta_hash((PyDateTime_Delta *)self->offset);
3216}
3217
3218/* Check argument type passed to tzname, utcoffset, or dst methods.
3219 Returns 0 for good argument. Returns -1 and sets exception info
3220 otherwise.
3221 */
3222static int
3223_timezone_check_argument(PyObject *dt, const char *meth)
3224{
3225 if (dt == Py_None || PyDateTime_Check(dt))
3226 return 0;
3227 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3228 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3229 return -1;
3230}
3231
3232static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003233timezone_repr(PyDateTime_TimeZone *self)
3234{
3235 /* Note that although timezone is not subclassable, it is convenient
3236 to use Py_TYPE(self)->tp_name here. */
3237 const char *type_name = Py_TYPE(self)->tp_name;
3238
3239 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3240 return PyUnicode_FromFormat("%s.utc", type_name);
3241
3242 if (self->name == NULL)
3243 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3244
3245 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3246 self->name);
3247}
3248
3249
3250static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003251timezone_str(PyDateTime_TimeZone *self)
3252{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003253 int hours, minutes, seconds;
3254 PyObject *offset;
3255 char sign;
3256
3257 if (self->name != NULL) {
3258 Py_INCREF(self->name);
3259 return self->name;
3260 }
3261 /* Offset is normalized, so it is negative if days < 0 */
3262 if (GET_TD_DAYS(self->offset) < 0) {
3263 sign = '-';
3264 offset = delta_negative((PyDateTime_Delta *)self->offset);
3265 if (offset == NULL)
3266 return NULL;
3267 }
3268 else {
3269 sign = '+';
3270 offset = self->offset;
3271 Py_INCREF(offset);
3272 }
3273 /* Offset is not negative here. */
3274 seconds = GET_TD_SECONDS(offset);
3275 Py_DECREF(offset);
3276 minutes = divmod(seconds, 60, &seconds);
3277 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003278 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003279 assert(seconds == 0);
3280 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003281}
3282
3283static PyObject *
3284timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3285{
3286 if (_timezone_check_argument(dt, "tzname") == -1)
3287 return NULL;
3288
3289 return timezone_str(self);
3290}
3291
3292static PyObject *
3293timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3294{
3295 if (_timezone_check_argument(dt, "utcoffset") == -1)
3296 return NULL;
3297
3298 Py_INCREF(self->offset);
3299 return self->offset;
3300}
3301
3302static PyObject *
3303timezone_dst(PyObject *self, PyObject *dt)
3304{
3305 if (_timezone_check_argument(dt, "dst") == -1)
3306 return NULL;
3307
3308 Py_RETURN_NONE;
3309}
3310
3311static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003312timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3313{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003314 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003315 PyErr_SetString(PyExc_TypeError,
3316 "fromutc: argument must be a datetime");
3317 return NULL;
3318 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003319 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003320 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3321 "is not self");
3322 return NULL;
3323 }
3324
3325 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3326}
3327
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003328static PyObject *
3329timezone_getinitargs(PyDateTime_TimeZone *self)
3330{
3331 if (self->name == NULL)
3332 return Py_BuildValue("(O)", self->offset);
3333 return Py_BuildValue("(OO)", self->offset, self->name);
3334}
3335
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003336static PyMethodDef timezone_methods[] = {
3337 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3338 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003339 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003340
3341 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003342 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003343
3344 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003345 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003346
3347 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3348 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3349
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003350 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3351 PyDoc_STR("pickle support")},
3352
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003353 {NULL, NULL}
3354};
3355
3356static char timezone_doc[] =
3357PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3358
3359static PyTypeObject PyDateTime_TimeZoneType = {
3360 PyVarObject_HEAD_INIT(NULL, 0)
3361 "datetime.timezone", /* tp_name */
3362 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3363 0, /* tp_itemsize */
3364 (destructor)timezone_dealloc, /* tp_dealloc */
3365 0, /* tp_print */
3366 0, /* tp_getattr */
3367 0, /* tp_setattr */
3368 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003369 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003370 0, /* tp_as_number */
3371 0, /* tp_as_sequence */
3372 0, /* tp_as_mapping */
3373 (hashfunc)timezone_hash, /* tp_hash */
3374 0, /* tp_call */
3375 (reprfunc)timezone_str, /* tp_str */
3376 0, /* tp_getattro */
3377 0, /* tp_setattro */
3378 0, /* tp_as_buffer */
3379 Py_TPFLAGS_DEFAULT, /* tp_flags */
3380 timezone_doc, /* tp_doc */
3381 0, /* tp_traverse */
3382 0, /* tp_clear */
3383 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3384 0, /* tp_weaklistoffset */
3385 0, /* tp_iter */
3386 0, /* tp_iternext */
3387 timezone_methods, /* tp_methods */
3388 0, /* tp_members */
3389 0, /* tp_getset */
3390 &PyDateTime_TZInfoType, /* tp_base */
3391 0, /* tp_dict */
3392 0, /* tp_descr_get */
3393 0, /* tp_descr_set */
3394 0, /* tp_dictoffset */
3395 0, /* tp_init */
3396 0, /* tp_alloc */
3397 timezone_new, /* tp_new */
3398};
3399
Tim Peters2a799bf2002-12-16 20:18:38 +00003400/*
Tim Peters37f39822003-01-10 03:49:02 +00003401 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003402 */
3403
Tim Peters37f39822003-01-10 03:49:02 +00003404/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003405 */
3406
3407static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003408time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003410 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003411}
3412
Tim Peters37f39822003-01-10 03:49:02 +00003413static PyObject *
3414time_minute(PyDateTime_Time *self, void *unused)
3415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003416 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003417}
3418
3419/* The name time_second conflicted with some platform header file. */
3420static PyObject *
3421py_time_second(PyDateTime_Time *self, void *unused)
3422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003423 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003424}
3425
3426static PyObject *
3427time_microsecond(PyDateTime_Time *self, void *unused)
3428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003429 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003430}
3431
3432static PyObject *
3433time_tzinfo(PyDateTime_Time *self, void *unused)
3434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003435 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3436 Py_INCREF(result);
3437 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003438}
3439
3440static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003441 {"hour", (getter)time_hour},
3442 {"minute", (getter)time_minute},
3443 {"second", (getter)py_time_second},
3444 {"microsecond", (getter)time_microsecond},
3445 {"tzinfo", (getter)time_tzinfo},
3446 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003447};
3448
3449/*
3450 * Constructors.
3451 */
3452
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003453static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003454 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003455
Tim Peters2a799bf2002-12-16 20:18:38 +00003456static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003457time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003459 PyObject *self = NULL;
3460 PyObject *state;
3461 int hour = 0;
3462 int minute = 0;
3463 int second = 0;
3464 int usecond = 0;
3465 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003467 /* Check for invocation from pickle with __getstate__ state */
3468 if (PyTuple_GET_SIZE(args) >= 1 &&
3469 PyTuple_GET_SIZE(args) <= 2 &&
3470 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3471 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3472 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3473 {
3474 PyDateTime_Time *me;
3475 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003477 if (PyTuple_GET_SIZE(args) == 2) {
3478 tzinfo = PyTuple_GET_ITEM(args, 1);
3479 if (check_tzinfo_subclass(tzinfo) < 0) {
3480 PyErr_SetString(PyExc_TypeError, "bad "
3481 "tzinfo state arg");
3482 return NULL;
3483 }
3484 }
3485 aware = (char)(tzinfo != Py_None);
3486 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3487 if (me != NULL) {
3488 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003490 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3491 me->hashcode = -1;
3492 me->hastzinfo = aware;
3493 if (aware) {
3494 Py_INCREF(tzinfo);
3495 me->tzinfo = tzinfo;
3496 }
3497 }
3498 return (PyObject *)me;
3499 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003501 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3502 &hour, &minute, &second, &usecond,
3503 &tzinfo)) {
3504 if (check_time_args(hour, minute, second, usecond) < 0)
3505 return NULL;
3506 if (check_tzinfo_subclass(tzinfo) < 0)
3507 return NULL;
3508 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3509 type);
3510 }
3511 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003512}
3513
3514/*
3515 * Destructor.
3516 */
3517
3518static void
Tim Peters37f39822003-01-10 03:49:02 +00003519time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003521 if (HASTZINFO(self)) {
3522 Py_XDECREF(self->tzinfo);
3523 }
3524 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003525}
3526
3527/*
Tim Peters855fe882002-12-22 03:43:39 +00003528 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003529 */
3530
Tim Peters2a799bf2002-12-16 20:18:38 +00003531/* These are all METH_NOARGS, so don't need to check the arglist. */
3532static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003533time_utcoffset(PyObject *self, PyObject *unused) {
3534 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003535}
3536
3537static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003538time_dst(PyObject *self, PyObject *unused) {
3539 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003540}
3541
3542static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003543time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003544 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003545}
3546
3547/*
Tim Peters37f39822003-01-10 03:49:02 +00003548 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003549 */
3550
3551static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003552time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003553{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003554 const char *type_name = Py_TYPE(self)->tp_name;
3555 int h = TIME_GET_HOUR(self);
3556 int m = TIME_GET_MINUTE(self);
3557 int s = TIME_GET_SECOND(self);
3558 int us = TIME_GET_MICROSECOND(self);
3559 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003561 if (us)
3562 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3563 type_name, h, m, s, us);
3564 else if (s)
3565 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3566 type_name, h, m, s);
3567 else
3568 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3569 if (result != NULL && HASTZINFO(self))
3570 result = append_keyword_tzinfo(result, self->tzinfo);
3571 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003572}
3573
Tim Peters37f39822003-01-10 03:49:02 +00003574static PyObject *
3575time_str(PyDateTime_Time *self)
3576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003577 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003578}
Tim Peters2a799bf2002-12-16 20:18:38 +00003579
3580static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003581time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003583 char buf[100];
3584 PyObject *result;
3585 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003587 if (us)
3588 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3589 TIME_GET_HOUR(self),
3590 TIME_GET_MINUTE(self),
3591 TIME_GET_SECOND(self),
3592 us);
3593 else
3594 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3595 TIME_GET_HOUR(self),
3596 TIME_GET_MINUTE(self),
3597 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003598
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003599 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003600 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003602 /* We need to append the UTC offset. */
3603 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3604 Py_None) < 0) {
3605 Py_DECREF(result);
3606 return NULL;
3607 }
3608 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3609 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003610}
3611
Tim Peters37f39822003-01-10 03:49:02 +00003612static PyObject *
3613time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3614{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003615 PyObject *result;
3616 PyObject *tuple;
3617 PyObject *format;
3618 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003620 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3621 &format))
3622 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003624 /* Python's strftime does insane things with the year part of the
3625 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003626 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003627 */
3628 tuple = Py_BuildValue("iiiiiiiii",
3629 1900, 1, 1, /* year, month, day */
3630 TIME_GET_HOUR(self),
3631 TIME_GET_MINUTE(self),
3632 TIME_GET_SECOND(self),
3633 0, 1, -1); /* weekday, daynum, dst */
3634 if (tuple == NULL)
3635 return NULL;
3636 assert(PyTuple_Size(tuple) == 9);
3637 result = wrap_strftime((PyObject *)self, format, tuple,
3638 Py_None);
3639 Py_DECREF(tuple);
3640 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003641}
Tim Peters2a799bf2002-12-16 20:18:38 +00003642
3643/*
3644 * Miscellaneous methods.
3645 */
3646
Tim Peters37f39822003-01-10 03:49:02 +00003647static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003648time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003649{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003650 PyObject *result = NULL;
3651 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003652 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003653
Brian Curtindfc80e32011-08-10 20:28:54 -05003654 if (! PyTime_Check(other))
3655 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003656
3657 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003658 diff = memcmp(((PyDateTime_Time *)self)->data,
3659 ((PyDateTime_Time *)other)->data,
3660 _PyDateTime_TIME_DATASIZE);
3661 return diff_to_bool(diff, op);
3662 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003663 offset1 = time_utcoffset(self, NULL);
3664 if (offset1 == NULL)
3665 return NULL;
3666 offset2 = time_utcoffset(other, NULL);
3667 if (offset2 == NULL)
3668 goto done;
3669 /* If they're both naive, or both aware and have the same offsets,
3670 * we get off cheap. Note that if they're both naive, offset1 ==
3671 * offset2 == Py_None at this point.
3672 */
3673 if ((offset1 == offset2) ||
3674 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3675 delta_cmp(offset1, offset2) == 0)) {
3676 diff = memcmp(((PyDateTime_Time *)self)->data,
3677 ((PyDateTime_Time *)other)->data,
3678 _PyDateTime_TIME_DATASIZE);
3679 result = diff_to_bool(diff, op);
3680 }
3681 /* The hard case: both aware with different UTC offsets */
3682 else if (offset1 != Py_None && offset2 != Py_None) {
3683 int offsecs1, offsecs2;
3684 assert(offset1 != offset2); /* else last "if" handled it */
3685 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3686 TIME_GET_MINUTE(self) * 60 +
3687 TIME_GET_SECOND(self) -
3688 GET_TD_DAYS(offset1) * 86400 -
3689 GET_TD_SECONDS(offset1);
3690 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3691 TIME_GET_MINUTE(other) * 60 +
3692 TIME_GET_SECOND(other) -
3693 GET_TD_DAYS(offset2) * 86400 -
3694 GET_TD_SECONDS(offset2);
3695 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003696 if (diff == 0)
3697 diff = TIME_GET_MICROSECOND(self) -
3698 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003699 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003700 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003701 else {
3702 PyErr_SetString(PyExc_TypeError,
3703 "can't compare offset-naive and "
3704 "offset-aware times");
3705 }
3706 done:
3707 Py_DECREF(offset1);
3708 Py_XDECREF(offset2);
3709 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003710}
3711
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003712static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003713time_hash(PyDateTime_Time *self)
3714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003715 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003716 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003717
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003718 offset = time_utcoffset((PyObject *)self, NULL);
3719
3720 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003721 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003723 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003724 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003725 self->hashcode = generic_hash(
3726 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003727 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003728 PyObject *temp1, *temp2;
3729 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003730 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003731 seconds = TIME_GET_HOUR(self) * 3600 +
3732 TIME_GET_MINUTE(self) * 60 +
3733 TIME_GET_SECOND(self);
3734 microseconds = TIME_GET_MICROSECOND(self);
3735 temp1 = new_delta(0, seconds, microseconds, 1);
3736 if (temp1 == NULL) {
3737 Py_DECREF(offset);
3738 return -1;
3739 }
3740 temp2 = delta_subtract(temp1, offset);
3741 Py_DECREF(temp1);
3742 if (temp2 == NULL) {
3743 Py_DECREF(offset);
3744 return -1;
3745 }
3746 self->hashcode = PyObject_Hash(temp2);
3747 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003748 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003749 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003750 }
3751 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003752}
Tim Peters2a799bf2002-12-16 20:18:38 +00003753
Tim Peters12bf3392002-12-24 05:41:27 +00003754static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003755time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003757 PyObject *clone;
3758 PyObject *tuple;
3759 int hh = TIME_GET_HOUR(self);
3760 int mm = TIME_GET_MINUTE(self);
3761 int ss = TIME_GET_SECOND(self);
3762 int us = TIME_GET_MICROSECOND(self);
3763 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003765 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3766 time_kws,
3767 &hh, &mm, &ss, &us, &tzinfo))
3768 return NULL;
3769 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3770 if (tuple == NULL)
3771 return NULL;
3772 clone = time_new(Py_TYPE(self), tuple, NULL);
3773 Py_DECREF(tuple);
3774 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003775}
3776
Tim Peters2a799bf2002-12-16 20:18:38 +00003777static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003778time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003779{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003780 PyObject *offset, *tzinfo;
3781 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003783 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3784 /* Since utcoffset is in whole minutes, nothing can
3785 * alter the conclusion that this is nonzero.
3786 */
3787 return 1;
3788 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003789 tzinfo = GET_TIME_TZINFO(self);
3790 if (tzinfo != Py_None) {
3791 offset = call_utcoffset(tzinfo, Py_None);
3792 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003793 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003794 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3795 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003796 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003797 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003798}
3799
Tim Peters371935f2003-02-01 01:52:50 +00003800/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003801
Tim Peters33e0f382003-01-10 02:05:14 +00003802/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003803 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3804 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003805 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003806 */
3807static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003808time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003810 PyObject *basestate;
3811 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003813 basestate = PyBytes_FromStringAndSize((char *)self->data,
3814 _PyDateTime_TIME_DATASIZE);
3815 if (basestate != NULL) {
3816 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3817 result = PyTuple_Pack(1, basestate);
3818 else
3819 result = PyTuple_Pack(2, basestate, self->tzinfo);
3820 Py_DECREF(basestate);
3821 }
3822 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003823}
3824
3825static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003826time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003827{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003828 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003829}
3830
Tim Peters37f39822003-01-10 03:49:02 +00003831static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003833 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3834 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3835 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003837 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3838 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003840 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3841 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003843 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3844 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003846 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3847 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003849 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3850 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003852 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3853 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003855 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3856 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003859};
3860
Tim Peters37f39822003-01-10 03:49:02 +00003861static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003862PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3863\n\
3864All arguments are optional. tzinfo may be None, or an instance of\n\
3865a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003866
Tim Peters37f39822003-01-10 03:49:02 +00003867static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003868 0, /* nb_add */
3869 0, /* nb_subtract */
3870 0, /* nb_multiply */
3871 0, /* nb_remainder */
3872 0, /* nb_divmod */
3873 0, /* nb_power */
3874 0, /* nb_negative */
3875 0, /* nb_positive */
3876 0, /* nb_absolute */
3877 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003878};
3879
Neal Norwitz227b5332006-03-22 09:28:35 +00003880static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003881 PyVarObject_HEAD_INIT(NULL, 0)
3882 "datetime.time", /* tp_name */
3883 sizeof(PyDateTime_Time), /* tp_basicsize */
3884 0, /* tp_itemsize */
3885 (destructor)time_dealloc, /* tp_dealloc */
3886 0, /* tp_print */
3887 0, /* tp_getattr */
3888 0, /* tp_setattr */
3889 0, /* tp_reserved */
3890 (reprfunc)time_repr, /* tp_repr */
3891 &time_as_number, /* tp_as_number */
3892 0, /* tp_as_sequence */
3893 0, /* tp_as_mapping */
3894 (hashfunc)time_hash, /* tp_hash */
3895 0, /* tp_call */
3896 (reprfunc)time_str, /* tp_str */
3897 PyObject_GenericGetAttr, /* tp_getattro */
3898 0, /* tp_setattro */
3899 0, /* tp_as_buffer */
3900 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3901 time_doc, /* tp_doc */
3902 0, /* tp_traverse */
3903 0, /* tp_clear */
3904 time_richcompare, /* tp_richcompare */
3905 0, /* tp_weaklistoffset */
3906 0, /* tp_iter */
3907 0, /* tp_iternext */
3908 time_methods, /* tp_methods */
3909 0, /* tp_members */
3910 time_getset, /* tp_getset */
3911 0, /* tp_base */
3912 0, /* tp_dict */
3913 0, /* tp_descr_get */
3914 0, /* tp_descr_set */
3915 0, /* tp_dictoffset */
3916 0, /* tp_init */
3917 time_alloc, /* tp_alloc */
3918 time_new, /* tp_new */
3919 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003920};
3921
3922/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003923 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003924 */
3925
Tim Petersa9bc1682003-01-11 03:39:11 +00003926/* Accessor properties. Properties for day, month, and year are inherited
3927 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003928 */
3929
3930static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003931datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003932{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003933 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003934}
3935
Tim Petersa9bc1682003-01-11 03:39:11 +00003936static PyObject *
3937datetime_minute(PyDateTime_DateTime *self, void *unused)
3938{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003939 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003940}
3941
3942static PyObject *
3943datetime_second(PyDateTime_DateTime *self, void *unused)
3944{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003945 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003946}
3947
3948static PyObject *
3949datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003951 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003952}
3953
3954static PyObject *
3955datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003957 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3958 Py_INCREF(result);
3959 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003960}
3961
3962static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003963 {"hour", (getter)datetime_hour},
3964 {"minute", (getter)datetime_minute},
3965 {"second", (getter)datetime_second},
3966 {"microsecond", (getter)datetime_microsecond},
3967 {"tzinfo", (getter)datetime_tzinfo},
3968 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003969};
3970
3971/*
3972 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003973 */
3974
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003975static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003976 "year", "month", "day", "hour", "minute", "second",
3977 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003978};
3979
Tim Peters2a799bf2002-12-16 20:18:38 +00003980static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003981datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003983 PyObject *self = NULL;
3984 PyObject *state;
3985 int year;
3986 int month;
3987 int day;
3988 int hour = 0;
3989 int minute = 0;
3990 int second = 0;
3991 int usecond = 0;
3992 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003994 /* Check for invocation from pickle with __getstate__ state */
3995 if (PyTuple_GET_SIZE(args) >= 1 &&
3996 PyTuple_GET_SIZE(args) <= 2 &&
3997 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3998 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3999 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4000 {
4001 PyDateTime_DateTime *me;
4002 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 if (PyTuple_GET_SIZE(args) == 2) {
4005 tzinfo = PyTuple_GET_ITEM(args, 1);
4006 if (check_tzinfo_subclass(tzinfo) < 0) {
4007 PyErr_SetString(PyExc_TypeError, "bad "
4008 "tzinfo state arg");
4009 return NULL;
4010 }
4011 }
4012 aware = (char)(tzinfo != Py_None);
4013 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4014 if (me != NULL) {
4015 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004017 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4018 me->hashcode = -1;
4019 me->hastzinfo = aware;
4020 if (aware) {
4021 Py_INCREF(tzinfo);
4022 me->tzinfo = tzinfo;
4023 }
4024 }
4025 return (PyObject *)me;
4026 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004028 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4029 &year, &month, &day, &hour, &minute,
4030 &second, &usecond, &tzinfo)) {
4031 if (check_date_args(year, month, day) < 0)
4032 return NULL;
4033 if (check_time_args(hour, minute, second, usecond) < 0)
4034 return NULL;
4035 if (check_tzinfo_subclass(tzinfo) < 0)
4036 return NULL;
4037 self = new_datetime_ex(year, month, day,
4038 hour, minute, second, usecond,
4039 tzinfo, type);
4040 }
4041 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004042}
4043
Tim Petersa9bc1682003-01-11 03:39:11 +00004044/* TM_FUNC is the shared type of localtime() and gmtime(). */
4045typedef struct tm *(*TM_FUNC)(const time_t *timer);
4046
4047/* Internal helper.
4048 * Build datetime from a time_t and a distinct count of microseconds.
4049 * Pass localtime or gmtime for f, to control the interpretation of timet.
4050 */
4051static PyObject *
4052datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004053 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004054{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004055 struct tm *tm;
4056 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004058 tm = f(&timet);
4059 if (tm) {
4060 /* The platform localtime/gmtime may insert leap seconds,
4061 * indicated by tm->tm_sec > 59. We don't care about them,
4062 * except to the extent that passing them on to the datetime
4063 * constructor would raise ValueError for a reason that
4064 * made no sense to the user.
4065 */
4066 if (tm->tm_sec > 59)
4067 tm->tm_sec = 59;
4068 result = PyObject_CallFunction(cls, "iiiiiiiO",
4069 tm->tm_year + 1900,
4070 tm->tm_mon + 1,
4071 tm->tm_mday,
4072 tm->tm_hour,
4073 tm->tm_min,
4074 tm->tm_sec,
4075 us,
4076 tzinfo);
4077 }
4078 else
4079 PyErr_SetString(PyExc_ValueError,
4080 "timestamp out of range for "
4081 "platform localtime()/gmtime() function");
4082 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004083}
4084
4085/* Internal helper.
4086 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4087 * to control the interpretation of the timestamp. Since a double doesn't
4088 * have enough bits to cover a datetime's full range of precision, it's
4089 * better to call datetime_from_timet_and_us provided you have a way
4090 * to get that much precision (e.g., C time() isn't good enough).
4091 */
4092static PyObject *
4093datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004094 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004096 time_t timet;
4097 double fraction;
4098 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004100 timet = _PyTime_DoubleToTimet(timestamp);
4101 if (timet == (time_t)-1 && PyErr_Occurred())
4102 return NULL;
4103 fraction = timestamp - (double)timet;
4104 us = (int)round_to_long(fraction * 1e6);
4105 if (us < 0) {
4106 /* Truncation towards zero is not what we wanted
4107 for negative numbers (Python's mod semantics) */
4108 timet -= 1;
4109 us += 1000000;
4110 }
4111 /* If timestamp is less than one microsecond smaller than a
4112 * full second, round up. Otherwise, ValueErrors are raised
4113 * for some floats. */
4114 if (us == 1000000) {
4115 timet += 1;
4116 us = 0;
4117 }
4118 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004119}
4120
4121/* Internal helper.
4122 * Build most accurate possible datetime for current time. Pass localtime or
4123 * gmtime for f as appropriate.
4124 */
4125static PyObject *
4126datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4127{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004128 _PyTime_timeval t;
4129 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4131 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004132}
4133
Tim Peters2a799bf2002-12-16 20:18:38 +00004134/* Return best possible local time -- this isn't constrained by the
4135 * precision of a timestamp.
4136 */
4137static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004138datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004140 PyObject *self;
4141 PyObject *tzinfo = Py_None;
4142 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004144 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4145 &tzinfo))
4146 return NULL;
4147 if (check_tzinfo_subclass(tzinfo) < 0)
4148 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004150 self = datetime_best_possible(cls,
4151 tzinfo == Py_None ? localtime : gmtime,
4152 tzinfo);
4153 if (self != NULL && tzinfo != Py_None) {
4154 /* Convert UTC to tzinfo's zone. */
4155 PyObject *temp = self;
4156 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4157 Py_DECREF(temp);
4158 }
4159 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004160}
4161
Tim Petersa9bc1682003-01-11 03:39:11 +00004162/* Return best possible UTC time -- this isn't constrained by the
4163 * precision of a timestamp.
4164 */
4165static PyObject *
4166datetime_utcnow(PyObject *cls, PyObject *dummy)
4167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004168 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004169}
4170
Tim Peters2a799bf2002-12-16 20:18:38 +00004171/* Return new local datetime from timestamp (Python timestamp -- a double). */
4172static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004173datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004175 PyObject *self;
4176 double timestamp;
4177 PyObject *tzinfo = Py_None;
4178 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004180 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4181 keywords, &timestamp, &tzinfo))
4182 return NULL;
4183 if (check_tzinfo_subclass(tzinfo) < 0)
4184 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004186 self = datetime_from_timestamp(cls,
4187 tzinfo == Py_None ? localtime : gmtime,
4188 timestamp,
4189 tzinfo);
4190 if (self != NULL && tzinfo != Py_None) {
4191 /* Convert UTC to tzinfo's zone. */
4192 PyObject *temp = self;
4193 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4194 Py_DECREF(temp);
4195 }
4196 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004197}
4198
Tim Petersa9bc1682003-01-11 03:39:11 +00004199/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4200static PyObject *
4201datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4202{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004203 double timestamp;
4204 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004206 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4207 result = datetime_from_timestamp(cls, gmtime, timestamp,
4208 Py_None);
4209 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004210}
4211
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004212/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004213static PyObject *
4214datetime_strptime(PyObject *cls, PyObject *args)
4215{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004216 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004217 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004219 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4220 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004221
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004222 if (module == NULL) {
4223 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004224 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004225 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 }
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004227 return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4228 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004229}
4230
Tim Petersa9bc1682003-01-11 03:39:11 +00004231/* Return new datetime from date/datetime and time arguments. */
4232static PyObject *
4233datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004235 static char *keywords[] = {"date", "time", NULL};
4236 PyObject *date;
4237 PyObject *time;
4238 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004240 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4241 &PyDateTime_DateType, &date,
4242 &PyDateTime_TimeType, &time)) {
4243 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004245 if (HASTZINFO(time))
4246 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4247 result = PyObject_CallFunction(cls, "iiiiiiiO",
4248 GET_YEAR(date),
4249 GET_MONTH(date),
4250 GET_DAY(date),
4251 TIME_GET_HOUR(time),
4252 TIME_GET_MINUTE(time),
4253 TIME_GET_SECOND(time),
4254 TIME_GET_MICROSECOND(time),
4255 tzinfo);
4256 }
4257 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004258}
Tim Peters2a799bf2002-12-16 20:18:38 +00004259
4260/*
4261 * Destructor.
4262 */
4263
4264static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004265datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004267 if (HASTZINFO(self)) {
4268 Py_XDECREF(self->tzinfo);
4269 }
4270 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004271}
4272
4273/*
4274 * Indirect access to tzinfo methods.
4275 */
4276
Tim Peters2a799bf2002-12-16 20:18:38 +00004277/* These are all METH_NOARGS, so don't need to check the arglist. */
4278static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004279datetime_utcoffset(PyObject *self, PyObject *unused) {
4280 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004281}
4282
4283static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004284datetime_dst(PyObject *self, PyObject *unused) {
4285 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004286}
4287
4288static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004289datetime_tzname(PyObject *self, PyObject *unused) {
4290 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004291}
4292
4293/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004294 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004295 */
4296
Tim Petersa9bc1682003-01-11 03:39:11 +00004297/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4298 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004299 */
4300static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004301add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004302 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004304 /* Note that the C-level additions can't overflow, because of
4305 * invariant bounds on the member values.
4306 */
4307 int year = GET_YEAR(date);
4308 int month = GET_MONTH(date);
4309 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4310 int hour = DATE_GET_HOUR(date);
4311 int minute = DATE_GET_MINUTE(date);
4312 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4313 int microsecond = DATE_GET_MICROSECOND(date) +
4314 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004316 assert(factor == 1 || factor == -1);
4317 if (normalize_datetime(&year, &month, &day,
4318 &hour, &minute, &second, &microsecond) < 0)
4319 return NULL;
4320 else
4321 return new_datetime(year, month, day,
4322 hour, minute, second, microsecond,
4323 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004324}
4325
4326static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004327datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004329 if (PyDateTime_Check(left)) {
4330 /* datetime + ??? */
4331 if (PyDelta_Check(right))
4332 /* datetime + delta */
4333 return add_datetime_timedelta(
4334 (PyDateTime_DateTime *)left,
4335 (PyDateTime_Delta *)right,
4336 1);
4337 }
4338 else if (PyDelta_Check(left)) {
4339 /* delta + datetime */
4340 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4341 (PyDateTime_Delta *) left,
4342 1);
4343 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004344 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004345}
4346
4347static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004348datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004350 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004352 if (PyDateTime_Check(left)) {
4353 /* datetime - ??? */
4354 if (PyDateTime_Check(right)) {
4355 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004356 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004357 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004358
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004359 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4360 offset2 = offset1 = Py_None;
4361 Py_INCREF(offset1);
4362 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004363 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004364 else {
4365 offset1 = datetime_utcoffset(left, NULL);
4366 if (offset1 == NULL)
4367 return NULL;
4368 offset2 = datetime_utcoffset(right, NULL);
4369 if (offset2 == NULL) {
4370 Py_DECREF(offset1);
4371 return NULL;
4372 }
4373 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4374 PyErr_SetString(PyExc_TypeError,
4375 "can't subtract offset-naive and "
4376 "offset-aware datetimes");
4377 Py_DECREF(offset1);
4378 Py_DECREF(offset2);
4379 return NULL;
4380 }
4381 }
4382 if ((offset1 != offset2) &&
4383 delta_cmp(offset1, offset2) != 0) {
4384 offdiff = delta_subtract(offset1, offset2);
4385 if (offdiff == NULL) {
4386 Py_DECREF(offset1);
4387 Py_DECREF(offset2);
4388 return NULL;
4389 }
4390 }
4391 Py_DECREF(offset1);
4392 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004393 delta_d = ymd_to_ord(GET_YEAR(left),
4394 GET_MONTH(left),
4395 GET_DAY(left)) -
4396 ymd_to_ord(GET_YEAR(right),
4397 GET_MONTH(right),
4398 GET_DAY(right));
4399 /* These can't overflow, since the values are
4400 * normalized. At most this gives the number of
4401 * seconds in one day.
4402 */
4403 delta_s = (DATE_GET_HOUR(left) -
4404 DATE_GET_HOUR(right)) * 3600 +
4405 (DATE_GET_MINUTE(left) -
4406 DATE_GET_MINUTE(right)) * 60 +
4407 (DATE_GET_SECOND(left) -
4408 DATE_GET_SECOND(right));
4409 delta_us = DATE_GET_MICROSECOND(left) -
4410 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004412 if (offdiff != NULL) {
4413 PyObject *temp = result;
4414 result = delta_subtract(result, offdiff);
4415 Py_DECREF(temp);
4416 Py_DECREF(offdiff);
4417 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004418 }
4419 else if (PyDelta_Check(right)) {
4420 /* datetime - delta */
4421 result = add_datetime_timedelta(
4422 (PyDateTime_DateTime *)left,
4423 (PyDateTime_Delta *)right,
4424 -1);
4425 }
4426 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004428 if (result == Py_NotImplemented)
4429 Py_INCREF(result);
4430 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004431}
4432
4433/* Various ways to turn a datetime into a string. */
4434
4435static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004436datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004437{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004438 const char *type_name = Py_TYPE(self)->tp_name;
4439 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004441 if (DATE_GET_MICROSECOND(self)) {
4442 baserepr = PyUnicode_FromFormat(
4443 "%s(%d, %d, %d, %d, %d, %d, %d)",
4444 type_name,
4445 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4446 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4447 DATE_GET_SECOND(self),
4448 DATE_GET_MICROSECOND(self));
4449 }
4450 else if (DATE_GET_SECOND(self)) {
4451 baserepr = PyUnicode_FromFormat(
4452 "%s(%d, %d, %d, %d, %d, %d)",
4453 type_name,
4454 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4455 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4456 DATE_GET_SECOND(self));
4457 }
4458 else {
4459 baserepr = PyUnicode_FromFormat(
4460 "%s(%d, %d, %d, %d, %d)",
4461 type_name,
4462 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4463 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4464 }
4465 if (baserepr == NULL || ! HASTZINFO(self))
4466 return baserepr;
4467 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004468}
4469
Tim Petersa9bc1682003-01-11 03:39:11 +00004470static PyObject *
4471datetime_str(PyDateTime_DateTime *self)
4472{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004473 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004474}
Tim Peters2a799bf2002-12-16 20:18:38 +00004475
4476static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004477datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004478{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004479 int sep = 'T';
4480 static char *keywords[] = {"sep", NULL};
4481 char buffer[100];
4482 PyObject *result;
4483 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004485 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4486 return NULL;
4487 if (us)
4488 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4489 GET_YEAR(self), GET_MONTH(self),
4490 GET_DAY(self), (int)sep,
4491 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4492 DATE_GET_SECOND(self), us);
4493 else
4494 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4495 GET_YEAR(self), GET_MONTH(self),
4496 GET_DAY(self), (int)sep,
4497 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4498 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004500 if (!result || !HASTZINFO(self))
4501 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004503 /* We need to append the UTC offset. */
4504 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4505 (PyObject *)self) < 0) {
4506 Py_DECREF(result);
4507 return NULL;
4508 }
4509 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4510 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004511}
4512
Tim Petersa9bc1682003-01-11 03:39:11 +00004513static PyObject *
4514datetime_ctime(PyDateTime_DateTime *self)
4515{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004516 return format_ctime((PyDateTime_Date *)self,
4517 DATE_GET_HOUR(self),
4518 DATE_GET_MINUTE(self),
4519 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004520}
4521
Tim Peters2a799bf2002-12-16 20:18:38 +00004522/* Miscellaneous methods. */
4523
Tim Petersa9bc1682003-01-11 03:39:11 +00004524static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004525datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004526{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004527 PyObject *result = NULL;
4528 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004529 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004531 if (! PyDateTime_Check(other)) {
4532 if (PyDate_Check(other)) {
4533 /* Prevent invocation of date_richcompare. We want to
4534 return NotImplemented here to give the other object
4535 a chance. But since DateTime is a subclass of
4536 Date, if the other object is a Date, it would
4537 compute an ordering based on the date part alone,
4538 and we don't want that. So force unequal or
4539 uncomparable here in that case. */
4540 if (op == Py_EQ)
4541 Py_RETURN_FALSE;
4542 if (op == Py_NE)
4543 Py_RETURN_TRUE;
4544 return cmperror(self, other);
4545 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004546 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004547 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004548
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004549 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004550 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4551 ((PyDateTime_DateTime *)other)->data,
4552 _PyDateTime_DATETIME_DATASIZE);
4553 return diff_to_bool(diff, op);
4554 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004555 offset1 = datetime_utcoffset(self, NULL);
4556 if (offset1 == NULL)
4557 return NULL;
4558 offset2 = datetime_utcoffset(other, NULL);
4559 if (offset2 == NULL)
4560 goto done;
4561 /* If they're both naive, or both aware and have the same offsets,
4562 * we get off cheap. Note that if they're both naive, offset1 ==
4563 * offset2 == Py_None at this point.
4564 */
4565 if ((offset1 == offset2) ||
4566 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4567 delta_cmp(offset1, offset2) == 0)) {
4568 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4569 ((PyDateTime_DateTime *)other)->data,
4570 _PyDateTime_DATETIME_DATASIZE);
4571 result = diff_to_bool(diff, op);
4572 }
4573 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004574 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004575
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004576 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004577 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4578 other);
4579 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004580 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004581 diff = GET_TD_DAYS(delta);
4582 if (diff == 0)
4583 diff = GET_TD_SECONDS(delta) |
4584 GET_TD_MICROSECONDS(delta);
4585 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004586 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004587 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004588 else {
4589 PyErr_SetString(PyExc_TypeError,
4590 "can't compare offset-naive and "
4591 "offset-aware datetimes");
4592 }
4593 done:
4594 Py_DECREF(offset1);
4595 Py_XDECREF(offset2);
4596 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004597}
4598
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004599static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004600datetime_hash(PyDateTime_DateTime *self)
4601{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004602 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004603 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004604
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004605 offset = datetime_utcoffset((PyObject *)self, NULL);
4606
4607 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004608 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004610 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004611 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004612 self->hashcode = generic_hash(
4613 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004614 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004615 PyObject *temp1, *temp2;
4616 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004618 assert(HASTZINFO(self));
4619 days = ymd_to_ord(GET_YEAR(self),
4620 GET_MONTH(self),
4621 GET_DAY(self));
4622 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004623 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004624 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004625 temp1 = new_delta(days, seconds,
4626 DATE_GET_MICROSECOND(self),
4627 1);
4628 if (temp1 == NULL) {
4629 Py_DECREF(offset);
4630 return -1;
4631 }
4632 temp2 = delta_subtract(temp1, offset);
4633 Py_DECREF(temp1);
4634 if (temp2 == NULL) {
4635 Py_DECREF(offset);
4636 return -1;
4637 }
4638 self->hashcode = PyObject_Hash(temp2);
4639 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004640 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004641 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004642 }
4643 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004644}
Tim Peters2a799bf2002-12-16 20:18:38 +00004645
4646static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004647datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004649 PyObject *clone;
4650 PyObject *tuple;
4651 int y = GET_YEAR(self);
4652 int m = GET_MONTH(self);
4653 int d = GET_DAY(self);
4654 int hh = DATE_GET_HOUR(self);
4655 int mm = DATE_GET_MINUTE(self);
4656 int ss = DATE_GET_SECOND(self);
4657 int us = DATE_GET_MICROSECOND(self);
4658 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004660 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4661 datetime_kws,
4662 &y, &m, &d, &hh, &mm, &ss, &us,
4663 &tzinfo))
4664 return NULL;
4665 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4666 if (tuple == NULL)
4667 return NULL;
4668 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4669 Py_DECREF(tuple);
4670 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004671}
4672
4673static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004674datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004676 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004677 PyObject *offset;
4678 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004679 PyObject *tzinfo;
4680 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004682 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4683 &PyDateTime_TZInfoType, &tzinfo))
4684 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004686 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4687 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004689 /* Conversion to self's own time zone is a NOP. */
4690 if (self->tzinfo == tzinfo) {
4691 Py_INCREF(self);
4692 return (PyObject *)self;
4693 }
Tim Peters521fc152002-12-31 17:36:56 +00004694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004695 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004696 offset = datetime_utcoffset((PyObject *)self, NULL);
4697 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004698 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004699 if (offset == Py_None) {
4700 Py_DECREF(offset);
4701 NeedAware:
4702 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4703 "a naive datetime");
4704 return NULL;
4705 }
Tim Petersf3615152003-01-01 21:51:37 +00004706
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004707 /* result = self - offset */
4708 result = add_datetime_timedelta(self,
4709 (PyDateTime_Delta *)offset, -1);
4710 Py_DECREF(offset);
4711 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004712 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004714 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004715 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4716 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4717 Py_INCREF(tzinfo);
4718 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004719
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004720 temp = result;
4721 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4722 Py_DECREF(temp);
4723
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004724 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004725}
4726
4727static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004728datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004730 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004731
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004732 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004733 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004734
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004735 dst = call_dst(self->tzinfo, (PyObject *)self);
4736 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004737 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004738
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004739 if (dst != Py_None)
4740 dstflag = delta_bool((PyDateTime_Delta *)dst);
4741 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004742 }
4743 return build_struct_time(GET_YEAR(self),
4744 GET_MONTH(self),
4745 GET_DAY(self),
4746 DATE_GET_HOUR(self),
4747 DATE_GET_MINUTE(self),
4748 DATE_GET_SECOND(self),
4749 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004750}
4751
4752static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004753datetime_getdate(PyDateTime_DateTime *self)
4754{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004755 return new_date(GET_YEAR(self),
4756 GET_MONTH(self),
4757 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004758}
4759
4760static PyObject *
4761datetime_gettime(PyDateTime_DateTime *self)
4762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004763 return new_time(DATE_GET_HOUR(self),
4764 DATE_GET_MINUTE(self),
4765 DATE_GET_SECOND(self),
4766 DATE_GET_MICROSECOND(self),
4767 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004768}
4769
4770static PyObject *
4771datetime_gettimetz(PyDateTime_DateTime *self)
4772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004773 return new_time(DATE_GET_HOUR(self),
4774 DATE_GET_MINUTE(self),
4775 DATE_GET_SECOND(self),
4776 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004777 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004778}
4779
4780static PyObject *
4781datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004782{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004783 int y, m, d, hh, mm, ss;
4784 PyObject *tzinfo;
4785 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004786
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004787 tzinfo = GET_DT_TZINFO(self);
4788 if (tzinfo == Py_None) {
4789 utcself = self;
4790 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004791 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004792 else {
4793 PyObject *offset;
4794 offset = call_utcoffset(tzinfo, (PyObject *)self);
4795 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004796 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004797 if (offset == Py_None) {
4798 Py_DECREF(offset);
4799 utcself = self;
4800 Py_INCREF(utcself);
4801 }
4802 else {
4803 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4804 (PyDateTime_Delta *)offset, -1);
4805 Py_DECREF(offset);
4806 if (utcself == NULL)
4807 return NULL;
4808 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004809 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004810 y = GET_YEAR(utcself);
4811 m = GET_MONTH(utcself);
4812 d = GET_DAY(utcself);
4813 hh = DATE_GET_HOUR(utcself);
4814 mm = DATE_GET_MINUTE(utcself);
4815 ss = DATE_GET_SECOND(utcself);
4816
4817 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004818 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004819}
4820
Tim Peters371935f2003-02-01 01:52:50 +00004821/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004822
Tim Petersa9bc1682003-01-11 03:39:11 +00004823/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004824 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4825 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004826 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004827 */
4828static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004829datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004831 PyObject *basestate;
4832 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004834 basestate = PyBytes_FromStringAndSize((char *)self->data,
4835 _PyDateTime_DATETIME_DATASIZE);
4836 if (basestate != NULL) {
4837 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4838 result = PyTuple_Pack(1, basestate);
4839 else
4840 result = PyTuple_Pack(2, basestate, self->tzinfo);
4841 Py_DECREF(basestate);
4842 }
4843 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004844}
4845
4846static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004847datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004849 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004850}
4851
Tim Petersa9bc1682003-01-11 03:39:11 +00004852static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004854 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004856 {"now", (PyCFunction)datetime_now,
4857 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4858 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004860 {"utcnow", (PyCFunction)datetime_utcnow,
4861 METH_NOARGS | METH_CLASS,
4862 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004864 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4865 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4866 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004868 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4869 METH_VARARGS | METH_CLASS,
4870 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4871 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004873 {"strptime", (PyCFunction)datetime_strptime,
4874 METH_VARARGS | METH_CLASS,
4875 PyDoc_STR("string, format -> new datetime parsed from a string "
4876 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004878 {"combine", (PyCFunction)datetime_combine,
4879 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4880 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004884 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4885 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004887 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4888 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4891 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004893 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4894 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004896 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4897 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004899 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4900 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004902 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4903 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4904 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4905 "sep is used to separate the year from the time, and "
4906 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004908 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4909 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004911 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4912 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004914 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4915 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004917 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4918 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004920 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4921 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004923 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4924 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004926 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004927};
4928
Tim Petersa9bc1682003-01-11 03:39:11 +00004929static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004930PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4931\n\
4932The year, month and day arguments are required. tzinfo may be None, or an\n\
4933instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004934
Tim Petersa9bc1682003-01-11 03:39:11 +00004935static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004936 datetime_add, /* nb_add */
4937 datetime_subtract, /* nb_subtract */
4938 0, /* nb_multiply */
4939 0, /* nb_remainder */
4940 0, /* nb_divmod */
4941 0, /* nb_power */
4942 0, /* nb_negative */
4943 0, /* nb_positive */
4944 0, /* nb_absolute */
4945 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004946};
4947
Neal Norwitz227b5332006-03-22 09:28:35 +00004948static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004949 PyVarObject_HEAD_INIT(NULL, 0)
4950 "datetime.datetime", /* tp_name */
4951 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4952 0, /* tp_itemsize */
4953 (destructor)datetime_dealloc, /* tp_dealloc */
4954 0, /* tp_print */
4955 0, /* tp_getattr */
4956 0, /* tp_setattr */
4957 0, /* tp_reserved */
4958 (reprfunc)datetime_repr, /* tp_repr */
4959 &datetime_as_number, /* tp_as_number */
4960 0, /* tp_as_sequence */
4961 0, /* tp_as_mapping */
4962 (hashfunc)datetime_hash, /* tp_hash */
4963 0, /* tp_call */
4964 (reprfunc)datetime_str, /* tp_str */
4965 PyObject_GenericGetAttr, /* tp_getattro */
4966 0, /* tp_setattro */
4967 0, /* tp_as_buffer */
4968 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4969 datetime_doc, /* tp_doc */
4970 0, /* tp_traverse */
4971 0, /* tp_clear */
4972 datetime_richcompare, /* tp_richcompare */
4973 0, /* tp_weaklistoffset */
4974 0, /* tp_iter */
4975 0, /* tp_iternext */
4976 datetime_methods, /* tp_methods */
4977 0, /* tp_members */
4978 datetime_getset, /* tp_getset */
4979 &PyDateTime_DateType, /* tp_base */
4980 0, /* tp_dict */
4981 0, /* tp_descr_get */
4982 0, /* tp_descr_set */
4983 0, /* tp_dictoffset */
4984 0, /* tp_init */
4985 datetime_alloc, /* tp_alloc */
4986 datetime_new, /* tp_new */
4987 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004988};
4989
4990/* ---------------------------------------------------------------------------
4991 * Module methods and initialization.
4992 */
4993
4994static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004995 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004996};
4997
Tim Peters9ddf40b2004-06-20 22:41:32 +00004998/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4999 * datetime.h.
5000 */
5001static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005002 &PyDateTime_DateType,
5003 &PyDateTime_DateTimeType,
5004 &PyDateTime_TimeType,
5005 &PyDateTime_DeltaType,
5006 &PyDateTime_TZInfoType,
5007 new_date_ex,
5008 new_datetime_ex,
5009 new_time_ex,
5010 new_delta_ex,
5011 datetime_fromtimestamp,
5012 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005013};
5014
5015
Martin v. Löwis1a214512008-06-11 05:26:20 +00005016
5017static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005018 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005019 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005020 "Fast implementation of the datetime type.",
5021 -1,
5022 module_methods,
5023 NULL,
5024 NULL,
5025 NULL,
5026 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005027};
5028
Tim Peters2a799bf2002-12-16 20:18:38 +00005029PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005030PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005032 PyObject *m; /* a module object */
5033 PyObject *d; /* its dict */
5034 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005035 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005037 m = PyModule_Create(&datetimemodule);
5038 if (m == NULL)
5039 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005041 if (PyType_Ready(&PyDateTime_DateType) < 0)
5042 return NULL;
5043 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5044 return NULL;
5045 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5046 return NULL;
5047 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5048 return NULL;
5049 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5050 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005051 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5052 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005054 /* timedelta values */
5055 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005057 x = new_delta(0, 0, 1, 0);
5058 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5059 return NULL;
5060 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005062 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5063 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5064 return NULL;
5065 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005067 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5068 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5069 return NULL;
5070 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005072 /* date values */
5073 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005075 x = new_date(1, 1, 1);
5076 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5077 return NULL;
5078 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005080 x = new_date(MAXYEAR, 12, 31);
5081 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5082 return NULL;
5083 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005085 x = new_delta(1, 0, 0, 0);
5086 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5087 return NULL;
5088 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005090 /* time values */
5091 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005093 x = new_time(0, 0, 0, 0, Py_None);
5094 if (x == NULL || PyDict_SetItemString(d, "min", 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 x = new_time(23, 59, 59, 999999, Py_None);
5099 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5100 return NULL;
5101 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005103 x = new_delta(0, 0, 1, 0);
5104 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5105 return NULL;
5106 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005108 /* datetime values */
5109 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005111 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5112 if (x == NULL || PyDict_SetItemString(d, "min", 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 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5117 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5118 return NULL;
5119 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005121 x = new_delta(0, 0, 1, 0);
5122 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5123 return NULL;
5124 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005125
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005126 /* timezone values */
5127 d = PyDateTime_TimeZoneType.tp_dict;
5128
5129 delta = new_delta(0, 0, 0, 0);
5130 if (delta == NULL)
5131 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005132 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005133 Py_DECREF(delta);
5134 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5135 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005136 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005137
5138 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5139 if (delta == NULL)
5140 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005141 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005142 Py_DECREF(delta);
5143 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5144 return NULL;
5145 Py_DECREF(x);
5146
5147 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5148 if (delta == NULL)
5149 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005150 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005151 Py_DECREF(delta);
5152 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5153 return NULL;
5154 Py_DECREF(x);
5155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005156 /* module initialization */
5157 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5158 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005160 Py_INCREF(&PyDateTime_DateType);
5161 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005163 Py_INCREF(&PyDateTime_DateTimeType);
5164 PyModule_AddObject(m, "datetime",
5165 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005167 Py_INCREF(&PyDateTime_TimeType);
5168 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005170 Py_INCREF(&PyDateTime_DeltaType);
5171 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005173 Py_INCREF(&PyDateTime_TZInfoType);
5174 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005175
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005176 Py_INCREF(&PyDateTime_TimeZoneType);
5177 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005179 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5180 if (x == NULL)
5181 return NULL;
5182 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005184 /* A 4-year cycle has an extra leap day over what we'd get from
5185 * pasting together 4 single years.
5186 */
5187 assert(DI4Y == 4 * 365 + 1);
5188 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005190 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5191 * get from pasting together 4 100-year cycles.
5192 */
5193 assert(DI400Y == 4 * DI100Y + 1);
5194 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005196 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5197 * pasting together 25 4-year cycles.
5198 */
5199 assert(DI100Y == 25 * DI4Y - 1);
5200 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005202 us_per_us = PyLong_FromLong(1);
5203 us_per_ms = PyLong_FromLong(1000);
5204 us_per_second = PyLong_FromLong(1000000);
5205 us_per_minute = PyLong_FromLong(60000000);
5206 seconds_per_day = PyLong_FromLong(24 * 3600);
5207 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5208 us_per_minute == NULL || seconds_per_day == NULL)
5209 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005211 /* The rest are too big for 32-bit ints, but even
5212 * us_per_week fits in 40 bits, so doubles should be exact.
5213 */
5214 us_per_hour = PyLong_FromDouble(3600000000.0);
5215 us_per_day = PyLong_FromDouble(86400000000.0);
5216 us_per_week = PyLong_FromDouble(604800000000.0);
5217 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5218 return NULL;
5219 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005220}
Tim Petersf3615152003-01-01 21:51:37 +00005221
5222/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005223Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005224 x.n = x stripped of its timezone -- its naive time.
5225 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005226 return None
Tim Petersf3615152003-01-01 21:51:37 +00005227 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005228 return None
Tim Petersf3615152003-01-01 21:51:37 +00005229 x.s = x's standard offset, x.o - x.d
5230
5231Now some derived rules, where k is a duration (timedelta).
5232
52331. x.o = x.s + x.d
5234 This follows from the definition of x.s.
5235
Tim Petersc5dc4da2003-01-02 17:55:03 +000052362. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005237 This is actually a requirement, an assumption we need to make about
5238 sane tzinfo classes.
5239
52403. The naive UTC time corresponding to x is x.n - x.o.
5241 This is again a requirement for a sane tzinfo class.
5242
52434. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005244 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005245
Tim Petersc5dc4da2003-01-02 17:55:03 +000052465. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005247 Again follows from how arithmetic is defined.
5248
Tim Peters8bb5ad22003-01-24 02:44:45 +00005249Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005250(meaning that the various tzinfo methods exist, and don't blow up or return
5251None when called).
5252
Tim Petersa9bc1682003-01-11 03:39:11 +00005253The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005254x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005255
5256By #3, we want
5257
Tim Peters8bb5ad22003-01-24 02:44:45 +00005258 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005259
5260The algorithm starts by attaching tz to x.n, and calling that y. So
5261x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5262becomes true; in effect, we want to solve [2] for k:
5263
Tim Peters8bb5ad22003-01-24 02:44:45 +00005264 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005265
5266By #1, this is the same as
5267
Tim Peters8bb5ad22003-01-24 02:44:45 +00005268 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005269
5270By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5271Substituting that into [3],
5272
Tim Peters8bb5ad22003-01-24 02:44:45 +00005273 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5274 k - (y+k).s - (y+k).d = 0; rearranging,
5275 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5276 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005277
Tim Peters8bb5ad22003-01-24 02:44:45 +00005278On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5279approximate k by ignoring the (y+k).d term at first. Note that k can't be
5280very large, since all offset-returning methods return a duration of magnitude
5281less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5282be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005283
5284In any case, the new value is
5285
Tim Peters8bb5ad22003-01-24 02:44:45 +00005286 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005287
Tim Peters8bb5ad22003-01-24 02:44:45 +00005288It's helpful to step back at look at [4] from a higher level: it's simply
5289mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005290
5291At this point, if
5292
Tim Peters8bb5ad22003-01-24 02:44:45 +00005293 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005294
5295we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005296at the start of daylight time. Picture US Eastern for concreteness. The wall
5297time 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 +00005298sense then. The docs ask that an Eastern tzinfo class consider such a time to
5299be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5300on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005301the only spelling that makes sense on the local wall clock.
5302
Tim Petersc5dc4da2003-01-02 17:55:03 +00005303In fact, if [5] holds at this point, we do have the standard-time spelling,
5304but that takes a bit of proof. We first prove a stronger result. What's the
5305difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005306
Tim Peters8bb5ad22003-01-24 02:44:45 +00005307 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005308
Tim Petersc5dc4da2003-01-02 17:55:03 +00005309Now
5310 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005311 (y + y.s).n = by #5
5312 y.n + y.s = since y.n = x.n
5313 x.n + y.s = since z and y are have the same tzinfo member,
5314 y.s = z.s by #2
5315 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005316
Tim Petersc5dc4da2003-01-02 17:55:03 +00005317Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005318
Tim Petersc5dc4da2003-01-02 17:55:03 +00005319 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005320 x.n - ((x.n + z.s) - z.o) = expanding
5321 x.n - x.n - z.s + z.o = cancelling
5322 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005323 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005324
Tim Petersc5dc4da2003-01-02 17:55:03 +00005325So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005326
Tim Petersc5dc4da2003-01-02 17:55:03 +00005327If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005328spelling we wanted in the endcase described above. We're done. Contrarily,
5329if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005330
Tim Petersc5dc4da2003-01-02 17:55:03 +00005331If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5332add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005333local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005334
Tim Petersc5dc4da2003-01-02 17:55:03 +00005335Let
Tim Petersf3615152003-01-01 21:51:37 +00005336
Tim Peters4fede1a2003-01-04 00:26:59 +00005337 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005338
Tim Peters4fede1a2003-01-04 00:26:59 +00005339and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005340
Tim Peters8bb5ad22003-01-24 02:44:45 +00005341 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005342
Tim Peters8bb5ad22003-01-24 02:44:45 +00005343If so, we're done. If not, the tzinfo class is insane, according to the
5344assumptions we've made. This also requires a bit of proof. As before, let's
5345compute the difference between the LHS and RHS of [8] (and skipping some of
5346the justifications for the kinds of substitutions we've done several times
5347already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005348
Tim Peters8bb5ad22003-01-24 02:44:45 +00005349 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005350 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5351 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5352 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5353 - z.n + z.n - z.o + z'.o = cancel z.n
5354 - z.o + z'.o = #1 twice
5355 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5356 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005357
5358So 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 +00005359we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5360return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005361
Tim Peters8bb5ad22003-01-24 02:44:45 +00005362How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5363a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5364would have to change the result dst() returns: we start in DST, and moving
5365a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005366
Tim Peters8bb5ad22003-01-24 02:44:45 +00005367There isn't a sane case where this can happen. The closest it gets is at
5368the end of DST, where there's an hour in UTC with no spelling in a hybrid
5369tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5370that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5371UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5372time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5373clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5374standard time. Since that's what the local clock *does*, we want to map both
5375UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005376in local time, but so it goes -- it's the way the local clock works.
5377
Tim Peters8bb5ad22003-01-24 02:44:45 +00005378When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5379so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5380z' = 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 +00005381(correctly) concludes that z' is not UTC-equivalent to x.
5382
5383Because we know z.d said z was in daylight time (else [5] would have held and
5384we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005385and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005386return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5387but the reasoning doesn't depend on the example -- it depends on there being
5388two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005389z' must be in standard time, and is the spelling we want in this case.
5390
5391Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5392concerned (because it takes z' as being in standard time rather than the
5393daylight time we intend here), but returning it gives the real-life "local
5394clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5395tz.
5396
5397When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5398the 1:MM standard time spelling we want.
5399
5400So how can this break? One of the assumptions must be violated. Two
5401possibilities:
5402
54031) [2] effectively says that y.s is invariant across all y belong to a given
5404 time zone. This isn't true if, for political reasons or continental drift,
5405 a region decides to change its base offset from UTC.
5406
54072) There may be versions of "double daylight" time where the tail end of
5408 the analysis gives up a step too early. I haven't thought about that
5409 enough to say.
5410
5411In any case, it's clear that the default fromutc() is strong enough to handle
5412"almost all" time zones: so long as the standard offset is invariant, it
5413doesn't matter if daylight time transition points change from year to year, or
5414if daylight time is skipped in some years; it doesn't matter how large or
5415small dst() may get within its bounds; and it doesn't even matter if some
5416perverse time zone returns a negative dst()). So a breaking case must be
5417pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005418--------------------------------------------------------------------------- */