blob: 963a1acdf02421d968fb0432aecf4a4be925a953 [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
Tim Peters9ddf40b2004-06-20 22:41:32 +000010/* Differentiate between building the core module and building extension
11 * modules.
12 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000013#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000014#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000015#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000016#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000017#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000018
19/* We require that C int be at least 32 bits, and use int virtually
20 * everywhere. In just a few cases we use a temp long, where a Python
21 * API returns a C long. In such cases, we have to ensure that the
22 * final result fits in a C int (this can be an issue on 64-bit boxes).
23 */
24#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000025# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000026#endif
27
28#define MINYEAR 1
29#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000030#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000031
32/* Nine decimal digits is easy to communicate, and leaves enough room
33 * so that two delta days can be added w/o fear of overflowing a signed
34 * 32-bit int, and with plenty of room left over to absorb any possible
35 * carries from adding seconds.
36 */
37#define MAX_DELTA_DAYS 999999999
38
39/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040#define GET_YEAR PyDateTime_GET_YEAR
41#define GET_MONTH PyDateTime_GET_MONTH
42#define GET_DAY PyDateTime_GET_DAY
43#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
44#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
45#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
46#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000047
48/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
50 ((o)->data[1] = ((v) & 0x00ff)))
51#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
52#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000053
54/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000055#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
56#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
57#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
58#define DATE_SET_MICROSECOND(o, v) \
59 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
60 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
61 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000062
63/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
65#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
66#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
67#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
68#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
69#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
70#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
71#define TIME_SET_MICROSECOND(o, v) \
72 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
73 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
74 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000075
76/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
78#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
79#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081#define SET_TD_DAYS(o, v) ((o)->days = (v))
82#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000083#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
84
Tim Petersa032d2e2003-01-11 00:15:54 +000085/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
86 * p->hastzinfo.
87 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +000088#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
89#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
90 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
91#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
92 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +000093/* M is a char or int claiming to be a valid month. The macro is equivalent
94 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +000096 */
97#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
98
Tim Peters2a799bf2002-12-16 20:18:38 +000099/* Forward declarations. */
100static PyTypeObject PyDateTime_DateType;
101static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000102static PyTypeObject PyDateTime_DeltaType;
103static PyTypeObject PyDateTime_TimeType;
104static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000105static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000106
107/* ---------------------------------------------------------------------------
108 * Math utilities.
109 */
110
111/* k = i+j overflows iff k differs in sign from both inputs,
112 * iff k^i has sign bit set and k^j has sign bit set,
113 * iff (k^i)&(k^j) has sign bit set.
114 */
115#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000117
118/* Compute Python divmod(x, y), returning the quotient and storing the
119 * remainder into *r. The quotient is the floor of x/y, and that's
120 * the real point of this. C will probably truncate instead (C99
121 * requires truncation; C89 left it implementation-defined).
122 * Simplification: we *require* that y > 0 here. That's appropriate
123 * for all the uses made of it. This simplifies the code and makes
124 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
125 * overflow case).
126 */
127static int
128divmod(int x, int y, int *r)
129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 assert(y > 0);
133 quo = x / y;
134 *r = x - quo * y;
135 if (*r < 0) {
136 --quo;
137 *r += y;
138 }
139 assert(0 <= *r && *r < y);
140 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000141}
142
Tim Peters5d644dd2003-01-02 16:32:54 +0000143/* Round a double to the nearest long. |x| must be small enough to fit
144 * in a C long; this is not checked.
145 */
146static long
147round_to_long(double x)
148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 if (x >= 0.0)
150 x = floor(x + 0.5);
151 else
152 x = ceil(x - 0.5);
153 return (long)x;
Tim Peters5d644dd2003-01-02 16:32:54 +0000154}
155
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000156/* Nearest integer to m / n for integers m and n. Half-integer results
157 * are rounded to even.
158 */
159static PyObject *
160divide_nearest(PyObject *m, PyObject *n)
161{
162 PyObject *result;
163 PyObject *temp;
164
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000165 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000166 if (temp == NULL)
167 return NULL;
168 result = PyTuple_GET_ITEM(temp, 0);
169 Py_INCREF(result);
170 Py_DECREF(temp);
171
172 return result;
173}
174
Tim Peters2a799bf2002-12-16 20:18:38 +0000175/* ---------------------------------------------------------------------------
176 * General calendrical helper functions
177 */
178
179/* For each month ordinal in 1..12, the number of days in that month,
180 * and the number of days before that month in the same year. These
181 * are correct for non-leap years only.
182 */
183static int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 0, /* unused; this vector uses 1-based indexing */
185 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000186};
187
188static int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 0, /* unused; this vector uses 1-based indexing */
190 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000191};
192
193/* year -> 1 if leap year, else 0. */
194static int
195is_leap(int year)
196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 /* Cast year to unsigned. The result is the same either way, but
198 * C can generate faster code for unsigned mod than for signed
199 * mod (especially for % 4 -- a good compiler should just grab
200 * the last 2 bits when the LHS is unsigned).
201 */
202 const unsigned int ayear = (unsigned int)year;
203 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000204}
205
206/* year, month -> number of days in that month in that year */
207static int
208days_in_month(int year, int month)
209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 assert(month >= 1);
211 assert(month <= 12);
212 if (month == 2 && is_leap(year))
213 return 29;
214 else
215 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000216}
217
218/* year, month -> number of days in year preceeding first day of month */
219static int
220days_before_month(int year, int month)
221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 assert(month >= 1);
225 assert(month <= 12);
226 days = _days_before_month[month];
227 if (month > 2 && is_leap(year))
228 ++days;
229 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000230}
231
232/* year -> number of days before January 1st of year. Remember that we
233 * start with year 1, so days_before_year(1) == 0.
234 */
235static int
236days_before_year(int year)
237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 int y = year - 1;
239 /* This is incorrect if year <= 0; we really want the floor
240 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000241 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000243 assert (year >= 1);
244 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000245}
246
247/* Number of days in 4, 100, and 400 year cycles. That these have
248 * the correct values is asserted in the module init function.
249 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250#define DI4Y 1461 /* days_before_year(5); days in 4 years */
251#define DI100Y 36524 /* days_before_year(101); days in 100 years */
252#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000253
254/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
255static void
256ord_to_ymd(int ordinal, int *year, int *month, int *day)
257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
261 * leap years repeats exactly every 400 years. The basic strategy is
262 * to find the closest 400-year boundary at or before ordinal, then
263 * work with the offset from that boundary to ordinal. Life is much
264 * clearer if we subtract 1 from ordinal first -- then the values
265 * of ordinal at 400-year boundaries are exactly those divisible
266 * by DI400Y:
267 *
268 * D M Y n n-1
269 * -- --- ---- ---------- ----------------
270 * 31 Dec -400 -DI400Y -DI400Y -1
271 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
272 * ...
273 * 30 Dec 000 -1 -2
274 * 31 Dec 000 0 -1
275 * 1 Jan 001 1 0 400-year boundary
276 * 2 Jan 001 2 1
277 * 3 Jan 001 3 2
278 * ...
279 * 31 Dec 400 DI400Y DI400Y -1
280 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
281 */
282 assert(ordinal >= 1);
283 --ordinal;
284 n400 = ordinal / DI400Y;
285 n = ordinal % DI400Y;
286 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 /* Now n is the (non-negative) offset, in days, from January 1 of
289 * year, to the desired date. Now compute how many 100-year cycles
290 * precede n.
291 * Note that it's possible for n100 to equal 4! In that case 4 full
292 * 100-year cycles precede the desired day, which implies the
293 * desired day is December 31 at the end of a 400-year cycle.
294 */
295 n100 = n / DI100Y;
296 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 /* Now compute how many 4-year cycles precede it. */
299 n4 = n / DI4Y;
300 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 /* And now how many single years. Again n1 can be 4, and again
303 * meaning that the desired day is December 31 at the end of the
304 * 4-year cycle.
305 */
306 n1 = n / 365;
307 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 *year += n100 * 100 + n4 * 4 + n1;
310 if (n1 == 4 || n100 == 4) {
311 assert(n == 0);
312 *year -= 1;
313 *month = 12;
314 *day = 31;
315 return;
316 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 /* Now the year is correct, and n is the offset from January 1. We
319 * find the month via an estimate that's either exact or one too
320 * large.
321 */
322 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
323 assert(leapyear == is_leap(*year));
324 *month = (n + 50) >> 5;
325 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
326 if (preceding > n) {
327 /* estimate is too large */
328 *month -= 1;
329 preceding -= days_in_month(*year, *month);
330 }
331 n -= preceding;
332 assert(0 <= n);
333 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000336}
337
338/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
339static int
340ymd_to_ord(int year, int month, int day)
341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000343}
344
345/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
346static int
347weekday(int year, int month, int day)
348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000350}
351
352/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
353 * first calendar week containing a Thursday.
354 */
355static int
356iso_week1_monday(int year)
357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
359 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
360 int first_weekday = (first_day + 6) % 7;
361 /* ordinal of closest Monday at or before 1/1 */
362 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
365 week1_monday += 7;
366 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000367}
368
369/* ---------------------------------------------------------------------------
370 * Range checkers.
371 */
372
373/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
374 * If not, raise OverflowError and return -1.
375 */
376static int
377check_delta_day_range(int days)
378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
380 return 0;
381 PyErr_Format(PyExc_OverflowError,
382 "days=%d; must have magnitude <= %d",
383 days, MAX_DELTA_DAYS);
384 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000385}
386
387/* Check that date arguments are in range. Return 0 if they are. If they
388 * aren't, raise ValueError and return -1.
389 */
390static int
391check_date_args(int year, int month, int day)
392{
393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 if (year < MINYEAR || year > MAXYEAR) {
395 PyErr_SetString(PyExc_ValueError,
396 "year is out of range");
397 return -1;
398 }
399 if (month < 1 || month > 12) {
400 PyErr_SetString(PyExc_ValueError,
401 "month must be in 1..12");
402 return -1;
403 }
404 if (day < 1 || day > days_in_month(year, month)) {
405 PyErr_SetString(PyExc_ValueError,
406 "day is out of range for month");
407 return -1;
408 }
409 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000410}
411
412/* Check that time arguments are in range. Return 0 if they are. If they
413 * aren't, raise ValueError and return -1.
414 */
415static int
416check_time_args(int h, int m, int s, int us)
417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 if (h < 0 || h > 23) {
419 PyErr_SetString(PyExc_ValueError,
420 "hour must be in 0..23");
421 return -1;
422 }
423 if (m < 0 || m > 59) {
424 PyErr_SetString(PyExc_ValueError,
425 "minute must be in 0..59");
426 return -1;
427 }
428 if (s < 0 || s > 59) {
429 PyErr_SetString(PyExc_ValueError,
430 "second must be in 0..59");
431 return -1;
432 }
433 if (us < 0 || us > 999999) {
434 PyErr_SetString(PyExc_ValueError,
435 "microsecond must be in 0..999999");
436 return -1;
437 }
438 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000439}
440
441/* ---------------------------------------------------------------------------
442 * Normalization utilities.
443 */
444
445/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
446 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
447 * at least factor, enough of *lo is converted into "hi" units so that
448 * 0 <= *lo < factor. The input values must be such that int overflow
449 * is impossible.
450 */
451static void
452normalize_pair(int *hi, int *lo, int factor)
453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 assert(factor > 0);
455 assert(lo != hi);
456 if (*lo < 0 || *lo >= factor) {
457 const int num_hi = divmod(*lo, factor, lo);
458 const int new_hi = *hi + num_hi;
459 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
460 *hi = new_hi;
461 }
462 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000463}
464
465/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 * 0 <= *s < 24*3600
467 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000468 * The input values must be such that the internals don't overflow.
469 * The way this routine is used, we don't get close.
470 */
471static void
472normalize_d_s_us(int *d, int *s, int *us)
473{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 if (*us < 0 || *us >= 1000000) {
475 normalize_pair(s, us, 1000000);
476 /* |s| can't be bigger than about
477 * |original s| + |original us|/1000000 now.
478 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 }
481 if (*s < 0 || *s >= 24*3600) {
482 normalize_pair(d, s, 24*3600);
483 /* |d| can't be bigger than about
484 * |original d| +
485 * (|original s| + |original us|/1000000) / (24*3600) now.
486 */
487 }
488 assert(0 <= *s && *s < 24*3600);
489 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000490}
491
492/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 * 1 <= *m <= 12
494 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000495 * The input values must be such that the internals don't overflow.
496 * The way this routine is used, we don't get close.
497 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000498static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000499normalize_y_m_d(int *y, int *m, int *d)
500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000502
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000503 /* In actual use, m is always the month component extracted from a
504 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 /* Now only day can be out of bounds (year may also be out of bounds
510 * for a datetime object, but we don't care about that here).
511 * If day is out of bounds, what to do is arguable, but at least the
512 * method here is principled and explainable.
513 */
514 dim = days_in_month(*y, *m);
515 if (*d < 1 || *d > dim) {
516 /* Move day-1 days from the first of the month. First try to
517 * get off cheap if we're only one day out of range
518 * (adjustments for timezone alone can't be worse than that).
519 */
520 if (*d == 0) {
521 --*m;
522 if (*m > 0)
523 *d = days_in_month(*y, *m);
524 else {
525 --*y;
526 *m = 12;
527 *d = 31;
528 }
529 }
530 else if (*d == dim + 1) {
531 /* move forward a day */
532 ++*m;
533 *d = 1;
534 if (*m > 12) {
535 *m = 1;
536 ++*y;
537 }
538 }
539 else {
540 int ordinal = ymd_to_ord(*y, *m, 1) +
541 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000542 if (ordinal < 1 || ordinal > MAXORDINAL) {
543 goto error;
544 } else {
545 ord_to_ymd(ordinal, y, m, d);
546 return 0;
547 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 }
549 }
550 assert(*m > 0);
551 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000552 if (MINYEAR <= *y && *y <= MAXYEAR)
553 return 0;
554 error:
555 PyErr_SetString(PyExc_OverflowError,
556 "date value out of range");
557 return -1;
558
Tim Peters2a799bf2002-12-16 20:18:38 +0000559}
560
561/* Fiddle out-of-bounds months and days so that the result makes some kind
562 * of sense. The parameters are both inputs and outputs. Returns < 0 on
563 * failure, where failure means the adjusted year is out of bounds.
564 */
565static int
566normalize_date(int *year, int *month, int *day)
567{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000568 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000569}
570
571/* Force all the datetime fields into range. The parameters are both
572 * inputs and outputs. Returns < 0 on error.
573 */
574static int
575normalize_datetime(int *year, int *month, int *day,
576 int *hour, int *minute, int *second,
577 int *microsecond)
578{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 normalize_pair(second, microsecond, 1000000);
580 normalize_pair(minute, second, 60);
581 normalize_pair(hour, minute, 60);
582 normalize_pair(day, hour, 24);
583 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000584}
585
586/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000587 * Basic object allocation: tp_alloc implementations. These allocate
588 * Python objects of the right size and type, and do the Python object-
589 * initialization bit. If there's not enough memory, they return NULL after
590 * setting MemoryError. All data members remain uninitialized trash.
591 *
592 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000593 * member is needed. This is ugly, imprecise, and possibly insecure.
594 * tp_basicsize for the time and datetime types is set to the size of the
595 * struct that has room for the tzinfo member, so subclasses in Python will
596 * allocate enough space for a tzinfo member whether or not one is actually
597 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
598 * part is that PyType_GenericAlloc() (which subclasses in Python end up
599 * using) just happens today to effectively ignore the nitems argument
600 * when tp_itemsize is 0, which it is for these type objects. If that
601 * changes, perhaps the callers of tp_alloc slots in this file should
602 * be changed to force a 0 nitems argument unless the type being allocated
603 * is a base type implemented in this file (so that tp_alloc is time_alloc
604 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000605 */
606
607static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000608time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 self = (PyObject *)
613 PyObject_MALLOC(aware ?
614 sizeof(PyDateTime_Time) :
615 sizeof(_PyDateTime_BaseTime));
616 if (self == NULL)
617 return (PyObject *)PyErr_NoMemory();
618 PyObject_INIT(self, type);
619 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000620}
621
622static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000623datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 self = (PyObject *)
628 PyObject_MALLOC(aware ?
629 sizeof(PyDateTime_DateTime) :
630 sizeof(_PyDateTime_BaseDateTime));
631 if (self == NULL)
632 return (PyObject *)PyErr_NoMemory();
633 PyObject_INIT(self, type);
634 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000635}
636
637/* ---------------------------------------------------------------------------
638 * Helpers for setting object fields. These work on pointers to the
639 * appropriate base class.
640 */
641
642/* For date and datetime. */
643static void
644set_date_fields(PyDateTime_Date *self, int y, int m, int d)
645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 self->hashcode = -1;
647 SET_YEAR(self, y);
648 SET_MONTH(self, m);
649 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000650}
651
652/* ---------------------------------------------------------------------------
653 * Create various objects, mostly without range checking.
654 */
655
656/* Create a date instance with no range checking. */
657static PyObject *
658new_date_ex(int year, int month, int day, PyTypeObject *type)
659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
663 if (self != NULL)
664 set_date_fields(self, year, month, day);
665 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000666}
667
668#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000670
671/* Create a datetime instance with no range checking. */
672static PyObject *
673new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 PyDateTime_DateTime *self;
677 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
680 if (self != NULL) {
681 self->hastzinfo = aware;
682 set_date_fields((PyDateTime_Date *)self, year, month, day);
683 DATE_SET_HOUR(self, hour);
684 DATE_SET_MINUTE(self, minute);
685 DATE_SET_SECOND(self, second);
686 DATE_SET_MICROSECOND(self, usecond);
687 if (aware) {
688 Py_INCREF(tzinfo);
689 self->tzinfo = tzinfo;
690 }
691 }
692 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000693}
694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
696 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
697 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000698
699/* Create a time instance with no range checking. */
700static PyObject *
701new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000703{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 PyDateTime_Time *self;
705 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
708 if (self != NULL) {
709 self->hastzinfo = aware;
710 self->hashcode = -1;
711 TIME_SET_HOUR(self, hour);
712 TIME_SET_MINUTE(self, minute);
713 TIME_SET_SECOND(self, second);
714 TIME_SET_MICROSECOND(self, usecond);
715 if (aware) {
716 Py_INCREF(tzinfo);
717 self->tzinfo = tzinfo;
718 }
719 }
720 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000721}
722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723#define new_time(hh, mm, ss, us, tzinfo) \
724 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000725
726/* Create a timedelta instance. Normalize the members iff normalize is
727 * true. Passing false is a speed optimization, if you know for sure
728 * that seconds and microseconds are already in their proper ranges. In any
729 * case, raises OverflowError and returns NULL if the normalized days is out
730 * of range).
731 */
732static PyObject *
733new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 if (normalize)
739 normalize_d_s_us(&days, &seconds, &microseconds);
740 assert(0 <= seconds && seconds < 24*3600);
741 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 if (check_delta_day_range(days) < 0)
744 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
747 if (self != NULL) {
748 self->hashcode = -1;
749 SET_TD_DAYS(self, days);
750 SET_TD_SECONDS(self, seconds);
751 SET_TD_MICROSECONDS(self, microseconds);
752 }
753 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000754}
755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756#define new_delta(d, s, us, normalize) \
757 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000758
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000759
760typedef struct
761{
762 PyObject_HEAD
763 PyObject *offset;
764 PyObject *name;
765} PyDateTime_TimeZone;
766
Victor Stinner6ced7c42011-03-21 18:15:42 +0100767/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000768static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000769
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000770/* Create new timezone instance checking offset range. This
771 function does not check the name argument. Caller must assure
772 that offset is a timedelta instance and name is either NULL
773 or a unicode object. */
774static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000775create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000776{
777 PyDateTime_TimeZone *self;
778 PyTypeObject *type = &PyDateTime_TimeZoneType;
779
780 assert(offset != NULL);
781 assert(PyDelta_Check(offset));
782 assert(name == NULL || PyUnicode_Check(name));
783
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000784 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
785 if (self == NULL) {
786 return NULL;
787 }
788 Py_INCREF(offset);
789 self->offset = offset;
790 Py_XINCREF(name);
791 self->name = name;
792 return (PyObject *)self;
793}
794
795static int delta_bool(PyDateTime_Delta *self);
796
797static PyObject *
798new_timezone(PyObject *offset, PyObject *name)
799{
800 assert(offset != NULL);
801 assert(PyDelta_Check(offset));
802 assert(name == NULL || PyUnicode_Check(name));
803
804 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
805 Py_INCREF(PyDateTime_TimeZone_UTC);
806 return PyDateTime_TimeZone_UTC;
807 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000808 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
809 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
810 " representing a whole number of minutes");
811 return NULL;
812 }
813 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
814 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
815 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
816 " strictly between -timedelta(hours=24) and"
817 " timedelta(hours=24).");
818 return NULL;
819 }
820
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000821 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000822}
823
Tim Petersb0c854d2003-05-17 15:57:00 +0000824/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000825 * tzinfo helpers.
826 */
827
Tim Peters855fe882002-12-22 03:43:39 +0000828/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
829 * raise TypeError and return -1.
830 */
831static int
832check_tzinfo_subclass(PyObject *p)
833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 if (p == Py_None || PyTZInfo_Check(p))
835 return 0;
836 PyErr_Format(PyExc_TypeError,
837 "tzinfo argument must be None or of a tzinfo subclass, "
838 "not type '%s'",
839 Py_TYPE(p)->tp_name);
840 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000841}
842
Tim Peters2a799bf2002-12-16 20:18:38 +0000843/* If self has a tzinfo member, return a BORROWED reference to it. Else
844 * return NULL, which is NOT AN ERROR. There are no error returns here,
845 * and the caller must not decref the result.
846 */
847static PyObject *
848get_tzinfo_member(PyObject *self)
849{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 if (PyDateTime_Check(self) && HASTZINFO(self))
853 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
854 else if (PyTime_Check(self) && HASTZINFO(self))
855 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000858}
859
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000860/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
861 * be an instance of the tzinfo class. If the method returns None, this
862 * returns None. If the method doesn't return None or timedelta, TypeError is
863 * raised and this returns NULL. If it returns a timedelta and the value is
864 * out of range or isn't a whole number of minutes, ValueError is raised and
865 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000866 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000867static PyObject *
868call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000869{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000870 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000873 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000875
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000876 if (tzinfo == Py_None)
877 Py_RETURN_NONE;
878 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
879 if (offset == Py_None || offset == NULL)
880 return offset;
881 if (PyDelta_Check(offset)) {
882 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
883 Py_DECREF(offset);
884 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
885 " representing a whole number of minutes");
886 return NULL;
887 }
888 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
889 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
890 Py_DECREF(offset);
891 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
892 " strictly between -timedelta(hours=24) and"
893 " timedelta(hours=24).");
894 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 }
896 }
897 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000898 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 PyErr_Format(PyExc_TypeError,
900 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000901 "timedelta, not '%.200s'",
902 name, Py_TYPE(offset)->tp_name);
903 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000905
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000906 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000907}
908
909/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
910 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
911 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000912 * doesn't return None or timedelta, TypeError is raised and this returns -1.
913 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
914 * # of minutes), ValueError is raised and this returns -1. Else *none is
915 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000916 */
Tim Peters855fe882002-12-22 03:43:39 +0000917static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000918call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
919{
920 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000921}
922
Tim Peters2a799bf2002-12-16 20:18:38 +0000923/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
924 * result. tzinfo must be an instance of the tzinfo class. If dst()
925 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000926 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000927 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000928 * ValueError is raised and this returns -1. Else *none is set to 0 and
929 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000930 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000931static PyObject *
932call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000933{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000934 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000935}
936
Tim Petersbad8ff02002-12-30 20:52:32 +0000937/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000938 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000939 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000940 * returns NULL. If the result is a string, we ensure it is a Unicode
941 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000942 */
943static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000944call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200947 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 assert(tzinfo != NULL);
950 assert(check_tzinfo_subclass(tzinfo) >= 0);
951 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000954 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000955
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200956 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000957
958 if (result == NULL || result == Py_None)
959 return result;
960
961 if (!PyUnicode_Check(result)) {
962 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
963 "return None or a string, not '%s'",
964 Py_TYPE(result)->tp_name);
965 Py_DECREF(result);
966 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000968
969 return result;
Tim Peters00237032002-12-27 02:21:51 +0000970}
971
Tim Peters2a799bf2002-12-16 20:18:38 +0000972/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
973 * stuff
974 * ", tzinfo=" + repr(tzinfo)
975 * before the closing ")".
976 */
977static PyObject *
978append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 assert(PyUnicode_Check(repr));
983 assert(tzinfo);
984 if (tzinfo == Py_None)
985 return repr;
986 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200987 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
988 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 Py_DECREF(repr);
990 if (temp == NULL)
991 return NULL;
992 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
993 Py_DECREF(temp);
994 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +0000995}
996
997/* ---------------------------------------------------------------------------
998 * String format helpers.
999 */
1000
1001static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001002format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 static const char *DayNames[] = {
1005 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1006 };
1007 static const char *MonthNames[] = {
1008 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1009 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1010 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1015 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1016 GET_DAY(date), hours, minutes, seconds,
1017 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001018}
1019
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001020static PyObject *delta_negative(PyDateTime_Delta *self);
1021
Tim Peters2a799bf2002-12-16 20:18:38 +00001022/* Add an hours & minutes UTC offset string to buf. buf has no more than
1023 * buflen bytes remaining. The UTC offset is gotten by calling
1024 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1025 * *buf, and that's all. Else the returned value is checked for sanity (an
1026 * integer in range), and if that's OK it's converted to an hours & minutes
1027 * string of the form
1028 * sign HH sep MM
1029 * Returns 0 if everything is OK. If the return value from utcoffset() is
1030 * bogus, an appropriate exception is set and -1 is returned.
1031 */
1032static int
Tim Peters328fff72002-12-20 01:31:27 +00001033format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001035{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001036 PyObject *offset;
1037 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001041
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001042 offset = call_utcoffset(tzinfo, tzinfoarg);
1043 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001045 if (offset == Py_None) {
1046 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 *buf = '\0';
1048 return 0;
1049 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001050 /* Offset is normalized, so it is negative if days < 0 */
1051 if (GET_TD_DAYS(offset) < 0) {
1052 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001054 offset = delta_negative((PyDateTime_Delta *)offset);
1055 Py_DECREF(temp);
1056 if (offset == NULL)
1057 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001059 else {
1060 sign = '+';
1061 }
1062 /* Offset is not negative here. */
1063 seconds = GET_TD_SECONDS(offset);
1064 Py_DECREF(offset);
1065 minutes = divmod(seconds, 60, &seconds);
1066 hours = divmod(minutes, 60, &minutes);
1067 assert(seconds == 0);
1068 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001072}
1073
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001074static PyObject *
1075make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 PyObject *temp;
1078 PyObject *tzinfo = get_tzinfo_member(object);
1079 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001080 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001082 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);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001102 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 Py_DECREF(temp);
1104 if (Zreplacement == NULL)
1105 return NULL;
1106 if (!PyUnicode_Check(Zreplacement)) {
1107 PyErr_SetString(PyExc_TypeError,
1108 "tzname.replace() did not return a string");
1109 goto Error;
1110 }
1111 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001112
1113 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 Py_DECREF(Zreplacement);
1115 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001116}
1117
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001118static PyObject *
1119make_freplacement(PyObject *object)
1120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 char freplacement[64];
1122 if (PyTime_Check(object))
1123 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1124 else if (PyDateTime_Check(object))
1125 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1126 else
1127 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001130}
1131
Tim Peters2a799bf2002-12-16 20:18:38 +00001132/* I sure don't want to reproduce the strftime code from the time module,
1133 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001134 * giving special meanings to the %z, %Z and %f format codes via a
1135 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001136 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1137 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001138 */
1139static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001140wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1146 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1147 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 const char *pin; /* pointer to next char in input format */
1150 Py_ssize_t flen; /* length of input format */
1151 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 PyObject *newfmt = NULL; /* py string, the output format */
1154 char *pnew; /* pointer to available byte in output format */
1155 size_t totalnew; /* number bytes total in output format buffer,
1156 exclusive of trailing \0 */
1157 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 const char *ptoappend; /* ptr to string to append to output buffer */
1160 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 assert(object && format && timetuple);
1163 assert(PyUnicode_Check(format));
1164 /* Convert the input format to a C string and size */
1165 pin = _PyUnicode_AsStringAndSize(format, &flen);
1166 if (!pin)
1167 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 /* Scan the input format, looking for %z/%Z/%f escapes, building
1170 * a new format. Since computing the replacements for those codes
1171 * is expensive, don't unless they're actually used.
1172 */
1173 if (flen > INT_MAX - 1) {
1174 PyErr_NoMemory();
1175 goto Done;
1176 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 totalnew = flen + 1; /* realistic if no %z/%Z */
1179 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1180 if (newfmt == NULL) goto Done;
1181 pnew = PyBytes_AsString(newfmt);
1182 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 while ((ch = *pin++) != '\0') {
1185 if (ch != '%') {
1186 ptoappend = pin - 1;
1187 ntoappend = 1;
1188 }
1189 else if ((ch = *pin++) == '\0') {
1190 /* There's a lone trailing %; doesn't make sense. */
1191 PyErr_SetString(PyExc_ValueError, "strftime format "
1192 "ends with raw %");
1193 goto Done;
1194 }
1195 /* A % has been seen and ch is the character after it. */
1196 else if (ch == 'z') {
1197 if (zreplacement == NULL) {
1198 /* format utcoffset */
1199 char buf[100];
1200 PyObject *tzinfo = get_tzinfo_member(object);
1201 zreplacement = PyBytes_FromStringAndSize("", 0);
1202 if (zreplacement == NULL) goto Done;
1203 if (tzinfo != Py_None && tzinfo != NULL) {
1204 assert(tzinfoarg != NULL);
1205 if (format_utcoffset(buf,
1206 sizeof(buf),
1207 "",
1208 tzinfo,
1209 tzinfoarg) < 0)
1210 goto Done;
1211 Py_DECREF(zreplacement);
1212 zreplacement =
1213 PyBytes_FromStringAndSize(buf,
1214 strlen(buf));
1215 if (zreplacement == NULL)
1216 goto Done;
1217 }
1218 }
1219 assert(zreplacement != NULL);
1220 ptoappend = PyBytes_AS_STRING(zreplacement);
1221 ntoappend = PyBytes_GET_SIZE(zreplacement);
1222 }
1223 else if (ch == 'Z') {
1224 /* format tzname */
1225 if (Zreplacement == NULL) {
1226 Zreplacement = make_Zreplacement(object,
1227 tzinfoarg);
1228 if (Zreplacement == NULL)
1229 goto Done;
1230 }
1231 assert(Zreplacement != NULL);
1232 assert(PyUnicode_Check(Zreplacement));
1233 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1234 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001235 if (ptoappend == NULL)
1236 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 }
1238 else if (ch == 'f') {
1239 /* format microseconds */
1240 if (freplacement == NULL) {
1241 freplacement = make_freplacement(object);
1242 if (freplacement == NULL)
1243 goto Done;
1244 }
1245 assert(freplacement != NULL);
1246 assert(PyBytes_Check(freplacement));
1247 ptoappend = PyBytes_AS_STRING(freplacement);
1248 ntoappend = PyBytes_GET_SIZE(freplacement);
1249 }
1250 else {
1251 /* percent followed by neither z nor Z */
1252 ptoappend = pin - 2;
1253 ntoappend = 2;
1254 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 /* Append the ntoappend chars starting at ptoappend to
1257 * the new format.
1258 */
1259 if (ntoappend == 0)
1260 continue;
1261 assert(ptoappend != NULL);
1262 assert(ntoappend > 0);
1263 while (usednew + ntoappend > totalnew) {
1264 size_t bigger = totalnew << 1;
1265 if ((bigger >> 1) != totalnew) { /* overflow */
1266 PyErr_NoMemory();
1267 goto Done;
1268 }
1269 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1270 goto Done;
1271 totalnew = bigger;
1272 pnew = PyBytes_AsString(newfmt) + usednew;
1273 }
1274 memcpy(pnew, ptoappend, ntoappend);
1275 pnew += ntoappend;
1276 usednew += ntoappend;
1277 assert(usednew <= totalnew);
1278 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1281 goto Done;
1282 {
1283 PyObject *format;
1284 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 if (time == NULL)
1287 goto Done;
1288 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1289 if (format != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001290 _Py_IDENTIFIER(strftime);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001291
1292 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1293 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 Py_DECREF(format);
1295 }
1296 Py_DECREF(time);
1297 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001298 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 Py_XDECREF(freplacement);
1300 Py_XDECREF(zreplacement);
1301 Py_XDECREF(Zreplacement);
1302 Py_XDECREF(newfmt);
1303 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001304}
1305
Tim Peters2a799bf2002-12-16 20:18:38 +00001306/* ---------------------------------------------------------------------------
1307 * Wrap functions from the time module. These aren't directly available
1308 * from C. Perhaps they should be.
1309 */
1310
1311/* Call time.time() and return its result (a Python float). */
1312static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001313time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 PyObject *result = NULL;
1316 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001319 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001320
1321 result = _PyObject_CallMethodId(time, &PyId_time, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 Py_DECREF(time);
1323 }
1324 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001325}
1326
1327/* Build a time.struct_time. The weekday and day number are automatically
1328 * computed from the y,m,d args.
1329 */
1330static PyObject *
1331build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1332{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 PyObject *time;
1334 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 time = PyImport_ImportModuleNoBlock("time");
1337 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001338 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001339
1340 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1341 "((iiiiiiiii))",
1342 y, m, d,
1343 hh, mm, ss,
1344 weekday(y, m, d),
1345 days_before_month(y, m) + d,
1346 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 Py_DECREF(time);
1348 }
1349 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001350}
1351
1352/* ---------------------------------------------------------------------------
1353 * Miscellaneous helpers.
1354 */
1355
Mark Dickinsone94c6792009-02-02 20:36:42 +00001356/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001357 * The comparisons here all most naturally compute a cmp()-like result.
1358 * This little helper turns that into a bool result for rich comparisons.
1359 */
1360static PyObject *
1361diff_to_bool(int diff, int op)
1362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 PyObject *result;
1364 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 switch (op) {
1367 case Py_EQ: istrue = diff == 0; break;
1368 case Py_NE: istrue = diff != 0; break;
1369 case Py_LE: istrue = diff <= 0; break;
1370 case Py_GE: istrue = diff >= 0; break;
1371 case Py_LT: istrue = diff < 0; break;
1372 case Py_GT: istrue = diff > 0; break;
1373 default:
1374 assert(! "op unknown");
1375 istrue = 0; /* To shut up compiler */
1376 }
1377 result = istrue ? Py_True : Py_False;
1378 Py_INCREF(result);
1379 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001380}
1381
Tim Peters07534a62003-02-07 22:50:28 +00001382/* Raises a "can't compare" TypeError and returns NULL. */
1383static PyObject *
1384cmperror(PyObject *a, PyObject *b)
1385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 PyErr_Format(PyExc_TypeError,
1387 "can't compare %s to %s",
1388 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1389 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001390}
1391
Tim Peters2a799bf2002-12-16 20:18:38 +00001392/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001393 * Cached Python objects; these are set by the module init function.
1394 */
1395
1396/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397static PyObject *us_per_us = NULL; /* 1 */
1398static PyObject *us_per_ms = NULL; /* 1000 */
1399static PyObject *us_per_second = NULL; /* 1000000 */
1400static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1401static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1402static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1403static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001404static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1405
Tim Peters2a799bf2002-12-16 20:18:38 +00001406/* ---------------------------------------------------------------------------
1407 * Class implementations.
1408 */
1409
1410/*
1411 * PyDateTime_Delta implementation.
1412 */
1413
1414/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001415 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001416 * as a Python int or long.
1417 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1418 * due to ubiquitous overflow possibilities.
1419 */
1420static PyObject *
1421delta_to_microseconds(PyDateTime_Delta *self)
1422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001423 PyObject *x1 = NULL;
1424 PyObject *x2 = NULL;
1425 PyObject *x3 = NULL;
1426 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1429 if (x1 == NULL)
1430 goto Done;
1431 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1432 if (x2 == NULL)
1433 goto Done;
1434 Py_DECREF(x1);
1435 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 /* x2 has days in seconds */
1438 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1439 if (x1 == NULL)
1440 goto Done;
1441 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1442 if (x3 == NULL)
1443 goto Done;
1444 Py_DECREF(x1);
1445 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001446 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 /* x3 has days+seconds in seconds */
1449 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1450 if (x1 == NULL)
1451 goto Done;
1452 Py_DECREF(x3);
1453 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 /* x1 has days+seconds in us */
1456 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1457 if (x2 == NULL)
1458 goto Done;
1459 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001460
1461Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 Py_XDECREF(x1);
1463 Py_XDECREF(x2);
1464 Py_XDECREF(x3);
1465 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001466}
1467
1468/* Convert a number of us (as a Python int or long) to a timedelta.
1469 */
1470static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001471microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001472{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 int us;
1474 int s;
1475 int d;
1476 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 PyObject *tuple = NULL;
1479 PyObject *num = NULL;
1480 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 tuple = PyNumber_Divmod(pyus, us_per_second);
1483 if (tuple == NULL)
1484 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 num = PyTuple_GetItem(tuple, 1); /* us */
1487 if (num == NULL)
1488 goto Done;
1489 temp = PyLong_AsLong(num);
1490 num = NULL;
1491 if (temp == -1 && PyErr_Occurred())
1492 goto Done;
1493 assert(0 <= temp && temp < 1000000);
1494 us = (int)temp;
1495 if (us < 0) {
1496 /* The divisor was positive, so this must be an error. */
1497 assert(PyErr_Occurred());
1498 goto Done;
1499 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1502 if (num == NULL)
1503 goto Done;
1504 Py_INCREF(num);
1505 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 tuple = PyNumber_Divmod(num, seconds_per_day);
1508 if (tuple == NULL)
1509 goto Done;
1510 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 num = PyTuple_GetItem(tuple, 1); /* seconds */
1513 if (num == NULL)
1514 goto Done;
1515 temp = PyLong_AsLong(num);
1516 num = NULL;
1517 if (temp == -1 && PyErr_Occurred())
1518 goto Done;
1519 assert(0 <= temp && temp < 24*3600);
1520 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 if (s < 0) {
1523 /* The divisor was positive, so this must be an error. */
1524 assert(PyErr_Occurred());
1525 goto Done;
1526 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1529 if (num == NULL)
1530 goto Done;
1531 Py_INCREF(num);
1532 temp = PyLong_AsLong(num);
1533 if (temp == -1 && PyErr_Occurred())
1534 goto Done;
1535 d = (int)temp;
1536 if ((long)d != temp) {
1537 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1538 "large to fit in a C int");
1539 goto Done;
1540 }
1541 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001542
1543Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 Py_XDECREF(tuple);
1545 Py_XDECREF(num);
1546 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001547}
1548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549#define microseconds_to_delta(pymicros) \
1550 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001551
Tim Peters2a799bf2002-12-16 20:18:38 +00001552static PyObject *
1553multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 PyObject *pyus_in;
1556 PyObject *pyus_out;
1557 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 pyus_in = delta_to_microseconds(delta);
1560 if (pyus_in == NULL)
1561 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1564 Py_DECREF(pyus_in);
1565 if (pyus_out == NULL)
1566 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 result = microseconds_to_delta(pyus_out);
1569 Py_DECREF(pyus_out);
1570 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001571}
1572
1573static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001574multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1575{
1576 PyObject *result = NULL;
1577 PyObject *pyus_in = NULL, *temp, *pyus_out;
1578 PyObject *ratio = NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001579 _Py_IDENTIFIER(as_integer_ratio);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001580
1581 pyus_in = delta_to_microseconds(delta);
1582 if (pyus_in == NULL)
1583 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001584 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001585 if (ratio == NULL)
1586 goto error;
1587 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1588 Py_DECREF(pyus_in);
1589 pyus_in = NULL;
1590 if (temp == NULL)
1591 goto error;
1592 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1593 Py_DECREF(temp);
1594 if (pyus_out == NULL)
1595 goto error;
1596 result = microseconds_to_delta(pyus_out);
1597 Py_DECREF(pyus_out);
1598 error:
1599 Py_XDECREF(pyus_in);
1600 Py_XDECREF(ratio);
1601
1602 return result;
1603}
1604
1605static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001606divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 PyObject *pyus_in;
1609 PyObject *pyus_out;
1610 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 pyus_in = delta_to_microseconds(delta);
1613 if (pyus_in == NULL)
1614 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1617 Py_DECREF(pyus_in);
1618 if (pyus_out == NULL)
1619 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 result = microseconds_to_delta(pyus_out);
1622 Py_DECREF(pyus_out);
1623 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001624}
1625
1626static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001627divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 PyObject *pyus_left;
1630 PyObject *pyus_right;
1631 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 pyus_left = delta_to_microseconds(left);
1634 if (pyus_left == NULL)
1635 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 pyus_right = delta_to_microseconds(right);
1638 if (pyus_right == NULL) {
1639 Py_DECREF(pyus_left);
1640 return NULL;
1641 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1644 Py_DECREF(pyus_left);
1645 Py_DECREF(pyus_right);
1646 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001647}
1648
1649static PyObject *
1650truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 PyObject *pyus_left;
1653 PyObject *pyus_right;
1654 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 pyus_left = delta_to_microseconds(left);
1657 if (pyus_left == NULL)
1658 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 pyus_right = delta_to_microseconds(right);
1661 if (pyus_right == NULL) {
1662 Py_DECREF(pyus_left);
1663 return NULL;
1664 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1667 Py_DECREF(pyus_left);
1668 Py_DECREF(pyus_right);
1669 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001670}
1671
1672static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001673truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1674{
1675 PyObject *result = NULL;
1676 PyObject *pyus_in = NULL, *temp, *pyus_out;
1677 PyObject *ratio = NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001678 _Py_IDENTIFIER(as_integer_ratio);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001679
1680 pyus_in = delta_to_microseconds(delta);
1681 if (pyus_in == NULL)
1682 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001683 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001684 if (ratio == NULL)
1685 goto error;
1686 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1687 Py_DECREF(pyus_in);
1688 pyus_in = NULL;
1689 if (temp == NULL)
1690 goto error;
1691 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1692 Py_DECREF(temp);
1693 if (pyus_out == NULL)
1694 goto error;
1695 result = microseconds_to_delta(pyus_out);
1696 Py_DECREF(pyus_out);
1697 error:
1698 Py_XDECREF(pyus_in);
1699 Py_XDECREF(ratio);
1700
1701 return result;
1702}
1703
1704static PyObject *
1705truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1706{
1707 PyObject *result;
1708 PyObject *pyus_in, *pyus_out;
1709 pyus_in = delta_to_microseconds(delta);
1710 if (pyus_in == NULL)
1711 return NULL;
1712 pyus_out = divide_nearest(pyus_in, i);
1713 Py_DECREF(pyus_in);
1714 if (pyus_out == NULL)
1715 return NULL;
1716 result = microseconds_to_delta(pyus_out);
1717 Py_DECREF(pyus_out);
1718
1719 return result;
1720}
1721
1722static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001723delta_add(PyObject *left, PyObject *right)
1724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001725 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1728 /* delta + delta */
1729 /* The C-level additions can't overflow because of the
1730 * invariant bounds.
1731 */
1732 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1733 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1734 int microseconds = GET_TD_MICROSECONDS(left) +
1735 GET_TD_MICROSECONDS(right);
1736 result = new_delta(days, seconds, microseconds, 1);
1737 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001739 if (result == Py_NotImplemented)
1740 Py_INCREF(result);
1741 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001742}
1743
1744static PyObject *
1745delta_negative(PyDateTime_Delta *self)
1746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 return new_delta(-GET_TD_DAYS(self),
1748 -GET_TD_SECONDS(self),
1749 -GET_TD_MICROSECONDS(self),
1750 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001751}
1752
1753static PyObject *
1754delta_positive(PyDateTime_Delta *self)
1755{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 /* Could optimize this (by returning self) if this isn't a
1757 * subclass -- but who uses unary + ? Approximately nobody.
1758 */
1759 return new_delta(GET_TD_DAYS(self),
1760 GET_TD_SECONDS(self),
1761 GET_TD_MICROSECONDS(self),
1762 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001763}
1764
1765static PyObject *
1766delta_abs(PyDateTime_Delta *self)
1767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 assert(GET_TD_MICROSECONDS(self) >= 0);
1771 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 if (GET_TD_DAYS(self) < 0)
1774 result = delta_negative(self);
1775 else
1776 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001779}
1780
1781static PyObject *
1782delta_subtract(PyObject *left, PyObject *right)
1783{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1787 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001788 /* The C-level additions can't overflow because of the
1789 * invariant bounds.
1790 */
1791 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1792 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1793 int microseconds = GET_TD_MICROSECONDS(left) -
1794 GET_TD_MICROSECONDS(right);
1795 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 if (result == Py_NotImplemented)
1799 Py_INCREF(result);
1800 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001801}
1802
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001803static int
1804delta_cmp(PyObject *self, PyObject *other)
1805{
1806 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1807 if (diff == 0) {
1808 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1809 if (diff == 0)
1810 diff = GET_TD_MICROSECONDS(self) -
1811 GET_TD_MICROSECONDS(other);
1812 }
1813 return diff;
1814}
1815
Tim Peters2a799bf2002-12-16 20:18:38 +00001816static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001817delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001818{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001820 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 return diff_to_bool(diff, op);
1822 }
1823 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001824 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001826}
1827
1828static PyObject *delta_getstate(PyDateTime_Delta *self);
1829
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001830static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001831delta_hash(PyDateTime_Delta *self)
1832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 if (self->hashcode == -1) {
1834 PyObject *temp = delta_getstate(self);
1835 if (temp != NULL) {
1836 self->hashcode = PyObject_Hash(temp);
1837 Py_DECREF(temp);
1838 }
1839 }
1840 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001841}
1842
1843static PyObject *
1844delta_multiply(PyObject *left, PyObject *right)
1845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 if (PyDelta_Check(left)) {
1849 /* delta * ??? */
1850 if (PyLong_Check(right))
1851 result = multiply_int_timedelta(right,
1852 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001853 else if (PyFloat_Check(right))
1854 result = multiply_float_timedelta(right,
1855 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 }
1857 else if (PyLong_Check(left))
1858 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001859 (PyDateTime_Delta *) right);
1860 else if (PyFloat_Check(left))
1861 result = multiply_float_timedelta(left,
1862 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 if (result == Py_NotImplemented)
1865 Py_INCREF(result);
1866 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001867}
1868
1869static PyObject *
1870delta_divide(PyObject *left, PyObject *right)
1871{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 if (PyDelta_Check(left)) {
1875 /* delta * ??? */
1876 if (PyLong_Check(right))
1877 result = divide_timedelta_int(
1878 (PyDateTime_Delta *)left,
1879 right);
1880 else if (PyDelta_Check(right))
1881 result = divide_timedelta_timedelta(
1882 (PyDateTime_Delta *)left,
1883 (PyDateTime_Delta *)right);
1884 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (result == Py_NotImplemented)
1887 Py_INCREF(result);
1888 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001889}
1890
Mark Dickinson7c186e22010-04-20 22:32:49 +00001891static PyObject *
1892delta_truedivide(PyObject *left, PyObject *right)
1893{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 if (PyDelta_Check(left)) {
1897 if (PyDelta_Check(right))
1898 result = truedivide_timedelta_timedelta(
1899 (PyDateTime_Delta *)left,
1900 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001901 else if (PyFloat_Check(right))
1902 result = truedivide_timedelta_float(
1903 (PyDateTime_Delta *)left, right);
1904 else if (PyLong_Check(right))
1905 result = truedivide_timedelta_int(
1906 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 if (result == Py_NotImplemented)
1910 Py_INCREF(result);
1911 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001912}
1913
1914static PyObject *
1915delta_remainder(PyObject *left, PyObject *right)
1916{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 PyObject *pyus_left;
1918 PyObject *pyus_right;
1919 PyObject *pyus_remainder;
1920 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001921
Brian Curtindfc80e32011-08-10 20:28:54 -05001922 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1923 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1926 if (pyus_left == NULL)
1927 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1930 if (pyus_right == NULL) {
1931 Py_DECREF(pyus_left);
1932 return NULL;
1933 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1936 Py_DECREF(pyus_left);
1937 Py_DECREF(pyus_right);
1938 if (pyus_remainder == NULL)
1939 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 remainder = microseconds_to_delta(pyus_remainder);
1942 Py_DECREF(pyus_remainder);
1943 if (remainder == NULL)
1944 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001947}
1948
1949static PyObject *
1950delta_divmod(PyObject *left, PyObject *right)
1951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 PyObject *pyus_left;
1953 PyObject *pyus_right;
1954 PyObject *divmod;
1955 PyObject *delta;
1956 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001957
Brian Curtindfc80e32011-08-10 20:28:54 -05001958 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1959 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1962 if (pyus_left == NULL)
1963 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1966 if (pyus_right == NULL) {
1967 Py_DECREF(pyus_left);
1968 return NULL;
1969 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1972 Py_DECREF(pyus_left);
1973 Py_DECREF(pyus_right);
1974 if (divmod == NULL)
1975 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 assert(PyTuple_Size(divmod) == 2);
1978 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1979 if (delta == NULL) {
1980 Py_DECREF(divmod);
1981 return NULL;
1982 }
1983 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1984 Py_DECREF(delta);
1985 Py_DECREF(divmod);
1986 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001987}
1988
Tim Peters2a799bf2002-12-16 20:18:38 +00001989/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1990 * timedelta constructor. sofar is the # of microseconds accounted for
1991 * so far, and there are factor microseconds per current unit, the number
1992 * of which is given by num. num * factor is added to sofar in a
1993 * numerically careful way, and that's the result. Any fractional
1994 * microseconds left over (this can happen if num is a float type) are
1995 * added into *leftover.
1996 * Note that there are many ways this can give an error (NULL) return.
1997 */
1998static PyObject *
1999accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2000 double *leftover)
2001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 PyObject *prod;
2003 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 if (PyLong_Check(num)) {
2008 prod = PyNumber_Multiply(num, factor);
2009 if (prod == NULL)
2010 return NULL;
2011 sum = PyNumber_Add(sofar, prod);
2012 Py_DECREF(prod);
2013 return sum;
2014 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 if (PyFloat_Check(num)) {
2017 double dnum;
2018 double fracpart;
2019 double intpart;
2020 PyObject *x;
2021 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 /* The Plan: decompose num into an integer part and a
2024 * fractional part, num = intpart + fracpart.
2025 * Then num * factor ==
2026 * intpart * factor + fracpart * factor
2027 * and the LHS can be computed exactly in long arithmetic.
2028 * The RHS is again broken into an int part and frac part.
2029 * and the frac part is added into *leftover.
2030 */
2031 dnum = PyFloat_AsDouble(num);
2032 if (dnum == -1.0 && PyErr_Occurred())
2033 return NULL;
2034 fracpart = modf(dnum, &intpart);
2035 x = PyLong_FromDouble(intpart);
2036 if (x == NULL)
2037 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 prod = PyNumber_Multiply(x, factor);
2040 Py_DECREF(x);
2041 if (prod == NULL)
2042 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002044 sum = PyNumber_Add(sofar, prod);
2045 Py_DECREF(prod);
2046 if (sum == NULL)
2047 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 if (fracpart == 0.0)
2050 return sum;
2051 /* So far we've lost no information. Dealing with the
2052 * fractional part requires float arithmetic, and may
2053 * lose a little info.
2054 */
2055 assert(PyLong_Check(factor));
2056 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 dnum *= fracpart;
2059 fracpart = modf(dnum, &intpart);
2060 x = PyLong_FromDouble(intpart);
2061 if (x == NULL) {
2062 Py_DECREF(sum);
2063 return NULL;
2064 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 y = PyNumber_Add(sum, x);
2067 Py_DECREF(sum);
2068 Py_DECREF(x);
2069 *leftover += fracpart;
2070 return y;
2071 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 PyErr_Format(PyExc_TypeError,
2074 "unsupported type for timedelta %s component: %s",
2075 tag, Py_TYPE(num)->tp_name);
2076 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002077}
2078
2079static PyObject *
2080delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2081{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 /* Argument objects. */
2085 PyObject *day = NULL;
2086 PyObject *second = NULL;
2087 PyObject *us = NULL;
2088 PyObject *ms = NULL;
2089 PyObject *minute = NULL;
2090 PyObject *hour = NULL;
2091 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 PyObject *x = NULL; /* running sum of microseconds */
2094 PyObject *y = NULL; /* temp sum of microseconds */
2095 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 static char *keywords[] = {
2098 "days", "seconds", "microseconds", "milliseconds",
2099 "minutes", "hours", "weeks", NULL
2100 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2103 keywords,
2104 &day, &second, &us,
2105 &ms, &minute, &hour, &week) == 0)
2106 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 x = PyLong_FromLong(0);
2109 if (x == NULL)
2110 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112#define CLEANUP \
2113 Py_DECREF(x); \
2114 x = y; \
2115 if (x == NULL) \
2116 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 if (us) {
2119 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2120 CLEANUP;
2121 }
2122 if (ms) {
2123 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2124 CLEANUP;
2125 }
2126 if (second) {
2127 y = accum("seconds", x, second, us_per_second, &leftover_us);
2128 CLEANUP;
2129 }
2130 if (minute) {
2131 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2132 CLEANUP;
2133 }
2134 if (hour) {
2135 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2136 CLEANUP;
2137 }
2138 if (day) {
2139 y = accum("days", x, day, us_per_day, &leftover_us);
2140 CLEANUP;
2141 }
2142 if (week) {
2143 y = accum("weeks", x, week, us_per_week, &leftover_us);
2144 CLEANUP;
2145 }
2146 if (leftover_us) {
2147 /* Round to nearest whole # of us, and add into x. */
2148 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2149 if (temp == NULL) {
2150 Py_DECREF(x);
2151 goto Done;
2152 }
2153 y = PyNumber_Add(x, temp);
2154 Py_DECREF(temp);
2155 CLEANUP;
2156 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 self = microseconds_to_delta_ex(x, type);
2159 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002160Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002162
2163#undef CLEANUP
2164}
2165
2166static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002167delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 return (GET_TD_DAYS(self) != 0
2170 || GET_TD_SECONDS(self) != 0
2171 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002172}
2173
2174static PyObject *
2175delta_repr(PyDateTime_Delta *self)
2176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 if (GET_TD_MICROSECONDS(self) != 0)
2178 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2179 Py_TYPE(self)->tp_name,
2180 GET_TD_DAYS(self),
2181 GET_TD_SECONDS(self),
2182 GET_TD_MICROSECONDS(self));
2183 if (GET_TD_SECONDS(self) != 0)
2184 return PyUnicode_FromFormat("%s(%d, %d)",
2185 Py_TYPE(self)->tp_name,
2186 GET_TD_DAYS(self),
2187 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 return PyUnicode_FromFormat("%s(%d)",
2190 Py_TYPE(self)->tp_name,
2191 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002192}
2193
2194static PyObject *
2195delta_str(PyDateTime_Delta *self)
2196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 int us = GET_TD_MICROSECONDS(self);
2198 int seconds = GET_TD_SECONDS(self);
2199 int minutes = divmod(seconds, 60, &seconds);
2200 int hours = divmod(minutes, 60, &minutes);
2201 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002203 if (days) {
2204 if (us)
2205 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2206 days, (days == 1 || days == -1) ? "" : "s",
2207 hours, minutes, seconds, us);
2208 else
2209 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2210 days, (days == 1 || days == -1) ? "" : "s",
2211 hours, minutes, seconds);
2212 } else {
2213 if (us)
2214 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2215 hours, minutes, seconds, us);
2216 else
2217 return PyUnicode_FromFormat("%d:%02d:%02d",
2218 hours, minutes, seconds);
2219 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002220
Tim Peters2a799bf2002-12-16 20:18:38 +00002221}
2222
Tim Peters371935f2003-02-01 01:52:50 +00002223/* Pickle support, a simple use of __reduce__. */
2224
Tim Petersb57f8f02003-02-01 02:54:15 +00002225/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002226static PyObject *
2227delta_getstate(PyDateTime_Delta *self)
2228{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 return Py_BuildValue("iii", GET_TD_DAYS(self),
2230 GET_TD_SECONDS(self),
2231 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002232}
2233
Tim Peters2a799bf2002-12-16 20:18:38 +00002234static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002235delta_total_seconds(PyObject *self)
2236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 PyObject *total_seconds;
2238 PyObject *total_microseconds;
2239 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2242 if (total_microseconds == NULL)
2243 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245 one_million = PyLong_FromLong(1000000L);
2246 if (one_million == NULL) {
2247 Py_DECREF(total_microseconds);
2248 return NULL;
2249 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 Py_DECREF(total_microseconds);
2254 Py_DECREF(one_million);
2255 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002256}
2257
2258static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002259delta_reduce(PyDateTime_Delta* self)
2260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002261 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002262}
2263
2264#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2265
2266static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 {"days", T_INT, OFFSET(days), READONLY,
2269 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 {"seconds", T_INT, OFFSET(seconds), READONLY,
2272 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2275 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2276 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002277};
2278
2279static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2281 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2284 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002287};
2288
2289static char delta_doc[] =
2290PyDoc_STR("Difference between two datetime values.");
2291
2292static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 delta_add, /* nb_add */
2294 delta_subtract, /* nb_subtract */
2295 delta_multiply, /* nb_multiply */
2296 delta_remainder, /* nb_remainder */
2297 delta_divmod, /* nb_divmod */
2298 0, /* nb_power */
2299 (unaryfunc)delta_negative, /* nb_negative */
2300 (unaryfunc)delta_positive, /* nb_positive */
2301 (unaryfunc)delta_abs, /* nb_absolute */
2302 (inquiry)delta_bool, /* nb_bool */
2303 0, /*nb_invert*/
2304 0, /*nb_lshift*/
2305 0, /*nb_rshift*/
2306 0, /*nb_and*/
2307 0, /*nb_xor*/
2308 0, /*nb_or*/
2309 0, /*nb_int*/
2310 0, /*nb_reserved*/
2311 0, /*nb_float*/
2312 0, /*nb_inplace_add*/
2313 0, /*nb_inplace_subtract*/
2314 0, /*nb_inplace_multiply*/
2315 0, /*nb_inplace_remainder*/
2316 0, /*nb_inplace_power*/
2317 0, /*nb_inplace_lshift*/
2318 0, /*nb_inplace_rshift*/
2319 0, /*nb_inplace_and*/
2320 0, /*nb_inplace_xor*/
2321 0, /*nb_inplace_or*/
2322 delta_divide, /* nb_floor_divide */
2323 delta_truedivide, /* nb_true_divide */
2324 0, /* nb_inplace_floor_divide */
2325 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002326};
2327
2328static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002329 PyVarObject_HEAD_INIT(NULL, 0)
2330 "datetime.timedelta", /* tp_name */
2331 sizeof(PyDateTime_Delta), /* tp_basicsize */
2332 0, /* tp_itemsize */
2333 0, /* tp_dealloc */
2334 0, /* tp_print */
2335 0, /* tp_getattr */
2336 0, /* tp_setattr */
2337 0, /* tp_reserved */
2338 (reprfunc)delta_repr, /* tp_repr */
2339 &delta_as_number, /* tp_as_number */
2340 0, /* tp_as_sequence */
2341 0, /* tp_as_mapping */
2342 (hashfunc)delta_hash, /* tp_hash */
2343 0, /* tp_call */
2344 (reprfunc)delta_str, /* tp_str */
2345 PyObject_GenericGetAttr, /* tp_getattro */
2346 0, /* tp_setattro */
2347 0, /* tp_as_buffer */
2348 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2349 delta_doc, /* tp_doc */
2350 0, /* tp_traverse */
2351 0, /* tp_clear */
2352 delta_richcompare, /* tp_richcompare */
2353 0, /* tp_weaklistoffset */
2354 0, /* tp_iter */
2355 0, /* tp_iternext */
2356 delta_methods, /* tp_methods */
2357 delta_members, /* tp_members */
2358 0, /* tp_getset */
2359 0, /* tp_base */
2360 0, /* tp_dict */
2361 0, /* tp_descr_get */
2362 0, /* tp_descr_set */
2363 0, /* tp_dictoffset */
2364 0, /* tp_init */
2365 0, /* tp_alloc */
2366 delta_new, /* tp_new */
2367 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002368};
2369
2370/*
2371 * PyDateTime_Date implementation.
2372 */
2373
2374/* Accessor properties. */
2375
2376static PyObject *
2377date_year(PyDateTime_Date *self, void *unused)
2378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002380}
2381
2382static PyObject *
2383date_month(PyDateTime_Date *self, void *unused)
2384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002386}
2387
2388static PyObject *
2389date_day(PyDateTime_Date *self, void *unused)
2390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002392}
2393
2394static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 {"year", (getter)date_year},
2396 {"month", (getter)date_month},
2397 {"day", (getter)date_day},
2398 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002399};
2400
2401/* Constructors. */
2402
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002403static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002404
Tim Peters2a799bf2002-12-16 20:18:38 +00002405static PyObject *
2406date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 PyObject *self = NULL;
2409 PyObject *state;
2410 int year;
2411 int month;
2412 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 /* Check for invocation from pickle with __getstate__ state */
2415 if (PyTuple_GET_SIZE(args) == 1 &&
2416 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2417 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2418 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2419 {
2420 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002422 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2423 if (me != NULL) {
2424 char *pdata = PyBytes_AS_STRING(state);
2425 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2426 me->hashcode = -1;
2427 }
2428 return (PyObject *)me;
2429 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2432 &year, &month, &day)) {
2433 if (check_date_args(year, month, day) < 0)
2434 return NULL;
2435 self = new_date_ex(year, month, day, type);
2436 }
2437 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002438}
2439
2440/* Return new date from localtime(t). */
2441static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002442date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002443{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 struct tm *tm;
2445 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002446
Victor Stinner5d272cc2012-03-13 13:35:55 +01002447 if (_PyTime_ObjectToTime_t(obj, &t) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002448 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 tm = localtime(&t);
Victor Stinner21f58932012-03-14 00:15:40 +01002451 if (tm == NULL) {
2452 /* unconvertible time */
2453#ifdef EINVAL
2454 if (errno == 0)
2455 errno = EINVAL;
2456#endif
2457 PyErr_SetFromErrno(PyExc_OSError);
2458 return NULL;
2459 }
2460
2461 return PyObject_CallFunction(cls, "iii",
2462 tm->tm_year + 1900,
2463 tm->tm_mon + 1,
2464 tm->tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002465}
2466
2467/* Return new date from current time.
2468 * We say this is equivalent to fromtimestamp(time.time()), and the
2469 * only way to be sure of that is to *call* time.time(). That's not
2470 * generally the same as calling C's time.
2471 */
2472static PyObject *
2473date_today(PyObject *cls, PyObject *dummy)
2474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 PyObject *time;
2476 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002477 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002479 time = time_time();
2480 if (time == NULL)
2481 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 /* Note well: today() is a class method, so this may not call
2484 * date.fromtimestamp. For example, it may call
2485 * datetime.fromtimestamp. That's why we need all the accuracy
2486 * time.time() delivers; if someone were gonzo about optimization,
2487 * date.today() could get away with plain C time().
2488 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002489 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 Py_DECREF(time);
2491 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002492}
2493
2494/* Return new date from given timestamp (Python timestamp -- a double). */
2495static PyObject *
2496date_fromtimestamp(PyObject *cls, PyObject *args)
2497{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002498 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002500
Victor Stinner5d272cc2012-03-13 13:35:55 +01002501 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2502 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002503 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002504}
2505
2506/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2507 * the ordinal is out of range.
2508 */
2509static PyObject *
2510date_fromordinal(PyObject *cls, PyObject *args)
2511{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 PyObject *result = NULL;
2513 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002515 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2516 int year;
2517 int month;
2518 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 if (ordinal < 1)
2521 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2522 ">= 1");
2523 else {
2524 ord_to_ymd(ordinal, &year, &month, &day);
2525 result = PyObject_CallFunction(cls, "iii",
2526 year, month, day);
2527 }
2528 }
2529 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002530}
2531
2532/*
2533 * Date arithmetic.
2534 */
2535
2536/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2537 * instead.
2538 */
2539static PyObject *
2540add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2541{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002542 PyObject *result = NULL;
2543 int year = GET_YEAR(date);
2544 int month = GET_MONTH(date);
2545 int deltadays = GET_TD_DAYS(delta);
2546 /* C-level overflow is impossible because |deltadays| < 1e9. */
2547 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002549 if (normalize_date(&year, &month, &day) >= 0)
2550 result = new_date(year, month, day);
2551 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002552}
2553
2554static PyObject *
2555date_add(PyObject *left, PyObject *right)
2556{
Brian Curtindfc80e32011-08-10 20:28:54 -05002557 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2558 Py_RETURN_NOTIMPLEMENTED;
2559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 if (PyDate_Check(left)) {
2561 /* date + ??? */
2562 if (PyDelta_Check(right))
2563 /* date + delta */
2564 return add_date_timedelta((PyDateTime_Date *) left,
2565 (PyDateTime_Delta *) right,
2566 0);
2567 }
2568 else {
2569 /* ??? + date
2570 * 'right' must be one of us, or we wouldn't have been called
2571 */
2572 if (PyDelta_Check(left))
2573 /* delta + date */
2574 return add_date_timedelta((PyDateTime_Date *) right,
2575 (PyDateTime_Delta *) left,
2576 0);
2577 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002578 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002579}
2580
2581static PyObject *
2582date_subtract(PyObject *left, PyObject *right)
2583{
Brian Curtindfc80e32011-08-10 20:28:54 -05002584 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2585 Py_RETURN_NOTIMPLEMENTED;
2586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 if (PyDate_Check(left)) {
2588 if (PyDate_Check(right)) {
2589 /* date - date */
2590 int left_ord = ymd_to_ord(GET_YEAR(left),
2591 GET_MONTH(left),
2592 GET_DAY(left));
2593 int right_ord = ymd_to_ord(GET_YEAR(right),
2594 GET_MONTH(right),
2595 GET_DAY(right));
2596 return new_delta(left_ord - right_ord, 0, 0, 0);
2597 }
2598 if (PyDelta_Check(right)) {
2599 /* date - delta */
2600 return add_date_timedelta((PyDateTime_Date *) left,
2601 (PyDateTime_Delta *) right,
2602 1);
2603 }
2604 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002605 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002606}
2607
2608
2609/* Various ways to turn a date into a string. */
2610
2611static PyObject *
2612date_repr(PyDateTime_Date *self)
2613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002614 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2615 Py_TYPE(self)->tp_name,
2616 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002617}
2618
2619static PyObject *
2620date_isoformat(PyDateTime_Date *self)
2621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 return PyUnicode_FromFormat("%04d-%02d-%02d",
2623 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002624}
2625
Tim Peterse2df5ff2003-05-02 18:39:55 +00002626/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002627static PyObject *
2628date_str(PyDateTime_Date *self)
2629{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002630 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002631
2632 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002633}
2634
2635
2636static PyObject *
2637date_ctime(PyDateTime_Date *self)
2638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002639 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002640}
2641
2642static PyObject *
2643date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002645 /* This method can be inherited, and needs to call the
2646 * timetuple() method appropriate to self's class.
2647 */
2648 PyObject *result;
2649 PyObject *tuple;
2650 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002651 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002652 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2655 &format))
2656 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002657
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002658 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 if (tuple == NULL)
2660 return NULL;
2661 result = wrap_strftime((PyObject *)self, format, tuple,
2662 (PyObject *)self);
2663 Py_DECREF(tuple);
2664 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002665}
2666
Eric Smith1ba31142007-09-11 18:06:02 +00002667static PyObject *
2668date_format(PyDateTime_Date *self, PyObject *args)
2669{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002671 _Py_IDENTIFIER(strftime);
Eric Smith1ba31142007-09-11 18:06:02 +00002672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002673 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2674 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002676 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002677 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002678 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002679
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002680 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002681}
2682
Tim Peters2a799bf2002-12-16 20:18:38 +00002683/* ISO methods. */
2684
2685static PyObject *
2686date_isoweekday(PyDateTime_Date *self)
2687{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002688 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002690 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002691}
2692
2693static PyObject *
2694date_isocalendar(PyDateTime_Date *self)
2695{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002696 int year = GET_YEAR(self);
2697 int week1_monday = iso_week1_monday(year);
2698 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2699 int week;
2700 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002702 week = divmod(today - week1_monday, 7, &day);
2703 if (week < 0) {
2704 --year;
2705 week1_monday = iso_week1_monday(year);
2706 week = divmod(today - week1_monday, 7, &day);
2707 }
2708 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2709 ++year;
2710 week = 0;
2711 }
2712 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002713}
2714
2715/* Miscellaneous methods. */
2716
Tim Peters2a799bf2002-12-16 20:18:38 +00002717static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002718date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 if (PyDate_Check(other)) {
2721 int diff = memcmp(((PyDateTime_Date *)self)->data,
2722 ((PyDateTime_Date *)other)->data,
2723 _PyDateTime_DATE_DATASIZE);
2724 return diff_to_bool(diff, op);
2725 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002726 else
2727 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002728}
2729
2730static PyObject *
2731date_timetuple(PyDateTime_Date *self)
2732{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002733 return build_struct_time(GET_YEAR(self),
2734 GET_MONTH(self),
2735 GET_DAY(self),
2736 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002737}
2738
Tim Peters12bf3392002-12-24 05:41:27 +00002739static PyObject *
2740date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2741{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002742 PyObject *clone;
2743 PyObject *tuple;
2744 int year = GET_YEAR(self);
2745 int month = GET_MONTH(self);
2746 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002748 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2749 &year, &month, &day))
2750 return NULL;
2751 tuple = Py_BuildValue("iii", year, month, day);
2752 if (tuple == NULL)
2753 return NULL;
2754 clone = date_new(Py_TYPE(self), tuple, NULL);
2755 Py_DECREF(tuple);
2756 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002757}
2758
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002759static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002760generic_hash(unsigned char *data, int len)
2761{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002762 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002763}
2764
2765
2766static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002767
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002768static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002769date_hash(PyDateTime_Date *self)
2770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002771 if (self->hashcode == -1)
2772 self->hashcode = generic_hash(
2773 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002775 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002776}
2777
2778static PyObject *
2779date_toordinal(PyDateTime_Date *self)
2780{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002781 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2782 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002783}
2784
2785static PyObject *
2786date_weekday(PyDateTime_Date *self)
2787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002788 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002790 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002791}
2792
Tim Peters371935f2003-02-01 01:52:50 +00002793/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002794
Tim Petersb57f8f02003-02-01 02:54:15 +00002795/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002796static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002797date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002799 PyObject* field;
2800 field = PyBytes_FromStringAndSize((char*)self->data,
2801 _PyDateTime_DATE_DATASIZE);
2802 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002803}
2804
2805static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002806date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002807{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002808 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002809}
2810
2811static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002813 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2816 METH_CLASS,
2817 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2818 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002820 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2821 METH_CLASS,
2822 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2823 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002824
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002825 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2826 PyDoc_STR("Current date or datetime: same as "
2827 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002829 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2832 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002834 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2835 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2838 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002840 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2841 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002843 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2844 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2845 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2848 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2851 PyDoc_STR("Return the day of the week represented by the date.\n"
2852 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2855 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2856 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002858 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2859 PyDoc_STR("Return the day of the week represented by the date.\n"
2860 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2863 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002865 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2866 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002869};
2870
2871static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002872PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002873
2874static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 date_add, /* nb_add */
2876 date_subtract, /* nb_subtract */
2877 0, /* nb_multiply */
2878 0, /* nb_remainder */
2879 0, /* nb_divmod */
2880 0, /* nb_power */
2881 0, /* nb_negative */
2882 0, /* nb_positive */
2883 0, /* nb_absolute */
2884 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002885};
2886
2887static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002888 PyVarObject_HEAD_INIT(NULL, 0)
2889 "datetime.date", /* tp_name */
2890 sizeof(PyDateTime_Date), /* tp_basicsize */
2891 0, /* tp_itemsize */
2892 0, /* tp_dealloc */
2893 0, /* tp_print */
2894 0, /* tp_getattr */
2895 0, /* tp_setattr */
2896 0, /* tp_reserved */
2897 (reprfunc)date_repr, /* tp_repr */
2898 &date_as_number, /* tp_as_number */
2899 0, /* tp_as_sequence */
2900 0, /* tp_as_mapping */
2901 (hashfunc)date_hash, /* tp_hash */
2902 0, /* tp_call */
2903 (reprfunc)date_str, /* tp_str */
2904 PyObject_GenericGetAttr, /* tp_getattro */
2905 0, /* tp_setattro */
2906 0, /* tp_as_buffer */
2907 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2908 date_doc, /* tp_doc */
2909 0, /* tp_traverse */
2910 0, /* tp_clear */
2911 date_richcompare, /* tp_richcompare */
2912 0, /* tp_weaklistoffset */
2913 0, /* tp_iter */
2914 0, /* tp_iternext */
2915 date_methods, /* tp_methods */
2916 0, /* tp_members */
2917 date_getset, /* tp_getset */
2918 0, /* tp_base */
2919 0, /* tp_dict */
2920 0, /* tp_descr_get */
2921 0, /* tp_descr_set */
2922 0, /* tp_dictoffset */
2923 0, /* tp_init */
2924 0, /* tp_alloc */
2925 date_new, /* tp_new */
2926 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002927};
2928
2929/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002930 * PyDateTime_TZInfo implementation.
2931 */
2932
2933/* This is a pure abstract base class, so doesn't do anything beyond
2934 * raising NotImplemented exceptions. Real tzinfo classes need
2935 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002936 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002937 * be subclasses of this tzinfo class, which is easy and quick to check).
2938 *
2939 * Note: For reasons having to do with pickling of subclasses, we have
2940 * to allow tzinfo objects to be instantiated. This wasn't an issue
2941 * in the Python implementation (__init__() could raise NotImplementedError
2942 * there without ill effect), but doing so in the C implementation hit a
2943 * brick wall.
2944 */
2945
2946static PyObject *
2947tzinfo_nogo(const char* methodname)
2948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002949 PyErr_Format(PyExc_NotImplementedError,
2950 "a tzinfo subclass must implement %s()",
2951 methodname);
2952 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002953}
2954
2955/* Methods. A subclass must implement these. */
2956
Tim Peters52dcce22003-01-23 16:36:11 +00002957static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002958tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2959{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002960 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002961}
2962
Tim Peters52dcce22003-01-23 16:36:11 +00002963static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002964tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2965{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002966 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002967}
2968
Tim Peters52dcce22003-01-23 16:36:11 +00002969static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002970tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002972 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002973}
2974
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002975
2976static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2977 PyDateTime_Delta *delta,
2978 int factor);
2979static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2980static PyObject *datetime_dst(PyObject *self, PyObject *);
2981
Tim Peters52dcce22003-01-23 16:36:11 +00002982static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002983tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002984{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002985 PyObject *result = NULL;
2986 PyObject *off = NULL, *dst = NULL;
2987 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002988
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002989 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002990 PyErr_SetString(PyExc_TypeError,
2991 "fromutc: argument must be a datetime");
2992 return NULL;
2993 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002994 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002995 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2996 "is not self");
2997 return NULL;
2998 }
Tim Peters52dcce22003-01-23 16:36:11 +00002999
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003000 off = datetime_utcoffset(dt, NULL);
3001 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003002 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003003 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003004 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3005 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003006 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003007 }
Tim Peters52dcce22003-01-23 16:36:11 +00003008
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003009 dst = datetime_dst(dt, NULL);
3010 if (dst == NULL)
3011 goto Fail;
3012 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003013 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3014 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003015 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003016 }
Tim Peters52dcce22003-01-23 16:36:11 +00003017
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003018 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3019 if (delta == NULL)
3020 goto Fail;
3021 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003022 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003023 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003024
3025 Py_DECREF(dst);
3026 dst = call_dst(GET_DT_TZINFO(dt), result);
3027 if (dst == NULL)
3028 goto Fail;
3029 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003030 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003031 if (delta_bool(delta) != 0) {
3032 PyObject *temp = result;
3033 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3034 (PyDateTime_Delta *)dst, 1);
3035 Py_DECREF(temp);
3036 if (result == NULL)
3037 goto Fail;
3038 }
3039 Py_DECREF(delta);
3040 Py_DECREF(dst);
3041 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003042 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003043
3044Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003045 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3046 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003048 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003049Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003050 Py_XDECREF(off);
3051 Py_XDECREF(dst);
3052 Py_XDECREF(delta);
3053 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003054 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003055}
3056
Tim Peters2a799bf2002-12-16 20:18:38 +00003057/*
3058 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003059 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003060 */
3061
Guido van Rossum177e41a2003-01-30 22:06:23 +00003062static PyObject *
3063tzinfo_reduce(PyObject *self)
3064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003065 PyObject *args, *state, *tmp;
3066 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003067 _Py_IDENTIFIER(__getinitargs__);
3068 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003070 tmp = PyTuple_New(0);
3071 if (tmp == NULL)
3072 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003073
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003074 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003075 if (getinitargs != NULL) {
3076 args = PyObject_CallObject(getinitargs, tmp);
3077 Py_DECREF(getinitargs);
3078 if (args == NULL) {
3079 Py_DECREF(tmp);
3080 return NULL;
3081 }
3082 }
3083 else {
3084 PyErr_Clear();
3085 args = tmp;
3086 Py_INCREF(args);
3087 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003088
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003089 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003090 if (getstate != NULL) {
3091 state = PyObject_CallObject(getstate, tmp);
3092 Py_DECREF(getstate);
3093 if (state == NULL) {
3094 Py_DECREF(args);
3095 Py_DECREF(tmp);
3096 return NULL;
3097 }
3098 }
3099 else {
3100 PyObject **dictptr;
3101 PyErr_Clear();
3102 state = Py_None;
3103 dictptr = _PyObject_GetDictPtr(self);
3104 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3105 state = *dictptr;
3106 Py_INCREF(state);
3107 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003109 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003111 if (state == Py_None) {
3112 Py_DECREF(state);
3113 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3114 }
3115 else
3116 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003117}
Tim Peters2a799bf2002-12-16 20:18:38 +00003118
3119static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003121 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3122 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003124 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003125 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3126 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3129 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003131 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003132 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003134 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3135 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003137 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003138};
3139
3140static char tzinfo_doc[] =
3141PyDoc_STR("Abstract base class for time zone info objects.");
3142
Neal Norwitz227b5332006-03-22 09:28:35 +00003143static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003144 PyVarObject_HEAD_INIT(NULL, 0)
3145 "datetime.tzinfo", /* tp_name */
3146 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3147 0, /* tp_itemsize */
3148 0, /* tp_dealloc */
3149 0, /* tp_print */
3150 0, /* tp_getattr */
3151 0, /* tp_setattr */
3152 0, /* tp_reserved */
3153 0, /* tp_repr */
3154 0, /* tp_as_number */
3155 0, /* tp_as_sequence */
3156 0, /* tp_as_mapping */
3157 0, /* tp_hash */
3158 0, /* tp_call */
3159 0, /* tp_str */
3160 PyObject_GenericGetAttr, /* tp_getattro */
3161 0, /* tp_setattro */
3162 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003163 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003164 tzinfo_doc, /* tp_doc */
3165 0, /* tp_traverse */
3166 0, /* tp_clear */
3167 0, /* tp_richcompare */
3168 0, /* tp_weaklistoffset */
3169 0, /* tp_iter */
3170 0, /* tp_iternext */
3171 tzinfo_methods, /* tp_methods */
3172 0, /* tp_members */
3173 0, /* tp_getset */
3174 0, /* tp_base */
3175 0, /* tp_dict */
3176 0, /* tp_descr_get */
3177 0, /* tp_descr_set */
3178 0, /* tp_dictoffset */
3179 0, /* tp_init */
3180 0, /* tp_alloc */
3181 PyType_GenericNew, /* tp_new */
3182 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003183};
3184
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003185static char *timezone_kws[] = {"offset", "name", NULL};
3186
3187static PyObject *
3188timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3189{
3190 PyObject *offset;
3191 PyObject *name = NULL;
3192 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3193 &PyDateTime_DeltaType, &offset,
3194 &PyUnicode_Type, &name))
3195 return new_timezone(offset, name);
3196
3197 return NULL;
3198}
3199
3200static void
3201timezone_dealloc(PyDateTime_TimeZone *self)
3202{
3203 Py_CLEAR(self->offset);
3204 Py_CLEAR(self->name);
3205 Py_TYPE(self)->tp_free((PyObject *)self);
3206}
3207
3208static PyObject *
3209timezone_richcompare(PyDateTime_TimeZone *self,
3210 PyDateTime_TimeZone *other, int op)
3211{
Brian Curtindfc80e32011-08-10 20:28:54 -05003212 if (op != Py_EQ && op != Py_NE)
3213 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003214 return delta_richcompare(self->offset, other->offset, op);
3215}
3216
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003217static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003218timezone_hash(PyDateTime_TimeZone *self)
3219{
3220 return delta_hash((PyDateTime_Delta *)self->offset);
3221}
3222
3223/* Check argument type passed to tzname, utcoffset, or dst methods.
3224 Returns 0 for good argument. Returns -1 and sets exception info
3225 otherwise.
3226 */
3227static int
3228_timezone_check_argument(PyObject *dt, const char *meth)
3229{
3230 if (dt == Py_None || PyDateTime_Check(dt))
3231 return 0;
3232 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3233 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3234 return -1;
3235}
3236
3237static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003238timezone_repr(PyDateTime_TimeZone *self)
3239{
3240 /* Note that although timezone is not subclassable, it is convenient
3241 to use Py_TYPE(self)->tp_name here. */
3242 const char *type_name = Py_TYPE(self)->tp_name;
3243
3244 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3245 return PyUnicode_FromFormat("%s.utc", type_name);
3246
3247 if (self->name == NULL)
3248 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3249
3250 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3251 self->name);
3252}
3253
3254
3255static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003256timezone_str(PyDateTime_TimeZone *self)
3257{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003258 int hours, minutes, seconds;
3259 PyObject *offset;
3260 char sign;
3261
3262 if (self->name != NULL) {
3263 Py_INCREF(self->name);
3264 return self->name;
3265 }
3266 /* Offset is normalized, so it is negative if days < 0 */
3267 if (GET_TD_DAYS(self->offset) < 0) {
3268 sign = '-';
3269 offset = delta_negative((PyDateTime_Delta *)self->offset);
3270 if (offset == NULL)
3271 return NULL;
3272 }
3273 else {
3274 sign = '+';
3275 offset = self->offset;
3276 Py_INCREF(offset);
3277 }
3278 /* Offset is not negative here. */
3279 seconds = GET_TD_SECONDS(offset);
3280 Py_DECREF(offset);
3281 minutes = divmod(seconds, 60, &seconds);
3282 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003283 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003284 assert(seconds == 0);
3285 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003286}
3287
3288static PyObject *
3289timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3290{
3291 if (_timezone_check_argument(dt, "tzname") == -1)
3292 return NULL;
3293
3294 return timezone_str(self);
3295}
3296
3297static PyObject *
3298timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3299{
3300 if (_timezone_check_argument(dt, "utcoffset") == -1)
3301 return NULL;
3302
3303 Py_INCREF(self->offset);
3304 return self->offset;
3305}
3306
3307static PyObject *
3308timezone_dst(PyObject *self, PyObject *dt)
3309{
3310 if (_timezone_check_argument(dt, "dst") == -1)
3311 return NULL;
3312
3313 Py_RETURN_NONE;
3314}
3315
3316static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003317timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3318{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003319 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003320 PyErr_SetString(PyExc_TypeError,
3321 "fromutc: argument must be a datetime");
3322 return NULL;
3323 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003324 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003325 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3326 "is not self");
3327 return NULL;
3328 }
3329
3330 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3331}
3332
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003333static PyObject *
3334timezone_getinitargs(PyDateTime_TimeZone *self)
3335{
3336 if (self->name == NULL)
3337 return Py_BuildValue("(O)", self->offset);
3338 return Py_BuildValue("(OO)", self->offset, self->name);
3339}
3340
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003341static PyMethodDef timezone_methods[] = {
3342 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3343 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003344 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003345
3346 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003347 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003348
3349 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003350 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003351
3352 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3353 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3354
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003355 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3356 PyDoc_STR("pickle support")},
3357
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003358 {NULL, NULL}
3359};
3360
3361static char timezone_doc[] =
3362PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3363
3364static PyTypeObject PyDateTime_TimeZoneType = {
3365 PyVarObject_HEAD_INIT(NULL, 0)
3366 "datetime.timezone", /* tp_name */
3367 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3368 0, /* tp_itemsize */
3369 (destructor)timezone_dealloc, /* tp_dealloc */
3370 0, /* tp_print */
3371 0, /* tp_getattr */
3372 0, /* tp_setattr */
3373 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003374 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003375 0, /* tp_as_number */
3376 0, /* tp_as_sequence */
3377 0, /* tp_as_mapping */
3378 (hashfunc)timezone_hash, /* tp_hash */
3379 0, /* tp_call */
3380 (reprfunc)timezone_str, /* tp_str */
3381 0, /* tp_getattro */
3382 0, /* tp_setattro */
3383 0, /* tp_as_buffer */
3384 Py_TPFLAGS_DEFAULT, /* tp_flags */
3385 timezone_doc, /* tp_doc */
3386 0, /* tp_traverse */
3387 0, /* tp_clear */
3388 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3389 0, /* tp_weaklistoffset */
3390 0, /* tp_iter */
3391 0, /* tp_iternext */
3392 timezone_methods, /* tp_methods */
3393 0, /* tp_members */
3394 0, /* tp_getset */
3395 &PyDateTime_TZInfoType, /* tp_base */
3396 0, /* tp_dict */
3397 0, /* tp_descr_get */
3398 0, /* tp_descr_set */
3399 0, /* tp_dictoffset */
3400 0, /* tp_init */
3401 0, /* tp_alloc */
3402 timezone_new, /* tp_new */
3403};
3404
Tim Peters2a799bf2002-12-16 20:18:38 +00003405/*
Tim Peters37f39822003-01-10 03:49:02 +00003406 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003407 */
3408
Tim Peters37f39822003-01-10 03:49:02 +00003409/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003410 */
3411
3412static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003413time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003415 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003416}
3417
Tim Peters37f39822003-01-10 03:49:02 +00003418static PyObject *
3419time_minute(PyDateTime_Time *self, void *unused)
3420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003421 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003422}
3423
3424/* The name time_second conflicted with some platform header file. */
3425static PyObject *
3426py_time_second(PyDateTime_Time *self, void *unused)
3427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003428 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003429}
3430
3431static PyObject *
3432time_microsecond(PyDateTime_Time *self, void *unused)
3433{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003434 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003435}
3436
3437static PyObject *
3438time_tzinfo(PyDateTime_Time *self, void *unused)
3439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003440 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3441 Py_INCREF(result);
3442 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003443}
3444
3445static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003446 {"hour", (getter)time_hour},
3447 {"minute", (getter)time_minute},
3448 {"second", (getter)py_time_second},
3449 {"microsecond", (getter)time_microsecond},
3450 {"tzinfo", (getter)time_tzinfo},
3451 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003452};
3453
3454/*
3455 * Constructors.
3456 */
3457
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003458static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003459 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003460
Tim Peters2a799bf2002-12-16 20:18:38 +00003461static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003462time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003463{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003464 PyObject *self = NULL;
3465 PyObject *state;
3466 int hour = 0;
3467 int minute = 0;
3468 int second = 0;
3469 int usecond = 0;
3470 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003472 /* Check for invocation from pickle with __getstate__ state */
3473 if (PyTuple_GET_SIZE(args) >= 1 &&
3474 PyTuple_GET_SIZE(args) <= 2 &&
3475 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3476 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3477 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3478 {
3479 PyDateTime_Time *me;
3480 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003482 if (PyTuple_GET_SIZE(args) == 2) {
3483 tzinfo = PyTuple_GET_ITEM(args, 1);
3484 if (check_tzinfo_subclass(tzinfo) < 0) {
3485 PyErr_SetString(PyExc_TypeError, "bad "
3486 "tzinfo state arg");
3487 return NULL;
3488 }
3489 }
3490 aware = (char)(tzinfo != Py_None);
3491 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3492 if (me != NULL) {
3493 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003495 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3496 me->hashcode = -1;
3497 me->hastzinfo = aware;
3498 if (aware) {
3499 Py_INCREF(tzinfo);
3500 me->tzinfo = tzinfo;
3501 }
3502 }
3503 return (PyObject *)me;
3504 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003506 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3507 &hour, &minute, &second, &usecond,
3508 &tzinfo)) {
3509 if (check_time_args(hour, minute, second, usecond) < 0)
3510 return NULL;
3511 if (check_tzinfo_subclass(tzinfo) < 0)
3512 return NULL;
3513 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3514 type);
3515 }
3516 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003517}
3518
3519/*
3520 * Destructor.
3521 */
3522
3523static void
Tim Peters37f39822003-01-10 03:49:02 +00003524time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003525{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003526 if (HASTZINFO(self)) {
3527 Py_XDECREF(self->tzinfo);
3528 }
3529 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003530}
3531
3532/*
Tim Peters855fe882002-12-22 03:43:39 +00003533 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003534 */
3535
Tim Peters2a799bf2002-12-16 20:18:38 +00003536/* These are all METH_NOARGS, so don't need to check the arglist. */
3537static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003538time_utcoffset(PyObject *self, PyObject *unused) {
3539 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003540}
3541
3542static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003543time_dst(PyObject *self, PyObject *unused) {
3544 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003545}
3546
3547static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003548time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003549 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003550}
3551
3552/*
Tim Peters37f39822003-01-10 03:49:02 +00003553 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003554 */
3555
3556static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003557time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003558{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003559 const char *type_name = Py_TYPE(self)->tp_name;
3560 int h = TIME_GET_HOUR(self);
3561 int m = TIME_GET_MINUTE(self);
3562 int s = TIME_GET_SECOND(self);
3563 int us = TIME_GET_MICROSECOND(self);
3564 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003566 if (us)
3567 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3568 type_name, h, m, s, us);
3569 else if (s)
3570 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3571 type_name, h, m, s);
3572 else
3573 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3574 if (result != NULL && HASTZINFO(self))
3575 result = append_keyword_tzinfo(result, self->tzinfo);
3576 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003577}
3578
Tim Peters37f39822003-01-10 03:49:02 +00003579static PyObject *
3580time_str(PyDateTime_Time *self)
3581{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003582 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003583
3584 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003585}
Tim Peters2a799bf2002-12-16 20:18:38 +00003586
3587static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003588time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003590 char buf[100];
3591 PyObject *result;
3592 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003594 if (us)
3595 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3596 TIME_GET_HOUR(self),
3597 TIME_GET_MINUTE(self),
3598 TIME_GET_SECOND(self),
3599 us);
3600 else
3601 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3602 TIME_GET_HOUR(self),
3603 TIME_GET_MINUTE(self),
3604 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003605
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003606 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003607 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003609 /* We need to append the UTC offset. */
3610 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3611 Py_None) < 0) {
3612 Py_DECREF(result);
3613 return NULL;
3614 }
3615 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3616 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003617}
3618
Tim Peters37f39822003-01-10 03:49:02 +00003619static PyObject *
3620time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003622 PyObject *result;
3623 PyObject *tuple;
3624 PyObject *format;
3625 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003627 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3628 &format))
3629 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003631 /* Python's strftime does insane things with the year part of the
3632 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003633 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003634 */
3635 tuple = Py_BuildValue("iiiiiiiii",
3636 1900, 1, 1, /* year, month, day */
3637 TIME_GET_HOUR(self),
3638 TIME_GET_MINUTE(self),
3639 TIME_GET_SECOND(self),
3640 0, 1, -1); /* weekday, daynum, dst */
3641 if (tuple == NULL)
3642 return NULL;
3643 assert(PyTuple_Size(tuple) == 9);
3644 result = wrap_strftime((PyObject *)self, format, tuple,
3645 Py_None);
3646 Py_DECREF(tuple);
3647 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003648}
Tim Peters2a799bf2002-12-16 20:18:38 +00003649
3650/*
3651 * Miscellaneous methods.
3652 */
3653
Tim Peters37f39822003-01-10 03:49:02 +00003654static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003655time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003656{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003657 PyObject *result = NULL;
3658 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003659 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003660
Brian Curtindfc80e32011-08-10 20:28:54 -05003661 if (! PyTime_Check(other))
3662 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003663
3664 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003665 diff = memcmp(((PyDateTime_Time *)self)->data,
3666 ((PyDateTime_Time *)other)->data,
3667 _PyDateTime_TIME_DATASIZE);
3668 return diff_to_bool(diff, op);
3669 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003670 offset1 = time_utcoffset(self, NULL);
3671 if (offset1 == NULL)
3672 return NULL;
3673 offset2 = time_utcoffset(other, NULL);
3674 if (offset2 == NULL)
3675 goto done;
3676 /* If they're both naive, or both aware and have the same offsets,
3677 * we get off cheap. Note that if they're both naive, offset1 ==
3678 * offset2 == Py_None at this point.
3679 */
3680 if ((offset1 == offset2) ||
3681 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3682 delta_cmp(offset1, offset2) == 0)) {
3683 diff = memcmp(((PyDateTime_Time *)self)->data,
3684 ((PyDateTime_Time *)other)->data,
3685 _PyDateTime_TIME_DATASIZE);
3686 result = diff_to_bool(diff, op);
3687 }
3688 /* The hard case: both aware with different UTC offsets */
3689 else if (offset1 != Py_None && offset2 != Py_None) {
3690 int offsecs1, offsecs2;
3691 assert(offset1 != offset2); /* else last "if" handled it */
3692 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3693 TIME_GET_MINUTE(self) * 60 +
3694 TIME_GET_SECOND(self) -
3695 GET_TD_DAYS(offset1) * 86400 -
3696 GET_TD_SECONDS(offset1);
3697 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3698 TIME_GET_MINUTE(other) * 60 +
3699 TIME_GET_SECOND(other) -
3700 GET_TD_DAYS(offset2) * 86400 -
3701 GET_TD_SECONDS(offset2);
3702 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003703 if (diff == 0)
3704 diff = TIME_GET_MICROSECOND(self) -
3705 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003706 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003707 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003708 else {
3709 PyErr_SetString(PyExc_TypeError,
3710 "can't compare offset-naive and "
3711 "offset-aware times");
3712 }
3713 done:
3714 Py_DECREF(offset1);
3715 Py_XDECREF(offset2);
3716 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003717}
3718
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003719static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003720time_hash(PyDateTime_Time *self)
3721{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003722 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003723 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003724
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003725 offset = time_utcoffset((PyObject *)self, NULL);
3726
3727 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003728 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003730 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003731 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003732 self->hashcode = generic_hash(
3733 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003734 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003735 PyObject *temp1, *temp2;
3736 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003737 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003738 seconds = TIME_GET_HOUR(self) * 3600 +
3739 TIME_GET_MINUTE(self) * 60 +
3740 TIME_GET_SECOND(self);
3741 microseconds = TIME_GET_MICROSECOND(self);
3742 temp1 = new_delta(0, seconds, microseconds, 1);
3743 if (temp1 == NULL) {
3744 Py_DECREF(offset);
3745 return -1;
3746 }
3747 temp2 = delta_subtract(temp1, offset);
3748 Py_DECREF(temp1);
3749 if (temp2 == NULL) {
3750 Py_DECREF(offset);
3751 return -1;
3752 }
3753 self->hashcode = PyObject_Hash(temp2);
3754 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003755 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003756 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003757 }
3758 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003759}
Tim Peters2a799bf2002-12-16 20:18:38 +00003760
Tim Peters12bf3392002-12-24 05:41:27 +00003761static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003762time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003763{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003764 PyObject *clone;
3765 PyObject *tuple;
3766 int hh = TIME_GET_HOUR(self);
3767 int mm = TIME_GET_MINUTE(self);
3768 int ss = TIME_GET_SECOND(self);
3769 int us = TIME_GET_MICROSECOND(self);
3770 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003772 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3773 time_kws,
3774 &hh, &mm, &ss, &us, &tzinfo))
3775 return NULL;
3776 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3777 if (tuple == NULL)
3778 return NULL;
3779 clone = time_new(Py_TYPE(self), tuple, NULL);
3780 Py_DECREF(tuple);
3781 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003782}
3783
Tim Peters2a799bf2002-12-16 20:18:38 +00003784static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003785time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003786{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003787 PyObject *offset, *tzinfo;
3788 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003790 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3791 /* Since utcoffset is in whole minutes, nothing can
3792 * alter the conclusion that this is nonzero.
3793 */
3794 return 1;
3795 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003796 tzinfo = GET_TIME_TZINFO(self);
3797 if (tzinfo != Py_None) {
3798 offset = call_utcoffset(tzinfo, Py_None);
3799 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003800 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003801 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3802 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003803 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003804 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003805}
3806
Tim Peters371935f2003-02-01 01:52:50 +00003807/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003808
Tim Peters33e0f382003-01-10 02:05:14 +00003809/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003810 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3811 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003812 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003813 */
3814static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003815time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003817 PyObject *basestate;
3818 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003820 basestate = PyBytes_FromStringAndSize((char *)self->data,
3821 _PyDateTime_TIME_DATASIZE);
3822 if (basestate != NULL) {
3823 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3824 result = PyTuple_Pack(1, basestate);
3825 else
3826 result = PyTuple_Pack(2, basestate, self->tzinfo);
3827 Py_DECREF(basestate);
3828 }
3829 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003830}
3831
3832static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003833time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003836}
3837
Tim Peters37f39822003-01-10 03:49:02 +00003838static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003840 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3841 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3842 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003844 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3845 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003847 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3848 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003850 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3851 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003853 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3854 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003856 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3857 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003859 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3860 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003862 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3863 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003865 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003866};
3867
Tim Peters37f39822003-01-10 03:49:02 +00003868static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003869PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3870\n\
3871All arguments are optional. tzinfo may be None, or an instance of\n\
3872a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003873
Tim Peters37f39822003-01-10 03:49:02 +00003874static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003875 0, /* nb_add */
3876 0, /* nb_subtract */
3877 0, /* nb_multiply */
3878 0, /* nb_remainder */
3879 0, /* nb_divmod */
3880 0, /* nb_power */
3881 0, /* nb_negative */
3882 0, /* nb_positive */
3883 0, /* nb_absolute */
3884 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003885};
3886
Neal Norwitz227b5332006-03-22 09:28:35 +00003887static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003888 PyVarObject_HEAD_INIT(NULL, 0)
3889 "datetime.time", /* tp_name */
3890 sizeof(PyDateTime_Time), /* tp_basicsize */
3891 0, /* tp_itemsize */
3892 (destructor)time_dealloc, /* tp_dealloc */
3893 0, /* tp_print */
3894 0, /* tp_getattr */
3895 0, /* tp_setattr */
3896 0, /* tp_reserved */
3897 (reprfunc)time_repr, /* tp_repr */
3898 &time_as_number, /* tp_as_number */
3899 0, /* tp_as_sequence */
3900 0, /* tp_as_mapping */
3901 (hashfunc)time_hash, /* tp_hash */
3902 0, /* tp_call */
3903 (reprfunc)time_str, /* tp_str */
3904 PyObject_GenericGetAttr, /* tp_getattro */
3905 0, /* tp_setattro */
3906 0, /* tp_as_buffer */
3907 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3908 time_doc, /* tp_doc */
3909 0, /* tp_traverse */
3910 0, /* tp_clear */
3911 time_richcompare, /* tp_richcompare */
3912 0, /* tp_weaklistoffset */
3913 0, /* tp_iter */
3914 0, /* tp_iternext */
3915 time_methods, /* tp_methods */
3916 0, /* tp_members */
3917 time_getset, /* tp_getset */
3918 0, /* tp_base */
3919 0, /* tp_dict */
3920 0, /* tp_descr_get */
3921 0, /* tp_descr_set */
3922 0, /* tp_dictoffset */
3923 0, /* tp_init */
3924 time_alloc, /* tp_alloc */
3925 time_new, /* tp_new */
3926 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003927};
3928
3929/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003930 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003931 */
3932
Tim Petersa9bc1682003-01-11 03:39:11 +00003933/* Accessor properties. Properties for day, month, and year are inherited
3934 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003935 */
3936
3937static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003938datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003940 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003941}
3942
Tim Petersa9bc1682003-01-11 03:39:11 +00003943static PyObject *
3944datetime_minute(PyDateTime_DateTime *self, void *unused)
3945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003946 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003947}
3948
3949static PyObject *
3950datetime_second(PyDateTime_DateTime *self, void *unused)
3951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003952 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003953}
3954
3955static PyObject *
3956datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003958 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003959}
3960
3961static PyObject *
3962datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003964 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3965 Py_INCREF(result);
3966 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003967}
3968
3969static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003970 {"hour", (getter)datetime_hour},
3971 {"minute", (getter)datetime_minute},
3972 {"second", (getter)datetime_second},
3973 {"microsecond", (getter)datetime_microsecond},
3974 {"tzinfo", (getter)datetime_tzinfo},
3975 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003976};
3977
3978/*
3979 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003980 */
3981
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003982static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003983 "year", "month", "day", "hour", "minute", "second",
3984 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003985};
3986
Tim Peters2a799bf2002-12-16 20:18:38 +00003987static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003988datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003990 PyObject *self = NULL;
3991 PyObject *state;
3992 int year;
3993 int month;
3994 int day;
3995 int hour = 0;
3996 int minute = 0;
3997 int second = 0;
3998 int usecond = 0;
3999 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 /* Check for invocation from pickle with __getstate__ state */
4002 if (PyTuple_GET_SIZE(args) >= 1 &&
4003 PyTuple_GET_SIZE(args) <= 2 &&
4004 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4005 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4006 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4007 {
4008 PyDateTime_DateTime *me;
4009 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004011 if (PyTuple_GET_SIZE(args) == 2) {
4012 tzinfo = PyTuple_GET_ITEM(args, 1);
4013 if (check_tzinfo_subclass(tzinfo) < 0) {
4014 PyErr_SetString(PyExc_TypeError, "bad "
4015 "tzinfo state arg");
4016 return NULL;
4017 }
4018 }
4019 aware = (char)(tzinfo != Py_None);
4020 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4021 if (me != NULL) {
4022 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004024 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4025 me->hashcode = -1;
4026 me->hastzinfo = aware;
4027 if (aware) {
4028 Py_INCREF(tzinfo);
4029 me->tzinfo = tzinfo;
4030 }
4031 }
4032 return (PyObject *)me;
4033 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004035 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4036 &year, &month, &day, &hour, &minute,
4037 &second, &usecond, &tzinfo)) {
4038 if (check_date_args(year, month, day) < 0)
4039 return NULL;
4040 if (check_time_args(hour, minute, second, usecond) < 0)
4041 return NULL;
4042 if (check_tzinfo_subclass(tzinfo) < 0)
4043 return NULL;
4044 self = new_datetime_ex(year, month, day,
4045 hour, minute, second, usecond,
4046 tzinfo, type);
4047 }
4048 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004049}
4050
Tim Petersa9bc1682003-01-11 03:39:11 +00004051/* TM_FUNC is the shared type of localtime() and gmtime(). */
4052typedef struct tm *(*TM_FUNC)(const time_t *timer);
4053
4054/* Internal helper.
4055 * Build datetime from a time_t and a distinct count of microseconds.
4056 * Pass localtime or gmtime for f, to control the interpretation of timet.
4057 */
4058static PyObject *
4059datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004060 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004061{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004062 struct tm *tm;
Tim Petersa9bc1682003-01-11 03:39:11 +00004063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004064 tm = f(&timet);
Victor Stinner21f58932012-03-14 00:15:40 +01004065 if (tm == NULL) {
4066#ifdef EINVAL
4067 if (errno == 0)
4068 errno = EINVAL;
4069#endif
4070 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004071 }
Victor Stinner21f58932012-03-14 00:15:40 +01004072
4073 /* The platform localtime/gmtime may insert leap seconds,
4074 * indicated by tm->tm_sec > 59. We don't care about them,
4075 * except to the extent that passing them on to the datetime
4076 * constructor would raise ValueError for a reason that
4077 * made no sense to the user.
4078 */
4079 if (tm->tm_sec > 59)
4080 tm->tm_sec = 59;
4081 return PyObject_CallFunction(cls, "iiiiiiiO",
4082 tm->tm_year + 1900,
4083 tm->tm_mon + 1,
4084 tm->tm_mday,
4085 tm->tm_hour,
4086 tm->tm_min,
4087 tm->tm_sec,
4088 us,
4089 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004090}
4091
4092/* Internal helper.
4093 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4094 * to control the interpretation of the timestamp. Since a double doesn't
4095 * have enough bits to cover a datetime's full range of precision, it's
4096 * better to call datetime_from_timet_and_us provided you have a way
4097 * to get that much precision (e.g., C time() isn't good enough).
4098 */
4099static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004100datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004101 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004102{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004103 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004104 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004105
Victor Stinner5d272cc2012-03-13 13:35:55 +01004106 if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004107 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004108 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004109}
4110
4111/* Internal helper.
4112 * Build most accurate possible datetime for current time. Pass localtime or
4113 * gmtime for f as appropriate.
4114 */
4115static PyObject *
4116datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4117{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004118 _PyTime_timeval t;
4119 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004120 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4121 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004122}
4123
Tim Peters2a799bf2002-12-16 20:18:38 +00004124/* Return best possible local time -- this isn't constrained by the
4125 * precision of a timestamp.
4126 */
4127static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004128datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 PyObject *self;
4131 PyObject *tzinfo = Py_None;
4132 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004134 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4135 &tzinfo))
4136 return NULL;
4137 if (check_tzinfo_subclass(tzinfo) < 0)
4138 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004140 self = datetime_best_possible(cls,
4141 tzinfo == Py_None ? localtime : gmtime,
4142 tzinfo);
4143 if (self != NULL && tzinfo != Py_None) {
4144 /* Convert UTC to tzinfo's zone. */
4145 PyObject *temp = self;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004146 _Py_IDENTIFIER(fromutc);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004147
4148 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004149 Py_DECREF(temp);
4150 }
4151 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004152}
4153
Tim Petersa9bc1682003-01-11 03:39:11 +00004154/* Return best possible UTC time -- this isn't constrained by the
4155 * precision of a timestamp.
4156 */
4157static PyObject *
4158datetime_utcnow(PyObject *cls, PyObject *dummy)
4159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004160 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004161}
4162
Tim Peters2a799bf2002-12-16 20:18:38 +00004163/* Return new local datetime from timestamp (Python timestamp -- a double). */
4164static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004165datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004167 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004168 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004169 PyObject *tzinfo = Py_None;
4170 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004171
Victor Stinner5d272cc2012-03-13 13:35:55 +01004172 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004173 keywords, &timestamp, &tzinfo))
4174 return NULL;
4175 if (check_tzinfo_subclass(tzinfo) < 0)
4176 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004178 self = datetime_from_timestamp(cls,
4179 tzinfo == Py_None ? localtime : gmtime,
4180 timestamp,
4181 tzinfo);
4182 if (self != NULL && tzinfo != Py_None) {
4183 /* Convert UTC to tzinfo's zone. */
4184 PyObject *temp = self;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004185 _Py_IDENTIFIER(fromutc);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004186
4187 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004188 Py_DECREF(temp);
4189 }
4190 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004191}
4192
Tim Petersa9bc1682003-01-11 03:39:11 +00004193/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4194static PyObject *
4195datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4196{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004197 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004198 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004199
Victor Stinner5d272cc2012-03-13 13:35:55 +01004200 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004201 result = datetime_from_timestamp(cls, gmtime, timestamp,
4202 Py_None);
4203 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004204}
4205
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004206/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004207static PyObject *
4208datetime_strptime(PyObject *cls, PyObject *args)
4209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004210 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004211 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004212 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004213
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004214 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004215 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004216
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004217 if (module == NULL) {
4218 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004219 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004220 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004221 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004222 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4223 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004224}
4225
Tim Petersa9bc1682003-01-11 03:39:11 +00004226/* Return new datetime from date/datetime and time arguments. */
4227static PyObject *
4228datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004230 static char *keywords[] = {"date", "time", NULL};
4231 PyObject *date;
4232 PyObject *time;
4233 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004235 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4236 &PyDateTime_DateType, &date,
4237 &PyDateTime_TimeType, &time)) {
4238 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004240 if (HASTZINFO(time))
4241 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4242 result = PyObject_CallFunction(cls, "iiiiiiiO",
4243 GET_YEAR(date),
4244 GET_MONTH(date),
4245 GET_DAY(date),
4246 TIME_GET_HOUR(time),
4247 TIME_GET_MINUTE(time),
4248 TIME_GET_SECOND(time),
4249 TIME_GET_MICROSECOND(time),
4250 tzinfo);
4251 }
4252 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004253}
Tim Peters2a799bf2002-12-16 20:18:38 +00004254
4255/*
4256 * Destructor.
4257 */
4258
4259static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004260datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004262 if (HASTZINFO(self)) {
4263 Py_XDECREF(self->tzinfo);
4264 }
4265 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004266}
4267
4268/*
4269 * Indirect access to tzinfo methods.
4270 */
4271
Tim Peters2a799bf2002-12-16 20:18:38 +00004272/* These are all METH_NOARGS, so don't need to check the arglist. */
4273static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004274datetime_utcoffset(PyObject *self, PyObject *unused) {
4275 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004276}
4277
4278static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004279datetime_dst(PyObject *self, PyObject *unused) {
4280 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004281}
4282
4283static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004284datetime_tzname(PyObject *self, PyObject *unused) {
4285 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004286}
4287
4288/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004289 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004290 */
4291
Tim Petersa9bc1682003-01-11 03:39:11 +00004292/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4293 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004294 */
4295static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004296add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004297 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004298{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004299 /* Note that the C-level additions can't overflow, because of
4300 * invariant bounds on the member values.
4301 */
4302 int year = GET_YEAR(date);
4303 int month = GET_MONTH(date);
4304 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4305 int hour = DATE_GET_HOUR(date);
4306 int minute = DATE_GET_MINUTE(date);
4307 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4308 int microsecond = DATE_GET_MICROSECOND(date) +
4309 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004311 assert(factor == 1 || factor == -1);
4312 if (normalize_datetime(&year, &month, &day,
4313 &hour, &minute, &second, &microsecond) < 0)
4314 return NULL;
4315 else
4316 return new_datetime(year, month, day,
4317 hour, minute, second, microsecond,
4318 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004319}
4320
4321static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004322datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004323{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004324 if (PyDateTime_Check(left)) {
4325 /* datetime + ??? */
4326 if (PyDelta_Check(right))
4327 /* datetime + delta */
4328 return add_datetime_timedelta(
4329 (PyDateTime_DateTime *)left,
4330 (PyDateTime_Delta *)right,
4331 1);
4332 }
4333 else if (PyDelta_Check(left)) {
4334 /* delta + datetime */
4335 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4336 (PyDateTime_Delta *) left,
4337 1);
4338 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004339 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004340}
4341
4342static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004343datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004345 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004347 if (PyDateTime_Check(left)) {
4348 /* datetime - ??? */
4349 if (PyDateTime_Check(right)) {
4350 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004351 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004352 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004353
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004354 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4355 offset2 = offset1 = Py_None;
4356 Py_INCREF(offset1);
4357 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004358 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004359 else {
4360 offset1 = datetime_utcoffset(left, NULL);
4361 if (offset1 == NULL)
4362 return NULL;
4363 offset2 = datetime_utcoffset(right, NULL);
4364 if (offset2 == NULL) {
4365 Py_DECREF(offset1);
4366 return NULL;
4367 }
4368 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4369 PyErr_SetString(PyExc_TypeError,
4370 "can't subtract offset-naive and "
4371 "offset-aware datetimes");
4372 Py_DECREF(offset1);
4373 Py_DECREF(offset2);
4374 return NULL;
4375 }
4376 }
4377 if ((offset1 != offset2) &&
4378 delta_cmp(offset1, offset2) != 0) {
4379 offdiff = delta_subtract(offset1, offset2);
4380 if (offdiff == NULL) {
4381 Py_DECREF(offset1);
4382 Py_DECREF(offset2);
4383 return NULL;
4384 }
4385 }
4386 Py_DECREF(offset1);
4387 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004388 delta_d = ymd_to_ord(GET_YEAR(left),
4389 GET_MONTH(left),
4390 GET_DAY(left)) -
4391 ymd_to_ord(GET_YEAR(right),
4392 GET_MONTH(right),
4393 GET_DAY(right));
4394 /* These can't overflow, since the values are
4395 * normalized. At most this gives the number of
4396 * seconds in one day.
4397 */
4398 delta_s = (DATE_GET_HOUR(left) -
4399 DATE_GET_HOUR(right)) * 3600 +
4400 (DATE_GET_MINUTE(left) -
4401 DATE_GET_MINUTE(right)) * 60 +
4402 (DATE_GET_SECOND(left) -
4403 DATE_GET_SECOND(right));
4404 delta_us = DATE_GET_MICROSECOND(left) -
4405 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004406 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004407 if (offdiff != NULL) {
4408 PyObject *temp = result;
4409 result = delta_subtract(result, offdiff);
4410 Py_DECREF(temp);
4411 Py_DECREF(offdiff);
4412 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004413 }
4414 else if (PyDelta_Check(right)) {
4415 /* datetime - delta */
4416 result = add_datetime_timedelta(
4417 (PyDateTime_DateTime *)left,
4418 (PyDateTime_Delta *)right,
4419 -1);
4420 }
4421 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004423 if (result == Py_NotImplemented)
4424 Py_INCREF(result);
4425 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004426}
4427
4428/* Various ways to turn a datetime into a string. */
4429
4430static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004431datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004433 const char *type_name = Py_TYPE(self)->tp_name;
4434 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004436 if (DATE_GET_MICROSECOND(self)) {
4437 baserepr = PyUnicode_FromFormat(
4438 "%s(%d, %d, %d, %d, %d, %d, %d)",
4439 type_name,
4440 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4441 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4442 DATE_GET_SECOND(self),
4443 DATE_GET_MICROSECOND(self));
4444 }
4445 else if (DATE_GET_SECOND(self)) {
4446 baserepr = PyUnicode_FromFormat(
4447 "%s(%d, %d, %d, %d, %d, %d)",
4448 type_name,
4449 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4450 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4451 DATE_GET_SECOND(self));
4452 }
4453 else {
4454 baserepr = PyUnicode_FromFormat(
4455 "%s(%d, %d, %d, %d, %d)",
4456 type_name,
4457 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4458 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4459 }
4460 if (baserepr == NULL || ! HASTZINFO(self))
4461 return baserepr;
4462 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004463}
4464
Tim Petersa9bc1682003-01-11 03:39:11 +00004465static PyObject *
4466datetime_str(PyDateTime_DateTime *self)
4467{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004468 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004469
4470 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004471}
Tim Peters2a799bf2002-12-16 20:18:38 +00004472
4473static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004474datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004476 int sep = 'T';
4477 static char *keywords[] = {"sep", NULL};
4478 char buffer[100];
4479 PyObject *result;
4480 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004482 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4483 return NULL;
4484 if (us)
4485 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4486 GET_YEAR(self), GET_MONTH(self),
4487 GET_DAY(self), (int)sep,
4488 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4489 DATE_GET_SECOND(self), us);
4490 else
4491 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4492 GET_YEAR(self), GET_MONTH(self),
4493 GET_DAY(self), (int)sep,
4494 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4495 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004497 if (!result || !HASTZINFO(self))
4498 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004500 /* We need to append the UTC offset. */
4501 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4502 (PyObject *)self) < 0) {
4503 Py_DECREF(result);
4504 return NULL;
4505 }
4506 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4507 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004508}
4509
Tim Petersa9bc1682003-01-11 03:39:11 +00004510static PyObject *
4511datetime_ctime(PyDateTime_DateTime *self)
4512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004513 return format_ctime((PyDateTime_Date *)self,
4514 DATE_GET_HOUR(self),
4515 DATE_GET_MINUTE(self),
4516 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004517}
4518
Tim Peters2a799bf2002-12-16 20:18:38 +00004519/* Miscellaneous methods. */
4520
Tim Petersa9bc1682003-01-11 03:39:11 +00004521static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004522datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004523{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004524 PyObject *result = NULL;
4525 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004526 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004528 if (! PyDateTime_Check(other)) {
4529 if (PyDate_Check(other)) {
4530 /* Prevent invocation of date_richcompare. We want to
4531 return NotImplemented here to give the other object
4532 a chance. But since DateTime is a subclass of
4533 Date, if the other object is a Date, it would
4534 compute an ordering based on the date part alone,
4535 and we don't want that. So force unequal or
4536 uncomparable here in that case. */
4537 if (op == Py_EQ)
4538 Py_RETURN_FALSE;
4539 if (op == Py_NE)
4540 Py_RETURN_TRUE;
4541 return cmperror(self, other);
4542 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004543 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004545
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004546 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004547 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4548 ((PyDateTime_DateTime *)other)->data,
4549 _PyDateTime_DATETIME_DATASIZE);
4550 return diff_to_bool(diff, op);
4551 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004552 offset1 = datetime_utcoffset(self, NULL);
4553 if (offset1 == NULL)
4554 return NULL;
4555 offset2 = datetime_utcoffset(other, NULL);
4556 if (offset2 == NULL)
4557 goto done;
4558 /* If they're both naive, or both aware and have the same offsets,
4559 * we get off cheap. Note that if they're both naive, offset1 ==
4560 * offset2 == Py_None at this point.
4561 */
4562 if ((offset1 == offset2) ||
4563 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4564 delta_cmp(offset1, offset2) == 0)) {
4565 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4566 ((PyDateTime_DateTime *)other)->data,
4567 _PyDateTime_DATETIME_DATASIZE);
4568 result = diff_to_bool(diff, op);
4569 }
4570 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004571 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004572
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004573 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004574 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4575 other);
4576 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004577 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004578 diff = GET_TD_DAYS(delta);
4579 if (diff == 0)
4580 diff = GET_TD_SECONDS(delta) |
4581 GET_TD_MICROSECONDS(delta);
4582 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004583 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004584 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004585 else {
4586 PyErr_SetString(PyExc_TypeError,
4587 "can't compare offset-naive and "
4588 "offset-aware datetimes");
4589 }
4590 done:
4591 Py_DECREF(offset1);
4592 Py_XDECREF(offset2);
4593 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004594}
4595
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004596static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004597datetime_hash(PyDateTime_DateTime *self)
4598{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004599 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004600 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004601
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004602 offset = datetime_utcoffset((PyObject *)self, NULL);
4603
4604 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004605 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004607 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004608 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004609 self->hashcode = generic_hash(
4610 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004611 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004612 PyObject *temp1, *temp2;
4613 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004615 assert(HASTZINFO(self));
4616 days = ymd_to_ord(GET_YEAR(self),
4617 GET_MONTH(self),
4618 GET_DAY(self));
4619 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004620 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004621 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004622 temp1 = new_delta(days, seconds,
4623 DATE_GET_MICROSECOND(self),
4624 1);
4625 if (temp1 == NULL) {
4626 Py_DECREF(offset);
4627 return -1;
4628 }
4629 temp2 = delta_subtract(temp1, offset);
4630 Py_DECREF(temp1);
4631 if (temp2 == NULL) {
4632 Py_DECREF(offset);
4633 return -1;
4634 }
4635 self->hashcode = PyObject_Hash(temp2);
4636 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004637 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004638 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 }
4640 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004641}
Tim Peters2a799bf2002-12-16 20:18:38 +00004642
4643static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004644datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004646 PyObject *clone;
4647 PyObject *tuple;
4648 int y = GET_YEAR(self);
4649 int m = GET_MONTH(self);
4650 int d = GET_DAY(self);
4651 int hh = DATE_GET_HOUR(self);
4652 int mm = DATE_GET_MINUTE(self);
4653 int ss = DATE_GET_SECOND(self);
4654 int us = DATE_GET_MICROSECOND(self);
4655 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004657 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4658 datetime_kws,
4659 &y, &m, &d, &hh, &mm, &ss, &us,
4660 &tzinfo))
4661 return NULL;
4662 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4663 if (tuple == NULL)
4664 return NULL;
4665 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4666 Py_DECREF(tuple);
4667 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004668}
4669
4670static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004671datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004673 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004674 PyObject *offset;
4675 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004676 PyObject *tzinfo;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004677 _Py_IDENTIFIER(fromutc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004678 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004680 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4681 &PyDateTime_TZInfoType, &tzinfo))
4682 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004684 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4685 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004687 /* Conversion to self's own time zone is a NOP. */
4688 if (self->tzinfo == tzinfo) {
4689 Py_INCREF(self);
4690 return (PyObject *)self;
4691 }
Tim Peters521fc152002-12-31 17:36:56 +00004692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004693 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004694 offset = datetime_utcoffset((PyObject *)self, NULL);
4695 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004696 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004697 if (offset == Py_None) {
4698 Py_DECREF(offset);
4699 NeedAware:
4700 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4701 "a naive datetime");
4702 return NULL;
4703 }
Tim Petersf3615152003-01-01 21:51:37 +00004704
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004705 /* result = self - offset */
4706 result = add_datetime_timedelta(self,
4707 (PyDateTime_Delta *)offset, -1);
4708 Py_DECREF(offset);
4709 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004710 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004712 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004713 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4714 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4715 Py_INCREF(tzinfo);
4716 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004717
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004718 temp = result;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004719 result = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004720 Py_DECREF(temp);
4721
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004722 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004723}
4724
4725static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004726datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004728 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004730 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004731 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004732
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004733 dst = call_dst(self->tzinfo, (PyObject *)self);
4734 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004735 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004736
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004737 if (dst != Py_None)
4738 dstflag = delta_bool((PyDateTime_Delta *)dst);
4739 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004740 }
4741 return build_struct_time(GET_YEAR(self),
4742 GET_MONTH(self),
4743 GET_DAY(self),
4744 DATE_GET_HOUR(self),
4745 DATE_GET_MINUTE(self),
4746 DATE_GET_SECOND(self),
4747 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004748}
4749
4750static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004751datetime_getdate(PyDateTime_DateTime *self)
4752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004753 return new_date(GET_YEAR(self),
4754 GET_MONTH(self),
4755 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004756}
4757
4758static PyObject *
4759datetime_gettime(PyDateTime_DateTime *self)
4760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004761 return new_time(DATE_GET_HOUR(self),
4762 DATE_GET_MINUTE(self),
4763 DATE_GET_SECOND(self),
4764 DATE_GET_MICROSECOND(self),
4765 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004766}
4767
4768static PyObject *
4769datetime_gettimetz(PyDateTime_DateTime *self)
4770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004771 return new_time(DATE_GET_HOUR(self),
4772 DATE_GET_MINUTE(self),
4773 DATE_GET_SECOND(self),
4774 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004775 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004776}
4777
4778static PyObject *
4779datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004780{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004781 int y, m, d, hh, mm, ss;
4782 PyObject *tzinfo;
4783 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004784
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004785 tzinfo = GET_DT_TZINFO(self);
4786 if (tzinfo == Py_None) {
4787 utcself = self;
4788 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004789 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004790 else {
4791 PyObject *offset;
4792 offset = call_utcoffset(tzinfo, (PyObject *)self);
4793 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004794 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004795 if (offset == Py_None) {
4796 Py_DECREF(offset);
4797 utcself = self;
4798 Py_INCREF(utcself);
4799 }
4800 else {
4801 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4802 (PyDateTime_Delta *)offset, -1);
4803 Py_DECREF(offset);
4804 if (utcself == NULL)
4805 return NULL;
4806 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004807 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004808 y = GET_YEAR(utcself);
4809 m = GET_MONTH(utcself);
4810 d = GET_DAY(utcself);
4811 hh = DATE_GET_HOUR(utcself);
4812 mm = DATE_GET_MINUTE(utcself);
4813 ss = DATE_GET_SECOND(utcself);
4814
4815 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004816 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004817}
4818
Tim Peters371935f2003-02-01 01:52:50 +00004819/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004820
Tim Petersa9bc1682003-01-11 03:39:11 +00004821/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004822 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4823 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004824 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004825 */
4826static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004827datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004829 PyObject *basestate;
4830 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004832 basestate = PyBytes_FromStringAndSize((char *)self->data,
4833 _PyDateTime_DATETIME_DATASIZE);
4834 if (basestate != NULL) {
4835 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4836 result = PyTuple_Pack(1, basestate);
4837 else
4838 result = PyTuple_Pack(2, basestate, self->tzinfo);
4839 Py_DECREF(basestate);
4840 }
4841 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004842}
4843
4844static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004845datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004847 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004848}
4849
Tim Petersa9bc1682003-01-11 03:39:11 +00004850static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004852 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004854 {"now", (PyCFunction)datetime_now,
4855 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4856 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004858 {"utcnow", (PyCFunction)datetime_utcnow,
4859 METH_NOARGS | METH_CLASS,
4860 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004862 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4863 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4864 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004866 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4867 METH_VARARGS | METH_CLASS,
4868 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4869 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004871 {"strptime", (PyCFunction)datetime_strptime,
4872 METH_VARARGS | METH_CLASS,
4873 PyDoc_STR("string, format -> new datetime parsed from a string "
4874 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004876 {"combine", (PyCFunction)datetime_combine,
4877 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4878 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004880 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4883 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004885 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4886 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004888 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4889 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004891 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4892 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004894 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4895 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004897 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4898 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004900 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4901 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4902 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4903 "sep is used to separate the year from the time, and "
4904 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004906 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4907 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004909 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4910 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004912 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4913 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004915 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4916 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004918 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4919 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004921 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4922 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004924 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004925};
4926
Tim Petersa9bc1682003-01-11 03:39:11 +00004927static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004928PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4929\n\
4930The year, month and day arguments are required. tzinfo may be None, or an\n\
4931instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004932
Tim Petersa9bc1682003-01-11 03:39:11 +00004933static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 datetime_add, /* nb_add */
4935 datetime_subtract, /* nb_subtract */
4936 0, /* nb_multiply */
4937 0, /* nb_remainder */
4938 0, /* nb_divmod */
4939 0, /* nb_power */
4940 0, /* nb_negative */
4941 0, /* nb_positive */
4942 0, /* nb_absolute */
4943 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004944};
4945
Neal Norwitz227b5332006-03-22 09:28:35 +00004946static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004947 PyVarObject_HEAD_INIT(NULL, 0)
4948 "datetime.datetime", /* tp_name */
4949 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4950 0, /* tp_itemsize */
4951 (destructor)datetime_dealloc, /* tp_dealloc */
4952 0, /* tp_print */
4953 0, /* tp_getattr */
4954 0, /* tp_setattr */
4955 0, /* tp_reserved */
4956 (reprfunc)datetime_repr, /* tp_repr */
4957 &datetime_as_number, /* tp_as_number */
4958 0, /* tp_as_sequence */
4959 0, /* tp_as_mapping */
4960 (hashfunc)datetime_hash, /* tp_hash */
4961 0, /* tp_call */
4962 (reprfunc)datetime_str, /* tp_str */
4963 PyObject_GenericGetAttr, /* tp_getattro */
4964 0, /* tp_setattro */
4965 0, /* tp_as_buffer */
4966 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4967 datetime_doc, /* tp_doc */
4968 0, /* tp_traverse */
4969 0, /* tp_clear */
4970 datetime_richcompare, /* tp_richcompare */
4971 0, /* tp_weaklistoffset */
4972 0, /* tp_iter */
4973 0, /* tp_iternext */
4974 datetime_methods, /* tp_methods */
4975 0, /* tp_members */
4976 datetime_getset, /* tp_getset */
4977 &PyDateTime_DateType, /* tp_base */
4978 0, /* tp_dict */
4979 0, /* tp_descr_get */
4980 0, /* tp_descr_set */
4981 0, /* tp_dictoffset */
4982 0, /* tp_init */
4983 datetime_alloc, /* tp_alloc */
4984 datetime_new, /* tp_new */
4985 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004986};
4987
4988/* ---------------------------------------------------------------------------
4989 * Module methods and initialization.
4990 */
4991
4992static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004993 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004994};
4995
Tim Peters9ddf40b2004-06-20 22:41:32 +00004996/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4997 * datetime.h.
4998 */
4999static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005000 &PyDateTime_DateType,
5001 &PyDateTime_DateTimeType,
5002 &PyDateTime_TimeType,
5003 &PyDateTime_DeltaType,
5004 &PyDateTime_TZInfoType,
5005 new_date_ex,
5006 new_datetime_ex,
5007 new_time_ex,
5008 new_delta_ex,
5009 datetime_fromtimestamp,
5010 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005011};
5012
5013
Martin v. Löwis1a214512008-06-11 05:26:20 +00005014
5015static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005016 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005017 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005018 "Fast implementation of the datetime type.",
5019 -1,
5020 module_methods,
5021 NULL,
5022 NULL,
5023 NULL,
5024 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005025};
5026
Tim Peters2a799bf2002-12-16 20:18:38 +00005027PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005028PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005030 PyObject *m; /* a module object */
5031 PyObject *d; /* its dict */
5032 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005033 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 m = PyModule_Create(&datetimemodule);
5036 if (m == NULL)
5037 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005039 if (PyType_Ready(&PyDateTime_DateType) < 0)
5040 return NULL;
5041 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5042 return NULL;
5043 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5044 return NULL;
5045 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5046 return NULL;
5047 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5048 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005049 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5050 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005052 /* timedelta values */
5053 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005054
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005055 x = new_delta(0, 0, 1, 0);
5056 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5057 return NULL;
5058 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005060 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5061 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5062 return NULL;
5063 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005065 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5066 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5067 return NULL;
5068 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005070 /* date values */
5071 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005073 x = new_date(1, 1, 1);
5074 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5075 return NULL;
5076 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005078 x = new_date(MAXYEAR, 12, 31);
5079 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5080 return NULL;
5081 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005083 x = new_delta(1, 0, 0, 0);
5084 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5085 return NULL;
5086 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005088 /* time values */
5089 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005091 x = new_time(0, 0, 0, 0, Py_None);
5092 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5093 return NULL;
5094 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005096 x = new_time(23, 59, 59, 999999, Py_None);
5097 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5098 return NULL;
5099 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005101 x = new_delta(0, 0, 1, 0);
5102 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5103 return NULL;
5104 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005106 /* datetime values */
5107 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005109 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5110 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5111 return NULL;
5112 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005114 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5115 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5116 return NULL;
5117 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005119 x = new_delta(0, 0, 1, 0);
5120 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5121 return NULL;
5122 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005123
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005124 /* timezone values */
5125 d = PyDateTime_TimeZoneType.tp_dict;
5126
5127 delta = new_delta(0, 0, 0, 0);
5128 if (delta == NULL)
5129 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005130 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005131 Py_DECREF(delta);
5132 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5133 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005134 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005135
5136 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5137 if (delta == NULL)
5138 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005139 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005140 Py_DECREF(delta);
5141 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5142 return NULL;
5143 Py_DECREF(x);
5144
5145 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5146 if (delta == NULL)
5147 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005148 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005149 Py_DECREF(delta);
5150 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5151 return NULL;
5152 Py_DECREF(x);
5153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005154 /* module initialization */
5155 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5156 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005158 Py_INCREF(&PyDateTime_DateType);
5159 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005161 Py_INCREF(&PyDateTime_DateTimeType);
5162 PyModule_AddObject(m, "datetime",
5163 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005165 Py_INCREF(&PyDateTime_TimeType);
5166 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005168 Py_INCREF(&PyDateTime_DeltaType);
5169 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005171 Py_INCREF(&PyDateTime_TZInfoType);
5172 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005173
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005174 Py_INCREF(&PyDateTime_TimeZoneType);
5175 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005177 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5178 if (x == NULL)
5179 return NULL;
5180 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005182 /* A 4-year cycle has an extra leap day over what we'd get from
5183 * pasting together 4 single years.
5184 */
5185 assert(DI4Y == 4 * 365 + 1);
5186 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005188 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5189 * get from pasting together 4 100-year cycles.
5190 */
5191 assert(DI400Y == 4 * DI100Y + 1);
5192 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005194 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5195 * pasting together 25 4-year cycles.
5196 */
5197 assert(DI100Y == 25 * DI4Y - 1);
5198 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005200 us_per_us = PyLong_FromLong(1);
5201 us_per_ms = PyLong_FromLong(1000);
5202 us_per_second = PyLong_FromLong(1000000);
5203 us_per_minute = PyLong_FromLong(60000000);
5204 seconds_per_day = PyLong_FromLong(24 * 3600);
5205 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5206 us_per_minute == NULL || seconds_per_day == NULL)
5207 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005209 /* The rest are too big for 32-bit ints, but even
5210 * us_per_week fits in 40 bits, so doubles should be exact.
5211 */
5212 us_per_hour = PyLong_FromDouble(3600000000.0);
5213 us_per_day = PyLong_FromDouble(86400000000.0);
5214 us_per_week = PyLong_FromDouble(604800000000.0);
5215 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5216 return NULL;
5217 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005218}
Tim Petersf3615152003-01-01 21:51:37 +00005219
5220/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005221Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005222 x.n = x stripped of its timezone -- its naive time.
5223 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005224 return None
Tim Petersf3615152003-01-01 21:51:37 +00005225 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005226 return None
Tim Petersf3615152003-01-01 21:51:37 +00005227 x.s = x's standard offset, x.o - x.d
5228
5229Now some derived rules, where k is a duration (timedelta).
5230
52311. x.o = x.s + x.d
5232 This follows from the definition of x.s.
5233
Tim Petersc5dc4da2003-01-02 17:55:03 +000052342. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005235 This is actually a requirement, an assumption we need to make about
5236 sane tzinfo classes.
5237
52383. The naive UTC time corresponding to x is x.n - x.o.
5239 This is again a requirement for a sane tzinfo class.
5240
52414. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005242 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005243
Tim Petersc5dc4da2003-01-02 17:55:03 +000052445. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005245 Again follows from how arithmetic is defined.
5246
Tim Peters8bb5ad22003-01-24 02:44:45 +00005247Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005248(meaning that the various tzinfo methods exist, and don't blow up or return
5249None when called).
5250
Tim Petersa9bc1682003-01-11 03:39:11 +00005251The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005252x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005253
5254By #3, we want
5255
Tim Peters8bb5ad22003-01-24 02:44:45 +00005256 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005257
5258The algorithm starts by attaching tz to x.n, and calling that y. So
5259x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5260becomes true; in effect, we want to solve [2] for k:
5261
Tim Peters8bb5ad22003-01-24 02:44:45 +00005262 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005263
5264By #1, this is the same as
5265
Tim Peters8bb5ad22003-01-24 02:44:45 +00005266 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005267
5268By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5269Substituting that into [3],
5270
Tim Peters8bb5ad22003-01-24 02:44:45 +00005271 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5272 k - (y+k).s - (y+k).d = 0; rearranging,
5273 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5274 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005275
Tim Peters8bb5ad22003-01-24 02:44:45 +00005276On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5277approximate k by ignoring the (y+k).d term at first. Note that k can't be
5278very large, since all offset-returning methods return a duration of magnitude
5279less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5280be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005281
5282In any case, the new value is
5283
Tim Peters8bb5ad22003-01-24 02:44:45 +00005284 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005285
Tim Peters8bb5ad22003-01-24 02:44:45 +00005286It's helpful to step back at look at [4] from a higher level: it's simply
5287mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005288
5289At this point, if
5290
Tim Peters8bb5ad22003-01-24 02:44:45 +00005291 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005292
5293we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005294at the start of daylight time. Picture US Eastern for concreteness. The wall
5295time 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 +00005296sense then. The docs ask that an Eastern tzinfo class consider such a time to
5297be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5298on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005299the only spelling that makes sense on the local wall clock.
5300
Tim Petersc5dc4da2003-01-02 17:55:03 +00005301In fact, if [5] holds at this point, we do have the standard-time spelling,
5302but that takes a bit of proof. We first prove a stronger result. What's the
5303difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005304
Tim Peters8bb5ad22003-01-24 02:44:45 +00005305 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005306
Tim Petersc5dc4da2003-01-02 17:55:03 +00005307Now
5308 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005309 (y + y.s).n = by #5
5310 y.n + y.s = since y.n = x.n
5311 x.n + y.s = since z and y are have the same tzinfo member,
5312 y.s = z.s by #2
5313 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005314
Tim Petersc5dc4da2003-01-02 17:55:03 +00005315Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005316
Tim Petersc5dc4da2003-01-02 17:55:03 +00005317 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005318 x.n - ((x.n + z.s) - z.o) = expanding
5319 x.n - x.n - z.s + z.o = cancelling
5320 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005321 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005322
Tim Petersc5dc4da2003-01-02 17:55:03 +00005323So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005324
Tim Petersc5dc4da2003-01-02 17:55:03 +00005325If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005326spelling we wanted in the endcase described above. We're done. Contrarily,
5327if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005328
Tim Petersc5dc4da2003-01-02 17:55:03 +00005329If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5330add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005331local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005332
Tim Petersc5dc4da2003-01-02 17:55:03 +00005333Let
Tim Petersf3615152003-01-01 21:51:37 +00005334
Tim Peters4fede1a2003-01-04 00:26:59 +00005335 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005336
Tim Peters4fede1a2003-01-04 00:26:59 +00005337and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005338
Tim Peters8bb5ad22003-01-24 02:44:45 +00005339 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005340
Tim Peters8bb5ad22003-01-24 02:44:45 +00005341If so, we're done. If not, the tzinfo class is insane, according to the
5342assumptions we've made. This also requires a bit of proof. As before, let's
5343compute the difference between the LHS and RHS of [8] (and skipping some of
5344the justifications for the kinds of substitutions we've done several times
5345already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005346
Tim Peters8bb5ad22003-01-24 02:44:45 +00005347 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005348 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5349 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5350 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5351 - z.n + z.n - z.o + z'.o = cancel z.n
5352 - z.o + z'.o = #1 twice
5353 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5354 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005355
5356So 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 +00005357we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5358return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005359
Tim Peters8bb5ad22003-01-24 02:44:45 +00005360How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5361a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5362would have to change the result dst() returns: we start in DST, and moving
5363a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005364
Tim Peters8bb5ad22003-01-24 02:44:45 +00005365There isn't a sane case where this can happen. The closest it gets is at
5366the end of DST, where there's an hour in UTC with no spelling in a hybrid
5367tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5368that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5369UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5370time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5371clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5372standard time. Since that's what the local clock *does*, we want to map both
5373UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005374in local time, but so it goes -- it's the way the local clock works.
5375
Tim Peters8bb5ad22003-01-24 02:44:45 +00005376When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5377so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5378z' = 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 +00005379(correctly) concludes that z' is not UTC-equivalent to x.
5380
5381Because we know z.d said z was in daylight time (else [5] would have held and
5382we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005383and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005384return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5385but the reasoning doesn't depend on the example -- it depends on there being
5386two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005387z' must be in standard time, and is the spelling we want in this case.
5388
5389Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5390concerned (because it takes z' as being in standard time rather than the
5391daylight time we intend here), but returning it gives the real-life "local
5392clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5393tz.
5394
5395When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5396the 1:MM standard time spelling we want.
5397
5398So how can this break? One of the assumptions must be violated. Two
5399possibilities:
5400
54011) [2] effectively says that y.s is invariant across all y belong to a given
5402 time zone. This isn't true if, for political reasons or continental drift,
5403 a region decides to change its base offset from UTC.
5404
54052) There may be versions of "double daylight" time where the tail end of
5406 the analysis gives up a step too early. I haven't thought about that
5407 enough to say.
5408
5409In any case, it's clear that the default fromutc() is strong enough to handle
5410"almost all" time zones: so long as the standard offset is invariant, it
5411doesn't matter if daylight time transition points change from year to year, or
5412if daylight time is skipped in some years; it doesn't matter how large or
5413small dst() may get within its bounds; and it doesn't even matter if some
5414perverse time zone returns a negative dst()). So a breaking case must be
5415pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005416--------------------------------------------------------------------------- */