blob: 669170add7d70467ed33c14a64302eb782986013 [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;
2446 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002447
Victor Stinner5d272cc2012-03-13 13:35:55 +01002448 if (_PyTime_ObjectToTime_t(obj, &t) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002449 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002451 tm = localtime(&t);
2452 if (tm)
2453 result = PyObject_CallFunction(cls, "iii",
2454 tm->tm_year + 1900,
2455 tm->tm_mon + 1,
2456 tm->tm_mday);
2457 else
2458 PyErr_SetString(PyExc_ValueError,
2459 "timestamp out of range for "
2460 "platform localtime() function");
2461 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002462}
2463
2464/* Return new date from current time.
2465 * We say this is equivalent to fromtimestamp(time.time()), and the
2466 * only way to be sure of that is to *call* time.time(). That's not
2467 * generally the same as calling C's time.
2468 */
2469static PyObject *
2470date_today(PyObject *cls, PyObject *dummy)
2471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 PyObject *time;
2473 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002474 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 time = time_time();
2477 if (time == NULL)
2478 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 /* Note well: today() is a class method, so this may not call
2481 * date.fromtimestamp. For example, it may call
2482 * datetime.fromtimestamp. That's why we need all the accuracy
2483 * time.time() delivers; if someone were gonzo about optimization,
2484 * date.today() could get away with plain C time().
2485 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002486 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002487 Py_DECREF(time);
2488 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002489}
2490
2491/* Return new date from given timestamp (Python timestamp -- a double). */
2492static PyObject *
2493date_fromtimestamp(PyObject *cls, PyObject *args)
2494{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002495 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002497
Victor Stinner5d272cc2012-03-13 13:35:55 +01002498 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2499 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002501}
2502
2503/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2504 * the ordinal is out of range.
2505 */
2506static PyObject *
2507date_fromordinal(PyObject *cls, PyObject *args)
2508{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 PyObject *result = NULL;
2510 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2513 int year;
2514 int month;
2515 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 if (ordinal < 1)
2518 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2519 ">= 1");
2520 else {
2521 ord_to_ymd(ordinal, &year, &month, &day);
2522 result = PyObject_CallFunction(cls, "iii",
2523 year, month, day);
2524 }
2525 }
2526 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002527}
2528
2529/*
2530 * Date arithmetic.
2531 */
2532
2533/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2534 * instead.
2535 */
2536static PyObject *
2537add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 PyObject *result = NULL;
2540 int year = GET_YEAR(date);
2541 int month = GET_MONTH(date);
2542 int deltadays = GET_TD_DAYS(delta);
2543 /* C-level overflow is impossible because |deltadays| < 1e9. */
2544 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002546 if (normalize_date(&year, &month, &day) >= 0)
2547 result = new_date(year, month, day);
2548 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002549}
2550
2551static PyObject *
2552date_add(PyObject *left, PyObject *right)
2553{
Brian Curtindfc80e32011-08-10 20:28:54 -05002554 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2555 Py_RETURN_NOTIMPLEMENTED;
2556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002557 if (PyDate_Check(left)) {
2558 /* date + ??? */
2559 if (PyDelta_Check(right))
2560 /* date + delta */
2561 return add_date_timedelta((PyDateTime_Date *) left,
2562 (PyDateTime_Delta *) right,
2563 0);
2564 }
2565 else {
2566 /* ??? + date
2567 * 'right' must be one of us, or we wouldn't have been called
2568 */
2569 if (PyDelta_Check(left))
2570 /* delta + date */
2571 return add_date_timedelta((PyDateTime_Date *) right,
2572 (PyDateTime_Delta *) left,
2573 0);
2574 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002575 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002576}
2577
2578static PyObject *
2579date_subtract(PyObject *left, PyObject *right)
2580{
Brian Curtindfc80e32011-08-10 20:28:54 -05002581 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2582 Py_RETURN_NOTIMPLEMENTED;
2583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002584 if (PyDate_Check(left)) {
2585 if (PyDate_Check(right)) {
2586 /* date - date */
2587 int left_ord = ymd_to_ord(GET_YEAR(left),
2588 GET_MONTH(left),
2589 GET_DAY(left));
2590 int right_ord = ymd_to_ord(GET_YEAR(right),
2591 GET_MONTH(right),
2592 GET_DAY(right));
2593 return new_delta(left_ord - right_ord, 0, 0, 0);
2594 }
2595 if (PyDelta_Check(right)) {
2596 /* date - delta */
2597 return add_date_timedelta((PyDateTime_Date *) left,
2598 (PyDateTime_Delta *) right,
2599 1);
2600 }
2601 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002602 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002603}
2604
2605
2606/* Various ways to turn a date into a string. */
2607
2608static PyObject *
2609date_repr(PyDateTime_Date *self)
2610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2612 Py_TYPE(self)->tp_name,
2613 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002614}
2615
2616static PyObject *
2617date_isoformat(PyDateTime_Date *self)
2618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002619 return PyUnicode_FromFormat("%04d-%02d-%02d",
2620 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002621}
2622
Tim Peterse2df5ff2003-05-02 18:39:55 +00002623/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002624static PyObject *
2625date_str(PyDateTime_Date *self)
2626{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002627 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002628
2629 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002630}
2631
2632
2633static PyObject *
2634date_ctime(PyDateTime_Date *self)
2635{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002637}
2638
2639static PyObject *
2640date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2641{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 /* This method can be inherited, and needs to call the
2643 * timetuple() method appropriate to self's class.
2644 */
2645 PyObject *result;
2646 PyObject *tuple;
2647 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002648 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002649 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002651 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2652 &format))
2653 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002654
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002655 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002656 if (tuple == NULL)
2657 return NULL;
2658 result = wrap_strftime((PyObject *)self, format, tuple,
2659 (PyObject *)self);
2660 Py_DECREF(tuple);
2661 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002662}
2663
Eric Smith1ba31142007-09-11 18:06:02 +00002664static PyObject *
2665date_format(PyDateTime_Date *self, PyObject *args)
2666{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002667 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002668 _Py_IDENTIFIER(strftime);
Eric Smith1ba31142007-09-11 18:06:02 +00002669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002670 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2671 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002673 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002674 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002675 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002676
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002677 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002678}
2679
Tim Peters2a799bf2002-12-16 20:18:38 +00002680/* ISO methods. */
2681
2682static PyObject *
2683date_isoweekday(PyDateTime_Date *self)
2684{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002685 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002687 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002688}
2689
2690static PyObject *
2691date_isocalendar(PyDateTime_Date *self)
2692{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002693 int year = GET_YEAR(self);
2694 int week1_monday = iso_week1_monday(year);
2695 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2696 int week;
2697 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002699 week = divmod(today - week1_monday, 7, &day);
2700 if (week < 0) {
2701 --year;
2702 week1_monday = iso_week1_monday(year);
2703 week = divmod(today - week1_monday, 7, &day);
2704 }
2705 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2706 ++year;
2707 week = 0;
2708 }
2709 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002710}
2711
2712/* Miscellaneous methods. */
2713
Tim Peters2a799bf2002-12-16 20:18:38 +00002714static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002715date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002717 if (PyDate_Check(other)) {
2718 int diff = memcmp(((PyDateTime_Date *)self)->data,
2719 ((PyDateTime_Date *)other)->data,
2720 _PyDateTime_DATE_DATASIZE);
2721 return diff_to_bool(diff, op);
2722 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002723 else
2724 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002725}
2726
2727static PyObject *
2728date_timetuple(PyDateTime_Date *self)
2729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002730 return build_struct_time(GET_YEAR(self),
2731 GET_MONTH(self),
2732 GET_DAY(self),
2733 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002734}
2735
Tim Peters12bf3392002-12-24 05:41:27 +00002736static PyObject *
2737date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2738{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002739 PyObject *clone;
2740 PyObject *tuple;
2741 int year = GET_YEAR(self);
2742 int month = GET_MONTH(self);
2743 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002745 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2746 &year, &month, &day))
2747 return NULL;
2748 tuple = Py_BuildValue("iii", year, month, day);
2749 if (tuple == NULL)
2750 return NULL;
2751 clone = date_new(Py_TYPE(self), tuple, NULL);
2752 Py_DECREF(tuple);
2753 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002754}
2755
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002756static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002757generic_hash(unsigned char *data, int len)
2758{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002759 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002760}
2761
2762
2763static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002764
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002765static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002766date_hash(PyDateTime_Date *self)
2767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002768 if (self->hashcode == -1)
2769 self->hashcode = generic_hash(
2770 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002773}
2774
2775static PyObject *
2776date_toordinal(PyDateTime_Date *self)
2777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002778 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2779 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002780}
2781
2782static PyObject *
2783date_weekday(PyDateTime_Date *self)
2784{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002785 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002787 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002788}
2789
Tim Peters371935f2003-02-01 01:52:50 +00002790/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002791
Tim Petersb57f8f02003-02-01 02:54:15 +00002792/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002793static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002794date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 PyObject* field;
2797 field = PyBytes_FromStringAndSize((char*)self->data,
2798 _PyDateTime_DATE_DATASIZE);
2799 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002800}
2801
2802static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002803date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002806}
2807
2808static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002812 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2813 METH_CLASS,
2814 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2815 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002817 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2818 METH_CLASS,
2819 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2820 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2823 PyDoc_STR("Current date or datetime: same as "
2824 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002826 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002828 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2829 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2832 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002834 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2835 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2838 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002840 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2841 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2842 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2845 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2848 PyDoc_STR("Return the day of the week represented by the date.\n"
2849 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2852 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2853 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002855 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2856 PyDoc_STR("Return the day of the week represented by the date.\n"
2857 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002859 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2860 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2863 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002865 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002866};
2867
2868static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002869PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002870
2871static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002872 date_add, /* nb_add */
2873 date_subtract, /* nb_subtract */
2874 0, /* nb_multiply */
2875 0, /* nb_remainder */
2876 0, /* nb_divmod */
2877 0, /* nb_power */
2878 0, /* nb_negative */
2879 0, /* nb_positive */
2880 0, /* nb_absolute */
2881 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002882};
2883
2884static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002885 PyVarObject_HEAD_INIT(NULL, 0)
2886 "datetime.date", /* tp_name */
2887 sizeof(PyDateTime_Date), /* tp_basicsize */
2888 0, /* tp_itemsize */
2889 0, /* tp_dealloc */
2890 0, /* tp_print */
2891 0, /* tp_getattr */
2892 0, /* tp_setattr */
2893 0, /* tp_reserved */
2894 (reprfunc)date_repr, /* tp_repr */
2895 &date_as_number, /* tp_as_number */
2896 0, /* tp_as_sequence */
2897 0, /* tp_as_mapping */
2898 (hashfunc)date_hash, /* tp_hash */
2899 0, /* tp_call */
2900 (reprfunc)date_str, /* tp_str */
2901 PyObject_GenericGetAttr, /* tp_getattro */
2902 0, /* tp_setattro */
2903 0, /* tp_as_buffer */
2904 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2905 date_doc, /* tp_doc */
2906 0, /* tp_traverse */
2907 0, /* tp_clear */
2908 date_richcompare, /* tp_richcompare */
2909 0, /* tp_weaklistoffset */
2910 0, /* tp_iter */
2911 0, /* tp_iternext */
2912 date_methods, /* tp_methods */
2913 0, /* tp_members */
2914 date_getset, /* tp_getset */
2915 0, /* tp_base */
2916 0, /* tp_dict */
2917 0, /* tp_descr_get */
2918 0, /* tp_descr_set */
2919 0, /* tp_dictoffset */
2920 0, /* tp_init */
2921 0, /* tp_alloc */
2922 date_new, /* tp_new */
2923 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002924};
2925
2926/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002927 * PyDateTime_TZInfo implementation.
2928 */
2929
2930/* This is a pure abstract base class, so doesn't do anything beyond
2931 * raising NotImplemented exceptions. Real tzinfo classes need
2932 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002933 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002934 * be subclasses of this tzinfo class, which is easy and quick to check).
2935 *
2936 * Note: For reasons having to do with pickling of subclasses, we have
2937 * to allow tzinfo objects to be instantiated. This wasn't an issue
2938 * in the Python implementation (__init__() could raise NotImplementedError
2939 * there without ill effect), but doing so in the C implementation hit a
2940 * brick wall.
2941 */
2942
2943static PyObject *
2944tzinfo_nogo(const char* methodname)
2945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002946 PyErr_Format(PyExc_NotImplementedError,
2947 "a tzinfo subclass must implement %s()",
2948 methodname);
2949 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002950}
2951
2952/* Methods. A subclass must implement these. */
2953
Tim Peters52dcce22003-01-23 16:36:11 +00002954static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002955tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002957 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002958}
2959
Tim Peters52dcce22003-01-23 16:36:11 +00002960static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002961tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002963 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002964}
2965
Tim Peters52dcce22003-01-23 16:36:11 +00002966static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002967tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002969 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002970}
2971
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002972
2973static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2974 PyDateTime_Delta *delta,
2975 int factor);
2976static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2977static PyObject *datetime_dst(PyObject *self, PyObject *);
2978
Tim Peters52dcce22003-01-23 16:36:11 +00002979static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002980tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002981{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002982 PyObject *result = NULL;
2983 PyObject *off = NULL, *dst = NULL;
2984 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002985
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002986 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002987 PyErr_SetString(PyExc_TypeError,
2988 "fromutc: argument must be a datetime");
2989 return NULL;
2990 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002991 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002992 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2993 "is not self");
2994 return NULL;
2995 }
Tim Peters52dcce22003-01-23 16:36:11 +00002996
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002997 off = datetime_utcoffset(dt, NULL);
2998 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002999 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003000 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003001 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3002 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003003 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003004 }
Tim Peters52dcce22003-01-23 16:36:11 +00003005
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003006 dst = datetime_dst(dt, NULL);
3007 if (dst == NULL)
3008 goto Fail;
3009 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003010 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3011 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003012 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003013 }
Tim Peters52dcce22003-01-23 16:36:11 +00003014
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003015 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3016 if (delta == NULL)
3017 goto Fail;
3018 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003019 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003020 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003021
3022 Py_DECREF(dst);
3023 dst = call_dst(GET_DT_TZINFO(dt), result);
3024 if (dst == NULL)
3025 goto Fail;
3026 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003027 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003028 if (delta_bool(delta) != 0) {
3029 PyObject *temp = result;
3030 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3031 (PyDateTime_Delta *)dst, 1);
3032 Py_DECREF(temp);
3033 if (result == NULL)
3034 goto Fail;
3035 }
3036 Py_DECREF(delta);
3037 Py_DECREF(dst);
3038 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003039 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003040
3041Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003042 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3043 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003045 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003046Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003047 Py_XDECREF(off);
3048 Py_XDECREF(dst);
3049 Py_XDECREF(delta);
3050 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003051 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003052}
3053
Tim Peters2a799bf2002-12-16 20:18:38 +00003054/*
3055 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003056 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003057 */
3058
Guido van Rossum177e41a2003-01-30 22:06:23 +00003059static PyObject *
3060tzinfo_reduce(PyObject *self)
3061{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 PyObject *args, *state, *tmp;
3063 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003064 _Py_IDENTIFIER(__getinitargs__);
3065 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003067 tmp = PyTuple_New(0);
3068 if (tmp == NULL)
3069 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003070
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003071 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003072 if (getinitargs != NULL) {
3073 args = PyObject_CallObject(getinitargs, tmp);
3074 Py_DECREF(getinitargs);
3075 if (args == NULL) {
3076 Py_DECREF(tmp);
3077 return NULL;
3078 }
3079 }
3080 else {
3081 PyErr_Clear();
3082 args = tmp;
3083 Py_INCREF(args);
3084 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003085
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003086 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003087 if (getstate != NULL) {
3088 state = PyObject_CallObject(getstate, tmp);
3089 Py_DECREF(getstate);
3090 if (state == NULL) {
3091 Py_DECREF(args);
3092 Py_DECREF(tmp);
3093 return NULL;
3094 }
3095 }
3096 else {
3097 PyObject **dictptr;
3098 PyErr_Clear();
3099 state = Py_None;
3100 dictptr = _PyObject_GetDictPtr(self);
3101 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3102 state = *dictptr;
3103 Py_INCREF(state);
3104 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003106 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003108 if (state == Py_None) {
3109 Py_DECREF(state);
3110 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3111 }
3112 else
3113 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003114}
Tim Peters2a799bf2002-12-16 20:18:38 +00003115
3116static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003118 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3119 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003121 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003122 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3123 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3126 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003129 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003131 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3132 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003134 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003135};
3136
3137static char tzinfo_doc[] =
3138PyDoc_STR("Abstract base class for time zone info objects.");
3139
Neal Norwitz227b5332006-03-22 09:28:35 +00003140static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003141 PyVarObject_HEAD_INIT(NULL, 0)
3142 "datetime.tzinfo", /* tp_name */
3143 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3144 0, /* tp_itemsize */
3145 0, /* tp_dealloc */
3146 0, /* tp_print */
3147 0, /* tp_getattr */
3148 0, /* tp_setattr */
3149 0, /* tp_reserved */
3150 0, /* tp_repr */
3151 0, /* tp_as_number */
3152 0, /* tp_as_sequence */
3153 0, /* tp_as_mapping */
3154 0, /* tp_hash */
3155 0, /* tp_call */
3156 0, /* tp_str */
3157 PyObject_GenericGetAttr, /* tp_getattro */
3158 0, /* tp_setattro */
3159 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003160 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003161 tzinfo_doc, /* tp_doc */
3162 0, /* tp_traverse */
3163 0, /* tp_clear */
3164 0, /* tp_richcompare */
3165 0, /* tp_weaklistoffset */
3166 0, /* tp_iter */
3167 0, /* tp_iternext */
3168 tzinfo_methods, /* tp_methods */
3169 0, /* tp_members */
3170 0, /* tp_getset */
3171 0, /* tp_base */
3172 0, /* tp_dict */
3173 0, /* tp_descr_get */
3174 0, /* tp_descr_set */
3175 0, /* tp_dictoffset */
3176 0, /* tp_init */
3177 0, /* tp_alloc */
3178 PyType_GenericNew, /* tp_new */
3179 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003180};
3181
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003182static char *timezone_kws[] = {"offset", "name", NULL};
3183
3184static PyObject *
3185timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3186{
3187 PyObject *offset;
3188 PyObject *name = NULL;
3189 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3190 &PyDateTime_DeltaType, &offset,
3191 &PyUnicode_Type, &name))
3192 return new_timezone(offset, name);
3193
3194 return NULL;
3195}
3196
3197static void
3198timezone_dealloc(PyDateTime_TimeZone *self)
3199{
3200 Py_CLEAR(self->offset);
3201 Py_CLEAR(self->name);
3202 Py_TYPE(self)->tp_free((PyObject *)self);
3203}
3204
3205static PyObject *
3206timezone_richcompare(PyDateTime_TimeZone *self,
3207 PyDateTime_TimeZone *other, int op)
3208{
Brian Curtindfc80e32011-08-10 20:28:54 -05003209 if (op != Py_EQ && op != Py_NE)
3210 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003211 return delta_richcompare(self->offset, other->offset, op);
3212}
3213
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003214static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003215timezone_hash(PyDateTime_TimeZone *self)
3216{
3217 return delta_hash((PyDateTime_Delta *)self->offset);
3218}
3219
3220/* Check argument type passed to tzname, utcoffset, or dst methods.
3221 Returns 0 for good argument. Returns -1 and sets exception info
3222 otherwise.
3223 */
3224static int
3225_timezone_check_argument(PyObject *dt, const char *meth)
3226{
3227 if (dt == Py_None || PyDateTime_Check(dt))
3228 return 0;
3229 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3230 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3231 return -1;
3232}
3233
3234static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003235timezone_repr(PyDateTime_TimeZone *self)
3236{
3237 /* Note that although timezone is not subclassable, it is convenient
3238 to use Py_TYPE(self)->tp_name here. */
3239 const char *type_name = Py_TYPE(self)->tp_name;
3240
3241 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3242 return PyUnicode_FromFormat("%s.utc", type_name);
3243
3244 if (self->name == NULL)
3245 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3246
3247 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3248 self->name);
3249}
3250
3251
3252static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003253timezone_str(PyDateTime_TimeZone *self)
3254{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003255 int hours, minutes, seconds;
3256 PyObject *offset;
3257 char sign;
3258
3259 if (self->name != NULL) {
3260 Py_INCREF(self->name);
3261 return self->name;
3262 }
3263 /* Offset is normalized, so it is negative if days < 0 */
3264 if (GET_TD_DAYS(self->offset) < 0) {
3265 sign = '-';
3266 offset = delta_negative((PyDateTime_Delta *)self->offset);
3267 if (offset == NULL)
3268 return NULL;
3269 }
3270 else {
3271 sign = '+';
3272 offset = self->offset;
3273 Py_INCREF(offset);
3274 }
3275 /* Offset is not negative here. */
3276 seconds = GET_TD_SECONDS(offset);
3277 Py_DECREF(offset);
3278 minutes = divmod(seconds, 60, &seconds);
3279 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003280 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003281 assert(seconds == 0);
3282 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003283}
3284
3285static PyObject *
3286timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3287{
3288 if (_timezone_check_argument(dt, "tzname") == -1)
3289 return NULL;
3290
3291 return timezone_str(self);
3292}
3293
3294static PyObject *
3295timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3296{
3297 if (_timezone_check_argument(dt, "utcoffset") == -1)
3298 return NULL;
3299
3300 Py_INCREF(self->offset);
3301 return self->offset;
3302}
3303
3304static PyObject *
3305timezone_dst(PyObject *self, PyObject *dt)
3306{
3307 if (_timezone_check_argument(dt, "dst") == -1)
3308 return NULL;
3309
3310 Py_RETURN_NONE;
3311}
3312
3313static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003314timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3315{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003316 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003317 PyErr_SetString(PyExc_TypeError,
3318 "fromutc: argument must be a datetime");
3319 return NULL;
3320 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003321 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003322 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3323 "is not self");
3324 return NULL;
3325 }
3326
3327 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3328}
3329
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003330static PyObject *
3331timezone_getinitargs(PyDateTime_TimeZone *self)
3332{
3333 if (self->name == NULL)
3334 return Py_BuildValue("(O)", self->offset);
3335 return Py_BuildValue("(OO)", self->offset, self->name);
3336}
3337
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003338static PyMethodDef timezone_methods[] = {
3339 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3340 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003341 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003342
3343 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003344 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003345
3346 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003347 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003348
3349 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3350 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3351
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003352 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3353 PyDoc_STR("pickle support")},
3354
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003355 {NULL, NULL}
3356};
3357
3358static char timezone_doc[] =
3359PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3360
3361static PyTypeObject PyDateTime_TimeZoneType = {
3362 PyVarObject_HEAD_INIT(NULL, 0)
3363 "datetime.timezone", /* tp_name */
3364 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3365 0, /* tp_itemsize */
3366 (destructor)timezone_dealloc, /* tp_dealloc */
3367 0, /* tp_print */
3368 0, /* tp_getattr */
3369 0, /* tp_setattr */
3370 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003371 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003372 0, /* tp_as_number */
3373 0, /* tp_as_sequence */
3374 0, /* tp_as_mapping */
3375 (hashfunc)timezone_hash, /* tp_hash */
3376 0, /* tp_call */
3377 (reprfunc)timezone_str, /* tp_str */
3378 0, /* tp_getattro */
3379 0, /* tp_setattro */
3380 0, /* tp_as_buffer */
3381 Py_TPFLAGS_DEFAULT, /* tp_flags */
3382 timezone_doc, /* tp_doc */
3383 0, /* tp_traverse */
3384 0, /* tp_clear */
3385 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3386 0, /* tp_weaklistoffset */
3387 0, /* tp_iter */
3388 0, /* tp_iternext */
3389 timezone_methods, /* tp_methods */
3390 0, /* tp_members */
3391 0, /* tp_getset */
3392 &PyDateTime_TZInfoType, /* tp_base */
3393 0, /* tp_dict */
3394 0, /* tp_descr_get */
3395 0, /* tp_descr_set */
3396 0, /* tp_dictoffset */
3397 0, /* tp_init */
3398 0, /* tp_alloc */
3399 timezone_new, /* tp_new */
3400};
3401
Tim Peters2a799bf2002-12-16 20:18:38 +00003402/*
Tim Peters37f39822003-01-10 03:49:02 +00003403 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003404 */
3405
Tim Peters37f39822003-01-10 03:49:02 +00003406/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003407 */
3408
3409static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003410time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003412 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003413}
3414
Tim Peters37f39822003-01-10 03:49:02 +00003415static PyObject *
3416time_minute(PyDateTime_Time *self, void *unused)
3417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003418 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003419}
3420
3421/* The name time_second conflicted with some platform header file. */
3422static PyObject *
3423py_time_second(PyDateTime_Time *self, void *unused)
3424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003425 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003426}
3427
3428static PyObject *
3429time_microsecond(PyDateTime_Time *self, void *unused)
3430{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003431 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003432}
3433
3434static PyObject *
3435time_tzinfo(PyDateTime_Time *self, void *unused)
3436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003437 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3438 Py_INCREF(result);
3439 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003440}
3441
3442static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003443 {"hour", (getter)time_hour},
3444 {"minute", (getter)time_minute},
3445 {"second", (getter)py_time_second},
3446 {"microsecond", (getter)time_microsecond},
3447 {"tzinfo", (getter)time_tzinfo},
3448 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003449};
3450
3451/*
3452 * Constructors.
3453 */
3454
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003455static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003456 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003457
Tim Peters2a799bf2002-12-16 20:18:38 +00003458static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003459time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003461 PyObject *self = NULL;
3462 PyObject *state;
3463 int hour = 0;
3464 int minute = 0;
3465 int second = 0;
3466 int usecond = 0;
3467 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003469 /* Check for invocation from pickle with __getstate__ state */
3470 if (PyTuple_GET_SIZE(args) >= 1 &&
3471 PyTuple_GET_SIZE(args) <= 2 &&
3472 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3473 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3474 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3475 {
3476 PyDateTime_Time *me;
3477 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003479 if (PyTuple_GET_SIZE(args) == 2) {
3480 tzinfo = PyTuple_GET_ITEM(args, 1);
3481 if (check_tzinfo_subclass(tzinfo) < 0) {
3482 PyErr_SetString(PyExc_TypeError, "bad "
3483 "tzinfo state arg");
3484 return NULL;
3485 }
3486 }
3487 aware = (char)(tzinfo != Py_None);
3488 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3489 if (me != NULL) {
3490 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003492 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3493 me->hashcode = -1;
3494 me->hastzinfo = aware;
3495 if (aware) {
3496 Py_INCREF(tzinfo);
3497 me->tzinfo = tzinfo;
3498 }
3499 }
3500 return (PyObject *)me;
3501 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003503 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3504 &hour, &minute, &second, &usecond,
3505 &tzinfo)) {
3506 if (check_time_args(hour, minute, second, usecond) < 0)
3507 return NULL;
3508 if (check_tzinfo_subclass(tzinfo) < 0)
3509 return NULL;
3510 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3511 type);
3512 }
3513 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003514}
3515
3516/*
3517 * Destructor.
3518 */
3519
3520static void
Tim Peters37f39822003-01-10 03:49:02 +00003521time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003523 if (HASTZINFO(self)) {
3524 Py_XDECREF(self->tzinfo);
3525 }
3526 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003527}
3528
3529/*
Tim Peters855fe882002-12-22 03:43:39 +00003530 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003531 */
3532
Tim Peters2a799bf2002-12-16 20:18:38 +00003533/* These are all METH_NOARGS, so don't need to check the arglist. */
3534static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003535time_utcoffset(PyObject *self, PyObject *unused) {
3536 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003537}
3538
3539static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003540time_dst(PyObject *self, PyObject *unused) {
3541 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003542}
3543
3544static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003545time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003546 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003547}
3548
3549/*
Tim Peters37f39822003-01-10 03:49:02 +00003550 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003551 */
3552
3553static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003554time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003556 const char *type_name = Py_TYPE(self)->tp_name;
3557 int h = TIME_GET_HOUR(self);
3558 int m = TIME_GET_MINUTE(self);
3559 int s = TIME_GET_SECOND(self);
3560 int us = TIME_GET_MICROSECOND(self);
3561 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003563 if (us)
3564 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3565 type_name, h, m, s, us);
3566 else if (s)
3567 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3568 type_name, h, m, s);
3569 else
3570 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3571 if (result != NULL && HASTZINFO(self))
3572 result = append_keyword_tzinfo(result, self->tzinfo);
3573 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003574}
3575
Tim Peters37f39822003-01-10 03:49:02 +00003576static PyObject *
3577time_str(PyDateTime_Time *self)
3578{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003579 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003580
3581 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003582}
Tim Peters2a799bf2002-12-16 20:18:38 +00003583
3584static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003585time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003586{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003587 char buf[100];
3588 PyObject *result;
3589 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003591 if (us)
3592 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3593 TIME_GET_HOUR(self),
3594 TIME_GET_MINUTE(self),
3595 TIME_GET_SECOND(self),
3596 us);
3597 else
3598 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3599 TIME_GET_HOUR(self),
3600 TIME_GET_MINUTE(self),
3601 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003602
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003603 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003604 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003606 /* We need to append the UTC offset. */
3607 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3608 Py_None) < 0) {
3609 Py_DECREF(result);
3610 return NULL;
3611 }
3612 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3613 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003614}
3615
Tim Peters37f39822003-01-10 03:49:02 +00003616static PyObject *
3617time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003619 PyObject *result;
3620 PyObject *tuple;
3621 PyObject *format;
3622 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003624 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3625 &format))
3626 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003628 /* Python's strftime does insane things with the year part of the
3629 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003630 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003631 */
3632 tuple = Py_BuildValue("iiiiiiiii",
3633 1900, 1, 1, /* year, month, day */
3634 TIME_GET_HOUR(self),
3635 TIME_GET_MINUTE(self),
3636 TIME_GET_SECOND(self),
3637 0, 1, -1); /* weekday, daynum, dst */
3638 if (tuple == NULL)
3639 return NULL;
3640 assert(PyTuple_Size(tuple) == 9);
3641 result = wrap_strftime((PyObject *)self, format, tuple,
3642 Py_None);
3643 Py_DECREF(tuple);
3644 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003645}
Tim Peters2a799bf2002-12-16 20:18:38 +00003646
3647/*
3648 * Miscellaneous methods.
3649 */
3650
Tim Peters37f39822003-01-10 03:49:02 +00003651static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003652time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003653{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003654 PyObject *result = NULL;
3655 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003656 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003657
Brian Curtindfc80e32011-08-10 20:28:54 -05003658 if (! PyTime_Check(other))
3659 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003660
3661 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003662 diff = memcmp(((PyDateTime_Time *)self)->data,
3663 ((PyDateTime_Time *)other)->data,
3664 _PyDateTime_TIME_DATASIZE);
3665 return diff_to_bool(diff, op);
3666 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003667 offset1 = time_utcoffset(self, NULL);
3668 if (offset1 == NULL)
3669 return NULL;
3670 offset2 = time_utcoffset(other, NULL);
3671 if (offset2 == NULL)
3672 goto done;
3673 /* If they're both naive, or both aware and have the same offsets,
3674 * we get off cheap. Note that if they're both naive, offset1 ==
3675 * offset2 == Py_None at this point.
3676 */
3677 if ((offset1 == offset2) ||
3678 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3679 delta_cmp(offset1, offset2) == 0)) {
3680 diff = memcmp(((PyDateTime_Time *)self)->data,
3681 ((PyDateTime_Time *)other)->data,
3682 _PyDateTime_TIME_DATASIZE);
3683 result = diff_to_bool(diff, op);
3684 }
3685 /* The hard case: both aware with different UTC offsets */
3686 else if (offset1 != Py_None && offset2 != Py_None) {
3687 int offsecs1, offsecs2;
3688 assert(offset1 != offset2); /* else last "if" handled it */
3689 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3690 TIME_GET_MINUTE(self) * 60 +
3691 TIME_GET_SECOND(self) -
3692 GET_TD_DAYS(offset1) * 86400 -
3693 GET_TD_SECONDS(offset1);
3694 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3695 TIME_GET_MINUTE(other) * 60 +
3696 TIME_GET_SECOND(other) -
3697 GET_TD_DAYS(offset2) * 86400 -
3698 GET_TD_SECONDS(offset2);
3699 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003700 if (diff == 0)
3701 diff = TIME_GET_MICROSECOND(self) -
3702 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003703 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003704 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003705 else {
3706 PyErr_SetString(PyExc_TypeError,
3707 "can't compare offset-naive and "
3708 "offset-aware times");
3709 }
3710 done:
3711 Py_DECREF(offset1);
3712 Py_XDECREF(offset2);
3713 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003714}
3715
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003716static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003717time_hash(PyDateTime_Time *self)
3718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003719 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003720 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003721
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003722 offset = time_utcoffset((PyObject *)self, NULL);
3723
3724 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003725 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003727 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003728 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003729 self->hashcode = generic_hash(
3730 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003731 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003732 PyObject *temp1, *temp2;
3733 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003734 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003735 seconds = TIME_GET_HOUR(self) * 3600 +
3736 TIME_GET_MINUTE(self) * 60 +
3737 TIME_GET_SECOND(self);
3738 microseconds = TIME_GET_MICROSECOND(self);
3739 temp1 = new_delta(0, seconds, microseconds, 1);
3740 if (temp1 == NULL) {
3741 Py_DECREF(offset);
3742 return -1;
3743 }
3744 temp2 = delta_subtract(temp1, offset);
3745 Py_DECREF(temp1);
3746 if (temp2 == NULL) {
3747 Py_DECREF(offset);
3748 return -1;
3749 }
3750 self->hashcode = PyObject_Hash(temp2);
3751 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003752 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003753 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003754 }
3755 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003756}
Tim Peters2a799bf2002-12-16 20:18:38 +00003757
Tim Peters12bf3392002-12-24 05:41:27 +00003758static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003759time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003761 PyObject *clone;
3762 PyObject *tuple;
3763 int hh = TIME_GET_HOUR(self);
3764 int mm = TIME_GET_MINUTE(self);
3765 int ss = TIME_GET_SECOND(self);
3766 int us = TIME_GET_MICROSECOND(self);
3767 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003769 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3770 time_kws,
3771 &hh, &mm, &ss, &us, &tzinfo))
3772 return NULL;
3773 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3774 if (tuple == NULL)
3775 return NULL;
3776 clone = time_new(Py_TYPE(self), tuple, NULL);
3777 Py_DECREF(tuple);
3778 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003779}
3780
Tim Peters2a799bf2002-12-16 20:18:38 +00003781static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003782time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003783{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003784 PyObject *offset, *tzinfo;
3785 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003787 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3788 /* Since utcoffset is in whole minutes, nothing can
3789 * alter the conclusion that this is nonzero.
3790 */
3791 return 1;
3792 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003793 tzinfo = GET_TIME_TZINFO(self);
3794 if (tzinfo != Py_None) {
3795 offset = call_utcoffset(tzinfo, Py_None);
3796 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003797 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003798 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3799 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003800 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003801 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003802}
3803
Tim Peters371935f2003-02-01 01:52:50 +00003804/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003805
Tim Peters33e0f382003-01-10 02:05:14 +00003806/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003807 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3808 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003809 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003810 */
3811static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003812time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003814 PyObject *basestate;
3815 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003817 basestate = PyBytes_FromStringAndSize((char *)self->data,
3818 _PyDateTime_TIME_DATASIZE);
3819 if (basestate != NULL) {
3820 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3821 result = PyTuple_Pack(1, basestate);
3822 else
3823 result = PyTuple_Pack(2, basestate, self->tzinfo);
3824 Py_DECREF(basestate);
3825 }
3826 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003827}
3828
3829static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003830time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003832 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003833}
3834
Tim Peters37f39822003-01-10 03:49:02 +00003835static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003837 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3838 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3839 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003841 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3842 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003844 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3845 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003847 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3848 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003850 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3851 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003853 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3854 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003856 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3857 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003859 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3860 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003862 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003863};
3864
Tim Peters37f39822003-01-10 03:49:02 +00003865static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003866PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3867\n\
3868All arguments are optional. tzinfo may be None, or an instance of\n\
3869a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003870
Tim Peters37f39822003-01-10 03:49:02 +00003871static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003872 0, /* nb_add */
3873 0, /* nb_subtract */
3874 0, /* nb_multiply */
3875 0, /* nb_remainder */
3876 0, /* nb_divmod */
3877 0, /* nb_power */
3878 0, /* nb_negative */
3879 0, /* nb_positive */
3880 0, /* nb_absolute */
3881 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003882};
3883
Neal Norwitz227b5332006-03-22 09:28:35 +00003884static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003885 PyVarObject_HEAD_INIT(NULL, 0)
3886 "datetime.time", /* tp_name */
3887 sizeof(PyDateTime_Time), /* tp_basicsize */
3888 0, /* tp_itemsize */
3889 (destructor)time_dealloc, /* tp_dealloc */
3890 0, /* tp_print */
3891 0, /* tp_getattr */
3892 0, /* tp_setattr */
3893 0, /* tp_reserved */
3894 (reprfunc)time_repr, /* tp_repr */
3895 &time_as_number, /* tp_as_number */
3896 0, /* tp_as_sequence */
3897 0, /* tp_as_mapping */
3898 (hashfunc)time_hash, /* tp_hash */
3899 0, /* tp_call */
3900 (reprfunc)time_str, /* tp_str */
3901 PyObject_GenericGetAttr, /* tp_getattro */
3902 0, /* tp_setattro */
3903 0, /* tp_as_buffer */
3904 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3905 time_doc, /* tp_doc */
3906 0, /* tp_traverse */
3907 0, /* tp_clear */
3908 time_richcompare, /* tp_richcompare */
3909 0, /* tp_weaklistoffset */
3910 0, /* tp_iter */
3911 0, /* tp_iternext */
3912 time_methods, /* tp_methods */
3913 0, /* tp_members */
3914 time_getset, /* tp_getset */
3915 0, /* tp_base */
3916 0, /* tp_dict */
3917 0, /* tp_descr_get */
3918 0, /* tp_descr_set */
3919 0, /* tp_dictoffset */
3920 0, /* tp_init */
3921 time_alloc, /* tp_alloc */
3922 time_new, /* tp_new */
3923 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003924};
3925
3926/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003927 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003928 */
3929
Tim Petersa9bc1682003-01-11 03:39:11 +00003930/* Accessor properties. Properties for day, month, and year are inherited
3931 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003932 */
3933
3934static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003935datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003936{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003937 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003938}
3939
Tim Petersa9bc1682003-01-11 03:39:11 +00003940static PyObject *
3941datetime_minute(PyDateTime_DateTime *self, void *unused)
3942{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003943 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003944}
3945
3946static PyObject *
3947datetime_second(PyDateTime_DateTime *self, void *unused)
3948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003949 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003950}
3951
3952static PyObject *
3953datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003955 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003956}
3957
3958static PyObject *
3959datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003961 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3962 Py_INCREF(result);
3963 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003964}
3965
3966static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003967 {"hour", (getter)datetime_hour},
3968 {"minute", (getter)datetime_minute},
3969 {"second", (getter)datetime_second},
3970 {"microsecond", (getter)datetime_microsecond},
3971 {"tzinfo", (getter)datetime_tzinfo},
3972 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003973};
3974
3975/*
3976 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003977 */
3978
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003979static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 "year", "month", "day", "hour", "minute", "second",
3981 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003982};
3983
Tim Peters2a799bf2002-12-16 20:18:38 +00003984static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003985datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003987 PyObject *self = NULL;
3988 PyObject *state;
3989 int year;
3990 int month;
3991 int day;
3992 int hour = 0;
3993 int minute = 0;
3994 int second = 0;
3995 int usecond = 0;
3996 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003998 /* Check for invocation from pickle with __getstate__ state */
3999 if (PyTuple_GET_SIZE(args) >= 1 &&
4000 PyTuple_GET_SIZE(args) <= 2 &&
4001 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4002 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4003 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4004 {
4005 PyDateTime_DateTime *me;
4006 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004008 if (PyTuple_GET_SIZE(args) == 2) {
4009 tzinfo = PyTuple_GET_ITEM(args, 1);
4010 if (check_tzinfo_subclass(tzinfo) < 0) {
4011 PyErr_SetString(PyExc_TypeError, "bad "
4012 "tzinfo state arg");
4013 return NULL;
4014 }
4015 }
4016 aware = (char)(tzinfo != Py_None);
4017 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4018 if (me != NULL) {
4019 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004021 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4022 me->hashcode = -1;
4023 me->hastzinfo = aware;
4024 if (aware) {
4025 Py_INCREF(tzinfo);
4026 me->tzinfo = tzinfo;
4027 }
4028 }
4029 return (PyObject *)me;
4030 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004032 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4033 &year, &month, &day, &hour, &minute,
4034 &second, &usecond, &tzinfo)) {
4035 if (check_date_args(year, month, day) < 0)
4036 return NULL;
4037 if (check_time_args(hour, minute, second, usecond) < 0)
4038 return NULL;
4039 if (check_tzinfo_subclass(tzinfo) < 0)
4040 return NULL;
4041 self = new_datetime_ex(year, month, day,
4042 hour, minute, second, usecond,
4043 tzinfo, type);
4044 }
4045 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004046}
4047
Tim Petersa9bc1682003-01-11 03:39:11 +00004048/* TM_FUNC is the shared type of localtime() and gmtime(). */
4049typedef struct tm *(*TM_FUNC)(const time_t *timer);
4050
4051/* Internal helper.
4052 * Build datetime from a time_t and a distinct count of microseconds.
4053 * Pass localtime or gmtime for f, to control the interpretation of timet.
4054 */
4055static PyObject *
4056datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004057 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004059 struct tm *tm;
4060 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004062 tm = f(&timet);
4063 if (tm) {
4064 /* The platform localtime/gmtime may insert leap seconds,
4065 * indicated by tm->tm_sec > 59. We don't care about them,
4066 * except to the extent that passing them on to the datetime
4067 * constructor would raise ValueError for a reason that
4068 * made no sense to the user.
4069 */
4070 if (tm->tm_sec > 59)
4071 tm->tm_sec = 59;
4072 result = PyObject_CallFunction(cls, "iiiiiiiO",
4073 tm->tm_year + 1900,
4074 tm->tm_mon + 1,
4075 tm->tm_mday,
4076 tm->tm_hour,
4077 tm->tm_min,
4078 tm->tm_sec,
4079 us,
4080 tzinfo);
4081 }
4082 else
4083 PyErr_SetString(PyExc_ValueError,
4084 "timestamp out of range for "
4085 "platform localtime()/gmtime() function");
4086 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004087}
4088
4089/* Internal helper.
4090 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4091 * to control the interpretation of the timestamp. Since a double doesn't
4092 * have enough bits to cover a datetime's full range of precision, it's
4093 * better to call datetime_from_timet_and_us provided you have a way
4094 * to get that much precision (e.g., C time() isn't good enough).
4095 */
4096static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004097datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004098 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004100 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004101 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004102
Victor Stinner5d272cc2012-03-13 13:35:55 +01004103 if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004104 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004105 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004106}
4107
4108/* Internal helper.
4109 * Build most accurate possible datetime for current time. Pass localtime or
4110 * gmtime for f as appropriate.
4111 */
4112static PyObject *
4113datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4114{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004115 _PyTime_timeval t;
4116 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004117 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4118 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004119}
4120
Tim Peters2a799bf2002-12-16 20:18:38 +00004121/* Return best possible local time -- this isn't constrained by the
4122 * precision of a timestamp.
4123 */
4124static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004125datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004127 PyObject *self;
4128 PyObject *tzinfo = Py_None;
4129 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004131 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4132 &tzinfo))
4133 return NULL;
4134 if (check_tzinfo_subclass(tzinfo) < 0)
4135 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004137 self = datetime_best_possible(cls,
4138 tzinfo == Py_None ? localtime : gmtime,
4139 tzinfo);
4140 if (self != NULL && tzinfo != Py_None) {
4141 /* Convert UTC to tzinfo's zone. */
4142 PyObject *temp = self;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004143 _Py_IDENTIFIER(fromutc);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004144
4145 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004146 Py_DECREF(temp);
4147 }
4148 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004149}
4150
Tim Petersa9bc1682003-01-11 03:39:11 +00004151/* Return best possible UTC time -- this isn't constrained by the
4152 * precision of a timestamp.
4153 */
4154static PyObject *
4155datetime_utcnow(PyObject *cls, PyObject *dummy)
4156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004157 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004158}
4159
Tim Peters2a799bf2002-12-16 20:18:38 +00004160/* Return new local datetime from timestamp (Python timestamp -- a double). */
4161static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004162datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004164 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004165 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004166 PyObject *tzinfo = Py_None;
4167 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004168
Victor Stinner5d272cc2012-03-13 13:35:55 +01004169 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004170 keywords, &timestamp, &tzinfo))
4171 return NULL;
4172 if (check_tzinfo_subclass(tzinfo) < 0)
4173 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004175 self = datetime_from_timestamp(cls,
4176 tzinfo == Py_None ? localtime : gmtime,
4177 timestamp,
4178 tzinfo);
4179 if (self != NULL && tzinfo != Py_None) {
4180 /* Convert UTC to tzinfo's zone. */
4181 PyObject *temp = self;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004182 _Py_IDENTIFIER(fromutc);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004183
4184 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004185 Py_DECREF(temp);
4186 }
4187 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004188}
4189
Tim Petersa9bc1682003-01-11 03:39:11 +00004190/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4191static PyObject *
4192datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4193{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004194 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004195 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004196
Victor Stinner5d272cc2012-03-13 13:35:55 +01004197 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004198 result = datetime_from_timestamp(cls, gmtime, timestamp,
4199 Py_None);
4200 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004201}
4202
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004203/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004204static PyObject *
4205datetime_strptime(PyObject *cls, PyObject *args)
4206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004207 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004208 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004209 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004210
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004211 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004212 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004213
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004214 if (module == NULL) {
4215 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004216 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004217 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004218 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004219 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4220 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004221}
4222
Tim Petersa9bc1682003-01-11 03:39:11 +00004223/* Return new datetime from date/datetime and time arguments. */
4224static PyObject *
4225datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4226{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004227 static char *keywords[] = {"date", "time", NULL};
4228 PyObject *date;
4229 PyObject *time;
4230 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4233 &PyDateTime_DateType, &date,
4234 &PyDateTime_TimeType, &time)) {
4235 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004237 if (HASTZINFO(time))
4238 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4239 result = PyObject_CallFunction(cls, "iiiiiiiO",
4240 GET_YEAR(date),
4241 GET_MONTH(date),
4242 GET_DAY(date),
4243 TIME_GET_HOUR(time),
4244 TIME_GET_MINUTE(time),
4245 TIME_GET_SECOND(time),
4246 TIME_GET_MICROSECOND(time),
4247 tzinfo);
4248 }
4249 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004250}
Tim Peters2a799bf2002-12-16 20:18:38 +00004251
4252/*
4253 * Destructor.
4254 */
4255
4256static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004257datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004259 if (HASTZINFO(self)) {
4260 Py_XDECREF(self->tzinfo);
4261 }
4262 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004263}
4264
4265/*
4266 * Indirect access to tzinfo methods.
4267 */
4268
Tim Peters2a799bf2002-12-16 20:18:38 +00004269/* These are all METH_NOARGS, so don't need to check the arglist. */
4270static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004271datetime_utcoffset(PyObject *self, PyObject *unused) {
4272 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004273}
4274
4275static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004276datetime_dst(PyObject *self, PyObject *unused) {
4277 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004278}
4279
4280static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004281datetime_tzname(PyObject *self, PyObject *unused) {
4282 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004283}
4284
4285/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004286 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004287 */
4288
Tim Petersa9bc1682003-01-11 03:39:11 +00004289/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4290 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004291 */
4292static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004293add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004294 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004295{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004296 /* Note that the C-level additions can't overflow, because of
4297 * invariant bounds on the member values.
4298 */
4299 int year = GET_YEAR(date);
4300 int month = GET_MONTH(date);
4301 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4302 int hour = DATE_GET_HOUR(date);
4303 int minute = DATE_GET_MINUTE(date);
4304 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4305 int microsecond = DATE_GET_MICROSECOND(date) +
4306 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004308 assert(factor == 1 || factor == -1);
4309 if (normalize_datetime(&year, &month, &day,
4310 &hour, &minute, &second, &microsecond) < 0)
4311 return NULL;
4312 else
4313 return new_datetime(year, month, day,
4314 hour, minute, second, microsecond,
4315 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004316}
4317
4318static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004319datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004320{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004321 if (PyDateTime_Check(left)) {
4322 /* datetime + ??? */
4323 if (PyDelta_Check(right))
4324 /* datetime + delta */
4325 return add_datetime_timedelta(
4326 (PyDateTime_DateTime *)left,
4327 (PyDateTime_Delta *)right,
4328 1);
4329 }
4330 else if (PyDelta_Check(left)) {
4331 /* delta + datetime */
4332 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4333 (PyDateTime_Delta *) left,
4334 1);
4335 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004336 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004337}
4338
4339static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004340datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004342 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004344 if (PyDateTime_Check(left)) {
4345 /* datetime - ??? */
4346 if (PyDateTime_Check(right)) {
4347 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004348 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004349 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004350
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004351 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4352 offset2 = offset1 = Py_None;
4353 Py_INCREF(offset1);
4354 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004355 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004356 else {
4357 offset1 = datetime_utcoffset(left, NULL);
4358 if (offset1 == NULL)
4359 return NULL;
4360 offset2 = datetime_utcoffset(right, NULL);
4361 if (offset2 == NULL) {
4362 Py_DECREF(offset1);
4363 return NULL;
4364 }
4365 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4366 PyErr_SetString(PyExc_TypeError,
4367 "can't subtract offset-naive and "
4368 "offset-aware datetimes");
4369 Py_DECREF(offset1);
4370 Py_DECREF(offset2);
4371 return NULL;
4372 }
4373 }
4374 if ((offset1 != offset2) &&
4375 delta_cmp(offset1, offset2) != 0) {
4376 offdiff = delta_subtract(offset1, offset2);
4377 if (offdiff == NULL) {
4378 Py_DECREF(offset1);
4379 Py_DECREF(offset2);
4380 return NULL;
4381 }
4382 }
4383 Py_DECREF(offset1);
4384 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004385 delta_d = ymd_to_ord(GET_YEAR(left),
4386 GET_MONTH(left),
4387 GET_DAY(left)) -
4388 ymd_to_ord(GET_YEAR(right),
4389 GET_MONTH(right),
4390 GET_DAY(right));
4391 /* These can't overflow, since the values are
4392 * normalized. At most this gives the number of
4393 * seconds in one day.
4394 */
4395 delta_s = (DATE_GET_HOUR(left) -
4396 DATE_GET_HOUR(right)) * 3600 +
4397 (DATE_GET_MINUTE(left) -
4398 DATE_GET_MINUTE(right)) * 60 +
4399 (DATE_GET_SECOND(left) -
4400 DATE_GET_SECOND(right));
4401 delta_us = DATE_GET_MICROSECOND(left) -
4402 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004403 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004404 if (offdiff != NULL) {
4405 PyObject *temp = result;
4406 result = delta_subtract(result, offdiff);
4407 Py_DECREF(temp);
4408 Py_DECREF(offdiff);
4409 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004410 }
4411 else if (PyDelta_Check(right)) {
4412 /* datetime - delta */
4413 result = add_datetime_timedelta(
4414 (PyDateTime_DateTime *)left,
4415 (PyDateTime_Delta *)right,
4416 -1);
4417 }
4418 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004420 if (result == Py_NotImplemented)
4421 Py_INCREF(result);
4422 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004423}
4424
4425/* Various ways to turn a datetime into a string. */
4426
4427static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004428datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004429{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004430 const char *type_name = Py_TYPE(self)->tp_name;
4431 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004433 if (DATE_GET_MICROSECOND(self)) {
4434 baserepr = PyUnicode_FromFormat(
4435 "%s(%d, %d, %d, %d, %d, %d, %d)",
4436 type_name,
4437 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4438 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4439 DATE_GET_SECOND(self),
4440 DATE_GET_MICROSECOND(self));
4441 }
4442 else if (DATE_GET_SECOND(self)) {
4443 baserepr = PyUnicode_FromFormat(
4444 "%s(%d, %d, %d, %d, %d, %d)",
4445 type_name,
4446 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4447 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4448 DATE_GET_SECOND(self));
4449 }
4450 else {
4451 baserepr = PyUnicode_FromFormat(
4452 "%s(%d, %d, %d, %d, %d)",
4453 type_name,
4454 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4455 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4456 }
4457 if (baserepr == NULL || ! HASTZINFO(self))
4458 return baserepr;
4459 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004460}
4461
Tim Petersa9bc1682003-01-11 03:39:11 +00004462static PyObject *
4463datetime_str(PyDateTime_DateTime *self)
4464{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004465 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004466
4467 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004468}
Tim Peters2a799bf2002-12-16 20:18:38 +00004469
4470static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004471datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004472{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004473 int sep = 'T';
4474 static char *keywords[] = {"sep", NULL};
4475 char buffer[100];
4476 PyObject *result;
4477 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004479 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4480 return NULL;
4481 if (us)
4482 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4483 GET_YEAR(self), GET_MONTH(self),
4484 GET_DAY(self), (int)sep,
4485 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4486 DATE_GET_SECOND(self), us);
4487 else
4488 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4489 GET_YEAR(self), GET_MONTH(self),
4490 GET_DAY(self), (int)sep,
4491 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4492 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004494 if (!result || !HASTZINFO(self))
4495 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004497 /* We need to append the UTC offset. */
4498 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4499 (PyObject *)self) < 0) {
4500 Py_DECREF(result);
4501 return NULL;
4502 }
4503 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4504 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004505}
4506
Tim Petersa9bc1682003-01-11 03:39:11 +00004507static PyObject *
4508datetime_ctime(PyDateTime_DateTime *self)
4509{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004510 return format_ctime((PyDateTime_Date *)self,
4511 DATE_GET_HOUR(self),
4512 DATE_GET_MINUTE(self),
4513 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004514}
4515
Tim Peters2a799bf2002-12-16 20:18:38 +00004516/* Miscellaneous methods. */
4517
Tim Petersa9bc1682003-01-11 03:39:11 +00004518static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004519datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004520{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004521 PyObject *result = NULL;
4522 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004523 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004525 if (! PyDateTime_Check(other)) {
4526 if (PyDate_Check(other)) {
4527 /* Prevent invocation of date_richcompare. We want to
4528 return NotImplemented here to give the other object
4529 a chance. But since DateTime is a subclass of
4530 Date, if the other object is a Date, it would
4531 compute an ordering based on the date part alone,
4532 and we don't want that. So force unequal or
4533 uncomparable here in that case. */
4534 if (op == Py_EQ)
4535 Py_RETURN_FALSE;
4536 if (op == Py_NE)
4537 Py_RETURN_TRUE;
4538 return cmperror(self, other);
4539 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004540 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004541 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004542
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004543 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4545 ((PyDateTime_DateTime *)other)->data,
4546 _PyDateTime_DATETIME_DATASIZE);
4547 return diff_to_bool(diff, op);
4548 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004549 offset1 = datetime_utcoffset(self, NULL);
4550 if (offset1 == NULL)
4551 return NULL;
4552 offset2 = datetime_utcoffset(other, NULL);
4553 if (offset2 == NULL)
4554 goto done;
4555 /* If they're both naive, or both aware and have the same offsets,
4556 * we get off cheap. Note that if they're both naive, offset1 ==
4557 * offset2 == Py_None at this point.
4558 */
4559 if ((offset1 == offset2) ||
4560 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4561 delta_cmp(offset1, offset2) == 0)) {
4562 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4563 ((PyDateTime_DateTime *)other)->data,
4564 _PyDateTime_DATETIME_DATASIZE);
4565 result = diff_to_bool(diff, op);
4566 }
4567 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004568 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004569
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004570 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004571 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4572 other);
4573 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004574 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004575 diff = GET_TD_DAYS(delta);
4576 if (diff == 0)
4577 diff = GET_TD_SECONDS(delta) |
4578 GET_TD_MICROSECONDS(delta);
4579 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004580 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004581 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004582 else {
4583 PyErr_SetString(PyExc_TypeError,
4584 "can't compare offset-naive and "
4585 "offset-aware datetimes");
4586 }
4587 done:
4588 Py_DECREF(offset1);
4589 Py_XDECREF(offset2);
4590 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004591}
4592
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004593static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004594datetime_hash(PyDateTime_DateTime *self)
4595{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004596 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004597 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004598
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004599 offset = datetime_utcoffset((PyObject *)self, NULL);
4600
4601 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004602 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004604 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004605 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004606 self->hashcode = generic_hash(
4607 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004608 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004609 PyObject *temp1, *temp2;
4610 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004612 assert(HASTZINFO(self));
4613 days = ymd_to_ord(GET_YEAR(self),
4614 GET_MONTH(self),
4615 GET_DAY(self));
4616 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004617 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004618 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004619 temp1 = new_delta(days, seconds,
4620 DATE_GET_MICROSECOND(self),
4621 1);
4622 if (temp1 == NULL) {
4623 Py_DECREF(offset);
4624 return -1;
4625 }
4626 temp2 = delta_subtract(temp1, offset);
4627 Py_DECREF(temp1);
4628 if (temp2 == NULL) {
4629 Py_DECREF(offset);
4630 return -1;
4631 }
4632 self->hashcode = PyObject_Hash(temp2);
4633 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004634 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004635 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004636 }
4637 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004638}
Tim Peters2a799bf2002-12-16 20:18:38 +00004639
4640static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004641datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004642{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004643 PyObject *clone;
4644 PyObject *tuple;
4645 int y = GET_YEAR(self);
4646 int m = GET_MONTH(self);
4647 int d = GET_DAY(self);
4648 int hh = DATE_GET_HOUR(self);
4649 int mm = DATE_GET_MINUTE(self);
4650 int ss = DATE_GET_SECOND(self);
4651 int us = DATE_GET_MICROSECOND(self);
4652 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004654 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4655 datetime_kws,
4656 &y, &m, &d, &hh, &mm, &ss, &us,
4657 &tzinfo))
4658 return NULL;
4659 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4660 if (tuple == NULL)
4661 return NULL;
4662 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4663 Py_DECREF(tuple);
4664 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004665}
4666
4667static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004668datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004669{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004670 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004671 PyObject *offset;
4672 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004673 PyObject *tzinfo;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004674 _Py_IDENTIFIER(fromutc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004675 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004677 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4678 &PyDateTime_TZInfoType, &tzinfo))
4679 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4682 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004684 /* Conversion to self's own time zone is a NOP. */
4685 if (self->tzinfo == tzinfo) {
4686 Py_INCREF(self);
4687 return (PyObject *)self;
4688 }
Tim Peters521fc152002-12-31 17:36:56 +00004689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004690 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004691 offset = datetime_utcoffset((PyObject *)self, NULL);
4692 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004693 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004694 if (offset == Py_None) {
4695 Py_DECREF(offset);
4696 NeedAware:
4697 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4698 "a naive datetime");
4699 return NULL;
4700 }
Tim Petersf3615152003-01-01 21:51:37 +00004701
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004702 /* result = self - offset */
4703 result = add_datetime_timedelta(self,
4704 (PyDateTime_Delta *)offset, -1);
4705 Py_DECREF(offset);
4706 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004707 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004709 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004710 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4711 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4712 Py_INCREF(tzinfo);
4713 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004714
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004715 temp = result;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004716 result = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004717 Py_DECREF(temp);
4718
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004719 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004720}
4721
4722static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004723datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004725 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004727 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004728 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004729
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004730 dst = call_dst(self->tzinfo, (PyObject *)self);
4731 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004732 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004733
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004734 if (dst != Py_None)
4735 dstflag = delta_bool((PyDateTime_Delta *)dst);
4736 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004737 }
4738 return build_struct_time(GET_YEAR(self),
4739 GET_MONTH(self),
4740 GET_DAY(self),
4741 DATE_GET_HOUR(self),
4742 DATE_GET_MINUTE(self),
4743 DATE_GET_SECOND(self),
4744 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004745}
4746
4747static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004748datetime_getdate(PyDateTime_DateTime *self)
4749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004750 return new_date(GET_YEAR(self),
4751 GET_MONTH(self),
4752 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004753}
4754
4755static PyObject *
4756datetime_gettime(PyDateTime_DateTime *self)
4757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004758 return new_time(DATE_GET_HOUR(self),
4759 DATE_GET_MINUTE(self),
4760 DATE_GET_SECOND(self),
4761 DATE_GET_MICROSECOND(self),
4762 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004763}
4764
4765static PyObject *
4766datetime_gettimetz(PyDateTime_DateTime *self)
4767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004768 return new_time(DATE_GET_HOUR(self),
4769 DATE_GET_MINUTE(self),
4770 DATE_GET_SECOND(self),
4771 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004772 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004773}
4774
4775static PyObject *
4776datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004777{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004778 int y, m, d, hh, mm, ss;
4779 PyObject *tzinfo;
4780 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004781
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004782 tzinfo = GET_DT_TZINFO(self);
4783 if (tzinfo == Py_None) {
4784 utcself = self;
4785 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004786 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004787 else {
4788 PyObject *offset;
4789 offset = call_utcoffset(tzinfo, (PyObject *)self);
4790 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004791 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004792 if (offset == Py_None) {
4793 Py_DECREF(offset);
4794 utcself = self;
4795 Py_INCREF(utcself);
4796 }
4797 else {
4798 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4799 (PyDateTime_Delta *)offset, -1);
4800 Py_DECREF(offset);
4801 if (utcself == NULL)
4802 return NULL;
4803 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004804 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004805 y = GET_YEAR(utcself);
4806 m = GET_MONTH(utcself);
4807 d = GET_DAY(utcself);
4808 hh = DATE_GET_HOUR(utcself);
4809 mm = DATE_GET_MINUTE(utcself);
4810 ss = DATE_GET_SECOND(utcself);
4811
4812 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004813 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004814}
4815
Tim Peters371935f2003-02-01 01:52:50 +00004816/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004817
Tim Petersa9bc1682003-01-11 03:39:11 +00004818/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004819 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4820 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004821 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004822 */
4823static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004824datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004826 PyObject *basestate;
4827 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004829 basestate = PyBytes_FromStringAndSize((char *)self->data,
4830 _PyDateTime_DATETIME_DATASIZE);
4831 if (basestate != NULL) {
4832 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4833 result = PyTuple_Pack(1, basestate);
4834 else
4835 result = PyTuple_Pack(2, basestate, self->tzinfo);
4836 Py_DECREF(basestate);
4837 }
4838 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004839}
4840
4841static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004842datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004843{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004844 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004845}
4846
Tim Petersa9bc1682003-01-11 03:39:11 +00004847static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004849 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004851 {"now", (PyCFunction)datetime_now,
4852 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4853 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004855 {"utcnow", (PyCFunction)datetime_utcnow,
4856 METH_NOARGS | METH_CLASS,
4857 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004859 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4860 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4861 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004863 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4864 METH_VARARGS | METH_CLASS,
4865 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4866 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004868 {"strptime", (PyCFunction)datetime_strptime,
4869 METH_VARARGS | METH_CLASS,
4870 PyDoc_STR("string, format -> new datetime parsed from a string "
4871 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004873 {"combine", (PyCFunction)datetime_combine,
4874 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4875 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004877 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004879 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4880 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4883 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004885 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4886 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004888 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4889 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004891 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4892 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004894 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4895 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004897 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4898 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4899 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4900 "sep is used to separate the year from the time, and "
4901 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004903 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4904 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004906 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4907 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004909 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4910 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004912 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4913 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004915 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4916 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004918 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4919 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004921 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004922};
4923
Tim Petersa9bc1682003-01-11 03:39:11 +00004924static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004925PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4926\n\
4927The year, month and day arguments are required. tzinfo may be None, or an\n\
4928instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004929
Tim Petersa9bc1682003-01-11 03:39:11 +00004930static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004931 datetime_add, /* nb_add */
4932 datetime_subtract, /* nb_subtract */
4933 0, /* nb_multiply */
4934 0, /* nb_remainder */
4935 0, /* nb_divmod */
4936 0, /* nb_power */
4937 0, /* nb_negative */
4938 0, /* nb_positive */
4939 0, /* nb_absolute */
4940 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004941};
4942
Neal Norwitz227b5332006-03-22 09:28:35 +00004943static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004944 PyVarObject_HEAD_INIT(NULL, 0)
4945 "datetime.datetime", /* tp_name */
4946 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4947 0, /* tp_itemsize */
4948 (destructor)datetime_dealloc, /* tp_dealloc */
4949 0, /* tp_print */
4950 0, /* tp_getattr */
4951 0, /* tp_setattr */
4952 0, /* tp_reserved */
4953 (reprfunc)datetime_repr, /* tp_repr */
4954 &datetime_as_number, /* tp_as_number */
4955 0, /* tp_as_sequence */
4956 0, /* tp_as_mapping */
4957 (hashfunc)datetime_hash, /* tp_hash */
4958 0, /* tp_call */
4959 (reprfunc)datetime_str, /* tp_str */
4960 PyObject_GenericGetAttr, /* tp_getattro */
4961 0, /* tp_setattro */
4962 0, /* tp_as_buffer */
4963 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4964 datetime_doc, /* tp_doc */
4965 0, /* tp_traverse */
4966 0, /* tp_clear */
4967 datetime_richcompare, /* tp_richcompare */
4968 0, /* tp_weaklistoffset */
4969 0, /* tp_iter */
4970 0, /* tp_iternext */
4971 datetime_methods, /* tp_methods */
4972 0, /* tp_members */
4973 datetime_getset, /* tp_getset */
4974 &PyDateTime_DateType, /* tp_base */
4975 0, /* tp_dict */
4976 0, /* tp_descr_get */
4977 0, /* tp_descr_set */
4978 0, /* tp_dictoffset */
4979 0, /* tp_init */
4980 datetime_alloc, /* tp_alloc */
4981 datetime_new, /* tp_new */
4982 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004983};
4984
4985/* ---------------------------------------------------------------------------
4986 * Module methods and initialization.
4987 */
4988
4989static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004990 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004991};
4992
Tim Peters9ddf40b2004-06-20 22:41:32 +00004993/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4994 * datetime.h.
4995 */
4996static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004997 &PyDateTime_DateType,
4998 &PyDateTime_DateTimeType,
4999 &PyDateTime_TimeType,
5000 &PyDateTime_DeltaType,
5001 &PyDateTime_TZInfoType,
5002 new_date_ex,
5003 new_datetime_ex,
5004 new_time_ex,
5005 new_delta_ex,
5006 datetime_fromtimestamp,
5007 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005008};
5009
5010
Martin v. Löwis1a214512008-06-11 05:26:20 +00005011
5012static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005013 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005014 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005015 "Fast implementation of the datetime type.",
5016 -1,
5017 module_methods,
5018 NULL,
5019 NULL,
5020 NULL,
5021 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005022};
5023
Tim Peters2a799bf2002-12-16 20:18:38 +00005024PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005025PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005026{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005027 PyObject *m; /* a module object */
5028 PyObject *d; /* its dict */
5029 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005030 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005032 m = PyModule_Create(&datetimemodule);
5033 if (m == NULL)
5034 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005036 if (PyType_Ready(&PyDateTime_DateType) < 0)
5037 return NULL;
5038 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5039 return NULL;
5040 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5041 return NULL;
5042 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5043 return NULL;
5044 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5045 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005046 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5047 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005049 /* timedelta values */
5050 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005052 x = new_delta(0, 0, 1, 0);
5053 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5054 return NULL;
5055 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005057 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5058 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5059 return NULL;
5060 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005062 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5063 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5064 return NULL;
5065 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005067 /* date values */
5068 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005070 x = new_date(1, 1, 1);
5071 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5072 return NULL;
5073 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005075 x = new_date(MAXYEAR, 12, 31);
5076 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5077 return NULL;
5078 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005080 x = new_delta(1, 0, 0, 0);
5081 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5082 return NULL;
5083 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005085 /* time values */
5086 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005088 x = new_time(0, 0, 0, 0, Py_None);
5089 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5090 return NULL;
5091 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005093 x = new_time(23, 59, 59, 999999, Py_None);
5094 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5095 return NULL;
5096 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005098 x = new_delta(0, 0, 1, 0);
5099 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5100 return NULL;
5101 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005103 /* datetime values */
5104 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005106 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5107 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5108 return NULL;
5109 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005111 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5112 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5113 return NULL;
5114 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005116 x = new_delta(0, 0, 1, 0);
5117 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5118 return NULL;
5119 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005120
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005121 /* timezone values */
5122 d = PyDateTime_TimeZoneType.tp_dict;
5123
5124 delta = new_delta(0, 0, 0, 0);
5125 if (delta == NULL)
5126 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005127 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005128 Py_DECREF(delta);
5129 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5130 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005131 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005132
5133 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5134 if (delta == NULL)
5135 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005136 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005137 Py_DECREF(delta);
5138 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5139 return NULL;
5140 Py_DECREF(x);
5141
5142 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5143 if (delta == NULL)
5144 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005145 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005146 Py_DECREF(delta);
5147 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5148 return NULL;
5149 Py_DECREF(x);
5150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005151 /* module initialization */
5152 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5153 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005155 Py_INCREF(&PyDateTime_DateType);
5156 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005158 Py_INCREF(&PyDateTime_DateTimeType);
5159 PyModule_AddObject(m, "datetime",
5160 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005162 Py_INCREF(&PyDateTime_TimeType);
5163 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005165 Py_INCREF(&PyDateTime_DeltaType);
5166 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005168 Py_INCREF(&PyDateTime_TZInfoType);
5169 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005170
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005171 Py_INCREF(&PyDateTime_TimeZoneType);
5172 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005174 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5175 if (x == NULL)
5176 return NULL;
5177 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005179 /* A 4-year cycle has an extra leap day over what we'd get from
5180 * pasting together 4 single years.
5181 */
5182 assert(DI4Y == 4 * 365 + 1);
5183 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005185 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5186 * get from pasting together 4 100-year cycles.
5187 */
5188 assert(DI400Y == 4 * DI100Y + 1);
5189 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005191 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5192 * pasting together 25 4-year cycles.
5193 */
5194 assert(DI100Y == 25 * DI4Y - 1);
5195 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005197 us_per_us = PyLong_FromLong(1);
5198 us_per_ms = PyLong_FromLong(1000);
5199 us_per_second = PyLong_FromLong(1000000);
5200 us_per_minute = PyLong_FromLong(60000000);
5201 seconds_per_day = PyLong_FromLong(24 * 3600);
5202 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5203 us_per_minute == NULL || seconds_per_day == NULL)
5204 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005206 /* The rest are too big for 32-bit ints, but even
5207 * us_per_week fits in 40 bits, so doubles should be exact.
5208 */
5209 us_per_hour = PyLong_FromDouble(3600000000.0);
5210 us_per_day = PyLong_FromDouble(86400000000.0);
5211 us_per_week = PyLong_FromDouble(604800000000.0);
5212 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5213 return NULL;
5214 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005215}
Tim Petersf3615152003-01-01 21:51:37 +00005216
5217/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005218Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005219 x.n = x stripped of its timezone -- its naive time.
5220 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005221 return None
Tim Petersf3615152003-01-01 21:51:37 +00005222 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005223 return None
Tim Petersf3615152003-01-01 21:51:37 +00005224 x.s = x's standard offset, x.o - x.d
5225
5226Now some derived rules, where k is a duration (timedelta).
5227
52281. x.o = x.s + x.d
5229 This follows from the definition of x.s.
5230
Tim Petersc5dc4da2003-01-02 17:55:03 +000052312. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005232 This is actually a requirement, an assumption we need to make about
5233 sane tzinfo classes.
5234
52353. The naive UTC time corresponding to x is x.n - x.o.
5236 This is again a requirement for a sane tzinfo class.
5237
52384. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005239 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005240
Tim Petersc5dc4da2003-01-02 17:55:03 +000052415. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005242 Again follows from how arithmetic is defined.
5243
Tim Peters8bb5ad22003-01-24 02:44:45 +00005244Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005245(meaning that the various tzinfo methods exist, and don't blow up or return
5246None when called).
5247
Tim Petersa9bc1682003-01-11 03:39:11 +00005248The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005249x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005250
5251By #3, we want
5252
Tim Peters8bb5ad22003-01-24 02:44:45 +00005253 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005254
5255The algorithm starts by attaching tz to x.n, and calling that y. So
5256x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5257becomes true; in effect, we want to solve [2] for k:
5258
Tim Peters8bb5ad22003-01-24 02:44:45 +00005259 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005260
5261By #1, this is the same as
5262
Tim Peters8bb5ad22003-01-24 02:44:45 +00005263 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005264
5265By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5266Substituting that into [3],
5267
Tim Peters8bb5ad22003-01-24 02:44:45 +00005268 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5269 k - (y+k).s - (y+k).d = 0; rearranging,
5270 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5271 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005272
Tim Peters8bb5ad22003-01-24 02:44:45 +00005273On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5274approximate k by ignoring the (y+k).d term at first. Note that k can't be
5275very large, since all offset-returning methods return a duration of magnitude
5276less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5277be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005278
5279In any case, the new value is
5280
Tim Peters8bb5ad22003-01-24 02:44:45 +00005281 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005282
Tim Peters8bb5ad22003-01-24 02:44:45 +00005283It's helpful to step back at look at [4] from a higher level: it's simply
5284mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005285
5286At this point, if
5287
Tim Peters8bb5ad22003-01-24 02:44:45 +00005288 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005289
5290we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005291at the start of daylight time. Picture US Eastern for concreteness. The wall
5292time 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 +00005293sense then. The docs ask that an Eastern tzinfo class consider such a time to
5294be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5295on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005296the only spelling that makes sense on the local wall clock.
5297
Tim Petersc5dc4da2003-01-02 17:55:03 +00005298In fact, if [5] holds at this point, we do have the standard-time spelling,
5299but that takes a bit of proof. We first prove a stronger result. What's the
5300difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005301
Tim Peters8bb5ad22003-01-24 02:44:45 +00005302 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005303
Tim Petersc5dc4da2003-01-02 17:55:03 +00005304Now
5305 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005306 (y + y.s).n = by #5
5307 y.n + y.s = since y.n = x.n
5308 x.n + y.s = since z and y are have the same tzinfo member,
5309 y.s = z.s by #2
5310 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005311
Tim Petersc5dc4da2003-01-02 17:55:03 +00005312Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005313
Tim Petersc5dc4da2003-01-02 17:55:03 +00005314 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005315 x.n - ((x.n + z.s) - z.o) = expanding
5316 x.n - x.n - z.s + z.o = cancelling
5317 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005318 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005319
Tim Petersc5dc4da2003-01-02 17:55:03 +00005320So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005321
Tim Petersc5dc4da2003-01-02 17:55:03 +00005322If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005323spelling we wanted in the endcase described above. We're done. Contrarily,
5324if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005325
Tim Petersc5dc4da2003-01-02 17:55:03 +00005326If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5327add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005328local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005329
Tim Petersc5dc4da2003-01-02 17:55:03 +00005330Let
Tim Petersf3615152003-01-01 21:51:37 +00005331
Tim Peters4fede1a2003-01-04 00:26:59 +00005332 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005333
Tim Peters4fede1a2003-01-04 00:26:59 +00005334and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005335
Tim Peters8bb5ad22003-01-24 02:44:45 +00005336 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005337
Tim Peters8bb5ad22003-01-24 02:44:45 +00005338If so, we're done. If not, the tzinfo class is insane, according to the
5339assumptions we've made. This also requires a bit of proof. As before, let's
5340compute the difference between the LHS and RHS of [8] (and skipping some of
5341the justifications for the kinds of substitutions we've done several times
5342already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005343
Tim Peters8bb5ad22003-01-24 02:44:45 +00005344 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005345 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5346 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5347 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5348 - z.n + z.n - z.o + z'.o = cancel z.n
5349 - z.o + z'.o = #1 twice
5350 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5351 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005352
5353So 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 +00005354we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5355return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005356
Tim Peters8bb5ad22003-01-24 02:44:45 +00005357How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5358a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5359would have to change the result dst() returns: we start in DST, and moving
5360a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005361
Tim Peters8bb5ad22003-01-24 02:44:45 +00005362There isn't a sane case where this can happen. The closest it gets is at
5363the end of DST, where there's an hour in UTC with no spelling in a hybrid
5364tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5365that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5366UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5367time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5368clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5369standard time. Since that's what the local clock *does*, we want to map both
5370UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005371in local time, but so it goes -- it's the way the local clock works.
5372
Tim Peters8bb5ad22003-01-24 02:44:45 +00005373When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5374so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5375z' = 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 +00005376(correctly) concludes that z' is not UTC-equivalent to x.
5377
5378Because we know z.d said z was in daylight time (else [5] would have held and
5379we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005380and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005381return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5382but the reasoning doesn't depend on the example -- it depends on there being
5383two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005384z' must be in standard time, and is the spelling we want in this case.
5385
5386Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5387concerned (because it takes z' as being in standard time rather than the
5388daylight time we intend here), but returning it gives the real-life "local
5389clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5390tz.
5391
5392When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5393the 1:MM standard time spelling we want.
5394
5395So how can this break? One of the assumptions must be violated. Two
5396possibilities:
5397
53981) [2] effectively says that y.s is invariant across all y belong to a given
5399 time zone. This isn't true if, for political reasons or continental drift,
5400 a region decides to change its base offset from UTC.
5401
54022) There may be versions of "double daylight" time where the tail end of
5403 the analysis gives up a step too early. I haven't thought about that
5404 enough to say.
5405
5406In any case, it's clear that the default fromutc() is strong enough to handle
5407"almost all" time zones: so long as the standard offset is invariant, it
5408doesn't matter if daylight time transition points change from year to year, or
5409if daylight time is skipped in some years; it doesn't matter how large or
5410small dst() may get within its bounds; and it doesn't even matter if some
5411perverse time zone returns a negative dst()). So a breaking case must be
5412pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005413--------------------------------------------------------------------------- */