blob: f50cae0bd840f24aab38e2e2f762dbfb72a79597 [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
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00001169 /* Give up if the year is before 1000.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 * Python strftime() plays games with the year, and different
1171 * games depending on whether envar PYTHON2K is set. This makes
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00001172 * years before 1000 a nightmare, even if the platform strftime
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 * supports them (and not all do).
1174 * We could get a lot farther here by avoiding Python's strftime
1175 * wrapper and calling the C strftime() directly, but that isn't
1176 * an option in the Python implementation of this module.
1177 */
1178 {
1179 long year;
1180 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1181 if (pyyear == NULL) return NULL;
1182 assert(PyLong_Check(pyyear));
1183 year = PyLong_AsLong(pyyear);
1184 Py_DECREF(pyyear);
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00001185 if (year < 1000) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 PyErr_Format(PyExc_ValueError, "year=%ld is before "
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00001187 "1000; the datetime strftime() "
1188 "methods require year >= 1000",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 year);
1190 return NULL;
1191 }
1192 }
Tim Petersd6844152002-12-22 20:58:42 +00001193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 /* Scan the input format, looking for %z/%Z/%f escapes, building
1195 * a new format. Since computing the replacements for those codes
1196 * is expensive, don't unless they're actually used.
1197 */
1198 if (flen > INT_MAX - 1) {
1199 PyErr_NoMemory();
1200 goto Done;
1201 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 totalnew = flen + 1; /* realistic if no %z/%Z */
1204 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1205 if (newfmt == NULL) goto Done;
1206 pnew = PyBytes_AsString(newfmt);
1207 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 while ((ch = *pin++) != '\0') {
1210 if (ch != '%') {
1211 ptoappend = pin - 1;
1212 ntoappend = 1;
1213 }
1214 else if ((ch = *pin++) == '\0') {
1215 /* There's a lone trailing %; doesn't make sense. */
1216 PyErr_SetString(PyExc_ValueError, "strftime format "
1217 "ends with raw %");
1218 goto Done;
1219 }
1220 /* A % has been seen and ch is the character after it. */
1221 else if (ch == 'z') {
1222 if (zreplacement == NULL) {
1223 /* format utcoffset */
1224 char buf[100];
1225 PyObject *tzinfo = get_tzinfo_member(object);
1226 zreplacement = PyBytes_FromStringAndSize("", 0);
1227 if (zreplacement == NULL) goto Done;
1228 if (tzinfo != Py_None && tzinfo != NULL) {
1229 assert(tzinfoarg != NULL);
1230 if (format_utcoffset(buf,
1231 sizeof(buf),
1232 "",
1233 tzinfo,
1234 tzinfoarg) < 0)
1235 goto Done;
1236 Py_DECREF(zreplacement);
1237 zreplacement =
1238 PyBytes_FromStringAndSize(buf,
1239 strlen(buf));
1240 if (zreplacement == NULL)
1241 goto Done;
1242 }
1243 }
1244 assert(zreplacement != NULL);
1245 ptoappend = PyBytes_AS_STRING(zreplacement);
1246 ntoappend = PyBytes_GET_SIZE(zreplacement);
1247 }
1248 else if (ch == 'Z') {
1249 /* format tzname */
1250 if (Zreplacement == NULL) {
1251 Zreplacement = make_Zreplacement(object,
1252 tzinfoarg);
1253 if (Zreplacement == NULL)
1254 goto Done;
1255 }
1256 assert(Zreplacement != NULL);
1257 assert(PyUnicode_Check(Zreplacement));
1258 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1259 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001260 if (ptoappend == NULL)
1261 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 }
1263 else if (ch == 'f') {
1264 /* format microseconds */
1265 if (freplacement == NULL) {
1266 freplacement = make_freplacement(object);
1267 if (freplacement == NULL)
1268 goto Done;
1269 }
1270 assert(freplacement != NULL);
1271 assert(PyBytes_Check(freplacement));
1272 ptoappend = PyBytes_AS_STRING(freplacement);
1273 ntoappend = PyBytes_GET_SIZE(freplacement);
1274 }
1275 else {
1276 /* percent followed by neither z nor Z */
1277 ptoappend = pin - 2;
1278 ntoappend = 2;
1279 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 /* Append the ntoappend chars starting at ptoappend to
1282 * the new format.
1283 */
1284 if (ntoappend == 0)
1285 continue;
1286 assert(ptoappend != NULL);
1287 assert(ntoappend > 0);
1288 while (usednew + ntoappend > totalnew) {
1289 size_t bigger = totalnew << 1;
1290 if ((bigger >> 1) != totalnew) { /* overflow */
1291 PyErr_NoMemory();
1292 goto Done;
1293 }
1294 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1295 goto Done;
1296 totalnew = bigger;
1297 pnew = PyBytes_AsString(newfmt) + usednew;
1298 }
1299 memcpy(pnew, ptoappend, ntoappend);
1300 pnew += ntoappend;
1301 usednew += ntoappend;
1302 assert(usednew <= totalnew);
1303 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1306 goto Done;
1307 {
1308 PyObject *format;
1309 PyObject *time = PyImport_ImportModuleNoBlock("time");
1310 if (time == NULL)
1311 goto Done;
1312 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1313 if (format != NULL) {
1314 result = PyObject_CallMethod(time, "strftime", "OO",
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001315 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 Py_DECREF(format);
1317 }
1318 Py_DECREF(time);
1319 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001320 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 Py_XDECREF(freplacement);
1322 Py_XDECREF(zreplacement);
1323 Py_XDECREF(Zreplacement);
1324 Py_XDECREF(newfmt);
1325 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001326}
1327
Tim Peters2a799bf2002-12-16 20:18:38 +00001328/* ---------------------------------------------------------------------------
1329 * Wrap functions from the time module. These aren't directly available
1330 * from C. Perhaps they should be.
1331 */
1332
1333/* Call time.time() and return its result (a Python float). */
1334static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001335time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 PyObject *result = NULL;
1338 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 if (time != NULL) {
1341 result = PyObject_CallMethod(time, "time", "()");
1342 Py_DECREF(time);
1343 }
1344 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001345}
1346
1347/* Build a time.struct_time. The weekday and day number are automatically
1348 * computed from the y,m,d args.
1349 */
1350static PyObject *
1351build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 PyObject *time;
1354 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 time = PyImport_ImportModuleNoBlock("time");
1357 if (time != NULL) {
1358 result = PyObject_CallMethod(time, "struct_time",
1359 "((iiiiiiiii))",
1360 y, m, d,
1361 hh, mm, ss,
1362 weekday(y, m, d),
1363 days_before_month(y, m) + d,
1364 dstflag);
1365 Py_DECREF(time);
1366 }
1367 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001368}
1369
1370/* ---------------------------------------------------------------------------
1371 * Miscellaneous helpers.
1372 */
1373
Mark Dickinsone94c6792009-02-02 20:36:42 +00001374/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001375 * The comparisons here all most naturally compute a cmp()-like result.
1376 * This little helper turns that into a bool result for rich comparisons.
1377 */
1378static PyObject *
1379diff_to_bool(int diff, int op)
1380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 PyObject *result;
1382 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 switch (op) {
1385 case Py_EQ: istrue = diff == 0; break;
1386 case Py_NE: istrue = diff != 0; break;
1387 case Py_LE: istrue = diff <= 0; break;
1388 case Py_GE: istrue = diff >= 0; break;
1389 case Py_LT: istrue = diff < 0; break;
1390 case Py_GT: istrue = diff > 0; break;
1391 default:
1392 assert(! "op unknown");
1393 istrue = 0; /* To shut up compiler */
1394 }
1395 result = istrue ? Py_True : Py_False;
1396 Py_INCREF(result);
1397 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001398}
1399
Tim Peters07534a62003-02-07 22:50:28 +00001400/* Raises a "can't compare" TypeError and returns NULL. */
1401static PyObject *
1402cmperror(PyObject *a, PyObject *b)
1403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 PyErr_Format(PyExc_TypeError,
1405 "can't compare %s to %s",
1406 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1407 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001408}
1409
Tim Peters2a799bf2002-12-16 20:18:38 +00001410/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001411 * Cached Python objects; these are set by the module init function.
1412 */
1413
1414/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415static PyObject *us_per_us = NULL; /* 1 */
1416static PyObject *us_per_ms = NULL; /* 1000 */
1417static PyObject *us_per_second = NULL; /* 1000000 */
1418static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1419static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1420static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1421static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001422static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1423
Tim Peters2a799bf2002-12-16 20:18:38 +00001424/* ---------------------------------------------------------------------------
1425 * Class implementations.
1426 */
1427
1428/*
1429 * PyDateTime_Delta implementation.
1430 */
1431
1432/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001434 * as a Python int or long.
1435 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1436 * due to ubiquitous overflow possibilities.
1437 */
1438static PyObject *
1439delta_to_microseconds(PyDateTime_Delta *self)
1440{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 PyObject *x1 = NULL;
1442 PyObject *x2 = NULL;
1443 PyObject *x3 = NULL;
1444 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1447 if (x1 == NULL)
1448 goto Done;
1449 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1450 if (x2 == NULL)
1451 goto Done;
1452 Py_DECREF(x1);
1453 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 /* x2 has days in seconds */
1456 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1457 if (x1 == NULL)
1458 goto Done;
1459 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1460 if (x3 == NULL)
1461 goto Done;
1462 Py_DECREF(x1);
1463 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001464 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 /* x3 has days+seconds in seconds */
1467 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1468 if (x1 == NULL)
1469 goto Done;
1470 Py_DECREF(x3);
1471 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 /* x1 has days+seconds in us */
1474 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1475 if (x2 == NULL)
1476 goto Done;
1477 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001478
1479Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 Py_XDECREF(x1);
1481 Py_XDECREF(x2);
1482 Py_XDECREF(x3);
1483 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001484}
1485
1486/* Convert a number of us (as a Python int or long) to a timedelta.
1487 */
1488static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001489microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 int us;
1492 int s;
1493 int d;
1494 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 PyObject *tuple = NULL;
1497 PyObject *num = NULL;
1498 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 tuple = PyNumber_Divmod(pyus, us_per_second);
1501 if (tuple == NULL)
1502 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 num = PyTuple_GetItem(tuple, 1); /* us */
1505 if (num == NULL)
1506 goto Done;
1507 temp = PyLong_AsLong(num);
1508 num = NULL;
1509 if (temp == -1 && PyErr_Occurred())
1510 goto Done;
1511 assert(0 <= temp && temp < 1000000);
1512 us = (int)temp;
1513 if (us < 0) {
1514 /* The divisor was positive, so this must be an error. */
1515 assert(PyErr_Occurred());
1516 goto Done;
1517 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1520 if (num == NULL)
1521 goto Done;
1522 Py_INCREF(num);
1523 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 tuple = PyNumber_Divmod(num, seconds_per_day);
1526 if (tuple == NULL)
1527 goto Done;
1528 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 num = PyTuple_GetItem(tuple, 1); /* seconds */
1531 if (num == NULL)
1532 goto Done;
1533 temp = PyLong_AsLong(num);
1534 num = NULL;
1535 if (temp == -1 && PyErr_Occurred())
1536 goto Done;
1537 assert(0 <= temp && temp < 24*3600);
1538 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 if (s < 0) {
1541 /* The divisor was positive, so this must be an error. */
1542 assert(PyErr_Occurred());
1543 goto Done;
1544 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1547 if (num == NULL)
1548 goto Done;
1549 Py_INCREF(num);
1550 temp = PyLong_AsLong(num);
1551 if (temp == -1 && PyErr_Occurred())
1552 goto Done;
1553 d = (int)temp;
1554 if ((long)d != temp) {
1555 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1556 "large to fit in a C int");
1557 goto Done;
1558 }
1559 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001560
1561Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 Py_XDECREF(tuple);
1563 Py_XDECREF(num);
1564 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001565}
1566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567#define microseconds_to_delta(pymicros) \
1568 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001569
Tim Peters2a799bf2002-12-16 20:18:38 +00001570static PyObject *
1571multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 PyObject *pyus_in;
1574 PyObject *pyus_out;
1575 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 pyus_in = delta_to_microseconds(delta);
1578 if (pyus_in == NULL)
1579 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1582 Py_DECREF(pyus_in);
1583 if (pyus_out == NULL)
1584 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 result = microseconds_to_delta(pyus_out);
1587 Py_DECREF(pyus_out);
1588 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001589}
1590
1591static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001592multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1593{
1594 PyObject *result = NULL;
1595 PyObject *pyus_in = NULL, *temp, *pyus_out;
1596 PyObject *ratio = NULL;
1597
1598 pyus_in = delta_to_microseconds(delta);
1599 if (pyus_in == NULL)
1600 return NULL;
1601 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1602 if (ratio == NULL)
1603 goto error;
1604 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1605 Py_DECREF(pyus_in);
1606 pyus_in = NULL;
1607 if (temp == NULL)
1608 goto error;
1609 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1610 Py_DECREF(temp);
1611 if (pyus_out == NULL)
1612 goto error;
1613 result = microseconds_to_delta(pyus_out);
1614 Py_DECREF(pyus_out);
1615 error:
1616 Py_XDECREF(pyus_in);
1617 Py_XDECREF(ratio);
1618
1619 return result;
1620}
1621
1622static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001623divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 PyObject *pyus_in;
1626 PyObject *pyus_out;
1627 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 pyus_in = delta_to_microseconds(delta);
1630 if (pyus_in == NULL)
1631 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1634 Py_DECREF(pyus_in);
1635 if (pyus_out == NULL)
1636 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 result = microseconds_to_delta(pyus_out);
1639 Py_DECREF(pyus_out);
1640 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001641}
1642
1643static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001644divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 PyObject *pyus_left;
1647 PyObject *pyus_right;
1648 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 pyus_left = delta_to_microseconds(left);
1651 if (pyus_left == NULL)
1652 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 pyus_right = delta_to_microseconds(right);
1655 if (pyus_right == NULL) {
1656 Py_DECREF(pyus_left);
1657 return NULL;
1658 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1661 Py_DECREF(pyus_left);
1662 Py_DECREF(pyus_right);
1663 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001664}
1665
1666static PyObject *
1667truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1668{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 PyObject *pyus_left;
1670 PyObject *pyus_right;
1671 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 pyus_left = delta_to_microseconds(left);
1674 if (pyus_left == NULL)
1675 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 pyus_right = delta_to_microseconds(right);
1678 if (pyus_right == NULL) {
1679 Py_DECREF(pyus_left);
1680 return NULL;
1681 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1684 Py_DECREF(pyus_left);
1685 Py_DECREF(pyus_right);
1686 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001687}
1688
1689static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001690truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1691{
1692 PyObject *result = NULL;
1693 PyObject *pyus_in = NULL, *temp, *pyus_out;
1694 PyObject *ratio = NULL;
1695
1696 pyus_in = delta_to_microseconds(delta);
1697 if (pyus_in == NULL)
1698 return NULL;
1699 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1700 if (ratio == NULL)
1701 goto error;
1702 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1703 Py_DECREF(pyus_in);
1704 pyus_in = NULL;
1705 if (temp == NULL)
1706 goto error;
1707 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1708 Py_DECREF(temp);
1709 if (pyus_out == NULL)
1710 goto error;
1711 result = microseconds_to_delta(pyus_out);
1712 Py_DECREF(pyus_out);
1713 error:
1714 Py_XDECREF(pyus_in);
1715 Py_XDECREF(ratio);
1716
1717 return result;
1718}
1719
1720static PyObject *
1721truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1722{
1723 PyObject *result;
1724 PyObject *pyus_in, *pyus_out;
1725 pyus_in = delta_to_microseconds(delta);
1726 if (pyus_in == NULL)
1727 return NULL;
1728 pyus_out = divide_nearest(pyus_in, i);
1729 Py_DECREF(pyus_in);
1730 if (pyus_out == NULL)
1731 return NULL;
1732 result = microseconds_to_delta(pyus_out);
1733 Py_DECREF(pyus_out);
1734
1735 return result;
1736}
1737
1738static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001739delta_add(PyObject *left, PyObject *right)
1740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001741 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1744 /* delta + delta */
1745 /* The C-level additions can't overflow because of the
1746 * invariant bounds.
1747 */
1748 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1749 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1750 int microseconds = GET_TD_MICROSECONDS(left) +
1751 GET_TD_MICROSECONDS(right);
1752 result = new_delta(days, seconds, microseconds, 1);
1753 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 if (result == Py_NotImplemented)
1756 Py_INCREF(result);
1757 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001758}
1759
1760static PyObject *
1761delta_negative(PyDateTime_Delta *self)
1762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 return new_delta(-GET_TD_DAYS(self),
1764 -GET_TD_SECONDS(self),
1765 -GET_TD_MICROSECONDS(self),
1766 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001767}
1768
1769static PyObject *
1770delta_positive(PyDateTime_Delta *self)
1771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 /* Could optimize this (by returning self) if this isn't a
1773 * subclass -- but who uses unary + ? Approximately nobody.
1774 */
1775 return new_delta(GET_TD_DAYS(self),
1776 GET_TD_SECONDS(self),
1777 GET_TD_MICROSECONDS(self),
1778 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001779}
1780
1781static PyObject *
1782delta_abs(PyDateTime_Delta *self)
1783{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 assert(GET_TD_MICROSECONDS(self) >= 0);
1787 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 if (GET_TD_DAYS(self) < 0)
1790 result = delta_negative(self);
1791 else
1792 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001795}
1796
1797static PyObject *
1798delta_subtract(PyObject *left, PyObject *right)
1799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1803 /* delta - delta */
1804 PyObject *minus_right = PyNumber_Negative(right);
1805 if (minus_right) {
1806 result = delta_add(left, minus_right);
1807 Py_DECREF(minus_right);
1808 }
1809 else
1810 result = NULL;
1811 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 if (result == Py_NotImplemented)
1814 Py_INCREF(result);
1815 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001816}
1817
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001818static int
1819delta_cmp(PyObject *self, PyObject *other)
1820{
1821 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1822 if (diff == 0) {
1823 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1824 if (diff == 0)
1825 diff = GET_TD_MICROSECONDS(self) -
1826 GET_TD_MICROSECONDS(other);
1827 }
1828 return diff;
1829}
1830
Tim Peters2a799bf2002-12-16 20:18:38 +00001831static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001832delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001835 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 return diff_to_bool(diff, op);
1837 }
1838 else {
1839 Py_INCREF(Py_NotImplemented);
1840 return Py_NotImplemented;
1841 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001842}
1843
1844static PyObject *delta_getstate(PyDateTime_Delta *self);
1845
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001846static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001847delta_hash(PyDateTime_Delta *self)
1848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 if (self->hashcode == -1) {
1850 PyObject *temp = delta_getstate(self);
1851 if (temp != NULL) {
1852 self->hashcode = PyObject_Hash(temp);
1853 Py_DECREF(temp);
1854 }
1855 }
1856 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001857}
1858
1859static PyObject *
1860delta_multiply(PyObject *left, PyObject *right)
1861{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 if (PyDelta_Check(left)) {
1865 /* delta * ??? */
1866 if (PyLong_Check(right))
1867 result = multiply_int_timedelta(right,
1868 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001869 else if (PyFloat_Check(right))
1870 result = multiply_float_timedelta(right,
1871 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 }
1873 else if (PyLong_Check(left))
1874 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001875 (PyDateTime_Delta *) right);
1876 else if (PyFloat_Check(left))
1877 result = multiply_float_timedelta(left,
1878 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 if (result == Py_NotImplemented)
1881 Py_INCREF(result);
1882 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001883}
1884
1885static PyObject *
1886delta_divide(PyObject *left, PyObject *right)
1887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 if (PyDelta_Check(left)) {
1891 /* delta * ??? */
1892 if (PyLong_Check(right))
1893 result = divide_timedelta_int(
1894 (PyDateTime_Delta *)left,
1895 right);
1896 else if (PyDelta_Check(right))
1897 result = divide_timedelta_timedelta(
1898 (PyDateTime_Delta *)left,
1899 (PyDateTime_Delta *)right);
1900 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 if (result == Py_NotImplemented)
1903 Py_INCREF(result);
1904 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001905}
1906
Mark Dickinson7c186e22010-04-20 22:32:49 +00001907static PyObject *
1908delta_truedivide(PyObject *left, PyObject *right)
1909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 if (PyDelta_Check(left)) {
1913 if (PyDelta_Check(right))
1914 result = truedivide_timedelta_timedelta(
1915 (PyDateTime_Delta *)left,
1916 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001917 else if (PyFloat_Check(right))
1918 result = truedivide_timedelta_float(
1919 (PyDateTime_Delta *)left, right);
1920 else if (PyLong_Check(right))
1921 result = truedivide_timedelta_int(
1922 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 if (result == Py_NotImplemented)
1926 Py_INCREF(result);
1927 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001928}
1929
1930static PyObject *
1931delta_remainder(PyObject *left, PyObject *right)
1932{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 PyObject *pyus_left;
1934 PyObject *pyus_right;
1935 PyObject *pyus_remainder;
1936 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
1939 Py_INCREF(Py_NotImplemented);
1940 return Py_NotImplemented;
1941 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1944 if (pyus_left == NULL)
1945 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1948 if (pyus_right == NULL) {
1949 Py_DECREF(pyus_left);
1950 return NULL;
1951 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1954 Py_DECREF(pyus_left);
1955 Py_DECREF(pyus_right);
1956 if (pyus_remainder == NULL)
1957 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 remainder = microseconds_to_delta(pyus_remainder);
1960 Py_DECREF(pyus_remainder);
1961 if (remainder == NULL)
1962 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001965}
1966
1967static PyObject *
1968delta_divmod(PyObject *left, PyObject *right)
1969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 PyObject *pyus_left;
1971 PyObject *pyus_right;
1972 PyObject *divmod;
1973 PyObject *delta;
1974 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
1977 Py_INCREF(Py_NotImplemented);
1978 return Py_NotImplemented;
1979 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1982 if (pyus_left == NULL)
1983 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1986 if (pyus_right == NULL) {
1987 Py_DECREF(pyus_left);
1988 return NULL;
1989 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1992 Py_DECREF(pyus_left);
1993 Py_DECREF(pyus_right);
1994 if (divmod == NULL)
1995 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 assert(PyTuple_Size(divmod) == 2);
1998 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1999 if (delta == NULL) {
2000 Py_DECREF(divmod);
2001 return NULL;
2002 }
2003 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2004 Py_DECREF(delta);
2005 Py_DECREF(divmod);
2006 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002007}
2008
Tim Peters2a799bf2002-12-16 20:18:38 +00002009/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2010 * timedelta constructor. sofar is the # of microseconds accounted for
2011 * so far, and there are factor microseconds per current unit, the number
2012 * of which is given by num. num * factor is added to sofar in a
2013 * numerically careful way, and that's the result. Any fractional
2014 * microseconds left over (this can happen if num is a float type) are
2015 * added into *leftover.
2016 * Note that there are many ways this can give an error (NULL) return.
2017 */
2018static PyObject *
2019accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2020 double *leftover)
2021{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 PyObject *prod;
2023 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 if (PyLong_Check(num)) {
2028 prod = PyNumber_Multiply(num, factor);
2029 if (prod == NULL)
2030 return NULL;
2031 sum = PyNumber_Add(sofar, prod);
2032 Py_DECREF(prod);
2033 return sum;
2034 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 if (PyFloat_Check(num)) {
2037 double dnum;
2038 double fracpart;
2039 double intpart;
2040 PyObject *x;
2041 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 /* The Plan: decompose num into an integer part and a
2044 * fractional part, num = intpart + fracpart.
2045 * Then num * factor ==
2046 * intpart * factor + fracpart * factor
2047 * and the LHS can be computed exactly in long arithmetic.
2048 * The RHS is again broken into an int part and frac part.
2049 * and the frac part is added into *leftover.
2050 */
2051 dnum = PyFloat_AsDouble(num);
2052 if (dnum == -1.0 && PyErr_Occurred())
2053 return NULL;
2054 fracpart = modf(dnum, &intpart);
2055 x = PyLong_FromDouble(intpart);
2056 if (x == NULL)
2057 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 prod = PyNumber_Multiply(x, factor);
2060 Py_DECREF(x);
2061 if (prod == NULL)
2062 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 sum = PyNumber_Add(sofar, prod);
2065 Py_DECREF(prod);
2066 if (sum == NULL)
2067 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 if (fracpart == 0.0)
2070 return sum;
2071 /* So far we've lost no information. Dealing with the
2072 * fractional part requires float arithmetic, and may
2073 * lose a little info.
2074 */
2075 assert(PyLong_Check(factor));
2076 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 dnum *= fracpart;
2079 fracpart = modf(dnum, &intpart);
2080 x = PyLong_FromDouble(intpart);
2081 if (x == NULL) {
2082 Py_DECREF(sum);
2083 return NULL;
2084 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 y = PyNumber_Add(sum, x);
2087 Py_DECREF(sum);
2088 Py_DECREF(x);
2089 *leftover += fracpart;
2090 return y;
2091 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 PyErr_Format(PyExc_TypeError,
2094 "unsupported type for timedelta %s component: %s",
2095 tag, Py_TYPE(num)->tp_name);
2096 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002097}
2098
2099static PyObject *
2100delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 /* Argument objects. */
2105 PyObject *day = NULL;
2106 PyObject *second = NULL;
2107 PyObject *us = NULL;
2108 PyObject *ms = NULL;
2109 PyObject *minute = NULL;
2110 PyObject *hour = NULL;
2111 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 PyObject *x = NULL; /* running sum of microseconds */
2114 PyObject *y = NULL; /* temp sum of microseconds */
2115 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 static char *keywords[] = {
2118 "days", "seconds", "microseconds", "milliseconds",
2119 "minutes", "hours", "weeks", NULL
2120 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002122 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2123 keywords,
2124 &day, &second, &us,
2125 &ms, &minute, &hour, &week) == 0)
2126 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 x = PyLong_FromLong(0);
2129 if (x == NULL)
2130 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002132#define CLEANUP \
2133 Py_DECREF(x); \
2134 x = y; \
2135 if (x == NULL) \
2136 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 if (us) {
2139 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2140 CLEANUP;
2141 }
2142 if (ms) {
2143 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2144 CLEANUP;
2145 }
2146 if (second) {
2147 y = accum("seconds", x, second, us_per_second, &leftover_us);
2148 CLEANUP;
2149 }
2150 if (minute) {
2151 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2152 CLEANUP;
2153 }
2154 if (hour) {
2155 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2156 CLEANUP;
2157 }
2158 if (day) {
2159 y = accum("days", x, day, us_per_day, &leftover_us);
2160 CLEANUP;
2161 }
2162 if (week) {
2163 y = accum("weeks", x, week, us_per_week, &leftover_us);
2164 CLEANUP;
2165 }
2166 if (leftover_us) {
2167 /* Round to nearest whole # of us, and add into x. */
2168 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2169 if (temp == NULL) {
2170 Py_DECREF(x);
2171 goto Done;
2172 }
2173 y = PyNumber_Add(x, temp);
2174 Py_DECREF(temp);
2175 CLEANUP;
2176 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 self = microseconds_to_delta_ex(x, type);
2179 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002180Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002182
2183#undef CLEANUP
2184}
2185
2186static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002187delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 return (GET_TD_DAYS(self) != 0
2190 || GET_TD_SECONDS(self) != 0
2191 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002192}
2193
2194static PyObject *
2195delta_repr(PyDateTime_Delta *self)
2196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 if (GET_TD_MICROSECONDS(self) != 0)
2198 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2199 Py_TYPE(self)->tp_name,
2200 GET_TD_DAYS(self),
2201 GET_TD_SECONDS(self),
2202 GET_TD_MICROSECONDS(self));
2203 if (GET_TD_SECONDS(self) != 0)
2204 return PyUnicode_FromFormat("%s(%d, %d)",
2205 Py_TYPE(self)->tp_name,
2206 GET_TD_DAYS(self),
2207 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 return PyUnicode_FromFormat("%s(%d)",
2210 Py_TYPE(self)->tp_name,
2211 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002212}
2213
2214static PyObject *
2215delta_str(PyDateTime_Delta *self)
2216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 int us = GET_TD_MICROSECONDS(self);
2218 int seconds = GET_TD_SECONDS(self);
2219 int minutes = divmod(seconds, 60, &seconds);
2220 int hours = divmod(minutes, 60, &minutes);
2221 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002223 if (days) {
2224 if (us)
2225 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2226 days, (days == 1 || days == -1) ? "" : "s",
2227 hours, minutes, seconds, us);
2228 else
2229 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2230 days, (days == 1 || days == -1) ? "" : "s",
2231 hours, minutes, seconds);
2232 } else {
2233 if (us)
2234 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2235 hours, minutes, seconds, us);
2236 else
2237 return PyUnicode_FromFormat("%d:%02d:%02d",
2238 hours, minutes, seconds);
2239 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002240
Tim Peters2a799bf2002-12-16 20:18:38 +00002241}
2242
Tim Peters371935f2003-02-01 01:52:50 +00002243/* Pickle support, a simple use of __reduce__. */
2244
Tim Petersb57f8f02003-02-01 02:54:15 +00002245/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002246static PyObject *
2247delta_getstate(PyDateTime_Delta *self)
2248{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 return Py_BuildValue("iii", GET_TD_DAYS(self),
2250 GET_TD_SECONDS(self),
2251 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002252}
2253
Tim Peters2a799bf2002-12-16 20:18:38 +00002254static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002255delta_total_seconds(PyObject *self)
2256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 PyObject *total_seconds;
2258 PyObject *total_microseconds;
2259 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2262 if (total_microseconds == NULL)
2263 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 one_million = PyLong_FromLong(1000000L);
2266 if (one_million == NULL) {
2267 Py_DECREF(total_microseconds);
2268 return NULL;
2269 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 Py_DECREF(total_microseconds);
2274 Py_DECREF(one_million);
2275 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002276}
2277
2278static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002279delta_reduce(PyDateTime_Delta* self)
2280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002281 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002282}
2283
2284#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2285
2286static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 {"days", T_INT, OFFSET(days), READONLY,
2289 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 {"seconds", T_INT, OFFSET(seconds), READONLY,
2292 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2295 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2296 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002297};
2298
2299static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002300 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2301 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002303 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2304 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002307};
2308
2309static char delta_doc[] =
2310PyDoc_STR("Difference between two datetime values.");
2311
2312static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002313 delta_add, /* nb_add */
2314 delta_subtract, /* nb_subtract */
2315 delta_multiply, /* nb_multiply */
2316 delta_remainder, /* nb_remainder */
2317 delta_divmod, /* nb_divmod */
2318 0, /* nb_power */
2319 (unaryfunc)delta_negative, /* nb_negative */
2320 (unaryfunc)delta_positive, /* nb_positive */
2321 (unaryfunc)delta_abs, /* nb_absolute */
2322 (inquiry)delta_bool, /* nb_bool */
2323 0, /*nb_invert*/
2324 0, /*nb_lshift*/
2325 0, /*nb_rshift*/
2326 0, /*nb_and*/
2327 0, /*nb_xor*/
2328 0, /*nb_or*/
2329 0, /*nb_int*/
2330 0, /*nb_reserved*/
2331 0, /*nb_float*/
2332 0, /*nb_inplace_add*/
2333 0, /*nb_inplace_subtract*/
2334 0, /*nb_inplace_multiply*/
2335 0, /*nb_inplace_remainder*/
2336 0, /*nb_inplace_power*/
2337 0, /*nb_inplace_lshift*/
2338 0, /*nb_inplace_rshift*/
2339 0, /*nb_inplace_and*/
2340 0, /*nb_inplace_xor*/
2341 0, /*nb_inplace_or*/
2342 delta_divide, /* nb_floor_divide */
2343 delta_truedivide, /* nb_true_divide */
2344 0, /* nb_inplace_floor_divide */
2345 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002346};
2347
2348static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 PyVarObject_HEAD_INIT(NULL, 0)
2350 "datetime.timedelta", /* tp_name */
2351 sizeof(PyDateTime_Delta), /* tp_basicsize */
2352 0, /* tp_itemsize */
2353 0, /* tp_dealloc */
2354 0, /* tp_print */
2355 0, /* tp_getattr */
2356 0, /* tp_setattr */
2357 0, /* tp_reserved */
2358 (reprfunc)delta_repr, /* tp_repr */
2359 &delta_as_number, /* tp_as_number */
2360 0, /* tp_as_sequence */
2361 0, /* tp_as_mapping */
2362 (hashfunc)delta_hash, /* tp_hash */
2363 0, /* tp_call */
2364 (reprfunc)delta_str, /* tp_str */
2365 PyObject_GenericGetAttr, /* tp_getattro */
2366 0, /* tp_setattro */
2367 0, /* tp_as_buffer */
2368 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2369 delta_doc, /* tp_doc */
2370 0, /* tp_traverse */
2371 0, /* tp_clear */
2372 delta_richcompare, /* tp_richcompare */
2373 0, /* tp_weaklistoffset */
2374 0, /* tp_iter */
2375 0, /* tp_iternext */
2376 delta_methods, /* tp_methods */
2377 delta_members, /* tp_members */
2378 0, /* tp_getset */
2379 0, /* tp_base */
2380 0, /* tp_dict */
2381 0, /* tp_descr_get */
2382 0, /* tp_descr_set */
2383 0, /* tp_dictoffset */
2384 0, /* tp_init */
2385 0, /* tp_alloc */
2386 delta_new, /* tp_new */
2387 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002388};
2389
2390/*
2391 * PyDateTime_Date implementation.
2392 */
2393
2394/* Accessor properties. */
2395
2396static PyObject *
2397date_year(PyDateTime_Date *self, void *unused)
2398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002400}
2401
2402static PyObject *
2403date_month(PyDateTime_Date *self, void *unused)
2404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002406}
2407
2408static PyObject *
2409date_day(PyDateTime_Date *self, void *unused)
2410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002412}
2413
2414static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 {"year", (getter)date_year},
2416 {"month", (getter)date_month},
2417 {"day", (getter)date_day},
2418 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002419};
2420
2421/* Constructors. */
2422
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002423static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002424
Tim Peters2a799bf2002-12-16 20:18:38 +00002425static PyObject *
2426date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 PyObject *self = NULL;
2429 PyObject *state;
2430 int year;
2431 int month;
2432 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 /* Check for invocation from pickle with __getstate__ state */
2435 if (PyTuple_GET_SIZE(args) == 1 &&
2436 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2437 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2438 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2439 {
2440 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2443 if (me != NULL) {
2444 char *pdata = PyBytes_AS_STRING(state);
2445 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2446 me->hashcode = -1;
2447 }
2448 return (PyObject *)me;
2449 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002451 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2452 &year, &month, &day)) {
2453 if (check_date_args(year, month, day) < 0)
2454 return NULL;
2455 self = new_date_ex(year, month, day, type);
2456 }
2457 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002458}
2459
2460/* Return new date from localtime(t). */
2461static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002462date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002463{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 struct tm *tm;
2465 time_t t;
2466 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002468 t = _PyTime_DoubleToTimet(ts);
2469 if (t == (time_t)-1 && PyErr_Occurred())
2470 return NULL;
2471 tm = localtime(&t);
2472 if (tm)
2473 result = PyObject_CallFunction(cls, "iii",
2474 tm->tm_year + 1900,
2475 tm->tm_mon + 1,
2476 tm->tm_mday);
2477 else
2478 PyErr_SetString(PyExc_ValueError,
2479 "timestamp out of range for "
2480 "platform localtime() function");
2481 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002482}
2483
2484/* Return new date from current time.
2485 * We say this is equivalent to fromtimestamp(time.time()), and the
2486 * only way to be sure of that is to *call* time.time(). That's not
2487 * generally the same as calling C's time.
2488 */
2489static PyObject *
2490date_today(PyObject *cls, PyObject *dummy)
2491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 PyObject *time;
2493 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002495 time = time_time();
2496 if (time == NULL)
2497 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 /* Note well: today() is a class method, so this may not call
2500 * date.fromtimestamp. For example, it may call
2501 * datetime.fromtimestamp. That's why we need all the accuracy
2502 * time.time() delivers; if someone were gonzo about optimization,
2503 * date.today() could get away with plain C time().
2504 */
2505 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2506 Py_DECREF(time);
2507 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002508}
2509
2510/* Return new date from given timestamp (Python timestamp -- a double). */
2511static PyObject *
2512date_fromtimestamp(PyObject *cls, PyObject *args)
2513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002514 double timestamp;
2515 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2518 result = date_local_from_time_t(cls, timestamp);
2519 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002520}
2521
2522/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2523 * the ordinal is out of range.
2524 */
2525static PyObject *
2526date_fromordinal(PyObject *cls, PyObject *args)
2527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 PyObject *result = NULL;
2529 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002531 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2532 int year;
2533 int month;
2534 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 if (ordinal < 1)
2537 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2538 ">= 1");
2539 else {
2540 ord_to_ymd(ordinal, &year, &month, &day);
2541 result = PyObject_CallFunction(cls, "iii",
2542 year, month, day);
2543 }
2544 }
2545 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002546}
2547
2548/*
2549 * Date arithmetic.
2550 */
2551
2552/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2553 * instead.
2554 */
2555static PyObject *
2556add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002558 PyObject *result = NULL;
2559 int year = GET_YEAR(date);
2560 int month = GET_MONTH(date);
2561 int deltadays = GET_TD_DAYS(delta);
2562 /* C-level overflow is impossible because |deltadays| < 1e9. */
2563 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 if (normalize_date(&year, &month, &day) >= 0)
2566 result = new_date(year, month, day);
2567 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002568}
2569
2570static PyObject *
2571date_add(PyObject *left, PyObject *right)
2572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002573 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2574 Py_INCREF(Py_NotImplemented);
2575 return Py_NotImplemented;
2576 }
2577 if (PyDate_Check(left)) {
2578 /* date + ??? */
2579 if (PyDelta_Check(right))
2580 /* date + delta */
2581 return add_date_timedelta((PyDateTime_Date *) left,
2582 (PyDateTime_Delta *) right,
2583 0);
2584 }
2585 else {
2586 /* ??? + date
2587 * 'right' must be one of us, or we wouldn't have been called
2588 */
2589 if (PyDelta_Check(left))
2590 /* delta + date */
2591 return add_date_timedelta((PyDateTime_Date *) right,
2592 (PyDateTime_Delta *) left,
2593 0);
2594 }
2595 Py_INCREF(Py_NotImplemented);
2596 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002597}
2598
2599static PyObject *
2600date_subtract(PyObject *left, PyObject *right)
2601{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002602 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2603 Py_INCREF(Py_NotImplemented);
2604 return Py_NotImplemented;
2605 }
2606 if (PyDate_Check(left)) {
2607 if (PyDate_Check(right)) {
2608 /* date - date */
2609 int left_ord = ymd_to_ord(GET_YEAR(left),
2610 GET_MONTH(left),
2611 GET_DAY(left));
2612 int right_ord = ymd_to_ord(GET_YEAR(right),
2613 GET_MONTH(right),
2614 GET_DAY(right));
2615 return new_delta(left_ord - right_ord, 0, 0, 0);
2616 }
2617 if (PyDelta_Check(right)) {
2618 /* date - delta */
2619 return add_date_timedelta((PyDateTime_Date *) left,
2620 (PyDateTime_Delta *) right,
2621 1);
2622 }
2623 }
2624 Py_INCREF(Py_NotImplemented);
2625 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002626}
2627
2628
2629/* Various ways to turn a date into a string. */
2630
2631static PyObject *
2632date_repr(PyDateTime_Date *self)
2633{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002634 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2635 Py_TYPE(self)->tp_name,
2636 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002637}
2638
2639static PyObject *
2640date_isoformat(PyDateTime_Date *self)
2641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 return PyUnicode_FromFormat("%04d-%02d-%02d",
2643 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002644}
2645
Tim Peterse2df5ff2003-05-02 18:39:55 +00002646/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002647static PyObject *
2648date_str(PyDateTime_Date *self)
2649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002651}
2652
2653
2654static PyObject *
2655date_ctime(PyDateTime_Date *self)
2656{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002657 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002658}
2659
2660static PyObject *
2661date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2662{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002663 /* This method can be inherited, and needs to call the
2664 * timetuple() method appropriate to self's class.
2665 */
2666 PyObject *result;
2667 PyObject *tuple;
2668 PyObject *format;
2669 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2672 &format))
2673 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002675 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2676 if (tuple == NULL)
2677 return NULL;
2678 result = wrap_strftime((PyObject *)self, format, tuple,
2679 (PyObject *)self);
2680 Py_DECREF(tuple);
2681 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002682}
2683
Eric Smith1ba31142007-09-11 18:06:02 +00002684static PyObject *
2685date_format(PyDateTime_Date *self, PyObject *args)
2686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002687 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002689 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2690 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002692 /* if the format is zero length, return str(self) */
2693 if (PyUnicode_GetSize(format) == 0)
2694 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002695
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002696 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002697}
2698
Tim Peters2a799bf2002-12-16 20:18:38 +00002699/* ISO methods. */
2700
2701static PyObject *
2702date_isoweekday(PyDateTime_Date *self)
2703{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002704 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002706 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002707}
2708
2709static PyObject *
2710date_isocalendar(PyDateTime_Date *self)
2711{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002712 int year = GET_YEAR(self);
2713 int week1_monday = iso_week1_monday(year);
2714 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2715 int week;
2716 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 week = divmod(today - week1_monday, 7, &day);
2719 if (week < 0) {
2720 --year;
2721 week1_monday = iso_week1_monday(year);
2722 week = divmod(today - week1_monday, 7, &day);
2723 }
2724 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2725 ++year;
2726 week = 0;
2727 }
2728 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002729}
2730
2731/* Miscellaneous methods. */
2732
Tim Peters2a799bf2002-12-16 20:18:38 +00002733static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002734date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002736 if (PyDate_Check(other)) {
2737 int diff = memcmp(((PyDateTime_Date *)self)->data,
2738 ((PyDateTime_Date *)other)->data,
2739 _PyDateTime_DATE_DATASIZE);
2740 return diff_to_bool(diff, op);
2741 }
2742 else {
2743 Py_INCREF(Py_NotImplemented);
2744 return Py_NotImplemented;
2745 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002746}
2747
2748static PyObject *
2749date_timetuple(PyDateTime_Date *self)
2750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002751 return build_struct_time(GET_YEAR(self),
2752 GET_MONTH(self),
2753 GET_DAY(self),
2754 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002755}
2756
Tim Peters12bf3392002-12-24 05:41:27 +00002757static PyObject *
2758date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002760 PyObject *clone;
2761 PyObject *tuple;
2762 int year = GET_YEAR(self);
2763 int month = GET_MONTH(self);
2764 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002766 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2767 &year, &month, &day))
2768 return NULL;
2769 tuple = Py_BuildValue("iii", year, month, day);
2770 if (tuple == NULL)
2771 return NULL;
2772 clone = date_new(Py_TYPE(self), tuple, NULL);
2773 Py_DECREF(tuple);
2774 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002775}
2776
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002777/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002778 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002779*/
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002780static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002781generic_hash(unsigned char *data, int len)
2782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002783 register unsigned char *p;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002784 register Py_hash_t x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002786 p = (unsigned char *) data;
2787 x = *p << 7;
2788 while (--len >= 0)
2789 x = (1000003*x) ^ *p++;
2790 x ^= len;
2791 if (x == -1)
2792 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002794 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002795}
2796
2797
2798static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002799
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002800static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002801date_hash(PyDateTime_Date *self)
2802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002803 if (self->hashcode == -1)
2804 self->hashcode = generic_hash(
2805 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002807 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002808}
2809
2810static PyObject *
2811date_toordinal(PyDateTime_Date *self)
2812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002813 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2814 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002815}
2816
2817static PyObject *
2818date_weekday(PyDateTime_Date *self)
2819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002820 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002823}
2824
Tim Peters371935f2003-02-01 01:52:50 +00002825/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002826
Tim Petersb57f8f02003-02-01 02:54:15 +00002827/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002828static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002829date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 PyObject* field;
2832 field = PyBytes_FromStringAndSize((char*)self->data,
2833 _PyDateTime_DATE_DATASIZE);
2834 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002835}
2836
2837static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002838date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002839{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002840 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002841}
2842
2843static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2848 METH_CLASS,
2849 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2850 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002852 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2853 METH_CLASS,
2854 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2855 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002857 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2858 PyDoc_STR("Current date or datetime: same as "
2859 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002861 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002863 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2864 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002866 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2867 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002869 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2870 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002872 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2873 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2876 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2877 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002879 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2880 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002882 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2883 PyDoc_STR("Return the day of the week represented by the date.\n"
2884 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002886 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2887 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2888 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2891 PyDoc_STR("Return the day of the week represented by the date.\n"
2892 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002894 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2895 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002897 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2898 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002900 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002901};
2902
2903static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002904PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002905
2906static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002907 date_add, /* nb_add */
2908 date_subtract, /* nb_subtract */
2909 0, /* nb_multiply */
2910 0, /* nb_remainder */
2911 0, /* nb_divmod */
2912 0, /* nb_power */
2913 0, /* nb_negative */
2914 0, /* nb_positive */
2915 0, /* nb_absolute */
2916 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002917};
2918
2919static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002920 PyVarObject_HEAD_INIT(NULL, 0)
2921 "datetime.date", /* tp_name */
2922 sizeof(PyDateTime_Date), /* tp_basicsize */
2923 0, /* tp_itemsize */
2924 0, /* tp_dealloc */
2925 0, /* tp_print */
2926 0, /* tp_getattr */
2927 0, /* tp_setattr */
2928 0, /* tp_reserved */
2929 (reprfunc)date_repr, /* tp_repr */
2930 &date_as_number, /* tp_as_number */
2931 0, /* tp_as_sequence */
2932 0, /* tp_as_mapping */
2933 (hashfunc)date_hash, /* tp_hash */
2934 0, /* tp_call */
2935 (reprfunc)date_str, /* tp_str */
2936 PyObject_GenericGetAttr, /* tp_getattro */
2937 0, /* tp_setattro */
2938 0, /* tp_as_buffer */
2939 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2940 date_doc, /* tp_doc */
2941 0, /* tp_traverse */
2942 0, /* tp_clear */
2943 date_richcompare, /* tp_richcompare */
2944 0, /* tp_weaklistoffset */
2945 0, /* tp_iter */
2946 0, /* tp_iternext */
2947 date_methods, /* tp_methods */
2948 0, /* tp_members */
2949 date_getset, /* tp_getset */
2950 0, /* tp_base */
2951 0, /* tp_dict */
2952 0, /* tp_descr_get */
2953 0, /* tp_descr_set */
2954 0, /* tp_dictoffset */
2955 0, /* tp_init */
2956 0, /* tp_alloc */
2957 date_new, /* tp_new */
2958 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002959};
2960
2961/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002962 * PyDateTime_TZInfo implementation.
2963 */
2964
2965/* This is a pure abstract base class, so doesn't do anything beyond
2966 * raising NotImplemented exceptions. Real tzinfo classes need
2967 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002968 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002969 * be subclasses of this tzinfo class, which is easy and quick to check).
2970 *
2971 * Note: For reasons having to do with pickling of subclasses, we have
2972 * to allow tzinfo objects to be instantiated. This wasn't an issue
2973 * in the Python implementation (__init__() could raise NotImplementedError
2974 * there without ill effect), but doing so in the C implementation hit a
2975 * brick wall.
2976 */
2977
2978static PyObject *
2979tzinfo_nogo(const char* methodname)
2980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002981 PyErr_Format(PyExc_NotImplementedError,
2982 "a tzinfo subclass must implement %s()",
2983 methodname);
2984 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002985}
2986
2987/* Methods. A subclass must implement these. */
2988
Tim Peters52dcce22003-01-23 16:36:11 +00002989static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002990tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2991{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002992 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002993}
2994
Tim Peters52dcce22003-01-23 16:36:11 +00002995static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002996tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2997{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002998 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002999}
3000
Tim Peters52dcce22003-01-23 16:36:11 +00003001static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003002tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003004 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003005}
3006
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003007
3008static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3009 PyDateTime_Delta *delta,
3010 int factor);
3011static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3012static PyObject *datetime_dst(PyObject *self, PyObject *);
3013
Tim Peters52dcce22003-01-23 16:36:11 +00003014static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003015tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003016{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003017 PyObject *result = NULL;
3018 PyObject *off = NULL, *dst = NULL;
3019 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003020
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003021 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003022 PyErr_SetString(PyExc_TypeError,
3023 "fromutc: argument must be a datetime");
3024 return NULL;
3025 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003026 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003027 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3028 "is not self");
3029 return NULL;
3030 }
Tim Peters52dcce22003-01-23 16:36:11 +00003031
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003032 off = datetime_utcoffset(dt, NULL);
3033 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003034 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003035 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003036 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3037 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003038 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003039 }
Tim Peters52dcce22003-01-23 16:36:11 +00003040
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003041 dst = datetime_dst(dt, NULL);
3042 if (dst == NULL)
3043 goto Fail;
3044 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003045 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3046 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003047 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003048 }
Tim Peters52dcce22003-01-23 16:36:11 +00003049
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003050 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3051 if (delta == NULL)
3052 goto Fail;
3053 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003054 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003055 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003056
3057 Py_DECREF(dst);
3058 dst = call_dst(GET_DT_TZINFO(dt), result);
3059 if (dst == NULL)
3060 goto Fail;
3061 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003063 if (delta_bool(delta) != 0) {
3064 PyObject *temp = result;
3065 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3066 (PyDateTime_Delta *)dst, 1);
3067 Py_DECREF(temp);
3068 if (result == NULL)
3069 goto Fail;
3070 }
3071 Py_DECREF(delta);
3072 Py_DECREF(dst);
3073 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003074 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003075
3076Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003077 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3078 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003080 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003081Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003082 Py_XDECREF(off);
3083 Py_XDECREF(dst);
3084 Py_XDECREF(delta);
3085 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003086 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003087}
3088
Tim Peters2a799bf2002-12-16 20:18:38 +00003089/*
3090 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003091 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003092 */
3093
Guido van Rossum177e41a2003-01-30 22:06:23 +00003094static PyObject *
3095tzinfo_reduce(PyObject *self)
3096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003097 PyObject *args, *state, *tmp;
3098 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003100 tmp = PyTuple_New(0);
3101 if (tmp == NULL)
3102 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003104 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3105 if (getinitargs != NULL) {
3106 args = PyObject_CallObject(getinitargs, tmp);
3107 Py_DECREF(getinitargs);
3108 if (args == NULL) {
3109 Py_DECREF(tmp);
3110 return NULL;
3111 }
3112 }
3113 else {
3114 PyErr_Clear();
3115 args = tmp;
3116 Py_INCREF(args);
3117 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003119 getstate = PyObject_GetAttrString(self, "__getstate__");
3120 if (getstate != NULL) {
3121 state = PyObject_CallObject(getstate, tmp);
3122 Py_DECREF(getstate);
3123 if (state == NULL) {
3124 Py_DECREF(args);
3125 Py_DECREF(tmp);
3126 return NULL;
3127 }
3128 }
3129 else {
3130 PyObject **dictptr;
3131 PyErr_Clear();
3132 state = Py_None;
3133 dictptr = _PyObject_GetDictPtr(self);
3134 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3135 state = *dictptr;
3136 Py_INCREF(state);
3137 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003141 if (state == Py_None) {
3142 Py_DECREF(state);
3143 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3144 }
3145 else
3146 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003147}
Tim Peters2a799bf2002-12-16 20:18:38 +00003148
3149static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003151 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3152 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003154 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003155 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3156 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003158 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3159 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003161 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003162 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003164 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3165 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003167 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003168};
3169
3170static char tzinfo_doc[] =
3171PyDoc_STR("Abstract base class for time zone info objects.");
3172
Neal Norwitz227b5332006-03-22 09:28:35 +00003173static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003174 PyVarObject_HEAD_INIT(NULL, 0)
3175 "datetime.tzinfo", /* tp_name */
3176 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3177 0, /* tp_itemsize */
3178 0, /* tp_dealloc */
3179 0, /* tp_print */
3180 0, /* tp_getattr */
3181 0, /* tp_setattr */
3182 0, /* tp_reserved */
3183 0, /* tp_repr */
3184 0, /* tp_as_number */
3185 0, /* tp_as_sequence */
3186 0, /* tp_as_mapping */
3187 0, /* tp_hash */
3188 0, /* tp_call */
3189 0, /* tp_str */
3190 PyObject_GenericGetAttr, /* tp_getattro */
3191 0, /* tp_setattro */
3192 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003193 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003194 tzinfo_doc, /* tp_doc */
3195 0, /* tp_traverse */
3196 0, /* tp_clear */
3197 0, /* tp_richcompare */
3198 0, /* tp_weaklistoffset */
3199 0, /* tp_iter */
3200 0, /* tp_iternext */
3201 tzinfo_methods, /* tp_methods */
3202 0, /* tp_members */
3203 0, /* tp_getset */
3204 0, /* tp_base */
3205 0, /* tp_dict */
3206 0, /* tp_descr_get */
3207 0, /* tp_descr_set */
3208 0, /* tp_dictoffset */
3209 0, /* tp_init */
3210 0, /* tp_alloc */
3211 PyType_GenericNew, /* tp_new */
3212 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003213};
3214
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003215static char *timezone_kws[] = {"offset", "name", NULL};
3216
3217static PyObject *
3218timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3219{
3220 PyObject *offset;
3221 PyObject *name = NULL;
3222 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3223 &PyDateTime_DeltaType, &offset,
3224 &PyUnicode_Type, &name))
3225 return new_timezone(offset, name);
3226
3227 return NULL;
3228}
3229
3230static void
3231timezone_dealloc(PyDateTime_TimeZone *self)
3232{
3233 Py_CLEAR(self->offset);
3234 Py_CLEAR(self->name);
3235 Py_TYPE(self)->tp_free((PyObject *)self);
3236}
3237
3238static PyObject *
3239timezone_richcompare(PyDateTime_TimeZone *self,
3240 PyDateTime_TimeZone *other, int op)
3241{
3242 if (op != Py_EQ && op != Py_NE) {
3243 Py_INCREF(Py_NotImplemented);
3244 return Py_NotImplemented;
3245 }
3246 return delta_richcompare(self->offset, other->offset, op);
3247}
3248
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003249static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003250timezone_hash(PyDateTime_TimeZone *self)
3251{
3252 return delta_hash((PyDateTime_Delta *)self->offset);
3253}
3254
3255/* Check argument type passed to tzname, utcoffset, or dst methods.
3256 Returns 0 for good argument. Returns -1 and sets exception info
3257 otherwise.
3258 */
3259static int
3260_timezone_check_argument(PyObject *dt, const char *meth)
3261{
3262 if (dt == Py_None || PyDateTime_Check(dt))
3263 return 0;
3264 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3265 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3266 return -1;
3267}
3268
3269static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003270timezone_repr(PyDateTime_TimeZone *self)
3271{
3272 /* Note that although timezone is not subclassable, it is convenient
3273 to use Py_TYPE(self)->tp_name here. */
3274 const char *type_name = Py_TYPE(self)->tp_name;
3275
3276 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3277 return PyUnicode_FromFormat("%s.utc", type_name);
3278
3279 if (self->name == NULL)
3280 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3281
3282 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3283 self->name);
3284}
3285
3286
3287static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003288timezone_str(PyDateTime_TimeZone *self)
3289{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003290 int hours, minutes, seconds;
3291 PyObject *offset;
3292 char sign;
3293
3294 if (self->name != NULL) {
3295 Py_INCREF(self->name);
3296 return self->name;
3297 }
3298 /* Offset is normalized, so it is negative if days < 0 */
3299 if (GET_TD_DAYS(self->offset) < 0) {
3300 sign = '-';
3301 offset = delta_negative((PyDateTime_Delta *)self->offset);
3302 if (offset == NULL)
3303 return NULL;
3304 }
3305 else {
3306 sign = '+';
3307 offset = self->offset;
3308 Py_INCREF(offset);
3309 }
3310 /* Offset is not negative here. */
3311 seconds = GET_TD_SECONDS(offset);
3312 Py_DECREF(offset);
3313 minutes = divmod(seconds, 60, &seconds);
3314 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003315 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003316 assert(seconds == 0);
3317 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003318}
3319
3320static PyObject *
3321timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3322{
3323 if (_timezone_check_argument(dt, "tzname") == -1)
3324 return NULL;
3325
3326 return timezone_str(self);
3327}
3328
3329static PyObject *
3330timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3331{
3332 if (_timezone_check_argument(dt, "utcoffset") == -1)
3333 return NULL;
3334
3335 Py_INCREF(self->offset);
3336 return self->offset;
3337}
3338
3339static PyObject *
3340timezone_dst(PyObject *self, PyObject *dt)
3341{
3342 if (_timezone_check_argument(dt, "dst") == -1)
3343 return NULL;
3344
3345 Py_RETURN_NONE;
3346}
3347
3348static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003349timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3350{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003351 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003352 PyErr_SetString(PyExc_TypeError,
3353 "fromutc: argument must be a datetime");
3354 return NULL;
3355 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003356 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003357 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3358 "is not self");
3359 return NULL;
3360 }
3361
3362 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3363}
3364
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003365static PyObject *
3366timezone_getinitargs(PyDateTime_TimeZone *self)
3367{
3368 if (self->name == NULL)
3369 return Py_BuildValue("(O)", self->offset);
3370 return Py_BuildValue("(OO)", self->offset, self->name);
3371}
3372
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003373static PyMethodDef timezone_methods[] = {
3374 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3375 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003376 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003377
3378 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003379 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003380
3381 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003382 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003383
3384 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3385 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3386
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003387 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3388 PyDoc_STR("pickle support")},
3389
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003390 {NULL, NULL}
3391};
3392
3393static char timezone_doc[] =
3394PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3395
3396static PyTypeObject PyDateTime_TimeZoneType = {
3397 PyVarObject_HEAD_INIT(NULL, 0)
3398 "datetime.timezone", /* tp_name */
3399 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3400 0, /* tp_itemsize */
3401 (destructor)timezone_dealloc, /* tp_dealloc */
3402 0, /* tp_print */
3403 0, /* tp_getattr */
3404 0, /* tp_setattr */
3405 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003406 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003407 0, /* tp_as_number */
3408 0, /* tp_as_sequence */
3409 0, /* tp_as_mapping */
3410 (hashfunc)timezone_hash, /* tp_hash */
3411 0, /* tp_call */
3412 (reprfunc)timezone_str, /* tp_str */
3413 0, /* tp_getattro */
3414 0, /* tp_setattro */
3415 0, /* tp_as_buffer */
3416 Py_TPFLAGS_DEFAULT, /* tp_flags */
3417 timezone_doc, /* tp_doc */
3418 0, /* tp_traverse */
3419 0, /* tp_clear */
3420 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3421 0, /* tp_weaklistoffset */
3422 0, /* tp_iter */
3423 0, /* tp_iternext */
3424 timezone_methods, /* tp_methods */
3425 0, /* tp_members */
3426 0, /* tp_getset */
3427 &PyDateTime_TZInfoType, /* tp_base */
3428 0, /* tp_dict */
3429 0, /* tp_descr_get */
3430 0, /* tp_descr_set */
3431 0, /* tp_dictoffset */
3432 0, /* tp_init */
3433 0, /* tp_alloc */
3434 timezone_new, /* tp_new */
3435};
3436
Tim Peters2a799bf2002-12-16 20:18:38 +00003437/*
Tim Peters37f39822003-01-10 03:49:02 +00003438 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003439 */
3440
Tim Peters37f39822003-01-10 03:49:02 +00003441/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003442 */
3443
3444static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003445time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003447 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003448}
3449
Tim Peters37f39822003-01-10 03:49:02 +00003450static PyObject *
3451time_minute(PyDateTime_Time *self, void *unused)
3452{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003453 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003454}
3455
3456/* The name time_second conflicted with some platform header file. */
3457static PyObject *
3458py_time_second(PyDateTime_Time *self, void *unused)
3459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003460 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003461}
3462
3463static PyObject *
3464time_microsecond(PyDateTime_Time *self, void *unused)
3465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003466 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003467}
3468
3469static PyObject *
3470time_tzinfo(PyDateTime_Time *self, void *unused)
3471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003472 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3473 Py_INCREF(result);
3474 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003475}
3476
3477static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003478 {"hour", (getter)time_hour},
3479 {"minute", (getter)time_minute},
3480 {"second", (getter)py_time_second},
3481 {"microsecond", (getter)time_microsecond},
3482 {"tzinfo", (getter)time_tzinfo},
3483 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003484};
3485
3486/*
3487 * Constructors.
3488 */
3489
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003490static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003491 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003492
Tim Peters2a799bf2002-12-16 20:18:38 +00003493static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003494time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003496 PyObject *self = NULL;
3497 PyObject *state;
3498 int hour = 0;
3499 int minute = 0;
3500 int second = 0;
3501 int usecond = 0;
3502 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003504 /* Check for invocation from pickle with __getstate__ state */
3505 if (PyTuple_GET_SIZE(args) >= 1 &&
3506 PyTuple_GET_SIZE(args) <= 2 &&
3507 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3508 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3509 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3510 {
3511 PyDateTime_Time *me;
3512 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003514 if (PyTuple_GET_SIZE(args) == 2) {
3515 tzinfo = PyTuple_GET_ITEM(args, 1);
3516 if (check_tzinfo_subclass(tzinfo) < 0) {
3517 PyErr_SetString(PyExc_TypeError, "bad "
3518 "tzinfo state arg");
3519 return NULL;
3520 }
3521 }
3522 aware = (char)(tzinfo != Py_None);
3523 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3524 if (me != NULL) {
3525 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003527 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3528 me->hashcode = -1;
3529 me->hastzinfo = aware;
3530 if (aware) {
3531 Py_INCREF(tzinfo);
3532 me->tzinfo = tzinfo;
3533 }
3534 }
3535 return (PyObject *)me;
3536 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003538 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3539 &hour, &minute, &second, &usecond,
3540 &tzinfo)) {
3541 if (check_time_args(hour, minute, second, usecond) < 0)
3542 return NULL;
3543 if (check_tzinfo_subclass(tzinfo) < 0)
3544 return NULL;
3545 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3546 type);
3547 }
3548 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003549}
3550
3551/*
3552 * Destructor.
3553 */
3554
3555static void
Tim Peters37f39822003-01-10 03:49:02 +00003556time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003558 if (HASTZINFO(self)) {
3559 Py_XDECREF(self->tzinfo);
3560 }
3561 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003562}
3563
3564/*
Tim Peters855fe882002-12-22 03:43:39 +00003565 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003566 */
3567
Tim Peters2a799bf2002-12-16 20:18:38 +00003568/* These are all METH_NOARGS, so don't need to check the arglist. */
3569static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003570time_utcoffset(PyObject *self, PyObject *unused) {
3571 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003572}
3573
3574static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003575time_dst(PyObject *self, PyObject *unused) {
3576 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003577}
3578
3579static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003580time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003581 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003582}
3583
3584/*
Tim Peters37f39822003-01-10 03:49:02 +00003585 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003586 */
3587
3588static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003589time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003590{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003591 const char *type_name = Py_TYPE(self)->tp_name;
3592 int h = TIME_GET_HOUR(self);
3593 int m = TIME_GET_MINUTE(self);
3594 int s = TIME_GET_SECOND(self);
3595 int us = TIME_GET_MICROSECOND(self);
3596 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003598 if (us)
3599 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3600 type_name, h, m, s, us);
3601 else if (s)
3602 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3603 type_name, h, m, s);
3604 else
3605 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3606 if (result != NULL && HASTZINFO(self))
3607 result = append_keyword_tzinfo(result, self->tzinfo);
3608 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003609}
3610
Tim Peters37f39822003-01-10 03:49:02 +00003611static PyObject *
3612time_str(PyDateTime_Time *self)
3613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003614 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003615}
Tim Peters2a799bf2002-12-16 20:18:38 +00003616
3617static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003618time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003620 char buf[100];
3621 PyObject *result;
3622 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003624 if (us)
3625 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3626 TIME_GET_HOUR(self),
3627 TIME_GET_MINUTE(self),
3628 TIME_GET_SECOND(self),
3629 us);
3630 else
3631 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3632 TIME_GET_HOUR(self),
3633 TIME_GET_MINUTE(self),
3634 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003635
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003636 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003637 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003639 /* We need to append the UTC offset. */
3640 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3641 Py_None) < 0) {
3642 Py_DECREF(result);
3643 return NULL;
3644 }
3645 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3646 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003647}
3648
Tim Peters37f39822003-01-10 03:49:02 +00003649static PyObject *
3650time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003652 PyObject *result;
3653 PyObject *tuple;
3654 PyObject *format;
3655 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003657 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3658 &format))
3659 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003661 /* Python's strftime does insane things with the year part of the
3662 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003663 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003664 */
3665 tuple = Py_BuildValue("iiiiiiiii",
3666 1900, 1, 1, /* year, month, day */
3667 TIME_GET_HOUR(self),
3668 TIME_GET_MINUTE(self),
3669 TIME_GET_SECOND(self),
3670 0, 1, -1); /* weekday, daynum, dst */
3671 if (tuple == NULL)
3672 return NULL;
3673 assert(PyTuple_Size(tuple) == 9);
3674 result = wrap_strftime((PyObject *)self, format, tuple,
3675 Py_None);
3676 Py_DECREF(tuple);
3677 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003678}
Tim Peters2a799bf2002-12-16 20:18:38 +00003679
3680/*
3681 * Miscellaneous methods.
3682 */
3683
Tim Peters37f39822003-01-10 03:49:02 +00003684static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003685time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003686{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003687 PyObject *result = NULL;
3688 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003689 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003691 if (! PyTime_Check(other)) {
3692 Py_INCREF(Py_NotImplemented);
3693 return Py_NotImplemented;
3694 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003695
3696 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003697 diff = memcmp(((PyDateTime_Time *)self)->data,
3698 ((PyDateTime_Time *)other)->data,
3699 _PyDateTime_TIME_DATASIZE);
3700 return diff_to_bool(diff, op);
3701 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003702 offset1 = time_utcoffset(self, NULL);
3703 if (offset1 == NULL)
3704 return NULL;
3705 offset2 = time_utcoffset(other, NULL);
3706 if (offset2 == NULL)
3707 goto done;
3708 /* If they're both naive, or both aware and have the same offsets,
3709 * we get off cheap. Note that if they're both naive, offset1 ==
3710 * offset2 == Py_None at this point.
3711 */
3712 if ((offset1 == offset2) ||
3713 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3714 delta_cmp(offset1, offset2) == 0)) {
3715 diff = memcmp(((PyDateTime_Time *)self)->data,
3716 ((PyDateTime_Time *)other)->data,
3717 _PyDateTime_TIME_DATASIZE);
3718 result = diff_to_bool(diff, op);
3719 }
3720 /* The hard case: both aware with different UTC offsets */
3721 else if (offset1 != Py_None && offset2 != Py_None) {
3722 int offsecs1, offsecs2;
3723 assert(offset1 != offset2); /* else last "if" handled it */
3724 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3725 TIME_GET_MINUTE(self) * 60 +
3726 TIME_GET_SECOND(self) -
3727 GET_TD_DAYS(offset1) * 86400 -
3728 GET_TD_SECONDS(offset1);
3729 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3730 TIME_GET_MINUTE(other) * 60 +
3731 TIME_GET_SECOND(other) -
3732 GET_TD_DAYS(offset2) * 86400 -
3733 GET_TD_SECONDS(offset2);
3734 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003735 if (diff == 0)
3736 diff = TIME_GET_MICROSECOND(self) -
3737 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003738 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003739 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003740 else {
3741 PyErr_SetString(PyExc_TypeError,
3742 "can't compare offset-naive and "
3743 "offset-aware times");
3744 }
3745 done:
3746 Py_DECREF(offset1);
3747 Py_XDECREF(offset2);
3748 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003749}
3750
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003751static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003752time_hash(PyDateTime_Time *self)
3753{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003754 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003755 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003756
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003757 offset = time_utcoffset((PyObject *)self, NULL);
3758
3759 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003760 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003762 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003763 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003764 self->hashcode = generic_hash(
3765 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003766 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003767 PyObject *temp1, *temp2;
3768 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003769 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003770 seconds = TIME_GET_HOUR(self) * 3600 +
3771 TIME_GET_MINUTE(self) * 60 +
3772 TIME_GET_SECOND(self);
3773 microseconds = TIME_GET_MICROSECOND(self);
3774 temp1 = new_delta(0, seconds, microseconds, 1);
3775 if (temp1 == NULL) {
3776 Py_DECREF(offset);
3777 return -1;
3778 }
3779 temp2 = delta_subtract(temp1, offset);
3780 Py_DECREF(temp1);
3781 if (temp2 == NULL) {
3782 Py_DECREF(offset);
3783 return -1;
3784 }
3785 self->hashcode = PyObject_Hash(temp2);
3786 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003787 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003788 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003789 }
3790 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003791}
Tim Peters2a799bf2002-12-16 20:18:38 +00003792
Tim Peters12bf3392002-12-24 05:41:27 +00003793static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003794time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003796 PyObject *clone;
3797 PyObject *tuple;
3798 int hh = TIME_GET_HOUR(self);
3799 int mm = TIME_GET_MINUTE(self);
3800 int ss = TIME_GET_SECOND(self);
3801 int us = TIME_GET_MICROSECOND(self);
3802 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003804 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3805 time_kws,
3806 &hh, &mm, &ss, &us, &tzinfo))
3807 return NULL;
3808 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3809 if (tuple == NULL)
3810 return NULL;
3811 clone = time_new(Py_TYPE(self), tuple, NULL);
3812 Py_DECREF(tuple);
3813 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003814}
3815
Tim Peters2a799bf2002-12-16 20:18:38 +00003816static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003817time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003818{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003819 PyObject *offset, *tzinfo;
3820 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003822 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3823 /* Since utcoffset is in whole minutes, nothing can
3824 * alter the conclusion that this is nonzero.
3825 */
3826 return 1;
3827 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003828 tzinfo = GET_TIME_TZINFO(self);
3829 if (tzinfo != Py_None) {
3830 offset = call_utcoffset(tzinfo, Py_None);
3831 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003832 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003833 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3834 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003836 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003837}
3838
Tim Peters371935f2003-02-01 01:52:50 +00003839/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003840
Tim Peters33e0f382003-01-10 02:05:14 +00003841/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003842 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3843 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003844 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003845 */
3846static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003847time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003849 PyObject *basestate;
3850 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003852 basestate = PyBytes_FromStringAndSize((char *)self->data,
3853 _PyDateTime_TIME_DATASIZE);
3854 if (basestate != NULL) {
3855 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3856 result = PyTuple_Pack(1, basestate);
3857 else
3858 result = PyTuple_Pack(2, basestate, self->tzinfo);
3859 Py_DECREF(basestate);
3860 }
3861 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003862}
3863
3864static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003865time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003866{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003867 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003868}
3869
Tim Peters37f39822003-01-10 03:49:02 +00003870static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003872 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3873 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3874 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003876 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3877 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003879 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3880 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003882 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3883 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003885 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3886 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003888 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3889 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003891 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3892 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003894 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3895 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003897 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003898};
3899
Tim Peters37f39822003-01-10 03:49:02 +00003900static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003901PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3902\n\
3903All arguments are optional. tzinfo may be None, or an instance of\n\
3904a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003905
Tim Peters37f39822003-01-10 03:49:02 +00003906static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003907 0, /* nb_add */
3908 0, /* nb_subtract */
3909 0, /* nb_multiply */
3910 0, /* nb_remainder */
3911 0, /* nb_divmod */
3912 0, /* nb_power */
3913 0, /* nb_negative */
3914 0, /* nb_positive */
3915 0, /* nb_absolute */
3916 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003917};
3918
Neal Norwitz227b5332006-03-22 09:28:35 +00003919static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003920 PyVarObject_HEAD_INIT(NULL, 0)
3921 "datetime.time", /* tp_name */
3922 sizeof(PyDateTime_Time), /* tp_basicsize */
3923 0, /* tp_itemsize */
3924 (destructor)time_dealloc, /* tp_dealloc */
3925 0, /* tp_print */
3926 0, /* tp_getattr */
3927 0, /* tp_setattr */
3928 0, /* tp_reserved */
3929 (reprfunc)time_repr, /* tp_repr */
3930 &time_as_number, /* tp_as_number */
3931 0, /* tp_as_sequence */
3932 0, /* tp_as_mapping */
3933 (hashfunc)time_hash, /* tp_hash */
3934 0, /* tp_call */
3935 (reprfunc)time_str, /* tp_str */
3936 PyObject_GenericGetAttr, /* tp_getattro */
3937 0, /* tp_setattro */
3938 0, /* tp_as_buffer */
3939 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3940 time_doc, /* tp_doc */
3941 0, /* tp_traverse */
3942 0, /* tp_clear */
3943 time_richcompare, /* tp_richcompare */
3944 0, /* tp_weaklistoffset */
3945 0, /* tp_iter */
3946 0, /* tp_iternext */
3947 time_methods, /* tp_methods */
3948 0, /* tp_members */
3949 time_getset, /* tp_getset */
3950 0, /* tp_base */
3951 0, /* tp_dict */
3952 0, /* tp_descr_get */
3953 0, /* tp_descr_set */
3954 0, /* tp_dictoffset */
3955 0, /* tp_init */
3956 time_alloc, /* tp_alloc */
3957 time_new, /* tp_new */
3958 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003959};
3960
3961/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003962 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003963 */
3964
Tim Petersa9bc1682003-01-11 03:39:11 +00003965/* Accessor properties. Properties for day, month, and year are inherited
3966 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003967 */
3968
3969static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003970datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003972 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003973}
3974
Tim Petersa9bc1682003-01-11 03:39:11 +00003975static PyObject *
3976datetime_minute(PyDateTime_DateTime *self, void *unused)
3977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003979}
3980
3981static PyObject *
3982datetime_second(PyDateTime_DateTime *self, void *unused)
3983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003984 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003985}
3986
3987static PyObject *
3988datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003990 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003991}
3992
3993static PyObject *
3994datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3995{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003996 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3997 Py_INCREF(result);
3998 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003999}
4000
4001static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004002 {"hour", (getter)datetime_hour},
4003 {"minute", (getter)datetime_minute},
4004 {"second", (getter)datetime_second},
4005 {"microsecond", (getter)datetime_microsecond},
4006 {"tzinfo", (getter)datetime_tzinfo},
4007 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004008};
4009
4010/*
4011 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004012 */
4013
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004014static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004015 "year", "month", "day", "hour", "minute", "second",
4016 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004017};
4018
Tim Peters2a799bf2002-12-16 20:18:38 +00004019static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004020datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004021{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004022 PyObject *self = NULL;
4023 PyObject *state;
4024 int year;
4025 int month;
4026 int day;
4027 int hour = 0;
4028 int minute = 0;
4029 int second = 0;
4030 int usecond = 0;
4031 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004033 /* Check for invocation from pickle with __getstate__ state */
4034 if (PyTuple_GET_SIZE(args) >= 1 &&
4035 PyTuple_GET_SIZE(args) <= 2 &&
4036 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4037 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4038 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4039 {
4040 PyDateTime_DateTime *me;
4041 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004043 if (PyTuple_GET_SIZE(args) == 2) {
4044 tzinfo = PyTuple_GET_ITEM(args, 1);
4045 if (check_tzinfo_subclass(tzinfo) < 0) {
4046 PyErr_SetString(PyExc_TypeError, "bad "
4047 "tzinfo state arg");
4048 return NULL;
4049 }
4050 }
4051 aware = (char)(tzinfo != Py_None);
4052 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4053 if (me != NULL) {
4054 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004056 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4057 me->hashcode = -1;
4058 me->hastzinfo = aware;
4059 if (aware) {
4060 Py_INCREF(tzinfo);
4061 me->tzinfo = tzinfo;
4062 }
4063 }
4064 return (PyObject *)me;
4065 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004067 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4068 &year, &month, &day, &hour, &minute,
4069 &second, &usecond, &tzinfo)) {
4070 if (check_date_args(year, month, day) < 0)
4071 return NULL;
4072 if (check_time_args(hour, minute, second, usecond) < 0)
4073 return NULL;
4074 if (check_tzinfo_subclass(tzinfo) < 0)
4075 return NULL;
4076 self = new_datetime_ex(year, month, day,
4077 hour, minute, second, usecond,
4078 tzinfo, type);
4079 }
4080 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004081}
4082
Tim Petersa9bc1682003-01-11 03:39:11 +00004083/* TM_FUNC is the shared type of localtime() and gmtime(). */
4084typedef struct tm *(*TM_FUNC)(const time_t *timer);
4085
4086/* Internal helper.
4087 * Build datetime from a time_t and a distinct count of microseconds.
4088 * Pass localtime or gmtime for f, to control the interpretation of timet.
4089 */
4090static PyObject *
4091datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004092 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004094 struct tm *tm;
4095 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004097 tm = f(&timet);
4098 if (tm) {
4099 /* The platform localtime/gmtime may insert leap seconds,
4100 * indicated by tm->tm_sec > 59. We don't care about them,
4101 * except to the extent that passing them on to the datetime
4102 * constructor would raise ValueError for a reason that
4103 * made no sense to the user.
4104 */
4105 if (tm->tm_sec > 59)
4106 tm->tm_sec = 59;
4107 result = PyObject_CallFunction(cls, "iiiiiiiO",
4108 tm->tm_year + 1900,
4109 tm->tm_mon + 1,
4110 tm->tm_mday,
4111 tm->tm_hour,
4112 tm->tm_min,
4113 tm->tm_sec,
4114 us,
4115 tzinfo);
4116 }
4117 else
4118 PyErr_SetString(PyExc_ValueError,
4119 "timestamp out of range for "
4120 "platform localtime()/gmtime() function");
4121 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004122}
4123
4124/* Internal helper.
4125 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4126 * to control the interpretation of the timestamp. Since a double doesn't
4127 * have enough bits to cover a datetime's full range of precision, it's
4128 * better to call datetime_from_timet_and_us provided you have a way
4129 * to get that much precision (e.g., C time() isn't good enough).
4130 */
4131static PyObject *
4132datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004133 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004135 time_t timet;
4136 double fraction;
4137 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004139 timet = _PyTime_DoubleToTimet(timestamp);
4140 if (timet == (time_t)-1 && PyErr_Occurred())
4141 return NULL;
4142 fraction = timestamp - (double)timet;
4143 us = (int)round_to_long(fraction * 1e6);
4144 if (us < 0) {
4145 /* Truncation towards zero is not what we wanted
4146 for negative numbers (Python's mod semantics) */
4147 timet -= 1;
4148 us += 1000000;
4149 }
4150 /* If timestamp is less than one microsecond smaller than a
4151 * full second, round up. Otherwise, ValueErrors are raised
4152 * for some floats. */
4153 if (us == 1000000) {
4154 timet += 1;
4155 us = 0;
4156 }
4157 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004158}
4159
4160/* Internal helper.
4161 * Build most accurate possible datetime for current time. Pass localtime or
4162 * gmtime for f as appropriate.
4163 */
4164static PyObject *
4165datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4166{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004167 _PyTime_timeval t;
4168 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004169 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4170 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004171}
4172
Tim Peters2a799bf2002-12-16 20:18:38 +00004173/* Return best possible local time -- this isn't constrained by the
4174 * precision of a timestamp.
4175 */
4176static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004177datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004179 PyObject *self;
4180 PyObject *tzinfo = Py_None;
4181 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4184 &tzinfo))
4185 return NULL;
4186 if (check_tzinfo_subclass(tzinfo) < 0)
4187 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004189 self = datetime_best_possible(cls,
4190 tzinfo == Py_None ? localtime : gmtime,
4191 tzinfo);
4192 if (self != NULL && tzinfo != Py_None) {
4193 /* Convert UTC to tzinfo's zone. */
4194 PyObject *temp = self;
4195 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4196 Py_DECREF(temp);
4197 }
4198 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004199}
4200
Tim Petersa9bc1682003-01-11 03:39:11 +00004201/* Return best possible UTC time -- this isn't constrained by the
4202 * precision of a timestamp.
4203 */
4204static PyObject *
4205datetime_utcnow(PyObject *cls, PyObject *dummy)
4206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004207 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004208}
4209
Tim Peters2a799bf2002-12-16 20:18:38 +00004210/* Return new local datetime from timestamp (Python timestamp -- a double). */
4211static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004212datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004214 PyObject *self;
4215 double timestamp;
4216 PyObject *tzinfo = Py_None;
4217 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004219 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4220 keywords, &timestamp, &tzinfo))
4221 return NULL;
4222 if (check_tzinfo_subclass(tzinfo) < 0)
4223 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004225 self = datetime_from_timestamp(cls,
4226 tzinfo == Py_None ? localtime : gmtime,
4227 timestamp,
4228 tzinfo);
4229 if (self != NULL && tzinfo != Py_None) {
4230 /* Convert UTC to tzinfo's zone. */
4231 PyObject *temp = self;
4232 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4233 Py_DECREF(temp);
4234 }
4235 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004236}
4237
Tim Petersa9bc1682003-01-11 03:39:11 +00004238/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4239static PyObject *
4240datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004242 double timestamp;
4243 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004245 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4246 result = datetime_from_timestamp(cls, gmtime, timestamp,
4247 Py_None);
4248 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004249}
4250
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004251/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004252static PyObject *
4253datetime_strptime(PyObject *cls, PyObject *args)
4254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004255 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004256 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004258 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4259 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004260
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004261 if (module == NULL) {
4262 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004263 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004264 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004265 }
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004266 return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4267 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004268}
4269
Tim Petersa9bc1682003-01-11 03:39:11 +00004270/* Return new datetime from date/datetime and time arguments. */
4271static PyObject *
4272datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004274 static char *keywords[] = {"date", "time", NULL};
4275 PyObject *date;
4276 PyObject *time;
4277 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004279 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4280 &PyDateTime_DateType, &date,
4281 &PyDateTime_TimeType, &time)) {
4282 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004284 if (HASTZINFO(time))
4285 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4286 result = PyObject_CallFunction(cls, "iiiiiiiO",
4287 GET_YEAR(date),
4288 GET_MONTH(date),
4289 GET_DAY(date),
4290 TIME_GET_HOUR(time),
4291 TIME_GET_MINUTE(time),
4292 TIME_GET_SECOND(time),
4293 TIME_GET_MICROSECOND(time),
4294 tzinfo);
4295 }
4296 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004297}
Tim Peters2a799bf2002-12-16 20:18:38 +00004298
4299/*
4300 * Destructor.
4301 */
4302
4303static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004304datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004306 if (HASTZINFO(self)) {
4307 Py_XDECREF(self->tzinfo);
4308 }
4309 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004310}
4311
4312/*
4313 * Indirect access to tzinfo methods.
4314 */
4315
Tim Peters2a799bf2002-12-16 20:18:38 +00004316/* These are all METH_NOARGS, so don't need to check the arglist. */
4317static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004318datetime_utcoffset(PyObject *self, PyObject *unused) {
4319 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004320}
4321
4322static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004323datetime_dst(PyObject *self, PyObject *unused) {
4324 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004325}
4326
4327static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004328datetime_tzname(PyObject *self, PyObject *unused) {
4329 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004330}
4331
4332/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004333 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004334 */
4335
Tim Petersa9bc1682003-01-11 03:39:11 +00004336/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4337 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004338 */
4339static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004340add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004341 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004343 /* Note that the C-level additions can't overflow, because of
4344 * invariant bounds on the member values.
4345 */
4346 int year = GET_YEAR(date);
4347 int month = GET_MONTH(date);
4348 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4349 int hour = DATE_GET_HOUR(date);
4350 int minute = DATE_GET_MINUTE(date);
4351 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4352 int microsecond = DATE_GET_MICROSECOND(date) +
4353 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004355 assert(factor == 1 || factor == -1);
4356 if (normalize_datetime(&year, &month, &day,
4357 &hour, &minute, &second, &microsecond) < 0)
4358 return NULL;
4359 else
4360 return new_datetime(year, month, day,
4361 hour, minute, second, microsecond,
4362 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004363}
4364
4365static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004366datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004368 if (PyDateTime_Check(left)) {
4369 /* datetime + ??? */
4370 if (PyDelta_Check(right))
4371 /* datetime + delta */
4372 return add_datetime_timedelta(
4373 (PyDateTime_DateTime *)left,
4374 (PyDateTime_Delta *)right,
4375 1);
4376 }
4377 else if (PyDelta_Check(left)) {
4378 /* delta + datetime */
4379 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4380 (PyDateTime_Delta *) left,
4381 1);
4382 }
4383 Py_INCREF(Py_NotImplemented);
4384 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004385}
4386
4387static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004388datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004389{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004390 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004392 if (PyDateTime_Check(left)) {
4393 /* datetime - ??? */
4394 if (PyDateTime_Check(right)) {
4395 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004396 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004397 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004398
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004399 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4400 offset2 = offset1 = Py_None;
4401 Py_INCREF(offset1);
4402 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004403 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004404 else {
4405 offset1 = datetime_utcoffset(left, NULL);
4406 if (offset1 == NULL)
4407 return NULL;
4408 offset2 = datetime_utcoffset(right, NULL);
4409 if (offset2 == NULL) {
4410 Py_DECREF(offset1);
4411 return NULL;
4412 }
4413 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4414 PyErr_SetString(PyExc_TypeError,
4415 "can't subtract offset-naive and "
4416 "offset-aware datetimes");
4417 Py_DECREF(offset1);
4418 Py_DECREF(offset2);
4419 return NULL;
4420 }
4421 }
4422 if ((offset1 != offset2) &&
4423 delta_cmp(offset1, offset2) != 0) {
4424 offdiff = delta_subtract(offset1, offset2);
4425 if (offdiff == NULL) {
4426 Py_DECREF(offset1);
4427 Py_DECREF(offset2);
4428 return NULL;
4429 }
4430 }
4431 Py_DECREF(offset1);
4432 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004433 delta_d = ymd_to_ord(GET_YEAR(left),
4434 GET_MONTH(left),
4435 GET_DAY(left)) -
4436 ymd_to_ord(GET_YEAR(right),
4437 GET_MONTH(right),
4438 GET_DAY(right));
4439 /* These can't overflow, since the values are
4440 * normalized. At most this gives the number of
4441 * seconds in one day.
4442 */
4443 delta_s = (DATE_GET_HOUR(left) -
4444 DATE_GET_HOUR(right)) * 3600 +
4445 (DATE_GET_MINUTE(left) -
4446 DATE_GET_MINUTE(right)) * 60 +
4447 (DATE_GET_SECOND(left) -
4448 DATE_GET_SECOND(right));
4449 delta_us = DATE_GET_MICROSECOND(left) -
4450 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004451 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004452 if (offdiff != NULL) {
4453 PyObject *temp = result;
4454 result = delta_subtract(result, offdiff);
4455 Py_DECREF(temp);
4456 Py_DECREF(offdiff);
4457 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004458 }
4459 else if (PyDelta_Check(right)) {
4460 /* datetime - delta */
4461 result = add_datetime_timedelta(
4462 (PyDateTime_DateTime *)left,
4463 (PyDateTime_Delta *)right,
4464 -1);
4465 }
4466 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004467
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004468 if (result == Py_NotImplemented)
4469 Py_INCREF(result);
4470 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004471}
4472
4473/* Various ways to turn a datetime into a string. */
4474
4475static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004476datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004478 const char *type_name = Py_TYPE(self)->tp_name;
4479 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004481 if (DATE_GET_MICROSECOND(self)) {
4482 baserepr = PyUnicode_FromFormat(
4483 "%s(%d, %d, %d, %d, %d, %d, %d)",
4484 type_name,
4485 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4486 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4487 DATE_GET_SECOND(self),
4488 DATE_GET_MICROSECOND(self));
4489 }
4490 else if (DATE_GET_SECOND(self)) {
4491 baserepr = PyUnicode_FromFormat(
4492 "%s(%d, %d, %d, %d, %d, %d)",
4493 type_name,
4494 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4495 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4496 DATE_GET_SECOND(self));
4497 }
4498 else {
4499 baserepr = PyUnicode_FromFormat(
4500 "%s(%d, %d, %d, %d, %d)",
4501 type_name,
4502 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4503 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4504 }
4505 if (baserepr == NULL || ! HASTZINFO(self))
4506 return baserepr;
4507 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004508}
4509
Tim Petersa9bc1682003-01-11 03:39:11 +00004510static PyObject *
4511datetime_str(PyDateTime_DateTime *self)
4512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004513 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004514}
Tim Peters2a799bf2002-12-16 20:18:38 +00004515
4516static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004517datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004519 int sep = 'T';
4520 static char *keywords[] = {"sep", NULL};
4521 char buffer[100];
4522 PyObject *result;
4523 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004525 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4526 return NULL;
4527 if (us)
4528 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4529 GET_YEAR(self), GET_MONTH(self),
4530 GET_DAY(self), (int)sep,
4531 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4532 DATE_GET_SECOND(self), us);
4533 else
4534 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4535 GET_YEAR(self), GET_MONTH(self),
4536 GET_DAY(self), (int)sep,
4537 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4538 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004540 if (!result || !HASTZINFO(self))
4541 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004543 /* We need to append the UTC offset. */
4544 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4545 (PyObject *)self) < 0) {
4546 Py_DECREF(result);
4547 return NULL;
4548 }
4549 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4550 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004551}
4552
Tim Petersa9bc1682003-01-11 03:39:11 +00004553static PyObject *
4554datetime_ctime(PyDateTime_DateTime *self)
4555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004556 return format_ctime((PyDateTime_Date *)self,
4557 DATE_GET_HOUR(self),
4558 DATE_GET_MINUTE(self),
4559 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004560}
4561
Tim Peters2a799bf2002-12-16 20:18:38 +00004562/* Miscellaneous methods. */
4563
Tim Petersa9bc1682003-01-11 03:39:11 +00004564static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004565datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004566{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004567 PyObject *result = NULL;
4568 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004569 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004571 if (! PyDateTime_Check(other)) {
4572 if (PyDate_Check(other)) {
4573 /* Prevent invocation of date_richcompare. We want to
4574 return NotImplemented here to give the other object
4575 a chance. But since DateTime is a subclass of
4576 Date, if the other object is a Date, it would
4577 compute an ordering based on the date part alone,
4578 and we don't want that. So force unequal or
4579 uncomparable here in that case. */
4580 if (op == Py_EQ)
4581 Py_RETURN_FALSE;
4582 if (op == Py_NE)
4583 Py_RETURN_TRUE;
4584 return cmperror(self, other);
4585 }
4586 Py_INCREF(Py_NotImplemented);
4587 return Py_NotImplemented;
4588 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004589
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004590 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004591 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4592 ((PyDateTime_DateTime *)other)->data,
4593 _PyDateTime_DATETIME_DATASIZE);
4594 return diff_to_bool(diff, op);
4595 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004596 offset1 = datetime_utcoffset(self, NULL);
4597 if (offset1 == NULL)
4598 return NULL;
4599 offset2 = datetime_utcoffset(other, NULL);
4600 if (offset2 == NULL)
4601 goto done;
4602 /* If they're both naive, or both aware and have the same offsets,
4603 * we get off cheap. Note that if they're both naive, offset1 ==
4604 * offset2 == Py_None at this point.
4605 */
4606 if ((offset1 == offset2) ||
4607 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4608 delta_cmp(offset1, offset2) == 0)) {
4609 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4610 ((PyDateTime_DateTime *)other)->data,
4611 _PyDateTime_DATETIME_DATASIZE);
4612 result = diff_to_bool(diff, op);
4613 }
4614 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004615 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004616
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004617 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004618 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4619 other);
4620 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004621 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004622 diff = GET_TD_DAYS(delta);
4623 if (diff == 0)
4624 diff = GET_TD_SECONDS(delta) |
4625 GET_TD_MICROSECONDS(delta);
4626 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004627 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004628 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004629 else {
4630 PyErr_SetString(PyExc_TypeError,
4631 "can't compare offset-naive and "
4632 "offset-aware datetimes");
4633 }
4634 done:
4635 Py_DECREF(offset1);
4636 Py_XDECREF(offset2);
4637 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004638}
4639
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004640static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004641datetime_hash(PyDateTime_DateTime *self)
4642{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004643 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004644 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004645
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004646 offset = datetime_utcoffset((PyObject *)self, NULL);
4647
4648 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004649 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004651 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004652 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004653 self->hashcode = generic_hash(
4654 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004655 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004656 PyObject *temp1, *temp2;
4657 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004659 assert(HASTZINFO(self));
4660 days = ymd_to_ord(GET_YEAR(self),
4661 GET_MONTH(self),
4662 GET_DAY(self));
4663 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004664 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004665 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004666 temp1 = new_delta(days, seconds,
4667 DATE_GET_MICROSECOND(self),
4668 1);
4669 if (temp1 == NULL) {
4670 Py_DECREF(offset);
4671 return -1;
4672 }
4673 temp2 = delta_subtract(temp1, offset);
4674 Py_DECREF(temp1);
4675 if (temp2 == NULL) {
4676 Py_DECREF(offset);
4677 return -1;
4678 }
4679 self->hashcode = PyObject_Hash(temp2);
4680 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004682 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 }
4684 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004685}
Tim Peters2a799bf2002-12-16 20:18:38 +00004686
4687static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004688datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004689{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004690 PyObject *clone;
4691 PyObject *tuple;
4692 int y = GET_YEAR(self);
4693 int m = GET_MONTH(self);
4694 int d = GET_DAY(self);
4695 int hh = DATE_GET_HOUR(self);
4696 int mm = DATE_GET_MINUTE(self);
4697 int ss = DATE_GET_SECOND(self);
4698 int us = DATE_GET_MICROSECOND(self);
4699 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004701 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4702 datetime_kws,
4703 &y, &m, &d, &hh, &mm, &ss, &us,
4704 &tzinfo))
4705 return NULL;
4706 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4707 if (tuple == NULL)
4708 return NULL;
4709 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4710 Py_DECREF(tuple);
4711 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004712}
4713
4714static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004715datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004717 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004718 PyObject *offset;
4719 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004720 PyObject *tzinfo;
4721 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004723 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4724 &PyDateTime_TZInfoType, &tzinfo))
4725 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004727 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4728 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004730 /* Conversion to self's own time zone is a NOP. */
4731 if (self->tzinfo == tzinfo) {
4732 Py_INCREF(self);
4733 return (PyObject *)self;
4734 }
Tim Peters521fc152002-12-31 17:36:56 +00004735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004736 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004737 offset = datetime_utcoffset((PyObject *)self, NULL);
4738 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004739 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004740 if (offset == Py_None) {
4741 Py_DECREF(offset);
4742 NeedAware:
4743 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4744 "a naive datetime");
4745 return NULL;
4746 }
Tim Petersf3615152003-01-01 21:51:37 +00004747
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004748 /* result = self - offset */
4749 result = add_datetime_timedelta(self,
4750 (PyDateTime_Delta *)offset, -1);
4751 Py_DECREF(offset);
4752 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004753 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004755 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004756 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4757 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4758 Py_INCREF(tzinfo);
4759 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004760
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004761 temp = result;
4762 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4763 Py_DECREF(temp);
4764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004765 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004766}
4767
4768static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004769datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004771 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004773 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004774 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004775
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004776 dst = call_dst(self->tzinfo, (PyObject *)self);
4777 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004778 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004779
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004780 if (dst != Py_None)
4781 dstflag = delta_bool((PyDateTime_Delta *)dst);
4782 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004783 }
4784 return build_struct_time(GET_YEAR(self),
4785 GET_MONTH(self),
4786 GET_DAY(self),
4787 DATE_GET_HOUR(self),
4788 DATE_GET_MINUTE(self),
4789 DATE_GET_SECOND(self),
4790 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004791}
4792
4793static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004794datetime_getdate(PyDateTime_DateTime *self)
4795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004796 return new_date(GET_YEAR(self),
4797 GET_MONTH(self),
4798 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004799}
4800
4801static PyObject *
4802datetime_gettime(PyDateTime_DateTime *self)
4803{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004804 return new_time(DATE_GET_HOUR(self),
4805 DATE_GET_MINUTE(self),
4806 DATE_GET_SECOND(self),
4807 DATE_GET_MICROSECOND(self),
4808 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004809}
4810
4811static PyObject *
4812datetime_gettimetz(PyDateTime_DateTime *self)
4813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004814 return new_time(DATE_GET_HOUR(self),
4815 DATE_GET_MINUTE(self),
4816 DATE_GET_SECOND(self),
4817 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004818 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004819}
4820
4821static PyObject *
4822datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004823{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004824 int y, m, d, hh, mm, ss;
4825 PyObject *tzinfo;
4826 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004827
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004828 tzinfo = GET_DT_TZINFO(self);
4829 if (tzinfo == Py_None) {
4830 utcself = self;
4831 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004832 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004833 else {
4834 PyObject *offset;
4835 offset = call_utcoffset(tzinfo, (PyObject *)self);
4836 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004837 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004838 if (offset == Py_None) {
4839 Py_DECREF(offset);
4840 utcself = self;
4841 Py_INCREF(utcself);
4842 }
4843 else {
4844 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4845 (PyDateTime_Delta *)offset, -1);
4846 Py_DECREF(offset);
4847 if (utcself == NULL)
4848 return NULL;
4849 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004850 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004851 y = GET_YEAR(utcself);
4852 m = GET_MONTH(utcself);
4853 d = GET_DAY(utcself);
4854 hh = DATE_GET_HOUR(utcself);
4855 mm = DATE_GET_MINUTE(utcself);
4856 ss = DATE_GET_SECOND(utcself);
4857
4858 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004859 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004860}
4861
Tim Peters371935f2003-02-01 01:52:50 +00004862/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004863
Tim Petersa9bc1682003-01-11 03:39:11 +00004864/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004865 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4866 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004867 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004868 */
4869static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004870datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004871{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004872 PyObject *basestate;
4873 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004875 basestate = PyBytes_FromStringAndSize((char *)self->data,
4876 _PyDateTime_DATETIME_DATASIZE);
4877 if (basestate != NULL) {
4878 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4879 result = PyTuple_Pack(1, basestate);
4880 else
4881 result = PyTuple_Pack(2, basestate, self->tzinfo);
4882 Py_DECREF(basestate);
4883 }
4884 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004885}
4886
4887static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004888datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004891}
4892
Tim Petersa9bc1682003-01-11 03:39:11 +00004893static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004895 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004897 {"now", (PyCFunction)datetime_now,
4898 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4899 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004901 {"utcnow", (PyCFunction)datetime_utcnow,
4902 METH_NOARGS | METH_CLASS,
4903 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004905 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4906 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4907 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004909 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4910 METH_VARARGS | METH_CLASS,
4911 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4912 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004914 {"strptime", (PyCFunction)datetime_strptime,
4915 METH_VARARGS | METH_CLASS,
4916 PyDoc_STR("string, format -> new datetime parsed from a string "
4917 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004919 {"combine", (PyCFunction)datetime_combine,
4920 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4921 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004923 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004925 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4926 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004928 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4929 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004931 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4932 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4935 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004937 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4938 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004940 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4941 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004943 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4944 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4945 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4946 "sep is used to separate the year from the time, and "
4947 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004949 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4950 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004952 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4953 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004955 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4956 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004958 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4959 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004961 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4962 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004964 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4965 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004967 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004968};
4969
Tim Petersa9bc1682003-01-11 03:39:11 +00004970static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004971PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4972\n\
4973The year, month and day arguments are required. tzinfo may be None, or an\n\
4974instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004975
Tim Petersa9bc1682003-01-11 03:39:11 +00004976static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004977 datetime_add, /* nb_add */
4978 datetime_subtract, /* nb_subtract */
4979 0, /* nb_multiply */
4980 0, /* nb_remainder */
4981 0, /* nb_divmod */
4982 0, /* nb_power */
4983 0, /* nb_negative */
4984 0, /* nb_positive */
4985 0, /* nb_absolute */
4986 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004987};
4988
Neal Norwitz227b5332006-03-22 09:28:35 +00004989static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004990 PyVarObject_HEAD_INIT(NULL, 0)
4991 "datetime.datetime", /* tp_name */
4992 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4993 0, /* tp_itemsize */
4994 (destructor)datetime_dealloc, /* tp_dealloc */
4995 0, /* tp_print */
4996 0, /* tp_getattr */
4997 0, /* tp_setattr */
4998 0, /* tp_reserved */
4999 (reprfunc)datetime_repr, /* tp_repr */
5000 &datetime_as_number, /* tp_as_number */
5001 0, /* tp_as_sequence */
5002 0, /* tp_as_mapping */
5003 (hashfunc)datetime_hash, /* tp_hash */
5004 0, /* tp_call */
5005 (reprfunc)datetime_str, /* tp_str */
5006 PyObject_GenericGetAttr, /* tp_getattro */
5007 0, /* tp_setattro */
5008 0, /* tp_as_buffer */
5009 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5010 datetime_doc, /* tp_doc */
5011 0, /* tp_traverse */
5012 0, /* tp_clear */
5013 datetime_richcompare, /* tp_richcompare */
5014 0, /* tp_weaklistoffset */
5015 0, /* tp_iter */
5016 0, /* tp_iternext */
5017 datetime_methods, /* tp_methods */
5018 0, /* tp_members */
5019 datetime_getset, /* tp_getset */
5020 &PyDateTime_DateType, /* tp_base */
5021 0, /* tp_dict */
5022 0, /* tp_descr_get */
5023 0, /* tp_descr_set */
5024 0, /* tp_dictoffset */
5025 0, /* tp_init */
5026 datetime_alloc, /* tp_alloc */
5027 datetime_new, /* tp_new */
5028 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005029};
5030
5031/* ---------------------------------------------------------------------------
5032 * Module methods and initialization.
5033 */
5034
5035static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005036 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005037};
5038
Tim Peters9ddf40b2004-06-20 22:41:32 +00005039/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5040 * datetime.h.
5041 */
5042static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005043 &PyDateTime_DateType,
5044 &PyDateTime_DateTimeType,
5045 &PyDateTime_TimeType,
5046 &PyDateTime_DeltaType,
5047 &PyDateTime_TZInfoType,
5048 new_date_ex,
5049 new_datetime_ex,
5050 new_time_ex,
5051 new_delta_ex,
5052 datetime_fromtimestamp,
5053 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005054};
5055
5056
Martin v. Löwis1a214512008-06-11 05:26:20 +00005057
5058static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005059 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005060 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005061 "Fast implementation of the datetime type.",
5062 -1,
5063 module_methods,
5064 NULL,
5065 NULL,
5066 NULL,
5067 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005068};
5069
Tim Peters2a799bf2002-12-16 20:18:38 +00005070PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005071PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005073 PyObject *m; /* a module object */
5074 PyObject *d; /* its dict */
5075 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005076 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005078 m = PyModule_Create(&datetimemodule);
5079 if (m == NULL)
5080 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005082 if (PyType_Ready(&PyDateTime_DateType) < 0)
5083 return NULL;
5084 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5085 return NULL;
5086 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5087 return NULL;
5088 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5089 return NULL;
5090 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5091 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005092 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5093 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005095 /* timedelta values */
5096 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005098 x = new_delta(0, 0, 1, 0);
5099 if (x == NULL || PyDict_SetItemString(d, "resolution", 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(-MAX_DELTA_DAYS, 0, 0, 0);
5104 if (x == NULL || PyDict_SetItemString(d, "min", 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 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5109 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5110 return NULL;
5111 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005113 /* date values */
5114 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005116 x = new_date(1, 1, 1);
5117 if (x == NULL || PyDict_SetItemString(d, "min", 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_date(MAXYEAR, 12, 31);
5122 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5123 return NULL;
5124 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005126 x = new_delta(1, 0, 0, 0);
5127 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5128 return NULL;
5129 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005131 /* time values */
5132 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005134 x = new_time(0, 0, 0, 0, Py_None);
5135 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5136 return NULL;
5137 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005139 x = new_time(23, 59, 59, 999999, Py_None);
5140 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5141 return NULL;
5142 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005144 x = new_delta(0, 0, 1, 0);
5145 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5146 return NULL;
5147 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005149 /* datetime values */
5150 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005152 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5153 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5154 return NULL;
5155 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005157 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5158 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5159 return NULL;
5160 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005162 x = new_delta(0, 0, 1, 0);
5163 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5164 return NULL;
5165 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005166
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005167 /* timezone values */
5168 d = PyDateTime_TimeZoneType.tp_dict;
5169
5170 delta = new_delta(0, 0, 0, 0);
5171 if (delta == NULL)
5172 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005173 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005174 Py_DECREF(delta);
5175 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5176 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005177 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005178
5179 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5180 if (delta == NULL)
5181 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005182 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005183 Py_DECREF(delta);
5184 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5185 return NULL;
5186 Py_DECREF(x);
5187
5188 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5189 if (delta == NULL)
5190 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005191 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005192 Py_DECREF(delta);
5193 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5194 return NULL;
5195 Py_DECREF(x);
5196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005197 /* module initialization */
5198 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5199 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005201 Py_INCREF(&PyDateTime_DateType);
5202 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005204 Py_INCREF(&PyDateTime_DateTimeType);
5205 PyModule_AddObject(m, "datetime",
5206 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005208 Py_INCREF(&PyDateTime_TimeType);
5209 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005211 Py_INCREF(&PyDateTime_DeltaType);
5212 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005214 Py_INCREF(&PyDateTime_TZInfoType);
5215 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005216
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005217 Py_INCREF(&PyDateTime_TimeZoneType);
5218 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005220 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5221 if (x == NULL)
5222 return NULL;
5223 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005225 /* A 4-year cycle has an extra leap day over what we'd get from
5226 * pasting together 4 single years.
5227 */
5228 assert(DI4Y == 4 * 365 + 1);
5229 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005231 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5232 * get from pasting together 4 100-year cycles.
5233 */
5234 assert(DI400Y == 4 * DI100Y + 1);
5235 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005237 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5238 * pasting together 25 4-year cycles.
5239 */
5240 assert(DI100Y == 25 * DI4Y - 1);
5241 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 us_per_us = PyLong_FromLong(1);
5244 us_per_ms = PyLong_FromLong(1000);
5245 us_per_second = PyLong_FromLong(1000000);
5246 us_per_minute = PyLong_FromLong(60000000);
5247 seconds_per_day = PyLong_FromLong(24 * 3600);
5248 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5249 us_per_minute == NULL || seconds_per_day == NULL)
5250 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005252 /* The rest are too big for 32-bit ints, but even
5253 * us_per_week fits in 40 bits, so doubles should be exact.
5254 */
5255 us_per_hour = PyLong_FromDouble(3600000000.0);
5256 us_per_day = PyLong_FromDouble(86400000000.0);
5257 us_per_week = PyLong_FromDouble(604800000000.0);
5258 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5259 return NULL;
5260 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005261}
Tim Petersf3615152003-01-01 21:51:37 +00005262
5263/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005264Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005265 x.n = x stripped of its timezone -- its naive time.
5266 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005267 return None
Tim Petersf3615152003-01-01 21:51:37 +00005268 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005269 return None
Tim Petersf3615152003-01-01 21:51:37 +00005270 x.s = x's standard offset, x.o - x.d
5271
5272Now some derived rules, where k is a duration (timedelta).
5273
52741. x.o = x.s + x.d
5275 This follows from the definition of x.s.
5276
Tim Petersc5dc4da2003-01-02 17:55:03 +000052772. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005278 This is actually a requirement, an assumption we need to make about
5279 sane tzinfo classes.
5280
52813. The naive UTC time corresponding to x is x.n - x.o.
5282 This is again a requirement for a sane tzinfo class.
5283
52844. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005285 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005286
Tim Petersc5dc4da2003-01-02 17:55:03 +000052875. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005288 Again follows from how arithmetic is defined.
5289
Tim Peters8bb5ad22003-01-24 02:44:45 +00005290Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005291(meaning that the various tzinfo methods exist, and don't blow up or return
5292None when called).
5293
Tim Petersa9bc1682003-01-11 03:39:11 +00005294The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005295x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005296
5297By #3, we want
5298
Tim Peters8bb5ad22003-01-24 02:44:45 +00005299 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005300
5301The algorithm starts by attaching tz to x.n, and calling that y. So
5302x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5303becomes true; in effect, we want to solve [2] for k:
5304
Tim Peters8bb5ad22003-01-24 02:44:45 +00005305 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005306
5307By #1, this is the same as
5308
Tim Peters8bb5ad22003-01-24 02:44:45 +00005309 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005310
5311By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5312Substituting that into [3],
5313
Tim Peters8bb5ad22003-01-24 02:44:45 +00005314 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5315 k - (y+k).s - (y+k).d = 0; rearranging,
5316 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5317 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005318
Tim Peters8bb5ad22003-01-24 02:44:45 +00005319On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5320approximate k by ignoring the (y+k).d term at first. Note that k can't be
5321very large, since all offset-returning methods return a duration of magnitude
5322less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5323be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005324
5325In any case, the new value is
5326
Tim Peters8bb5ad22003-01-24 02:44:45 +00005327 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005328
Tim Peters8bb5ad22003-01-24 02:44:45 +00005329It's helpful to step back at look at [4] from a higher level: it's simply
5330mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005331
5332At this point, if
5333
Tim Peters8bb5ad22003-01-24 02:44:45 +00005334 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005335
5336we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005337at the start of daylight time. Picture US Eastern for concreteness. The wall
5338time 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 +00005339sense then. The docs ask that an Eastern tzinfo class consider such a time to
5340be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5341on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005342the only spelling that makes sense on the local wall clock.
5343
Tim Petersc5dc4da2003-01-02 17:55:03 +00005344In fact, if [5] holds at this point, we do have the standard-time spelling,
5345but that takes a bit of proof. We first prove a stronger result. What's the
5346difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005347
Tim Peters8bb5ad22003-01-24 02:44:45 +00005348 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005349
Tim Petersc5dc4da2003-01-02 17:55:03 +00005350Now
5351 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005352 (y + y.s).n = by #5
5353 y.n + y.s = since y.n = x.n
5354 x.n + y.s = since z and y are have the same tzinfo member,
5355 y.s = z.s by #2
5356 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005357
Tim Petersc5dc4da2003-01-02 17:55:03 +00005358Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005359
Tim Petersc5dc4da2003-01-02 17:55:03 +00005360 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005361 x.n - ((x.n + z.s) - z.o) = expanding
5362 x.n - x.n - z.s + z.o = cancelling
5363 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005364 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005365
Tim Petersc5dc4da2003-01-02 17:55:03 +00005366So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005367
Tim Petersc5dc4da2003-01-02 17:55:03 +00005368If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005369spelling we wanted in the endcase described above. We're done. Contrarily,
5370if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005371
Tim Petersc5dc4da2003-01-02 17:55:03 +00005372If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5373add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005374local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005375
Tim Petersc5dc4da2003-01-02 17:55:03 +00005376Let
Tim Petersf3615152003-01-01 21:51:37 +00005377
Tim Peters4fede1a2003-01-04 00:26:59 +00005378 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005379
Tim Peters4fede1a2003-01-04 00:26:59 +00005380and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005381
Tim Peters8bb5ad22003-01-24 02:44:45 +00005382 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005383
Tim Peters8bb5ad22003-01-24 02:44:45 +00005384If so, we're done. If not, the tzinfo class is insane, according to the
5385assumptions we've made. This also requires a bit of proof. As before, let's
5386compute the difference between the LHS and RHS of [8] (and skipping some of
5387the justifications for the kinds of substitutions we've done several times
5388already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005389
Tim Peters8bb5ad22003-01-24 02:44:45 +00005390 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005391 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5392 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5393 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5394 - z.n + z.n - z.o + z'.o = cancel z.n
5395 - z.o + z'.o = #1 twice
5396 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5397 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005398
5399So 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 +00005400we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5401return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005402
Tim Peters8bb5ad22003-01-24 02:44:45 +00005403How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5404a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5405would have to change the result dst() returns: we start in DST, and moving
5406a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005407
Tim Peters8bb5ad22003-01-24 02:44:45 +00005408There isn't a sane case where this can happen. The closest it gets is at
5409the end of DST, where there's an hour in UTC with no spelling in a hybrid
5410tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5411that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5412UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5413time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5414clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5415standard time. Since that's what the local clock *does*, we want to map both
5416UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005417in local time, but so it goes -- it's the way the local clock works.
5418
Tim Peters8bb5ad22003-01-24 02:44:45 +00005419When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5420so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5421z' = 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 +00005422(correctly) concludes that z' is not UTC-equivalent to x.
5423
5424Because we know z.d said z was in daylight time (else [5] would have held and
5425we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005426and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005427return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5428but the reasoning doesn't depend on the example -- it depends on there being
5429two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005430z' must be in standard time, and is the spelling we want in this case.
5431
5432Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5433concerned (because it takes z' as being in standard time rather than the
5434daylight time we intend here), but returning it gives the real-life "local
5435clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5436tz.
5437
5438When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5439the 1:MM standard time spelling we want.
5440
5441So how can this break? One of the assumptions must be violated. Two
5442possibilities:
5443
54441) [2] effectively says that y.s is invariant across all y belong to a given
5445 time zone. This isn't true if, for political reasons or continental drift,
5446 a region decides to change its base offset from UTC.
5447
54482) There may be versions of "double daylight" time where the tail end of
5449 the analysis gives up a step too early. I haven't thought about that
5450 enough to say.
5451
5452In any case, it's clear that the default fromutc() is strong enough to handle
5453"almost all" time zones: so long as the standard offset is invariant, it
5454doesn't matter if daylight time transition points change from year to year, or
5455if daylight time is skipped in some years; it doesn't matter how large or
5456small dst() may get within its bounds; and it doesn't even matter if some
5457perverse time zone returns a negative dst()). So a breaking case must be
5458pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005459--------------------------------------------------------------------------- */