blob: d3a502db91fe9b7a6224baac4cc657649db65b50 [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 Belopolskya4415142012-06-08 12:33:09 -0400769/* The interned Epoch datetime instance */
770static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000771
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000772/* Create new timezone instance checking offset range. This
773 function does not check the name argument. Caller must assure
774 that offset is a timedelta instance and name is either NULL
775 or a unicode object. */
776static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000777create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000778{
779 PyDateTime_TimeZone *self;
780 PyTypeObject *type = &PyDateTime_TimeZoneType;
781
782 assert(offset != NULL);
783 assert(PyDelta_Check(offset));
784 assert(name == NULL || PyUnicode_Check(name));
785
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000786 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
787 if (self == NULL) {
788 return NULL;
789 }
790 Py_INCREF(offset);
791 self->offset = offset;
792 Py_XINCREF(name);
793 self->name = name;
794 return (PyObject *)self;
795}
796
797static int delta_bool(PyDateTime_Delta *self);
798
799static PyObject *
800new_timezone(PyObject *offset, PyObject *name)
801{
802 assert(offset != NULL);
803 assert(PyDelta_Check(offset));
804 assert(name == NULL || PyUnicode_Check(name));
805
806 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
807 Py_INCREF(PyDateTime_TimeZone_UTC);
808 return PyDateTime_TimeZone_UTC;
809 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000810 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
811 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
812 " representing a whole number of minutes");
813 return NULL;
814 }
815 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
816 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
817 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
818 " strictly between -timedelta(hours=24) and"
819 " timedelta(hours=24).");
820 return NULL;
821 }
822
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000823 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000824}
825
Tim Petersb0c854d2003-05-17 15:57:00 +0000826/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000827 * tzinfo helpers.
828 */
829
Tim Peters855fe882002-12-22 03:43:39 +0000830/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
831 * raise TypeError and return -1.
832 */
833static int
834check_tzinfo_subclass(PyObject *p)
835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 if (p == Py_None || PyTZInfo_Check(p))
837 return 0;
838 PyErr_Format(PyExc_TypeError,
839 "tzinfo argument must be None or of a tzinfo subclass, "
840 "not type '%s'",
841 Py_TYPE(p)->tp_name);
842 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000843}
844
Tim Peters2a799bf2002-12-16 20:18:38 +0000845/* If self has a tzinfo member, return a BORROWED reference to it. Else
846 * return NULL, which is NOT AN ERROR. There are no error returns here,
847 * and the caller must not decref the result.
848 */
849static PyObject *
850get_tzinfo_member(PyObject *self)
851{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 if (PyDateTime_Check(self) && HASTZINFO(self))
855 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
856 else if (PyTime_Check(self) && HASTZINFO(self))
857 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000860}
861
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000862/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
863 * be an instance of the tzinfo class. If the method returns None, this
864 * returns None. If the method doesn't return None or timedelta, TypeError is
865 * raised and this returns NULL. If it returns a timedelta and the value is
866 * out of range or isn't a whole number of minutes, ValueError is raised and
867 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000868 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000869static PyObject *
870call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000871{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000872 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000875 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000877
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000878 if (tzinfo == Py_None)
879 Py_RETURN_NONE;
880 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
881 if (offset == Py_None || offset == NULL)
882 return offset;
883 if (PyDelta_Check(offset)) {
884 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
885 Py_DECREF(offset);
886 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
887 " representing a whole number of minutes");
888 return NULL;
889 }
890 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
891 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
892 Py_DECREF(offset);
893 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
894 " strictly between -timedelta(hours=24) and"
895 " timedelta(hours=24).");
896 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 }
898 }
899 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000900 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 PyErr_Format(PyExc_TypeError,
902 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000903 "timedelta, not '%.200s'",
904 name, Py_TYPE(offset)->tp_name);
905 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000907
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000908 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000909}
910
911/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
912 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
913 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000914 * doesn't return None or timedelta, TypeError is raised and this returns -1.
915 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
916 * # of minutes), ValueError is raised and this returns -1. Else *none is
917 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000918 */
Tim Peters855fe882002-12-22 03:43:39 +0000919static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000920call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
921{
922 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000923}
924
Tim Peters2a799bf2002-12-16 20:18:38 +0000925/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
926 * result. tzinfo must be an instance of the tzinfo class. If dst()
927 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000928 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000929 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000930 * ValueError is raised and this returns -1. Else *none is set to 0 and
931 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000932 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000933static PyObject *
934call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000935{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000936 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000937}
938
Tim Petersbad8ff02002-12-30 20:52:32 +0000939/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000940 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000941 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000942 * returns NULL. If the result is a string, we ensure it is a Unicode
943 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000944 */
945static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000946call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200949 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 assert(tzinfo != NULL);
952 assert(check_tzinfo_subclass(tzinfo) >= 0);
953 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000956 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000957
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200958 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000959
960 if (result == NULL || result == Py_None)
961 return result;
962
963 if (!PyUnicode_Check(result)) {
964 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
965 "return None or a string, not '%s'",
966 Py_TYPE(result)->tp_name);
967 Py_DECREF(result);
968 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000970
971 return result;
Tim Peters00237032002-12-27 02:21:51 +0000972}
973
Tim Peters2a799bf2002-12-16 20:18:38 +0000974/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
975 * stuff
976 * ", tzinfo=" + repr(tzinfo)
977 * before the closing ")".
978 */
979static PyObject *
980append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 assert(PyUnicode_Check(repr));
985 assert(tzinfo);
986 if (tzinfo == Py_None)
987 return repr;
988 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200989 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
990 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 Py_DECREF(repr);
992 if (temp == NULL)
993 return NULL;
994 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
995 Py_DECREF(temp);
996 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +0000997}
998
999/* ---------------------------------------------------------------------------
1000 * String format helpers.
1001 */
1002
1003static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001004format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 static const char *DayNames[] = {
1007 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1008 };
1009 static const char *MonthNames[] = {
1010 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1011 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1012 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1017 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1018 GET_DAY(date), hours, minutes, seconds,
1019 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001020}
1021
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001022static PyObject *delta_negative(PyDateTime_Delta *self);
1023
Tim Peters2a799bf2002-12-16 20:18:38 +00001024/* Add an hours & minutes UTC offset string to buf. buf has no more than
1025 * buflen bytes remaining. The UTC offset is gotten by calling
1026 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1027 * *buf, and that's all. Else the returned value is checked for sanity (an
1028 * integer in range), and if that's OK it's converted to an hours & minutes
1029 * string of the form
1030 * sign HH sep MM
1031 * Returns 0 if everything is OK. If the return value from utcoffset() is
1032 * bogus, an appropriate exception is set and -1 is returned.
1033 */
1034static int
Tim Peters328fff72002-12-20 01:31:27 +00001035format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001037{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001038 PyObject *offset;
1039 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001043
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001044 offset = call_utcoffset(tzinfo, tzinfoarg);
1045 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001047 if (offset == Py_None) {
1048 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 *buf = '\0';
1050 return 0;
1051 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001052 /* Offset is normalized, so it is negative if days < 0 */
1053 if (GET_TD_DAYS(offset) < 0) {
1054 PyObject *temp = offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 sign = '-';
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001056 offset = delta_negative((PyDateTime_Delta *)offset);
1057 Py_DECREF(temp);
1058 if (offset == NULL)
1059 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001061 else {
1062 sign = '+';
1063 }
1064 /* Offset is not negative here. */
1065 seconds = GET_TD_SECONDS(offset);
1066 Py_DECREF(offset);
1067 minutes = divmod(seconds, 60, &seconds);
1068 hours = divmod(minutes, 60, &minutes);
1069 assert(seconds == 0);
1070 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001074}
1075
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001076static PyObject *
1077make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 PyObject *temp;
1080 PyObject *tzinfo = get_tzinfo_member(object);
1081 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001082 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 if (Zreplacement == NULL)
1085 return NULL;
1086 if (tzinfo == Py_None || tzinfo == NULL)
1087 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 assert(tzinfoarg != NULL);
1090 temp = call_tzname(tzinfo, tzinfoarg);
1091 if (temp == NULL)
1092 goto Error;
1093 if (temp == Py_None) {
1094 Py_DECREF(temp);
1095 return Zreplacement;
1096 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 assert(PyUnicode_Check(temp));
1099 /* Since the tzname is getting stuffed into the
1100 * format, we have to double any % signs so that
1101 * strftime doesn't treat them as format codes.
1102 */
1103 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001104 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 Py_DECREF(temp);
1106 if (Zreplacement == NULL)
1107 return NULL;
1108 if (!PyUnicode_Check(Zreplacement)) {
1109 PyErr_SetString(PyExc_TypeError,
1110 "tzname.replace() did not return a string");
1111 goto Error;
1112 }
1113 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001114
1115 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 Py_DECREF(Zreplacement);
1117 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001118}
1119
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001120static PyObject *
1121make_freplacement(PyObject *object)
1122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 char freplacement[64];
1124 if (PyTime_Check(object))
1125 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1126 else if (PyDateTime_Check(object))
1127 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1128 else
1129 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001132}
1133
Tim Peters2a799bf2002-12-16 20:18:38 +00001134/* I sure don't want to reproduce the strftime code from the time module,
1135 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001136 * giving special meanings to the %z, %Z and %f format codes via a
1137 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001138 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1139 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001140 */
1141static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001142wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1148 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1149 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 const char *pin; /* pointer to next char in input format */
1152 Py_ssize_t flen; /* length of input format */
1153 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 PyObject *newfmt = NULL; /* py string, the output format */
1156 char *pnew; /* pointer to available byte in output format */
1157 size_t totalnew; /* number bytes total in output format buffer,
1158 exclusive of trailing \0 */
1159 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 const char *ptoappend; /* ptr to string to append to output buffer */
1162 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 assert(object && format && timetuple);
1165 assert(PyUnicode_Check(format));
1166 /* Convert the input format to a C string and size */
1167 pin = _PyUnicode_AsStringAndSize(format, &flen);
1168 if (!pin)
1169 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 /* Scan the input format, looking for %z/%Z/%f escapes, building
1172 * a new format. Since computing the replacements for those codes
1173 * is expensive, don't unless they're actually used.
1174 */
1175 if (flen > INT_MAX - 1) {
1176 PyErr_NoMemory();
1177 goto Done;
1178 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 totalnew = flen + 1; /* realistic if no %z/%Z */
1181 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1182 if (newfmt == NULL) goto Done;
1183 pnew = PyBytes_AsString(newfmt);
1184 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 while ((ch = *pin++) != '\0') {
1187 if (ch != '%') {
1188 ptoappend = pin - 1;
1189 ntoappend = 1;
1190 }
1191 else if ((ch = *pin++) == '\0') {
1192 /* There's a lone trailing %; doesn't make sense. */
1193 PyErr_SetString(PyExc_ValueError, "strftime format "
1194 "ends with raw %");
1195 goto Done;
1196 }
1197 /* A % has been seen and ch is the character after it. */
1198 else if (ch == 'z') {
1199 if (zreplacement == NULL) {
1200 /* format utcoffset */
1201 char buf[100];
1202 PyObject *tzinfo = get_tzinfo_member(object);
1203 zreplacement = PyBytes_FromStringAndSize("", 0);
1204 if (zreplacement == NULL) goto Done;
1205 if (tzinfo != Py_None && tzinfo != NULL) {
1206 assert(tzinfoarg != NULL);
1207 if (format_utcoffset(buf,
1208 sizeof(buf),
1209 "",
1210 tzinfo,
1211 tzinfoarg) < 0)
1212 goto Done;
1213 Py_DECREF(zreplacement);
1214 zreplacement =
1215 PyBytes_FromStringAndSize(buf,
1216 strlen(buf));
1217 if (zreplacement == NULL)
1218 goto Done;
1219 }
1220 }
1221 assert(zreplacement != NULL);
1222 ptoappend = PyBytes_AS_STRING(zreplacement);
1223 ntoappend = PyBytes_GET_SIZE(zreplacement);
1224 }
1225 else if (ch == 'Z') {
1226 /* format tzname */
1227 if (Zreplacement == NULL) {
1228 Zreplacement = make_Zreplacement(object,
1229 tzinfoarg);
1230 if (Zreplacement == NULL)
1231 goto Done;
1232 }
1233 assert(Zreplacement != NULL);
1234 assert(PyUnicode_Check(Zreplacement));
1235 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1236 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001237 if (ptoappend == NULL)
1238 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 }
1240 else if (ch == 'f') {
1241 /* format microseconds */
1242 if (freplacement == NULL) {
1243 freplacement = make_freplacement(object);
1244 if (freplacement == NULL)
1245 goto Done;
1246 }
1247 assert(freplacement != NULL);
1248 assert(PyBytes_Check(freplacement));
1249 ptoappend = PyBytes_AS_STRING(freplacement);
1250 ntoappend = PyBytes_GET_SIZE(freplacement);
1251 }
1252 else {
1253 /* percent followed by neither z nor Z */
1254 ptoappend = pin - 2;
1255 ntoappend = 2;
1256 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 /* Append the ntoappend chars starting at ptoappend to
1259 * the new format.
1260 */
1261 if (ntoappend == 0)
1262 continue;
1263 assert(ptoappend != NULL);
1264 assert(ntoappend > 0);
1265 while (usednew + ntoappend > totalnew) {
1266 size_t bigger = totalnew << 1;
1267 if ((bigger >> 1) != totalnew) { /* overflow */
1268 PyErr_NoMemory();
1269 goto Done;
1270 }
1271 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1272 goto Done;
1273 totalnew = bigger;
1274 pnew = PyBytes_AsString(newfmt) + usednew;
1275 }
1276 memcpy(pnew, ptoappend, ntoappend);
1277 pnew += ntoappend;
1278 usednew += ntoappend;
1279 assert(usednew <= totalnew);
1280 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1283 goto Done;
1284 {
1285 PyObject *format;
1286 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 if (time == NULL)
1289 goto Done;
1290 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1291 if (format != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001292 _Py_IDENTIFIER(strftime);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001293
1294 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1295 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 Py_DECREF(format);
1297 }
1298 Py_DECREF(time);
1299 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001300 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 Py_XDECREF(freplacement);
1302 Py_XDECREF(zreplacement);
1303 Py_XDECREF(Zreplacement);
1304 Py_XDECREF(newfmt);
1305 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001306}
1307
Tim Peters2a799bf2002-12-16 20:18:38 +00001308/* ---------------------------------------------------------------------------
1309 * Wrap functions from the time module. These aren't directly available
1310 * from C. Perhaps they should be.
1311 */
1312
1313/* Call time.time() and return its result (a Python float). */
1314static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001315time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 PyObject *result = NULL;
1318 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001321 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001322
1323 result = _PyObject_CallMethodId(time, &PyId_time, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 Py_DECREF(time);
1325 }
1326 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001327}
1328
1329/* Build a time.struct_time. The weekday and day number are automatically
1330 * computed from the y,m,d args.
1331 */
1332static PyObject *
1333build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 PyObject *time;
1336 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 time = PyImport_ImportModuleNoBlock("time");
1339 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001340 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001341
1342 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1343 "((iiiiiiiii))",
1344 y, m, d,
1345 hh, mm, ss,
1346 weekday(y, m, d),
1347 days_before_month(y, m) + d,
1348 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 Py_DECREF(time);
1350 }
1351 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001352}
1353
1354/* ---------------------------------------------------------------------------
1355 * Miscellaneous helpers.
1356 */
1357
Mark Dickinsone94c6792009-02-02 20:36:42 +00001358/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001359 * The comparisons here all most naturally compute a cmp()-like result.
1360 * This little helper turns that into a bool result for rich comparisons.
1361 */
1362static PyObject *
1363diff_to_bool(int diff, int op)
1364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 PyObject *result;
1366 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 switch (op) {
1369 case Py_EQ: istrue = diff == 0; break;
1370 case Py_NE: istrue = diff != 0; break;
1371 case Py_LE: istrue = diff <= 0; break;
1372 case Py_GE: istrue = diff >= 0; break;
1373 case Py_LT: istrue = diff < 0; break;
1374 case Py_GT: istrue = diff > 0; break;
1375 default:
1376 assert(! "op unknown");
1377 istrue = 0; /* To shut up compiler */
1378 }
1379 result = istrue ? Py_True : Py_False;
1380 Py_INCREF(result);
1381 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001382}
1383
Tim Peters07534a62003-02-07 22:50:28 +00001384/* Raises a "can't compare" TypeError and returns NULL. */
1385static PyObject *
1386cmperror(PyObject *a, PyObject *b)
1387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 PyErr_Format(PyExc_TypeError,
1389 "can't compare %s to %s",
1390 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1391 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001392}
1393
Tim Peters2a799bf2002-12-16 20:18:38 +00001394/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001395 * Cached Python objects; these are set by the module init function.
1396 */
1397
1398/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399static PyObject *us_per_us = NULL; /* 1 */
1400static PyObject *us_per_ms = NULL; /* 1000 */
1401static PyObject *us_per_second = NULL; /* 1000000 */
1402static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1403static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1404static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1405static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001406static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1407
Tim Peters2a799bf2002-12-16 20:18:38 +00001408/* ---------------------------------------------------------------------------
1409 * Class implementations.
1410 */
1411
1412/*
1413 * PyDateTime_Delta implementation.
1414 */
1415
1416/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001418 * as a Python int or long.
1419 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1420 * due to ubiquitous overflow possibilities.
1421 */
1422static PyObject *
1423delta_to_microseconds(PyDateTime_Delta *self)
1424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 PyObject *x1 = NULL;
1426 PyObject *x2 = NULL;
1427 PyObject *x3 = NULL;
1428 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1431 if (x1 == NULL)
1432 goto Done;
1433 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1434 if (x2 == NULL)
1435 goto Done;
1436 Py_DECREF(x1);
1437 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 /* x2 has days in seconds */
1440 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1441 if (x1 == NULL)
1442 goto Done;
1443 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1444 if (x3 == NULL)
1445 goto Done;
1446 Py_DECREF(x1);
1447 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001448 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 /* x3 has days+seconds in seconds */
1451 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1452 if (x1 == NULL)
1453 goto Done;
1454 Py_DECREF(x3);
1455 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 /* x1 has days+seconds in us */
1458 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1459 if (x2 == NULL)
1460 goto Done;
1461 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001462
1463Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 Py_XDECREF(x1);
1465 Py_XDECREF(x2);
1466 Py_XDECREF(x3);
1467 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001468}
1469
1470/* Convert a number of us (as a Python int or long) to a timedelta.
1471 */
1472static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001473microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 int us;
1476 int s;
1477 int d;
1478 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 PyObject *tuple = NULL;
1481 PyObject *num = NULL;
1482 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 tuple = PyNumber_Divmod(pyus, us_per_second);
1485 if (tuple == NULL)
1486 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 num = PyTuple_GetItem(tuple, 1); /* us */
1489 if (num == NULL)
1490 goto Done;
1491 temp = PyLong_AsLong(num);
1492 num = NULL;
1493 if (temp == -1 && PyErr_Occurred())
1494 goto Done;
1495 assert(0 <= temp && temp < 1000000);
1496 us = (int)temp;
1497 if (us < 0) {
1498 /* The divisor was positive, so this must be an error. */
1499 assert(PyErr_Occurred());
1500 goto Done;
1501 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1504 if (num == NULL)
1505 goto Done;
1506 Py_INCREF(num);
1507 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 tuple = PyNumber_Divmod(num, seconds_per_day);
1510 if (tuple == NULL)
1511 goto Done;
1512 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001513
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001514 num = PyTuple_GetItem(tuple, 1); /* seconds */
1515 if (num == NULL)
1516 goto Done;
1517 temp = PyLong_AsLong(num);
1518 num = NULL;
1519 if (temp == -1 && PyErr_Occurred())
1520 goto Done;
1521 assert(0 <= temp && temp < 24*3600);
1522 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 if (s < 0) {
1525 /* The divisor was positive, so this must be an error. */
1526 assert(PyErr_Occurred());
1527 goto Done;
1528 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1531 if (num == NULL)
1532 goto Done;
1533 Py_INCREF(num);
1534 temp = PyLong_AsLong(num);
1535 if (temp == -1 && PyErr_Occurred())
1536 goto Done;
1537 d = (int)temp;
1538 if ((long)d != temp) {
1539 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1540 "large to fit in a C int");
1541 goto Done;
1542 }
1543 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001544
1545Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 Py_XDECREF(tuple);
1547 Py_XDECREF(num);
1548 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001549}
1550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551#define microseconds_to_delta(pymicros) \
1552 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001553
Tim Peters2a799bf2002-12-16 20:18:38 +00001554static PyObject *
1555multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 PyObject *pyus_in;
1558 PyObject *pyus_out;
1559 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 pyus_in = delta_to_microseconds(delta);
1562 if (pyus_in == NULL)
1563 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1566 Py_DECREF(pyus_in);
1567 if (pyus_out == NULL)
1568 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 result = microseconds_to_delta(pyus_out);
1571 Py_DECREF(pyus_out);
1572 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001573}
1574
1575static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001576multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1577{
1578 PyObject *result = NULL;
1579 PyObject *pyus_in = NULL, *temp, *pyus_out;
1580 PyObject *ratio = NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001581 _Py_IDENTIFIER(as_integer_ratio);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001582
1583 pyus_in = delta_to_microseconds(delta);
1584 if (pyus_in == NULL)
1585 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001586 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001587 if (ratio == NULL)
1588 goto error;
1589 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1590 Py_DECREF(pyus_in);
1591 pyus_in = NULL;
1592 if (temp == NULL)
1593 goto error;
1594 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1595 Py_DECREF(temp);
1596 if (pyus_out == NULL)
1597 goto error;
1598 result = microseconds_to_delta(pyus_out);
1599 Py_DECREF(pyus_out);
1600 error:
1601 Py_XDECREF(pyus_in);
1602 Py_XDECREF(ratio);
1603
1604 return result;
1605}
1606
1607static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001608divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 PyObject *pyus_in;
1611 PyObject *pyus_out;
1612 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 pyus_in = delta_to_microseconds(delta);
1615 if (pyus_in == NULL)
1616 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1619 Py_DECREF(pyus_in);
1620 if (pyus_out == NULL)
1621 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 result = microseconds_to_delta(pyus_out);
1624 Py_DECREF(pyus_out);
1625 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001626}
1627
1628static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001629divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 PyObject *pyus_left;
1632 PyObject *pyus_right;
1633 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 pyus_left = delta_to_microseconds(left);
1636 if (pyus_left == NULL)
1637 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 pyus_right = delta_to_microseconds(right);
1640 if (pyus_right == NULL) {
1641 Py_DECREF(pyus_left);
1642 return NULL;
1643 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1646 Py_DECREF(pyus_left);
1647 Py_DECREF(pyus_right);
1648 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001649}
1650
1651static PyObject *
1652truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 PyObject *pyus_left;
1655 PyObject *pyus_right;
1656 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 pyus_left = delta_to_microseconds(left);
1659 if (pyus_left == NULL)
1660 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 pyus_right = delta_to_microseconds(right);
1663 if (pyus_right == NULL) {
1664 Py_DECREF(pyus_left);
1665 return NULL;
1666 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1669 Py_DECREF(pyus_left);
1670 Py_DECREF(pyus_right);
1671 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001672}
1673
1674static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001675truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1676{
1677 PyObject *result = NULL;
1678 PyObject *pyus_in = NULL, *temp, *pyus_out;
1679 PyObject *ratio = NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001680 _Py_IDENTIFIER(as_integer_ratio);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001681
1682 pyus_in = delta_to_microseconds(delta);
1683 if (pyus_in == NULL)
1684 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001685 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001686 if (ratio == NULL)
1687 goto error;
1688 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1689 Py_DECREF(pyus_in);
1690 pyus_in = NULL;
1691 if (temp == NULL)
1692 goto error;
1693 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1694 Py_DECREF(temp);
1695 if (pyus_out == NULL)
1696 goto error;
1697 result = microseconds_to_delta(pyus_out);
1698 Py_DECREF(pyus_out);
1699 error:
1700 Py_XDECREF(pyus_in);
1701 Py_XDECREF(ratio);
1702
1703 return result;
1704}
1705
1706static PyObject *
1707truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1708{
1709 PyObject *result;
1710 PyObject *pyus_in, *pyus_out;
1711 pyus_in = delta_to_microseconds(delta);
1712 if (pyus_in == NULL)
1713 return NULL;
1714 pyus_out = divide_nearest(pyus_in, i);
1715 Py_DECREF(pyus_in);
1716 if (pyus_out == NULL)
1717 return NULL;
1718 result = microseconds_to_delta(pyus_out);
1719 Py_DECREF(pyus_out);
1720
1721 return result;
1722}
1723
1724static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001725delta_add(PyObject *left, PyObject *right)
1726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001727 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1730 /* delta + delta */
1731 /* The C-level additions can't overflow because of the
1732 * invariant bounds.
1733 */
1734 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1735 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1736 int microseconds = GET_TD_MICROSECONDS(left) +
1737 GET_TD_MICROSECONDS(right);
1738 result = new_delta(days, seconds, microseconds, 1);
1739 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001741 if (result == Py_NotImplemented)
1742 Py_INCREF(result);
1743 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001744}
1745
1746static PyObject *
1747delta_negative(PyDateTime_Delta *self)
1748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 return new_delta(-GET_TD_DAYS(self),
1750 -GET_TD_SECONDS(self),
1751 -GET_TD_MICROSECONDS(self),
1752 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001753}
1754
1755static PyObject *
1756delta_positive(PyDateTime_Delta *self)
1757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 /* Could optimize this (by returning self) if this isn't a
1759 * subclass -- but who uses unary + ? Approximately nobody.
1760 */
1761 return new_delta(GET_TD_DAYS(self),
1762 GET_TD_SECONDS(self),
1763 GET_TD_MICROSECONDS(self),
1764 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001765}
1766
1767static PyObject *
1768delta_abs(PyDateTime_Delta *self)
1769{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 assert(GET_TD_MICROSECONDS(self) >= 0);
1773 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 if (GET_TD_DAYS(self) < 0)
1776 result = delta_negative(self);
1777 else
1778 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001781}
1782
1783static PyObject *
1784delta_subtract(PyObject *left, PyObject *right)
1785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1789 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001790 /* The C-level additions can't overflow because of the
1791 * invariant bounds.
1792 */
1793 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1794 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1795 int microseconds = GET_TD_MICROSECONDS(left) -
1796 GET_TD_MICROSECONDS(right);
1797 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 if (result == Py_NotImplemented)
1801 Py_INCREF(result);
1802 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001803}
1804
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001805static int
1806delta_cmp(PyObject *self, PyObject *other)
1807{
1808 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1809 if (diff == 0) {
1810 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1811 if (diff == 0)
1812 diff = GET_TD_MICROSECONDS(self) -
1813 GET_TD_MICROSECONDS(other);
1814 }
1815 return diff;
1816}
1817
Tim Peters2a799bf2002-12-16 20:18:38 +00001818static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001819delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001822 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 return diff_to_bool(diff, op);
1824 }
1825 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001826 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001828}
1829
1830static PyObject *delta_getstate(PyDateTime_Delta *self);
1831
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001832static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001833delta_hash(PyDateTime_Delta *self)
1834{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 if (self->hashcode == -1) {
1836 PyObject *temp = delta_getstate(self);
1837 if (temp != NULL) {
1838 self->hashcode = PyObject_Hash(temp);
1839 Py_DECREF(temp);
1840 }
1841 }
1842 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001843}
1844
1845static PyObject *
1846delta_multiply(PyObject *left, PyObject *right)
1847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 if (PyDelta_Check(left)) {
1851 /* delta * ??? */
1852 if (PyLong_Check(right))
1853 result = multiply_int_timedelta(right,
1854 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001855 else if (PyFloat_Check(right))
1856 result = multiply_float_timedelta(right,
1857 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 }
1859 else if (PyLong_Check(left))
1860 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001861 (PyDateTime_Delta *) right);
1862 else if (PyFloat_Check(left))
1863 result = multiply_float_timedelta(left,
1864 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 if (result == Py_NotImplemented)
1867 Py_INCREF(result);
1868 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001869}
1870
1871static PyObject *
1872delta_divide(PyObject *left, PyObject *right)
1873{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 if (PyDelta_Check(left)) {
1877 /* delta * ??? */
1878 if (PyLong_Check(right))
1879 result = divide_timedelta_int(
1880 (PyDateTime_Delta *)left,
1881 right);
1882 else if (PyDelta_Check(right))
1883 result = divide_timedelta_timedelta(
1884 (PyDateTime_Delta *)left,
1885 (PyDateTime_Delta *)right);
1886 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 if (result == Py_NotImplemented)
1889 Py_INCREF(result);
1890 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001891}
1892
Mark Dickinson7c186e22010-04-20 22:32:49 +00001893static PyObject *
1894delta_truedivide(PyObject *left, PyObject *right)
1895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 if (PyDelta_Check(left)) {
1899 if (PyDelta_Check(right))
1900 result = truedivide_timedelta_timedelta(
1901 (PyDateTime_Delta *)left,
1902 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001903 else if (PyFloat_Check(right))
1904 result = truedivide_timedelta_float(
1905 (PyDateTime_Delta *)left, right);
1906 else if (PyLong_Check(right))
1907 result = truedivide_timedelta_int(
1908 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (result == Py_NotImplemented)
1912 Py_INCREF(result);
1913 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001914}
1915
1916static PyObject *
1917delta_remainder(PyObject *left, PyObject *right)
1918{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 PyObject *pyus_left;
1920 PyObject *pyus_right;
1921 PyObject *pyus_remainder;
1922 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001923
Brian Curtindfc80e32011-08-10 20:28:54 -05001924 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1925 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1928 if (pyus_left == NULL)
1929 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1932 if (pyus_right == NULL) {
1933 Py_DECREF(pyus_left);
1934 return NULL;
1935 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1938 Py_DECREF(pyus_left);
1939 Py_DECREF(pyus_right);
1940 if (pyus_remainder == NULL)
1941 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 remainder = microseconds_to_delta(pyus_remainder);
1944 Py_DECREF(pyus_remainder);
1945 if (remainder == NULL)
1946 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001949}
1950
1951static PyObject *
1952delta_divmod(PyObject *left, PyObject *right)
1953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 PyObject *pyus_left;
1955 PyObject *pyus_right;
1956 PyObject *divmod;
1957 PyObject *delta;
1958 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001959
Brian Curtindfc80e32011-08-10 20:28:54 -05001960 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1961 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001963 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1964 if (pyus_left == NULL)
1965 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1968 if (pyus_right == NULL) {
1969 Py_DECREF(pyus_left);
1970 return NULL;
1971 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1974 Py_DECREF(pyus_left);
1975 Py_DECREF(pyus_right);
1976 if (divmod == NULL)
1977 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 assert(PyTuple_Size(divmod) == 2);
1980 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1981 if (delta == NULL) {
1982 Py_DECREF(divmod);
1983 return NULL;
1984 }
1985 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1986 Py_DECREF(delta);
1987 Py_DECREF(divmod);
1988 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001989}
1990
Tim Peters2a799bf2002-12-16 20:18:38 +00001991/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1992 * timedelta constructor. sofar is the # of microseconds accounted for
1993 * so far, and there are factor microseconds per current unit, the number
1994 * of which is given by num. num * factor is added to sofar in a
1995 * numerically careful way, and that's the result. Any fractional
1996 * microseconds left over (this can happen if num is a float type) are
1997 * added into *leftover.
1998 * Note that there are many ways this can give an error (NULL) return.
1999 */
2000static PyObject *
2001accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2002 double *leftover)
2003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 PyObject *prod;
2005 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 if (PyLong_Check(num)) {
2010 prod = PyNumber_Multiply(num, factor);
2011 if (prod == NULL)
2012 return NULL;
2013 sum = PyNumber_Add(sofar, prod);
2014 Py_DECREF(prod);
2015 return sum;
2016 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 if (PyFloat_Check(num)) {
2019 double dnum;
2020 double fracpart;
2021 double intpart;
2022 PyObject *x;
2023 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 /* The Plan: decompose num into an integer part and a
2026 * fractional part, num = intpart + fracpart.
2027 * Then num * factor ==
2028 * intpart * factor + fracpart * factor
2029 * and the LHS can be computed exactly in long arithmetic.
2030 * The RHS is again broken into an int part and frac part.
2031 * and the frac part is added into *leftover.
2032 */
2033 dnum = PyFloat_AsDouble(num);
2034 if (dnum == -1.0 && PyErr_Occurred())
2035 return NULL;
2036 fracpart = modf(dnum, &intpart);
2037 x = PyLong_FromDouble(intpart);
2038 if (x == NULL)
2039 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 prod = PyNumber_Multiply(x, factor);
2042 Py_DECREF(x);
2043 if (prod == NULL)
2044 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002046 sum = PyNumber_Add(sofar, prod);
2047 Py_DECREF(prod);
2048 if (sum == NULL)
2049 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 if (fracpart == 0.0)
2052 return sum;
2053 /* So far we've lost no information. Dealing with the
2054 * fractional part requires float arithmetic, and may
2055 * lose a little info.
2056 */
2057 assert(PyLong_Check(factor));
2058 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002060 dnum *= fracpart;
2061 fracpart = modf(dnum, &intpart);
2062 x = PyLong_FromDouble(intpart);
2063 if (x == NULL) {
2064 Py_DECREF(sum);
2065 return NULL;
2066 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 y = PyNumber_Add(sum, x);
2069 Py_DECREF(sum);
2070 Py_DECREF(x);
2071 *leftover += fracpart;
2072 return y;
2073 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 PyErr_Format(PyExc_TypeError,
2076 "unsupported type for timedelta %s component: %s",
2077 tag, Py_TYPE(num)->tp_name);
2078 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002079}
2080
2081static PyObject *
2082delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 /* Argument objects. */
2087 PyObject *day = NULL;
2088 PyObject *second = NULL;
2089 PyObject *us = NULL;
2090 PyObject *ms = NULL;
2091 PyObject *minute = NULL;
2092 PyObject *hour = NULL;
2093 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002094
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 PyObject *x = NULL; /* running sum of microseconds */
2096 PyObject *y = NULL; /* temp sum of microseconds */
2097 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 static char *keywords[] = {
2100 "days", "seconds", "microseconds", "milliseconds",
2101 "minutes", "hours", "weeks", NULL
2102 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2105 keywords,
2106 &day, &second, &us,
2107 &ms, &minute, &hour, &week) == 0)
2108 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 x = PyLong_FromLong(0);
2111 if (x == NULL)
2112 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114#define CLEANUP \
2115 Py_DECREF(x); \
2116 x = y; \
2117 if (x == NULL) \
2118 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 if (us) {
2121 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2122 CLEANUP;
2123 }
2124 if (ms) {
2125 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2126 CLEANUP;
2127 }
2128 if (second) {
2129 y = accum("seconds", x, second, us_per_second, &leftover_us);
2130 CLEANUP;
2131 }
2132 if (minute) {
2133 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2134 CLEANUP;
2135 }
2136 if (hour) {
2137 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2138 CLEANUP;
2139 }
2140 if (day) {
2141 y = accum("days", x, day, us_per_day, &leftover_us);
2142 CLEANUP;
2143 }
2144 if (week) {
2145 y = accum("weeks", x, week, us_per_week, &leftover_us);
2146 CLEANUP;
2147 }
2148 if (leftover_us) {
2149 /* Round to nearest whole # of us, and add into x. */
2150 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2151 if (temp == NULL) {
2152 Py_DECREF(x);
2153 goto Done;
2154 }
2155 y = PyNumber_Add(x, temp);
2156 Py_DECREF(temp);
2157 CLEANUP;
2158 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 self = microseconds_to_delta_ex(x, type);
2161 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002162Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002164
2165#undef CLEANUP
2166}
2167
2168static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002169delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 return (GET_TD_DAYS(self) != 0
2172 || GET_TD_SECONDS(self) != 0
2173 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002174}
2175
2176static PyObject *
2177delta_repr(PyDateTime_Delta *self)
2178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 if (GET_TD_MICROSECONDS(self) != 0)
2180 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2181 Py_TYPE(self)->tp_name,
2182 GET_TD_DAYS(self),
2183 GET_TD_SECONDS(self),
2184 GET_TD_MICROSECONDS(self));
2185 if (GET_TD_SECONDS(self) != 0)
2186 return PyUnicode_FromFormat("%s(%d, %d)",
2187 Py_TYPE(self)->tp_name,
2188 GET_TD_DAYS(self),
2189 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 return PyUnicode_FromFormat("%s(%d)",
2192 Py_TYPE(self)->tp_name,
2193 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002194}
2195
2196static PyObject *
2197delta_str(PyDateTime_Delta *self)
2198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 int us = GET_TD_MICROSECONDS(self);
2200 int seconds = GET_TD_SECONDS(self);
2201 int minutes = divmod(seconds, 60, &seconds);
2202 int hours = divmod(minutes, 60, &minutes);
2203 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002205 if (days) {
2206 if (us)
2207 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2208 days, (days == 1 || days == -1) ? "" : "s",
2209 hours, minutes, seconds, us);
2210 else
2211 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2212 days, (days == 1 || days == -1) ? "" : "s",
2213 hours, minutes, seconds);
2214 } else {
2215 if (us)
2216 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2217 hours, minutes, seconds, us);
2218 else
2219 return PyUnicode_FromFormat("%d:%02d:%02d",
2220 hours, minutes, seconds);
2221 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002222
Tim Peters2a799bf2002-12-16 20:18:38 +00002223}
2224
Tim Peters371935f2003-02-01 01:52:50 +00002225/* Pickle support, a simple use of __reduce__. */
2226
Tim Petersb57f8f02003-02-01 02:54:15 +00002227/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002228static PyObject *
2229delta_getstate(PyDateTime_Delta *self)
2230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 return Py_BuildValue("iii", GET_TD_DAYS(self),
2232 GET_TD_SECONDS(self),
2233 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002234}
2235
Tim Peters2a799bf2002-12-16 20:18:38 +00002236static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002237delta_total_seconds(PyObject *self)
2238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 PyObject *total_seconds;
2240 PyObject *total_microseconds;
2241 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2244 if (total_microseconds == NULL)
2245 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 one_million = PyLong_FromLong(1000000L);
2248 if (one_million == NULL) {
2249 Py_DECREF(total_microseconds);
2250 return NULL;
2251 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 Py_DECREF(total_microseconds);
2256 Py_DECREF(one_million);
2257 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002258}
2259
2260static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002261delta_reduce(PyDateTime_Delta* self)
2262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002264}
2265
2266#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2267
2268static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002270 {"days", T_INT, OFFSET(days), READONLY,
2271 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 {"seconds", T_INT, OFFSET(seconds), READONLY,
2274 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2277 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2278 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002279};
2280
2281static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2283 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2286 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002289};
2290
2291static char delta_doc[] =
2292PyDoc_STR("Difference between two datetime values.");
2293
2294static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 delta_add, /* nb_add */
2296 delta_subtract, /* nb_subtract */
2297 delta_multiply, /* nb_multiply */
2298 delta_remainder, /* nb_remainder */
2299 delta_divmod, /* nb_divmod */
2300 0, /* nb_power */
2301 (unaryfunc)delta_negative, /* nb_negative */
2302 (unaryfunc)delta_positive, /* nb_positive */
2303 (unaryfunc)delta_abs, /* nb_absolute */
2304 (inquiry)delta_bool, /* nb_bool */
2305 0, /*nb_invert*/
2306 0, /*nb_lshift*/
2307 0, /*nb_rshift*/
2308 0, /*nb_and*/
2309 0, /*nb_xor*/
2310 0, /*nb_or*/
2311 0, /*nb_int*/
2312 0, /*nb_reserved*/
2313 0, /*nb_float*/
2314 0, /*nb_inplace_add*/
2315 0, /*nb_inplace_subtract*/
2316 0, /*nb_inplace_multiply*/
2317 0, /*nb_inplace_remainder*/
2318 0, /*nb_inplace_power*/
2319 0, /*nb_inplace_lshift*/
2320 0, /*nb_inplace_rshift*/
2321 0, /*nb_inplace_and*/
2322 0, /*nb_inplace_xor*/
2323 0, /*nb_inplace_or*/
2324 delta_divide, /* nb_floor_divide */
2325 delta_truedivide, /* nb_true_divide */
2326 0, /* nb_inplace_floor_divide */
2327 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002328};
2329
2330static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002331 PyVarObject_HEAD_INIT(NULL, 0)
2332 "datetime.timedelta", /* tp_name */
2333 sizeof(PyDateTime_Delta), /* tp_basicsize */
2334 0, /* tp_itemsize */
2335 0, /* tp_dealloc */
2336 0, /* tp_print */
2337 0, /* tp_getattr */
2338 0, /* tp_setattr */
2339 0, /* tp_reserved */
2340 (reprfunc)delta_repr, /* tp_repr */
2341 &delta_as_number, /* tp_as_number */
2342 0, /* tp_as_sequence */
2343 0, /* tp_as_mapping */
2344 (hashfunc)delta_hash, /* tp_hash */
2345 0, /* tp_call */
2346 (reprfunc)delta_str, /* tp_str */
2347 PyObject_GenericGetAttr, /* tp_getattro */
2348 0, /* tp_setattro */
2349 0, /* tp_as_buffer */
2350 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2351 delta_doc, /* tp_doc */
2352 0, /* tp_traverse */
2353 0, /* tp_clear */
2354 delta_richcompare, /* tp_richcompare */
2355 0, /* tp_weaklistoffset */
2356 0, /* tp_iter */
2357 0, /* tp_iternext */
2358 delta_methods, /* tp_methods */
2359 delta_members, /* tp_members */
2360 0, /* tp_getset */
2361 0, /* tp_base */
2362 0, /* tp_dict */
2363 0, /* tp_descr_get */
2364 0, /* tp_descr_set */
2365 0, /* tp_dictoffset */
2366 0, /* tp_init */
2367 0, /* tp_alloc */
2368 delta_new, /* tp_new */
2369 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002370};
2371
2372/*
2373 * PyDateTime_Date implementation.
2374 */
2375
2376/* Accessor properties. */
2377
2378static PyObject *
2379date_year(PyDateTime_Date *self, void *unused)
2380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002382}
2383
2384static PyObject *
2385date_month(PyDateTime_Date *self, void *unused)
2386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002388}
2389
2390static PyObject *
2391date_day(PyDateTime_Date *self, void *unused)
2392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002394}
2395
2396static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 {"year", (getter)date_year},
2398 {"month", (getter)date_month},
2399 {"day", (getter)date_day},
2400 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002401};
2402
2403/* Constructors. */
2404
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002405static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002406
Tim Peters2a799bf2002-12-16 20:18:38 +00002407static PyObject *
2408date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 PyObject *self = NULL;
2411 PyObject *state;
2412 int year;
2413 int month;
2414 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 /* Check for invocation from pickle with __getstate__ state */
2417 if (PyTuple_GET_SIZE(args) == 1 &&
2418 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2419 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2420 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2421 {
2422 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2425 if (me != NULL) {
2426 char *pdata = PyBytes_AS_STRING(state);
2427 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2428 me->hashcode = -1;
2429 }
2430 return (PyObject *)me;
2431 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2434 &year, &month, &day)) {
2435 if (check_date_args(year, month, day) < 0)
2436 return NULL;
2437 self = new_date_ex(year, month, day, type);
2438 }
2439 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002440}
2441
2442/* Return new date from localtime(t). */
2443static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002444date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 struct tm *tm;
2447 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002448
Victor Stinner5d272cc2012-03-13 13:35:55 +01002449 if (_PyTime_ObjectToTime_t(obj, &t) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 tm = localtime(&t);
Victor Stinner21f58932012-03-14 00:15:40 +01002453 if (tm == NULL) {
2454 /* unconvertible time */
2455#ifdef EINVAL
2456 if (errno == 0)
2457 errno = EINVAL;
2458#endif
2459 PyErr_SetFromErrno(PyExc_OSError);
2460 return NULL;
2461 }
2462
2463 return PyObject_CallFunction(cls, "iii",
2464 tm->tm_year + 1900,
2465 tm->tm_mon + 1,
2466 tm->tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002467}
2468
2469/* Return new date from current time.
2470 * We say this is equivalent to fromtimestamp(time.time()), and the
2471 * only way to be sure of that is to *call* time.time(). That's not
2472 * generally the same as calling C's time.
2473 */
2474static PyObject *
2475date_today(PyObject *cls, PyObject *dummy)
2476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 PyObject *time;
2478 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002479 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 time = time_time();
2482 if (time == NULL)
2483 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 /* Note well: today() is a class method, so this may not call
2486 * date.fromtimestamp. For example, it may call
2487 * datetime.fromtimestamp. That's why we need all the accuracy
2488 * time.time() delivers; if someone were gonzo about optimization,
2489 * date.today() could get away with plain C time().
2490 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002491 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 Py_DECREF(time);
2493 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002494}
2495
2496/* Return new date from given timestamp (Python timestamp -- a double). */
2497static PyObject *
2498date_fromtimestamp(PyObject *cls, PyObject *args)
2499{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002500 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002501 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002502
Victor Stinner5d272cc2012-03-13 13:35:55 +01002503 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2504 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002505 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002506}
2507
2508/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2509 * the ordinal is out of range.
2510 */
2511static PyObject *
2512date_fromordinal(PyObject *cls, PyObject *args)
2513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002514 PyObject *result = NULL;
2515 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2518 int year;
2519 int month;
2520 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 if (ordinal < 1)
2523 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2524 ">= 1");
2525 else {
2526 ord_to_ymd(ordinal, &year, &month, &day);
2527 result = PyObject_CallFunction(cls, "iii",
2528 year, month, day);
2529 }
2530 }
2531 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002532}
2533
2534/*
2535 * Date arithmetic.
2536 */
2537
2538/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2539 * instead.
2540 */
2541static PyObject *
2542add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2543{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002544 PyObject *result = NULL;
2545 int year = GET_YEAR(date);
2546 int month = GET_MONTH(date);
2547 int deltadays = GET_TD_DAYS(delta);
2548 /* C-level overflow is impossible because |deltadays| < 1e9. */
2549 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 if (normalize_date(&year, &month, &day) >= 0)
2552 result = new_date(year, month, day);
2553 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002554}
2555
2556static PyObject *
2557date_add(PyObject *left, PyObject *right)
2558{
Brian Curtindfc80e32011-08-10 20:28:54 -05002559 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2560 Py_RETURN_NOTIMPLEMENTED;
2561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002562 if (PyDate_Check(left)) {
2563 /* date + ??? */
2564 if (PyDelta_Check(right))
2565 /* date + delta */
2566 return add_date_timedelta((PyDateTime_Date *) left,
2567 (PyDateTime_Delta *) right,
2568 0);
2569 }
2570 else {
2571 /* ??? + date
2572 * 'right' must be one of us, or we wouldn't have been called
2573 */
2574 if (PyDelta_Check(left))
2575 /* delta + date */
2576 return add_date_timedelta((PyDateTime_Date *) right,
2577 (PyDateTime_Delta *) left,
2578 0);
2579 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002580 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002581}
2582
2583static PyObject *
2584date_subtract(PyObject *left, PyObject *right)
2585{
Brian Curtindfc80e32011-08-10 20:28:54 -05002586 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2587 Py_RETURN_NOTIMPLEMENTED;
2588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002589 if (PyDate_Check(left)) {
2590 if (PyDate_Check(right)) {
2591 /* date - date */
2592 int left_ord = ymd_to_ord(GET_YEAR(left),
2593 GET_MONTH(left),
2594 GET_DAY(left));
2595 int right_ord = ymd_to_ord(GET_YEAR(right),
2596 GET_MONTH(right),
2597 GET_DAY(right));
2598 return new_delta(left_ord - right_ord, 0, 0, 0);
2599 }
2600 if (PyDelta_Check(right)) {
2601 /* date - delta */
2602 return add_date_timedelta((PyDateTime_Date *) left,
2603 (PyDateTime_Delta *) right,
2604 1);
2605 }
2606 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002607 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002608}
2609
2610
2611/* Various ways to turn a date into a string. */
2612
2613static PyObject *
2614date_repr(PyDateTime_Date *self)
2615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2617 Py_TYPE(self)->tp_name,
2618 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002619}
2620
2621static PyObject *
2622date_isoformat(PyDateTime_Date *self)
2623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002624 return PyUnicode_FromFormat("%04d-%02d-%02d",
2625 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002626}
2627
Tim Peterse2df5ff2003-05-02 18:39:55 +00002628/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002629static PyObject *
2630date_str(PyDateTime_Date *self)
2631{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002632 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002633
2634 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002635}
2636
2637
2638static PyObject *
2639date_ctime(PyDateTime_Date *self)
2640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002642}
2643
2644static PyObject *
2645date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2646{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002647 /* This method can be inherited, and needs to call the
2648 * timetuple() method appropriate to self's class.
2649 */
2650 PyObject *result;
2651 PyObject *tuple;
2652 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002653 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002656 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2657 &format))
2658 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002659
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002660 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002661 if (tuple == NULL)
2662 return NULL;
2663 result = wrap_strftime((PyObject *)self, format, tuple,
2664 (PyObject *)self);
2665 Py_DECREF(tuple);
2666 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002667}
2668
Eric Smith1ba31142007-09-11 18:06:02 +00002669static PyObject *
2670date_format(PyDateTime_Date *self, PyObject *args)
2671{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002672 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002673 _Py_IDENTIFIER(strftime);
Eric Smith1ba31142007-09-11 18:06:02 +00002674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002675 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2676 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002678 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002679 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002680 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002681
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002682 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002683}
2684
Tim Peters2a799bf2002-12-16 20:18:38 +00002685/* ISO methods. */
2686
2687static PyObject *
2688date_isoweekday(PyDateTime_Date *self)
2689{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002690 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002692 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002693}
2694
2695static PyObject *
2696date_isocalendar(PyDateTime_Date *self)
2697{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002698 int year = GET_YEAR(self);
2699 int week1_monday = iso_week1_monday(year);
2700 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2701 int week;
2702 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002704 week = divmod(today - week1_monday, 7, &day);
2705 if (week < 0) {
2706 --year;
2707 week1_monday = iso_week1_monday(year);
2708 week = divmod(today - week1_monday, 7, &day);
2709 }
2710 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2711 ++year;
2712 week = 0;
2713 }
2714 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002715}
2716
2717/* Miscellaneous methods. */
2718
Tim Peters2a799bf2002-12-16 20:18:38 +00002719static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002720date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002721{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002722 if (PyDate_Check(other)) {
2723 int diff = memcmp(((PyDateTime_Date *)self)->data,
2724 ((PyDateTime_Date *)other)->data,
2725 _PyDateTime_DATE_DATASIZE);
2726 return diff_to_bool(diff, op);
2727 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002728 else
2729 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002730}
2731
2732static PyObject *
2733date_timetuple(PyDateTime_Date *self)
2734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002735 return build_struct_time(GET_YEAR(self),
2736 GET_MONTH(self),
2737 GET_DAY(self),
2738 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002739}
2740
Tim Peters12bf3392002-12-24 05:41:27 +00002741static PyObject *
2742date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2743{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002744 PyObject *clone;
2745 PyObject *tuple;
2746 int year = GET_YEAR(self);
2747 int month = GET_MONTH(self);
2748 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002750 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2751 &year, &month, &day))
2752 return NULL;
2753 tuple = Py_BuildValue("iii", year, month, day);
2754 if (tuple == NULL)
2755 return NULL;
2756 clone = date_new(Py_TYPE(self), tuple, NULL);
2757 Py_DECREF(tuple);
2758 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002759}
2760
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002761static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002762generic_hash(unsigned char *data, int len)
2763{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002764 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002765}
2766
2767
2768static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002769
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002770static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002771date_hash(PyDateTime_Date *self)
2772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002773 if (self->hashcode == -1)
2774 self->hashcode = generic_hash(
2775 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002777 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002778}
2779
2780static PyObject *
2781date_toordinal(PyDateTime_Date *self)
2782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002783 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2784 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002785}
2786
2787static PyObject *
2788date_weekday(PyDateTime_Date *self)
2789{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002790 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002792 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002793}
2794
Tim Peters371935f2003-02-01 01:52:50 +00002795/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002796
Tim Petersb57f8f02003-02-01 02:54:15 +00002797/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002798static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002799date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002800{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002801 PyObject* field;
2802 field = PyBytes_FromStringAndSize((char*)self->data,
2803 _PyDateTime_DATE_DATASIZE);
2804 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002805}
2806
2807static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002808date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002811}
2812
2813static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002817 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2818 METH_CLASS,
2819 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2820 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2823 METH_CLASS,
2824 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2825 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002827 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2828 PyDoc_STR("Current date or datetime: same as "
2829 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002833 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2834 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2837 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002839 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2840 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002842 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2843 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2846 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2847 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2850 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002852 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2853 PyDoc_STR("Return the day of the week represented by the date.\n"
2854 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2857 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2858 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002860 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2861 PyDoc_STR("Return the day of the week represented by the date.\n"
2862 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2865 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002867 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2868 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002870 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002871};
2872
2873static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002874PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002875
2876static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002877 date_add, /* nb_add */
2878 date_subtract, /* nb_subtract */
2879 0, /* nb_multiply */
2880 0, /* nb_remainder */
2881 0, /* nb_divmod */
2882 0, /* nb_power */
2883 0, /* nb_negative */
2884 0, /* nb_positive */
2885 0, /* nb_absolute */
2886 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002887};
2888
2889static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 PyVarObject_HEAD_INIT(NULL, 0)
2891 "datetime.date", /* tp_name */
2892 sizeof(PyDateTime_Date), /* tp_basicsize */
2893 0, /* tp_itemsize */
2894 0, /* tp_dealloc */
2895 0, /* tp_print */
2896 0, /* tp_getattr */
2897 0, /* tp_setattr */
2898 0, /* tp_reserved */
2899 (reprfunc)date_repr, /* tp_repr */
2900 &date_as_number, /* tp_as_number */
2901 0, /* tp_as_sequence */
2902 0, /* tp_as_mapping */
2903 (hashfunc)date_hash, /* tp_hash */
2904 0, /* tp_call */
2905 (reprfunc)date_str, /* tp_str */
2906 PyObject_GenericGetAttr, /* tp_getattro */
2907 0, /* tp_setattro */
2908 0, /* tp_as_buffer */
2909 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2910 date_doc, /* tp_doc */
2911 0, /* tp_traverse */
2912 0, /* tp_clear */
2913 date_richcompare, /* tp_richcompare */
2914 0, /* tp_weaklistoffset */
2915 0, /* tp_iter */
2916 0, /* tp_iternext */
2917 date_methods, /* tp_methods */
2918 0, /* tp_members */
2919 date_getset, /* tp_getset */
2920 0, /* tp_base */
2921 0, /* tp_dict */
2922 0, /* tp_descr_get */
2923 0, /* tp_descr_set */
2924 0, /* tp_dictoffset */
2925 0, /* tp_init */
2926 0, /* tp_alloc */
2927 date_new, /* tp_new */
2928 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002929};
2930
2931/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002932 * PyDateTime_TZInfo implementation.
2933 */
2934
2935/* This is a pure abstract base class, so doesn't do anything beyond
2936 * raising NotImplemented exceptions. Real tzinfo classes need
2937 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002938 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002939 * be subclasses of this tzinfo class, which is easy and quick to check).
2940 *
2941 * Note: For reasons having to do with pickling of subclasses, we have
2942 * to allow tzinfo objects to be instantiated. This wasn't an issue
2943 * in the Python implementation (__init__() could raise NotImplementedError
2944 * there without ill effect), but doing so in the C implementation hit a
2945 * brick wall.
2946 */
2947
2948static PyObject *
2949tzinfo_nogo(const char* methodname)
2950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002951 PyErr_Format(PyExc_NotImplementedError,
2952 "a tzinfo subclass must implement %s()",
2953 methodname);
2954 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002955}
2956
2957/* Methods. A subclass must implement these. */
2958
Tim Peters52dcce22003-01-23 16:36:11 +00002959static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002960tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002962 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002963}
2964
Tim Peters52dcce22003-01-23 16:36:11 +00002965static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002966tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002968 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002969}
2970
Tim Peters52dcce22003-01-23 16:36:11 +00002971static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002972tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002974 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002975}
2976
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002977
2978static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2979 PyDateTime_Delta *delta,
2980 int factor);
2981static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2982static PyObject *datetime_dst(PyObject *self, PyObject *);
2983
Tim Peters52dcce22003-01-23 16:36:11 +00002984static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002985tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00002986{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002987 PyObject *result = NULL;
2988 PyObject *off = NULL, *dst = NULL;
2989 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002990
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002991 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002992 PyErr_SetString(PyExc_TypeError,
2993 "fromutc: argument must be a datetime");
2994 return NULL;
2995 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002996 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002997 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2998 "is not self");
2999 return NULL;
3000 }
Tim Peters52dcce22003-01-23 16:36:11 +00003001
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003002 off = datetime_utcoffset(dt, NULL);
3003 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003004 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003005 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003006 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3007 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003008 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003009 }
Tim Peters52dcce22003-01-23 16:36:11 +00003010
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003011 dst = datetime_dst(dt, NULL);
3012 if (dst == NULL)
3013 goto Fail;
3014 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3016 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003017 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003018 }
Tim Peters52dcce22003-01-23 16:36:11 +00003019
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003020 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3021 if (delta == NULL)
3022 goto Fail;
3023 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003024 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003025 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003026
3027 Py_DECREF(dst);
3028 dst = call_dst(GET_DT_TZINFO(dt), result);
3029 if (dst == NULL)
3030 goto Fail;
3031 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003032 goto Inconsistent;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003033 if (delta_bool(delta) != 0) {
3034 PyObject *temp = result;
3035 result = add_datetime_timedelta((PyDateTime_DateTime *)result,
3036 (PyDateTime_Delta *)dst, 1);
3037 Py_DECREF(temp);
3038 if (result == NULL)
3039 goto Fail;
3040 }
3041 Py_DECREF(delta);
3042 Py_DECREF(dst);
3043 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003044 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003045
3046Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003047 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3048 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003050 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003051Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003052 Py_XDECREF(off);
3053 Py_XDECREF(dst);
3054 Py_XDECREF(delta);
3055 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003056 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003057}
3058
Tim Peters2a799bf2002-12-16 20:18:38 +00003059/*
3060 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003061 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003062 */
3063
Guido van Rossum177e41a2003-01-30 22:06:23 +00003064static PyObject *
3065tzinfo_reduce(PyObject *self)
3066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003067 PyObject *args, *state, *tmp;
3068 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003069 _Py_IDENTIFIER(__getinitargs__);
3070 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003072 tmp = PyTuple_New(0);
3073 if (tmp == NULL)
3074 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003075
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003076 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003077 if (getinitargs != NULL) {
3078 args = PyObject_CallObject(getinitargs, tmp);
3079 Py_DECREF(getinitargs);
3080 if (args == NULL) {
3081 Py_DECREF(tmp);
3082 return NULL;
3083 }
3084 }
3085 else {
3086 PyErr_Clear();
3087 args = tmp;
3088 Py_INCREF(args);
3089 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003090
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003091 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003092 if (getstate != NULL) {
3093 state = PyObject_CallObject(getstate, tmp);
3094 Py_DECREF(getstate);
3095 if (state == NULL) {
3096 Py_DECREF(args);
3097 Py_DECREF(tmp);
3098 return NULL;
3099 }
3100 }
3101 else {
3102 PyObject **dictptr;
3103 PyErr_Clear();
3104 state = Py_None;
3105 dictptr = _PyObject_GetDictPtr(self);
3106 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3107 state = *dictptr;
3108 Py_INCREF(state);
3109 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003111 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003113 if (state == Py_None) {
3114 Py_DECREF(state);
3115 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3116 }
3117 else
3118 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003119}
Tim Peters2a799bf2002-12-16 20:18:38 +00003120
3121static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003123 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3124 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003126 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003127 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3128 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003130 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3131 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003133 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003134 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003136 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3137 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003140};
3141
3142static char tzinfo_doc[] =
3143PyDoc_STR("Abstract base class for time zone info objects.");
3144
Neal Norwitz227b5332006-03-22 09:28:35 +00003145static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003146 PyVarObject_HEAD_INIT(NULL, 0)
3147 "datetime.tzinfo", /* tp_name */
3148 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3149 0, /* tp_itemsize */
3150 0, /* tp_dealloc */
3151 0, /* tp_print */
3152 0, /* tp_getattr */
3153 0, /* tp_setattr */
3154 0, /* tp_reserved */
3155 0, /* tp_repr */
3156 0, /* tp_as_number */
3157 0, /* tp_as_sequence */
3158 0, /* tp_as_mapping */
3159 0, /* tp_hash */
3160 0, /* tp_call */
3161 0, /* tp_str */
3162 PyObject_GenericGetAttr, /* tp_getattro */
3163 0, /* tp_setattro */
3164 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003165 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003166 tzinfo_doc, /* tp_doc */
3167 0, /* tp_traverse */
3168 0, /* tp_clear */
3169 0, /* tp_richcompare */
3170 0, /* tp_weaklistoffset */
3171 0, /* tp_iter */
3172 0, /* tp_iternext */
3173 tzinfo_methods, /* tp_methods */
3174 0, /* tp_members */
3175 0, /* tp_getset */
3176 0, /* tp_base */
3177 0, /* tp_dict */
3178 0, /* tp_descr_get */
3179 0, /* tp_descr_set */
3180 0, /* tp_dictoffset */
3181 0, /* tp_init */
3182 0, /* tp_alloc */
3183 PyType_GenericNew, /* tp_new */
3184 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003185};
3186
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003187static char *timezone_kws[] = {"offset", "name", NULL};
3188
3189static PyObject *
3190timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3191{
3192 PyObject *offset;
3193 PyObject *name = NULL;
3194 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3195 &PyDateTime_DeltaType, &offset,
3196 &PyUnicode_Type, &name))
3197 return new_timezone(offset, name);
3198
3199 return NULL;
3200}
3201
3202static void
3203timezone_dealloc(PyDateTime_TimeZone *self)
3204{
3205 Py_CLEAR(self->offset);
3206 Py_CLEAR(self->name);
3207 Py_TYPE(self)->tp_free((PyObject *)self);
3208}
3209
3210static PyObject *
3211timezone_richcompare(PyDateTime_TimeZone *self,
3212 PyDateTime_TimeZone *other, int op)
3213{
Brian Curtindfc80e32011-08-10 20:28:54 -05003214 if (op != Py_EQ && op != Py_NE)
3215 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003216 return delta_richcompare(self->offset, other->offset, op);
3217}
3218
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003219static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003220timezone_hash(PyDateTime_TimeZone *self)
3221{
3222 return delta_hash((PyDateTime_Delta *)self->offset);
3223}
3224
3225/* Check argument type passed to tzname, utcoffset, or dst methods.
3226 Returns 0 for good argument. Returns -1 and sets exception info
3227 otherwise.
3228 */
3229static int
3230_timezone_check_argument(PyObject *dt, const char *meth)
3231{
3232 if (dt == Py_None || PyDateTime_Check(dt))
3233 return 0;
3234 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3235 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3236 return -1;
3237}
3238
3239static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003240timezone_repr(PyDateTime_TimeZone *self)
3241{
3242 /* Note that although timezone is not subclassable, it is convenient
3243 to use Py_TYPE(self)->tp_name here. */
3244 const char *type_name = Py_TYPE(self)->tp_name;
3245
3246 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3247 return PyUnicode_FromFormat("%s.utc", type_name);
3248
3249 if (self->name == NULL)
3250 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3251
3252 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3253 self->name);
3254}
3255
3256
3257static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003258timezone_str(PyDateTime_TimeZone *self)
3259{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003260 int hours, minutes, seconds;
3261 PyObject *offset;
3262 char sign;
3263
3264 if (self->name != NULL) {
3265 Py_INCREF(self->name);
3266 return self->name;
3267 }
3268 /* Offset is normalized, so it is negative if days < 0 */
3269 if (GET_TD_DAYS(self->offset) < 0) {
3270 sign = '-';
3271 offset = delta_negative((PyDateTime_Delta *)self->offset);
3272 if (offset == NULL)
3273 return NULL;
3274 }
3275 else {
3276 sign = '+';
3277 offset = self->offset;
3278 Py_INCREF(offset);
3279 }
3280 /* Offset is not negative here. */
3281 seconds = GET_TD_SECONDS(offset);
3282 Py_DECREF(offset);
3283 minutes = divmod(seconds, 60, &seconds);
3284 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003285 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003286 assert(seconds == 0);
3287 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003288}
3289
3290static PyObject *
3291timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3292{
3293 if (_timezone_check_argument(dt, "tzname") == -1)
3294 return NULL;
3295
3296 return timezone_str(self);
3297}
3298
3299static PyObject *
3300timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3301{
3302 if (_timezone_check_argument(dt, "utcoffset") == -1)
3303 return NULL;
3304
3305 Py_INCREF(self->offset);
3306 return self->offset;
3307}
3308
3309static PyObject *
3310timezone_dst(PyObject *self, PyObject *dt)
3311{
3312 if (_timezone_check_argument(dt, "dst") == -1)
3313 return NULL;
3314
3315 Py_RETURN_NONE;
3316}
3317
3318static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003319timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3320{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003321 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003322 PyErr_SetString(PyExc_TypeError,
3323 "fromutc: argument must be a datetime");
3324 return NULL;
3325 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003326 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003327 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3328 "is not self");
3329 return NULL;
3330 }
3331
3332 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3333}
3334
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003335static PyObject *
3336timezone_getinitargs(PyDateTime_TimeZone *self)
3337{
3338 if (self->name == NULL)
3339 return Py_BuildValue("(O)", self->offset);
3340 return Py_BuildValue("(OO)", self->offset, self->name);
3341}
3342
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003343static PyMethodDef timezone_methods[] = {
3344 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3345 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003346 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003347
3348 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003349 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003350
3351 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003352 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003353
3354 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3355 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3356
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003357 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3358 PyDoc_STR("pickle support")},
3359
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003360 {NULL, NULL}
3361};
3362
3363static char timezone_doc[] =
3364PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3365
3366static PyTypeObject PyDateTime_TimeZoneType = {
3367 PyVarObject_HEAD_INIT(NULL, 0)
3368 "datetime.timezone", /* tp_name */
3369 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3370 0, /* tp_itemsize */
3371 (destructor)timezone_dealloc, /* tp_dealloc */
3372 0, /* tp_print */
3373 0, /* tp_getattr */
3374 0, /* tp_setattr */
3375 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003376 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003377 0, /* tp_as_number */
3378 0, /* tp_as_sequence */
3379 0, /* tp_as_mapping */
3380 (hashfunc)timezone_hash, /* tp_hash */
3381 0, /* tp_call */
3382 (reprfunc)timezone_str, /* tp_str */
3383 0, /* tp_getattro */
3384 0, /* tp_setattro */
3385 0, /* tp_as_buffer */
3386 Py_TPFLAGS_DEFAULT, /* tp_flags */
3387 timezone_doc, /* tp_doc */
3388 0, /* tp_traverse */
3389 0, /* tp_clear */
3390 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3391 0, /* tp_weaklistoffset */
3392 0, /* tp_iter */
3393 0, /* tp_iternext */
3394 timezone_methods, /* tp_methods */
3395 0, /* tp_members */
3396 0, /* tp_getset */
3397 &PyDateTime_TZInfoType, /* tp_base */
3398 0, /* tp_dict */
3399 0, /* tp_descr_get */
3400 0, /* tp_descr_set */
3401 0, /* tp_dictoffset */
3402 0, /* tp_init */
3403 0, /* tp_alloc */
3404 timezone_new, /* tp_new */
3405};
3406
Tim Peters2a799bf2002-12-16 20:18:38 +00003407/*
Tim Peters37f39822003-01-10 03:49:02 +00003408 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003409 */
3410
Tim Peters37f39822003-01-10 03:49:02 +00003411/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003412 */
3413
3414static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003415time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003417 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003418}
3419
Tim Peters37f39822003-01-10 03:49:02 +00003420static PyObject *
3421time_minute(PyDateTime_Time *self, void *unused)
3422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003423 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003424}
3425
3426/* The name time_second conflicted with some platform header file. */
3427static PyObject *
3428py_time_second(PyDateTime_Time *self, void *unused)
3429{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003430 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003431}
3432
3433static PyObject *
3434time_microsecond(PyDateTime_Time *self, void *unused)
3435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003436 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003437}
3438
3439static PyObject *
3440time_tzinfo(PyDateTime_Time *self, void *unused)
3441{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003442 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3443 Py_INCREF(result);
3444 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003445}
3446
3447static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003448 {"hour", (getter)time_hour},
3449 {"minute", (getter)time_minute},
3450 {"second", (getter)py_time_second},
3451 {"microsecond", (getter)time_microsecond},
3452 {"tzinfo", (getter)time_tzinfo},
3453 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003454};
3455
3456/*
3457 * Constructors.
3458 */
3459
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003460static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003461 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003462
Tim Peters2a799bf2002-12-16 20:18:38 +00003463static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003464time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003466 PyObject *self = NULL;
3467 PyObject *state;
3468 int hour = 0;
3469 int minute = 0;
3470 int second = 0;
3471 int usecond = 0;
3472 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003474 /* Check for invocation from pickle with __getstate__ state */
3475 if (PyTuple_GET_SIZE(args) >= 1 &&
3476 PyTuple_GET_SIZE(args) <= 2 &&
3477 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3478 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3479 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3480 {
3481 PyDateTime_Time *me;
3482 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003484 if (PyTuple_GET_SIZE(args) == 2) {
3485 tzinfo = PyTuple_GET_ITEM(args, 1);
3486 if (check_tzinfo_subclass(tzinfo) < 0) {
3487 PyErr_SetString(PyExc_TypeError, "bad "
3488 "tzinfo state arg");
3489 return NULL;
3490 }
3491 }
3492 aware = (char)(tzinfo != Py_None);
3493 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3494 if (me != NULL) {
3495 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003497 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3498 me->hashcode = -1;
3499 me->hastzinfo = aware;
3500 if (aware) {
3501 Py_INCREF(tzinfo);
3502 me->tzinfo = tzinfo;
3503 }
3504 }
3505 return (PyObject *)me;
3506 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3509 &hour, &minute, &second, &usecond,
3510 &tzinfo)) {
3511 if (check_time_args(hour, minute, second, usecond) < 0)
3512 return NULL;
3513 if (check_tzinfo_subclass(tzinfo) < 0)
3514 return NULL;
3515 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3516 type);
3517 }
3518 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003519}
3520
3521/*
3522 * Destructor.
3523 */
3524
3525static void
Tim Peters37f39822003-01-10 03:49:02 +00003526time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003528 if (HASTZINFO(self)) {
3529 Py_XDECREF(self->tzinfo);
3530 }
3531 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003532}
3533
3534/*
Tim Peters855fe882002-12-22 03:43:39 +00003535 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003536 */
3537
Tim Peters2a799bf2002-12-16 20:18:38 +00003538/* These are all METH_NOARGS, so don't need to check the arglist. */
3539static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003540time_utcoffset(PyObject *self, PyObject *unused) {
3541 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003542}
3543
3544static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003545time_dst(PyObject *self, PyObject *unused) {
3546 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003547}
3548
3549static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003550time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003551 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003552}
3553
3554/*
Tim Peters37f39822003-01-10 03:49:02 +00003555 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003556 */
3557
3558static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003559time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003560{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003561 const char *type_name = Py_TYPE(self)->tp_name;
3562 int h = TIME_GET_HOUR(self);
3563 int m = TIME_GET_MINUTE(self);
3564 int s = TIME_GET_SECOND(self);
3565 int us = TIME_GET_MICROSECOND(self);
3566 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 if (us)
3569 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3570 type_name, h, m, s, us);
3571 else if (s)
3572 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3573 type_name, h, m, s);
3574 else
3575 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3576 if (result != NULL && HASTZINFO(self))
3577 result = append_keyword_tzinfo(result, self->tzinfo);
3578 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003579}
3580
Tim Peters37f39822003-01-10 03:49:02 +00003581static PyObject *
3582time_str(PyDateTime_Time *self)
3583{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003584 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003585
3586 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003587}
Tim Peters2a799bf2002-12-16 20:18:38 +00003588
3589static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003590time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003591{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003592 char buf[100];
3593 PyObject *result;
3594 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003595
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003596 if (us)
3597 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3598 TIME_GET_HOUR(self),
3599 TIME_GET_MINUTE(self),
3600 TIME_GET_SECOND(self),
3601 us);
3602 else
3603 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3604 TIME_GET_HOUR(self),
3605 TIME_GET_MINUTE(self),
3606 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003607
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003608 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003609 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003611 /* We need to append the UTC offset. */
3612 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3613 Py_None) < 0) {
3614 Py_DECREF(result);
3615 return NULL;
3616 }
3617 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3618 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003619}
3620
Tim Peters37f39822003-01-10 03:49:02 +00003621static PyObject *
3622time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003624 PyObject *result;
3625 PyObject *tuple;
3626 PyObject *format;
3627 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003629 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3630 &format))
3631 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003633 /* Python's strftime does insane things with the year part of the
3634 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003635 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003636 */
3637 tuple = Py_BuildValue("iiiiiiiii",
3638 1900, 1, 1, /* year, month, day */
3639 TIME_GET_HOUR(self),
3640 TIME_GET_MINUTE(self),
3641 TIME_GET_SECOND(self),
3642 0, 1, -1); /* weekday, daynum, dst */
3643 if (tuple == NULL)
3644 return NULL;
3645 assert(PyTuple_Size(tuple) == 9);
3646 result = wrap_strftime((PyObject *)self, format, tuple,
3647 Py_None);
3648 Py_DECREF(tuple);
3649 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003650}
Tim Peters2a799bf2002-12-16 20:18:38 +00003651
3652/*
3653 * Miscellaneous methods.
3654 */
3655
Tim Peters37f39822003-01-10 03:49:02 +00003656static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003657time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003658{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003659 PyObject *result = NULL;
3660 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003661 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003662
Brian Curtindfc80e32011-08-10 20:28:54 -05003663 if (! PyTime_Check(other))
3664 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003665
3666 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003667 diff = memcmp(((PyDateTime_Time *)self)->data,
3668 ((PyDateTime_Time *)other)->data,
3669 _PyDateTime_TIME_DATASIZE);
3670 return diff_to_bool(diff, op);
3671 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003672 offset1 = time_utcoffset(self, NULL);
3673 if (offset1 == NULL)
3674 return NULL;
3675 offset2 = time_utcoffset(other, NULL);
3676 if (offset2 == NULL)
3677 goto done;
3678 /* If they're both naive, or both aware and have the same offsets,
3679 * we get off cheap. Note that if they're both naive, offset1 ==
3680 * offset2 == Py_None at this point.
3681 */
3682 if ((offset1 == offset2) ||
3683 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3684 delta_cmp(offset1, offset2) == 0)) {
3685 diff = memcmp(((PyDateTime_Time *)self)->data,
3686 ((PyDateTime_Time *)other)->data,
3687 _PyDateTime_TIME_DATASIZE);
3688 result = diff_to_bool(diff, op);
3689 }
3690 /* The hard case: both aware with different UTC offsets */
3691 else if (offset1 != Py_None && offset2 != Py_None) {
3692 int offsecs1, offsecs2;
3693 assert(offset1 != offset2); /* else last "if" handled it */
3694 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3695 TIME_GET_MINUTE(self) * 60 +
3696 TIME_GET_SECOND(self) -
3697 GET_TD_DAYS(offset1) * 86400 -
3698 GET_TD_SECONDS(offset1);
3699 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3700 TIME_GET_MINUTE(other) * 60 +
3701 TIME_GET_SECOND(other) -
3702 GET_TD_DAYS(offset2) * 86400 -
3703 GET_TD_SECONDS(offset2);
3704 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003705 if (diff == 0)
3706 diff = TIME_GET_MICROSECOND(self) -
3707 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003708 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003709 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003710 else if (op == Py_EQ) {
3711 result = Py_False;
3712 Py_INCREF(result);
3713 }
3714 else if (op == Py_NE) {
3715 result = Py_True;
3716 Py_INCREF(result);
3717 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003718 else {
3719 PyErr_SetString(PyExc_TypeError,
3720 "can't compare offset-naive and "
3721 "offset-aware times");
3722 }
3723 done:
3724 Py_DECREF(offset1);
3725 Py_XDECREF(offset2);
3726 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003727}
3728
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003729static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003730time_hash(PyDateTime_Time *self)
3731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003732 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003733 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003734
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003735 offset = time_utcoffset((PyObject *)self, NULL);
3736
3737 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003738 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003740 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003741 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003742 self->hashcode = generic_hash(
3743 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003744 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003745 PyObject *temp1, *temp2;
3746 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003747 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003748 seconds = TIME_GET_HOUR(self) * 3600 +
3749 TIME_GET_MINUTE(self) * 60 +
3750 TIME_GET_SECOND(self);
3751 microseconds = TIME_GET_MICROSECOND(self);
3752 temp1 = new_delta(0, seconds, microseconds, 1);
3753 if (temp1 == NULL) {
3754 Py_DECREF(offset);
3755 return -1;
3756 }
3757 temp2 = delta_subtract(temp1, offset);
3758 Py_DECREF(temp1);
3759 if (temp2 == NULL) {
3760 Py_DECREF(offset);
3761 return -1;
3762 }
3763 self->hashcode = PyObject_Hash(temp2);
3764 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003765 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003766 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003767 }
3768 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003769}
Tim Peters2a799bf2002-12-16 20:18:38 +00003770
Tim Peters12bf3392002-12-24 05:41:27 +00003771static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003772time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003774 PyObject *clone;
3775 PyObject *tuple;
3776 int hh = TIME_GET_HOUR(self);
3777 int mm = TIME_GET_MINUTE(self);
3778 int ss = TIME_GET_SECOND(self);
3779 int us = TIME_GET_MICROSECOND(self);
3780 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003782 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3783 time_kws,
3784 &hh, &mm, &ss, &us, &tzinfo))
3785 return NULL;
3786 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3787 if (tuple == NULL)
3788 return NULL;
3789 clone = time_new(Py_TYPE(self), tuple, NULL);
3790 Py_DECREF(tuple);
3791 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003792}
3793
Tim Peters2a799bf2002-12-16 20:18:38 +00003794static int
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003795time_bool(PyObject *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003796{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003797 PyObject *offset, *tzinfo;
3798 int offsecs = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003800 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3801 /* Since utcoffset is in whole minutes, nothing can
3802 * alter the conclusion that this is nonzero.
3803 */
3804 return 1;
3805 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003806 tzinfo = GET_TIME_TZINFO(self);
3807 if (tzinfo != Py_None) {
3808 offset = call_utcoffset(tzinfo, Py_None);
3809 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003810 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003811 offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset);
3812 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003813 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003814 return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003815}
3816
Tim Peters371935f2003-02-01 01:52:50 +00003817/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003818
Tim Peters33e0f382003-01-10 02:05:14 +00003819/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003820 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3821 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003822 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003823 */
3824static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003825time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003827 PyObject *basestate;
3828 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003830 basestate = PyBytes_FromStringAndSize((char *)self->data,
3831 _PyDateTime_TIME_DATASIZE);
3832 if (basestate != NULL) {
3833 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3834 result = PyTuple_Pack(1, basestate);
3835 else
3836 result = PyTuple_Pack(2, basestate, self->tzinfo);
3837 Py_DECREF(basestate);
3838 }
3839 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003840}
3841
3842static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003843time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003844{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003845 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003846}
3847
Tim Peters37f39822003-01-10 03:49:02 +00003848static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003850 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3851 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3852 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003854 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3855 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003857 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3858 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003860 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3861 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003863 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3864 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003866 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3867 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003869 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3870 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003872 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3873 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003875 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003876};
3877
Tim Peters37f39822003-01-10 03:49:02 +00003878static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003879PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3880\n\
3881All arguments are optional. tzinfo may be None, or an instance of\n\
3882a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003883
Tim Peters37f39822003-01-10 03:49:02 +00003884static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003885 0, /* nb_add */
3886 0, /* nb_subtract */
3887 0, /* nb_multiply */
3888 0, /* nb_remainder */
3889 0, /* nb_divmod */
3890 0, /* nb_power */
3891 0, /* nb_negative */
3892 0, /* nb_positive */
3893 0, /* nb_absolute */
3894 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003895};
3896
Neal Norwitz227b5332006-03-22 09:28:35 +00003897static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003898 PyVarObject_HEAD_INIT(NULL, 0)
3899 "datetime.time", /* tp_name */
3900 sizeof(PyDateTime_Time), /* tp_basicsize */
3901 0, /* tp_itemsize */
3902 (destructor)time_dealloc, /* tp_dealloc */
3903 0, /* tp_print */
3904 0, /* tp_getattr */
3905 0, /* tp_setattr */
3906 0, /* tp_reserved */
3907 (reprfunc)time_repr, /* tp_repr */
3908 &time_as_number, /* tp_as_number */
3909 0, /* tp_as_sequence */
3910 0, /* tp_as_mapping */
3911 (hashfunc)time_hash, /* tp_hash */
3912 0, /* tp_call */
3913 (reprfunc)time_str, /* tp_str */
3914 PyObject_GenericGetAttr, /* tp_getattro */
3915 0, /* tp_setattro */
3916 0, /* tp_as_buffer */
3917 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3918 time_doc, /* tp_doc */
3919 0, /* tp_traverse */
3920 0, /* tp_clear */
3921 time_richcompare, /* tp_richcompare */
3922 0, /* tp_weaklistoffset */
3923 0, /* tp_iter */
3924 0, /* tp_iternext */
3925 time_methods, /* tp_methods */
3926 0, /* tp_members */
3927 time_getset, /* tp_getset */
3928 0, /* tp_base */
3929 0, /* tp_dict */
3930 0, /* tp_descr_get */
3931 0, /* tp_descr_set */
3932 0, /* tp_dictoffset */
3933 0, /* tp_init */
3934 time_alloc, /* tp_alloc */
3935 time_new, /* tp_new */
3936 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003937};
3938
3939/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003940 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003941 */
3942
Tim Petersa9bc1682003-01-11 03:39:11 +00003943/* Accessor properties. Properties for day, month, and year are inherited
3944 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003945 */
3946
3947static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003948datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003949{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003950 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003951}
3952
Tim Petersa9bc1682003-01-11 03:39:11 +00003953static PyObject *
3954datetime_minute(PyDateTime_DateTime *self, void *unused)
3955{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003956 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003957}
3958
3959static PyObject *
3960datetime_second(PyDateTime_DateTime *self, void *unused)
3961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003962 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003963}
3964
3965static PyObject *
3966datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3967{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003968 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003969}
3970
3971static PyObject *
3972datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3973{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003974 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3975 Py_INCREF(result);
3976 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003977}
3978
3979static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 {"hour", (getter)datetime_hour},
3981 {"minute", (getter)datetime_minute},
3982 {"second", (getter)datetime_second},
3983 {"microsecond", (getter)datetime_microsecond},
3984 {"tzinfo", (getter)datetime_tzinfo},
3985 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003986};
3987
3988/*
3989 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003990 */
3991
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003992static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003993 "year", "month", "day", "hour", "minute", "second",
3994 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003995};
3996
Tim Peters2a799bf2002-12-16 20:18:38 +00003997static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003998datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003999{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004000 PyObject *self = NULL;
4001 PyObject *state;
4002 int year;
4003 int month;
4004 int day;
4005 int hour = 0;
4006 int minute = 0;
4007 int second = 0;
4008 int usecond = 0;
4009 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004011 /* Check for invocation from pickle with __getstate__ state */
4012 if (PyTuple_GET_SIZE(args) >= 1 &&
4013 PyTuple_GET_SIZE(args) <= 2 &&
4014 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4015 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4016 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4017 {
4018 PyDateTime_DateTime *me;
4019 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004021 if (PyTuple_GET_SIZE(args) == 2) {
4022 tzinfo = PyTuple_GET_ITEM(args, 1);
4023 if (check_tzinfo_subclass(tzinfo) < 0) {
4024 PyErr_SetString(PyExc_TypeError, "bad "
4025 "tzinfo state arg");
4026 return NULL;
4027 }
4028 }
4029 aware = (char)(tzinfo != Py_None);
4030 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4031 if (me != NULL) {
4032 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004034 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4035 me->hashcode = -1;
4036 me->hastzinfo = aware;
4037 if (aware) {
4038 Py_INCREF(tzinfo);
4039 me->tzinfo = tzinfo;
4040 }
4041 }
4042 return (PyObject *)me;
4043 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004045 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4046 &year, &month, &day, &hour, &minute,
4047 &second, &usecond, &tzinfo)) {
4048 if (check_date_args(year, month, day) < 0)
4049 return NULL;
4050 if (check_time_args(hour, minute, second, usecond) < 0)
4051 return NULL;
4052 if (check_tzinfo_subclass(tzinfo) < 0)
4053 return NULL;
4054 self = new_datetime_ex(year, month, day,
4055 hour, minute, second, usecond,
4056 tzinfo, type);
4057 }
4058 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004059}
4060
Tim Petersa9bc1682003-01-11 03:39:11 +00004061/* TM_FUNC is the shared type of localtime() and gmtime(). */
4062typedef struct tm *(*TM_FUNC)(const time_t *timer);
4063
4064/* Internal helper.
4065 * Build datetime from a time_t and a distinct count of microseconds.
4066 * Pass localtime or gmtime for f, to control the interpretation of timet.
4067 */
4068static PyObject *
4069datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004070 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004072 struct tm *tm;
Tim Petersa9bc1682003-01-11 03:39:11 +00004073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004074 tm = f(&timet);
Victor Stinner21f58932012-03-14 00:15:40 +01004075 if (tm == NULL) {
4076#ifdef EINVAL
4077 if (errno == 0)
4078 errno = EINVAL;
4079#endif
4080 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004081 }
Victor Stinner21f58932012-03-14 00:15:40 +01004082
4083 /* The platform localtime/gmtime may insert leap seconds,
4084 * indicated by tm->tm_sec > 59. We don't care about them,
4085 * except to the extent that passing them on to the datetime
4086 * constructor would raise ValueError for a reason that
4087 * made no sense to the user.
4088 */
4089 if (tm->tm_sec > 59)
4090 tm->tm_sec = 59;
4091 return PyObject_CallFunction(cls, "iiiiiiiO",
4092 tm->tm_year + 1900,
4093 tm->tm_mon + 1,
4094 tm->tm_mday,
4095 tm->tm_hour,
4096 tm->tm_min,
4097 tm->tm_sec,
4098 us,
4099 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004100}
4101
4102/* Internal helper.
4103 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4104 * to control the interpretation of the timestamp. Since a double doesn't
4105 * have enough bits to cover a datetime's full range of precision, it's
4106 * better to call datetime_from_timet_and_us provided you have a way
4107 * to get that much precision (e.g., C time() isn't good enough).
4108 */
4109static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004110datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004111 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004113 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004114 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004115
Victor Stinner5d272cc2012-03-13 13:35:55 +01004116 if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004117 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004118 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004119}
4120
4121/* Internal helper.
4122 * Build most accurate possible datetime for current time. Pass localtime or
4123 * gmtime for f as appropriate.
4124 */
4125static PyObject *
4126datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4127{
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00004128 _PyTime_timeval t;
4129 _PyTime_gettimeofday(&t);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4131 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004132}
4133
Tim Peters2a799bf2002-12-16 20:18:38 +00004134/* Return best possible local time -- this isn't constrained by the
4135 * precision of a timestamp.
4136 */
4137static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004138datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004140 PyObject *self;
4141 PyObject *tzinfo = Py_None;
4142 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004144 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4145 &tzinfo))
4146 return NULL;
4147 if (check_tzinfo_subclass(tzinfo) < 0)
4148 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004150 self = datetime_best_possible(cls,
4151 tzinfo == Py_None ? localtime : gmtime,
4152 tzinfo);
4153 if (self != NULL && tzinfo != Py_None) {
4154 /* Convert UTC to tzinfo's zone. */
4155 PyObject *temp = self;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004156 _Py_IDENTIFIER(fromutc);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004157
4158 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004159 Py_DECREF(temp);
4160 }
4161 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004162}
4163
Tim Petersa9bc1682003-01-11 03:39:11 +00004164/* Return best possible UTC time -- this isn't constrained by the
4165 * precision of a timestamp.
4166 */
4167static PyObject *
4168datetime_utcnow(PyObject *cls, PyObject *dummy)
4169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004170 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004171}
4172
Tim Peters2a799bf2002-12-16 20:18:38 +00004173/* Return new local datetime from timestamp (Python timestamp -- a double). */
4174static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004175datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004178 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004179 PyObject *tzinfo = Py_None;
4180 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004181
Victor Stinner5d272cc2012-03-13 13:35:55 +01004182 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 keywords, &timestamp, &tzinfo))
4184 return NULL;
4185 if (check_tzinfo_subclass(tzinfo) < 0)
4186 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004188 self = datetime_from_timestamp(cls,
4189 tzinfo == Py_None ? localtime : gmtime,
4190 timestamp,
4191 tzinfo);
4192 if (self != NULL && tzinfo != Py_None) {
4193 /* Convert UTC to tzinfo's zone. */
4194 PyObject *temp = self;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004195 _Py_IDENTIFIER(fromutc);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004196
4197 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004198 Py_DECREF(temp);
4199 }
4200 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004201}
4202
Tim Petersa9bc1682003-01-11 03:39:11 +00004203/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4204static PyObject *
4205datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4206{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004207 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004208 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004209
Victor Stinner5d272cc2012-03-13 13:35:55 +01004210 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004211 result = datetime_from_timestamp(cls, gmtime, timestamp,
4212 Py_None);
4213 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004214}
4215
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004216/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004217static PyObject *
4218datetime_strptime(PyObject *cls, PyObject *args)
4219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004220 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004221 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004222 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004223
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004224 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004225 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004226
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004227 if (module == NULL) {
4228 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004229 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004230 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004231 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004232 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4233 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004234}
4235
Tim Petersa9bc1682003-01-11 03:39:11 +00004236/* Return new datetime from date/datetime and time arguments. */
4237static PyObject *
4238datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004240 static char *keywords[] = {"date", "time", NULL};
4241 PyObject *date;
4242 PyObject *time;
4243 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004245 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4246 &PyDateTime_DateType, &date,
4247 &PyDateTime_TimeType, &time)) {
4248 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004250 if (HASTZINFO(time))
4251 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4252 result = PyObject_CallFunction(cls, "iiiiiiiO",
4253 GET_YEAR(date),
4254 GET_MONTH(date),
4255 GET_DAY(date),
4256 TIME_GET_HOUR(time),
4257 TIME_GET_MINUTE(time),
4258 TIME_GET_SECOND(time),
4259 TIME_GET_MICROSECOND(time),
4260 tzinfo);
4261 }
4262 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004263}
Tim Peters2a799bf2002-12-16 20:18:38 +00004264
4265/*
4266 * Destructor.
4267 */
4268
4269static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004270datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004272 if (HASTZINFO(self)) {
4273 Py_XDECREF(self->tzinfo);
4274 }
4275 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004276}
4277
4278/*
4279 * Indirect access to tzinfo methods.
4280 */
4281
Tim Peters2a799bf2002-12-16 20:18:38 +00004282/* These are all METH_NOARGS, so don't need to check the arglist. */
4283static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004284datetime_utcoffset(PyObject *self, PyObject *unused) {
4285 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004286}
4287
4288static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004289datetime_dst(PyObject *self, PyObject *unused) {
4290 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004291}
4292
4293static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004294datetime_tzname(PyObject *self, PyObject *unused) {
4295 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004296}
4297
4298/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004299 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004300 */
4301
Tim Petersa9bc1682003-01-11 03:39:11 +00004302/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4303 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004304 */
4305static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004306add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004307 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004308{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004309 /* Note that the C-level additions can't overflow, because of
4310 * invariant bounds on the member values.
4311 */
4312 int year = GET_YEAR(date);
4313 int month = GET_MONTH(date);
4314 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4315 int hour = DATE_GET_HOUR(date);
4316 int minute = DATE_GET_MINUTE(date);
4317 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4318 int microsecond = DATE_GET_MICROSECOND(date) +
4319 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004321 assert(factor == 1 || factor == -1);
4322 if (normalize_datetime(&year, &month, &day,
4323 &hour, &minute, &second, &microsecond) < 0)
4324 return NULL;
4325 else
4326 return new_datetime(year, month, day,
4327 hour, minute, second, microsecond,
4328 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004329}
4330
4331static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004332datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004334 if (PyDateTime_Check(left)) {
4335 /* datetime + ??? */
4336 if (PyDelta_Check(right))
4337 /* datetime + delta */
4338 return add_datetime_timedelta(
4339 (PyDateTime_DateTime *)left,
4340 (PyDateTime_Delta *)right,
4341 1);
4342 }
4343 else if (PyDelta_Check(left)) {
4344 /* delta + datetime */
4345 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4346 (PyDateTime_Delta *) left,
4347 1);
4348 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004349 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004350}
4351
4352static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004353datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004355 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004357 if (PyDateTime_Check(left)) {
4358 /* datetime - ??? */
4359 if (PyDateTime_Check(right)) {
4360 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004361 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004362 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004363
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004364 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4365 offset2 = offset1 = Py_None;
4366 Py_INCREF(offset1);
4367 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004368 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004369 else {
4370 offset1 = datetime_utcoffset(left, NULL);
4371 if (offset1 == NULL)
4372 return NULL;
4373 offset2 = datetime_utcoffset(right, NULL);
4374 if (offset2 == NULL) {
4375 Py_DECREF(offset1);
4376 return NULL;
4377 }
4378 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4379 PyErr_SetString(PyExc_TypeError,
4380 "can't subtract offset-naive and "
4381 "offset-aware datetimes");
4382 Py_DECREF(offset1);
4383 Py_DECREF(offset2);
4384 return NULL;
4385 }
4386 }
4387 if ((offset1 != offset2) &&
4388 delta_cmp(offset1, offset2) != 0) {
4389 offdiff = delta_subtract(offset1, offset2);
4390 if (offdiff == NULL) {
4391 Py_DECREF(offset1);
4392 Py_DECREF(offset2);
4393 return NULL;
4394 }
4395 }
4396 Py_DECREF(offset1);
4397 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004398 delta_d = ymd_to_ord(GET_YEAR(left),
4399 GET_MONTH(left),
4400 GET_DAY(left)) -
4401 ymd_to_ord(GET_YEAR(right),
4402 GET_MONTH(right),
4403 GET_DAY(right));
4404 /* These can't overflow, since the values are
4405 * normalized. At most this gives the number of
4406 * seconds in one day.
4407 */
4408 delta_s = (DATE_GET_HOUR(left) -
4409 DATE_GET_HOUR(right)) * 3600 +
4410 (DATE_GET_MINUTE(left) -
4411 DATE_GET_MINUTE(right)) * 60 +
4412 (DATE_GET_SECOND(left) -
4413 DATE_GET_SECOND(right));
4414 delta_us = DATE_GET_MICROSECOND(left) -
4415 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004416 result = new_delta(delta_d, delta_s, delta_us, 1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004417 if (offdiff != NULL) {
4418 PyObject *temp = result;
4419 result = delta_subtract(result, offdiff);
4420 Py_DECREF(temp);
4421 Py_DECREF(offdiff);
4422 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004423 }
4424 else if (PyDelta_Check(right)) {
4425 /* datetime - delta */
4426 result = add_datetime_timedelta(
4427 (PyDateTime_DateTime *)left,
4428 (PyDateTime_Delta *)right,
4429 -1);
4430 }
4431 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004433 if (result == Py_NotImplemented)
4434 Py_INCREF(result);
4435 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004436}
4437
4438/* Various ways to turn a datetime into a string. */
4439
4440static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004441datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004442{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004443 const char *type_name = Py_TYPE(self)->tp_name;
4444 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004446 if (DATE_GET_MICROSECOND(self)) {
4447 baserepr = PyUnicode_FromFormat(
4448 "%s(%d, %d, %d, %d, %d, %d, %d)",
4449 type_name,
4450 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4451 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4452 DATE_GET_SECOND(self),
4453 DATE_GET_MICROSECOND(self));
4454 }
4455 else if (DATE_GET_SECOND(self)) {
4456 baserepr = PyUnicode_FromFormat(
4457 "%s(%d, %d, %d, %d, %d, %d)",
4458 type_name,
4459 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4460 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4461 DATE_GET_SECOND(self));
4462 }
4463 else {
4464 baserepr = PyUnicode_FromFormat(
4465 "%s(%d, %d, %d, %d, %d)",
4466 type_name,
4467 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4468 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4469 }
4470 if (baserepr == NULL || ! HASTZINFO(self))
4471 return baserepr;
4472 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004473}
4474
Tim Petersa9bc1682003-01-11 03:39:11 +00004475static PyObject *
4476datetime_str(PyDateTime_DateTime *self)
4477{
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004478 _Py_IDENTIFIER(isoformat);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004479
4480 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004481}
Tim Peters2a799bf2002-12-16 20:18:38 +00004482
4483static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004484datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004486 int sep = 'T';
4487 static char *keywords[] = {"sep", NULL};
4488 char buffer[100];
4489 PyObject *result;
4490 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004492 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4493 return NULL;
4494 if (us)
4495 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4496 GET_YEAR(self), GET_MONTH(self),
4497 GET_DAY(self), (int)sep,
4498 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4499 DATE_GET_SECOND(self), us);
4500 else
4501 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4502 GET_YEAR(self), GET_MONTH(self),
4503 GET_DAY(self), (int)sep,
4504 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4505 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004507 if (!result || !HASTZINFO(self))
4508 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004510 /* We need to append the UTC offset. */
4511 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4512 (PyObject *)self) < 0) {
4513 Py_DECREF(result);
4514 return NULL;
4515 }
4516 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4517 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004518}
4519
Tim Petersa9bc1682003-01-11 03:39:11 +00004520static PyObject *
4521datetime_ctime(PyDateTime_DateTime *self)
4522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004523 return format_ctime((PyDateTime_Date *)self,
4524 DATE_GET_HOUR(self),
4525 DATE_GET_MINUTE(self),
4526 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004527}
4528
Tim Peters2a799bf2002-12-16 20:18:38 +00004529/* Miscellaneous methods. */
4530
Tim Petersa9bc1682003-01-11 03:39:11 +00004531static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004532datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004533{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004534 PyObject *result = NULL;
4535 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004536 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004538 if (! PyDateTime_Check(other)) {
4539 if (PyDate_Check(other)) {
4540 /* Prevent invocation of date_richcompare. We want to
4541 return NotImplemented here to give the other object
4542 a chance. But since DateTime is a subclass of
4543 Date, if the other object is a Date, it would
4544 compute an ordering based on the date part alone,
4545 and we don't want that. So force unequal or
4546 uncomparable here in that case. */
4547 if (op == Py_EQ)
4548 Py_RETURN_FALSE;
4549 if (op == Py_NE)
4550 Py_RETURN_TRUE;
4551 return cmperror(self, other);
4552 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004553 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004554 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004555
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004556 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004557 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4558 ((PyDateTime_DateTime *)other)->data,
4559 _PyDateTime_DATETIME_DATASIZE);
4560 return diff_to_bool(diff, op);
4561 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004562 offset1 = datetime_utcoffset(self, NULL);
4563 if (offset1 == NULL)
4564 return NULL;
4565 offset2 = datetime_utcoffset(other, NULL);
4566 if (offset2 == NULL)
4567 goto done;
4568 /* If they're both naive, or both aware and have the same offsets,
4569 * we get off cheap. Note that if they're both naive, offset1 ==
4570 * offset2 == Py_None at this point.
4571 */
4572 if ((offset1 == offset2) ||
4573 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4574 delta_cmp(offset1, offset2) == 0)) {
4575 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4576 ((PyDateTime_DateTime *)other)->data,
4577 _PyDateTime_DATETIME_DATASIZE);
4578 result = diff_to_bool(diff, op);
4579 }
4580 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004581 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004582
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004583 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004584 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4585 other);
4586 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004587 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004588 diff = GET_TD_DAYS(delta);
4589 if (diff == 0)
4590 diff = GET_TD_SECONDS(delta) |
4591 GET_TD_MICROSECONDS(delta);
4592 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004593 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004594 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004595 else if (op == Py_EQ) {
4596 result = Py_False;
4597 Py_INCREF(result);
4598 }
4599 else if (op == Py_NE) {
4600 result = Py_True;
4601 Py_INCREF(result);
4602 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004603 else {
4604 PyErr_SetString(PyExc_TypeError,
4605 "can't compare offset-naive and "
4606 "offset-aware datetimes");
4607 }
4608 done:
4609 Py_DECREF(offset1);
4610 Py_XDECREF(offset2);
4611 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004612}
4613
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004614static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004615datetime_hash(PyDateTime_DateTime *self)
4616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004617 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004618 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004619
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004620 offset = datetime_utcoffset((PyObject *)self, NULL);
4621
4622 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004623 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004625 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004626 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004627 self->hashcode = generic_hash(
4628 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004629 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004630 PyObject *temp1, *temp2;
4631 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004633 assert(HASTZINFO(self));
4634 days = ymd_to_ord(GET_YEAR(self),
4635 GET_MONTH(self),
4636 GET_DAY(self));
4637 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004638 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004640 temp1 = new_delta(days, seconds,
4641 DATE_GET_MICROSECOND(self),
4642 1);
4643 if (temp1 == NULL) {
4644 Py_DECREF(offset);
4645 return -1;
4646 }
4647 temp2 = delta_subtract(temp1, offset);
4648 Py_DECREF(temp1);
4649 if (temp2 == NULL) {
4650 Py_DECREF(offset);
4651 return -1;
4652 }
4653 self->hashcode = PyObject_Hash(temp2);
4654 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004655 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004656 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004657 }
4658 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004659}
Tim Peters2a799bf2002-12-16 20:18:38 +00004660
4661static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004662datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004663{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004664 PyObject *clone;
4665 PyObject *tuple;
4666 int y = GET_YEAR(self);
4667 int m = GET_MONTH(self);
4668 int d = GET_DAY(self);
4669 int hh = DATE_GET_HOUR(self);
4670 int mm = DATE_GET_MINUTE(self);
4671 int ss = DATE_GET_SECOND(self);
4672 int us = DATE_GET_MICROSECOND(self);
4673 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004675 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4676 datetime_kws,
4677 &y, &m, &d, &hh, &mm, &ss, &us,
4678 &tzinfo))
4679 return NULL;
4680 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4681 if (tuple == NULL)
4682 return NULL;
4683 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4684 Py_DECREF(tuple);
4685 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004686}
4687
4688static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004689datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004690{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004691 PyObject *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004692 PyObject *offset;
4693 PyObject *temp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004694 PyObject *tzinfo;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004695 _Py_IDENTIFIER(fromutc);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004696 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004698 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4699 &PyDateTime_TZInfoType, &tzinfo))
4700 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004702 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4703 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004705 /* Conversion to self's own time zone is a NOP. */
4706 if (self->tzinfo == tzinfo) {
4707 Py_INCREF(self);
4708 return (PyObject *)self;
4709 }
Tim Peters521fc152002-12-31 17:36:56 +00004710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004711 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004712 offset = datetime_utcoffset((PyObject *)self, NULL);
4713 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004714 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004715 if (offset == Py_None) {
4716 Py_DECREF(offset);
4717 NeedAware:
4718 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4719 "a naive datetime");
4720 return NULL;
4721 }
Tim Petersf3615152003-01-01 21:51:37 +00004722
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004723 /* result = self - offset */
4724 result = add_datetime_timedelta(self,
4725 (PyDateTime_Delta *)offset, -1);
4726 Py_DECREF(offset);
4727 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004728 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004730 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004731 temp = ((PyDateTime_DateTime *)result)->tzinfo;
4732 ((PyDateTime_DateTime *)result)->tzinfo = tzinfo;
4733 Py_INCREF(tzinfo);
4734 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004735
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004736 temp = result;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004737 result = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004738 Py_DECREF(temp);
4739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004740 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004741}
4742
4743static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004744datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004746 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004748 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004749 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004750
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004751 dst = call_dst(self->tzinfo, (PyObject *)self);
4752 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004753 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004754
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004755 if (dst != Py_None)
4756 dstflag = delta_bool((PyDateTime_Delta *)dst);
4757 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004758 }
4759 return build_struct_time(GET_YEAR(self),
4760 GET_MONTH(self),
4761 GET_DAY(self),
4762 DATE_GET_HOUR(self),
4763 DATE_GET_MINUTE(self),
4764 DATE_GET_SECOND(self),
4765 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004766}
4767
4768static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04004769datetime_timestamp(PyDateTime_DateTime *self)
4770{
4771 PyObject *result;
4772
4773 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4774 PyObject *delta;
4775 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
4776 if (delta == NULL)
4777 return NULL;
4778 result = delta_total_seconds(delta);
4779 Py_DECREF(delta);
4780 }
4781 else {
4782 struct tm time;
4783 time_t timestamp;
4784 memset((void *) &time, '\0', sizeof(struct tm));
4785 time.tm_year = GET_YEAR(self) - 1900;
4786 time.tm_mon = GET_MONTH(self) - 1;
4787 time.tm_mday = GET_DAY(self);
4788 time.tm_hour = DATE_GET_HOUR(self);
4789 time.tm_min = DATE_GET_MINUTE(self);
4790 time.tm_sec = DATE_GET_SECOND(self);
4791 time.tm_wday = -1;
4792 time.tm_isdst = -1;
4793 timestamp = mktime(&time);
4794 /* Return value of -1 does not necessarily mean an error, but tm_wday
4795 * cannot remain set to -1 if mktime succeeded. */
4796 if (timestamp == (time_t)(-1) && time.tm_wday == -1) {
4797 PyErr_SetString(PyExc_OverflowError,
4798 "timestamp out of range");
4799 return NULL;
4800 }
4801 result = PyFloat_FromDouble(timestamp + DATE_GET_MICROSECOND(self) / 1e6);
4802 }
4803 return result;
4804}
4805
4806static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004807datetime_getdate(PyDateTime_DateTime *self)
4808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004809 return new_date(GET_YEAR(self),
4810 GET_MONTH(self),
4811 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004812}
4813
4814static PyObject *
4815datetime_gettime(PyDateTime_DateTime *self)
4816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004817 return new_time(DATE_GET_HOUR(self),
4818 DATE_GET_MINUTE(self),
4819 DATE_GET_SECOND(self),
4820 DATE_GET_MICROSECOND(self),
4821 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004822}
4823
4824static PyObject *
4825datetime_gettimetz(PyDateTime_DateTime *self)
4826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004827 return new_time(DATE_GET_HOUR(self),
4828 DATE_GET_MINUTE(self),
4829 DATE_GET_SECOND(self),
4830 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004831 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004832}
4833
4834static PyObject *
4835datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004836{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004837 int y, m, d, hh, mm, ss;
4838 PyObject *tzinfo;
4839 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004840
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004841 tzinfo = GET_DT_TZINFO(self);
4842 if (tzinfo == Py_None) {
4843 utcself = self;
4844 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004845 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004846 else {
4847 PyObject *offset;
4848 offset = call_utcoffset(tzinfo, (PyObject *)self);
4849 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004850 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004851 if (offset == Py_None) {
4852 Py_DECREF(offset);
4853 utcself = self;
4854 Py_INCREF(utcself);
4855 }
4856 else {
4857 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4858 (PyDateTime_Delta *)offset, -1);
4859 Py_DECREF(offset);
4860 if (utcself == NULL)
4861 return NULL;
4862 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004863 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004864 y = GET_YEAR(utcself);
4865 m = GET_MONTH(utcself);
4866 d = GET_DAY(utcself);
4867 hh = DATE_GET_HOUR(utcself);
4868 mm = DATE_GET_MINUTE(utcself);
4869 ss = DATE_GET_SECOND(utcself);
4870
4871 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004872 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004873}
4874
Tim Peters371935f2003-02-01 01:52:50 +00004875/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004876
Tim Petersa9bc1682003-01-11 03:39:11 +00004877/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004878 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4879 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004880 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004881 */
4882static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004883datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004885 PyObject *basestate;
4886 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004888 basestate = PyBytes_FromStringAndSize((char *)self->data,
4889 _PyDateTime_DATETIME_DATASIZE);
4890 if (basestate != NULL) {
4891 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4892 result = PyTuple_Pack(1, basestate);
4893 else
4894 result = PyTuple_Pack(2, basestate, self->tzinfo);
4895 Py_DECREF(basestate);
4896 }
4897 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004898}
4899
4900static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004901datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004902{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004903 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004904}
4905
Tim Petersa9bc1682003-01-11 03:39:11 +00004906static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004908 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004910 {"now", (PyCFunction)datetime_now,
4911 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4912 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004914 {"utcnow", (PyCFunction)datetime_utcnow,
4915 METH_NOARGS | METH_CLASS,
4916 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004918 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4919 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4920 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004922 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4923 METH_VARARGS | METH_CLASS,
4924 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4925 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004927 {"strptime", (PyCFunction)datetime_strptime,
4928 METH_VARARGS | METH_CLASS,
4929 PyDoc_STR("string, format -> new datetime parsed from a string "
4930 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004932 {"combine", (PyCFunction)datetime_combine,
4933 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4934 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004936 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004938 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4939 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004941 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4942 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004944 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4945 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004947 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4948 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004950 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4951 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004952
Alexander Belopolskya4415142012-06-08 12:33:09 -04004953 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
4954 PyDoc_STR("Return POSIX timestamp as float.")},
4955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004956 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4957 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004959 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4960 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4961 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4962 "sep is used to separate the year from the time, and "
4963 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004965 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4966 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004968 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4969 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004971 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4972 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004974 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4975 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004977 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4978 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004980 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4981 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004983 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004984};
4985
Tim Petersa9bc1682003-01-11 03:39:11 +00004986static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004987PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4988\n\
4989The year, month and day arguments are required. tzinfo may be None, or an\n\
4990instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004991
Tim Petersa9bc1682003-01-11 03:39:11 +00004992static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004993 datetime_add, /* nb_add */
4994 datetime_subtract, /* nb_subtract */
4995 0, /* nb_multiply */
4996 0, /* nb_remainder */
4997 0, /* nb_divmod */
4998 0, /* nb_power */
4999 0, /* nb_negative */
5000 0, /* nb_positive */
5001 0, /* nb_absolute */
5002 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005003};
5004
Neal Norwitz227b5332006-03-22 09:28:35 +00005005static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005006 PyVarObject_HEAD_INIT(NULL, 0)
5007 "datetime.datetime", /* tp_name */
5008 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5009 0, /* tp_itemsize */
5010 (destructor)datetime_dealloc, /* tp_dealloc */
5011 0, /* tp_print */
5012 0, /* tp_getattr */
5013 0, /* tp_setattr */
5014 0, /* tp_reserved */
5015 (reprfunc)datetime_repr, /* tp_repr */
5016 &datetime_as_number, /* tp_as_number */
5017 0, /* tp_as_sequence */
5018 0, /* tp_as_mapping */
5019 (hashfunc)datetime_hash, /* tp_hash */
5020 0, /* tp_call */
5021 (reprfunc)datetime_str, /* tp_str */
5022 PyObject_GenericGetAttr, /* tp_getattro */
5023 0, /* tp_setattro */
5024 0, /* tp_as_buffer */
5025 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5026 datetime_doc, /* tp_doc */
5027 0, /* tp_traverse */
5028 0, /* tp_clear */
5029 datetime_richcompare, /* tp_richcompare */
5030 0, /* tp_weaklistoffset */
5031 0, /* tp_iter */
5032 0, /* tp_iternext */
5033 datetime_methods, /* tp_methods */
5034 0, /* tp_members */
5035 datetime_getset, /* tp_getset */
5036 &PyDateTime_DateType, /* tp_base */
5037 0, /* tp_dict */
5038 0, /* tp_descr_get */
5039 0, /* tp_descr_set */
5040 0, /* tp_dictoffset */
5041 0, /* tp_init */
5042 datetime_alloc, /* tp_alloc */
5043 datetime_new, /* tp_new */
5044 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005045};
5046
5047/* ---------------------------------------------------------------------------
5048 * Module methods and initialization.
5049 */
5050
5051static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005052 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005053};
5054
Tim Peters9ddf40b2004-06-20 22:41:32 +00005055/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5056 * datetime.h.
5057 */
5058static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005059 &PyDateTime_DateType,
5060 &PyDateTime_DateTimeType,
5061 &PyDateTime_TimeType,
5062 &PyDateTime_DeltaType,
5063 &PyDateTime_TZInfoType,
5064 new_date_ex,
5065 new_datetime_ex,
5066 new_time_ex,
5067 new_delta_ex,
5068 datetime_fromtimestamp,
5069 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005070};
5071
5072
Martin v. Löwis1a214512008-06-11 05:26:20 +00005073
5074static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005075 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005076 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005077 "Fast implementation of the datetime type.",
5078 -1,
5079 module_methods,
5080 NULL,
5081 NULL,
5082 NULL,
5083 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005084};
5085
Tim Peters2a799bf2002-12-16 20:18:38 +00005086PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005087PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005088{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005089 PyObject *m; /* a module object */
5090 PyObject *d; /* its dict */
5091 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005092 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005094 m = PyModule_Create(&datetimemodule);
5095 if (m == NULL)
5096 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005098 if (PyType_Ready(&PyDateTime_DateType) < 0)
5099 return NULL;
5100 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5101 return NULL;
5102 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5103 return NULL;
5104 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5105 return NULL;
5106 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5107 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005108 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5109 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005111 /* timedelta values */
5112 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005114 x = new_delta(0, 0, 1, 0);
5115 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5116 return NULL;
5117 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005119 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5120 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5121 return NULL;
5122 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005124 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5125 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5126 return NULL;
5127 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005129 /* date values */
5130 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005132 x = new_date(1, 1, 1);
5133 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5134 return NULL;
5135 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005137 x = new_date(MAXYEAR, 12, 31);
5138 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5139 return NULL;
5140 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005142 x = new_delta(1, 0, 0, 0);
5143 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5144 return NULL;
5145 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005147 /* time values */
5148 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005150 x = new_time(0, 0, 0, 0, Py_None);
5151 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5152 return NULL;
5153 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005155 x = new_time(23, 59, 59, 999999, Py_None);
5156 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5157 return NULL;
5158 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005160 x = new_delta(0, 0, 1, 0);
5161 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5162 return NULL;
5163 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005165 /* datetime values */
5166 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005168 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5169 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5170 return NULL;
5171 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005173 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5174 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5175 return NULL;
5176 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005178 x = new_delta(0, 0, 1, 0);
5179 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5180 return NULL;
5181 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005182
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005183 /* timezone values */
5184 d = PyDateTime_TimeZoneType.tp_dict;
5185
5186 delta = new_delta(0, 0, 0, 0);
5187 if (delta == NULL)
5188 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005189 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005190 Py_DECREF(delta);
5191 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5192 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005193 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005194
5195 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5196 if (delta == NULL)
5197 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005198 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005199 Py_DECREF(delta);
5200 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5201 return NULL;
5202 Py_DECREF(x);
5203
5204 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5205 if (delta == NULL)
5206 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005207 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005208 Py_DECREF(delta);
5209 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5210 return NULL;
5211 Py_DECREF(x);
5212
Alexander Belopolskya4415142012-06-08 12:33:09 -04005213 /* Epoch */
5214 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
5215 PyDateTime_TimeZone_UTC);
5216 if (PyDateTime_Epoch == NULL)
5217 return NULL;
5218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005219 /* module initialization */
5220 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5221 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005223 Py_INCREF(&PyDateTime_DateType);
5224 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005226 Py_INCREF(&PyDateTime_DateTimeType);
5227 PyModule_AddObject(m, "datetime",
5228 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005230 Py_INCREF(&PyDateTime_TimeType);
5231 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005233 Py_INCREF(&PyDateTime_DeltaType);
5234 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005236 Py_INCREF(&PyDateTime_TZInfoType);
5237 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005238
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005239 Py_INCREF(&PyDateTime_TimeZoneType);
5240 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005242 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5243 if (x == NULL)
5244 return NULL;
5245 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005247 /* A 4-year cycle has an extra leap day over what we'd get from
5248 * pasting together 4 single years.
5249 */
5250 assert(DI4Y == 4 * 365 + 1);
5251 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005253 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5254 * get from pasting together 4 100-year cycles.
5255 */
5256 assert(DI400Y == 4 * DI100Y + 1);
5257 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005259 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5260 * pasting together 25 4-year cycles.
5261 */
5262 assert(DI100Y == 25 * DI4Y - 1);
5263 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005265 us_per_us = PyLong_FromLong(1);
5266 us_per_ms = PyLong_FromLong(1000);
5267 us_per_second = PyLong_FromLong(1000000);
5268 us_per_minute = PyLong_FromLong(60000000);
5269 seconds_per_day = PyLong_FromLong(24 * 3600);
5270 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5271 us_per_minute == NULL || seconds_per_day == NULL)
5272 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005274 /* The rest are too big for 32-bit ints, but even
5275 * us_per_week fits in 40 bits, so doubles should be exact.
5276 */
5277 us_per_hour = PyLong_FromDouble(3600000000.0);
5278 us_per_day = PyLong_FromDouble(86400000000.0);
5279 us_per_week = PyLong_FromDouble(604800000000.0);
5280 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5281 return NULL;
5282 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005283}
Tim Petersf3615152003-01-01 21:51:37 +00005284
5285/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005286Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005287 x.n = x stripped of its timezone -- its naive time.
5288 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005289 return None
Tim Petersf3615152003-01-01 21:51:37 +00005290 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005291 return None
Tim Petersf3615152003-01-01 21:51:37 +00005292 x.s = x's standard offset, x.o - x.d
5293
5294Now some derived rules, where k is a duration (timedelta).
5295
52961. x.o = x.s + x.d
5297 This follows from the definition of x.s.
5298
Tim Petersc5dc4da2003-01-02 17:55:03 +000052992. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005300 This is actually a requirement, an assumption we need to make about
5301 sane tzinfo classes.
5302
53033. The naive UTC time corresponding to x is x.n - x.o.
5304 This is again a requirement for a sane tzinfo class.
5305
53064. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005307 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005308
Tim Petersc5dc4da2003-01-02 17:55:03 +000053095. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005310 Again follows from how arithmetic is defined.
5311
Tim Peters8bb5ad22003-01-24 02:44:45 +00005312Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005313(meaning that the various tzinfo methods exist, and don't blow up or return
5314None when called).
5315
Tim Petersa9bc1682003-01-11 03:39:11 +00005316The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005317x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005318
5319By #3, we want
5320
Tim Peters8bb5ad22003-01-24 02:44:45 +00005321 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005322
5323The algorithm starts by attaching tz to x.n, and calling that y. So
5324x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5325becomes true; in effect, we want to solve [2] for k:
5326
Tim Peters8bb5ad22003-01-24 02:44:45 +00005327 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005328
5329By #1, this is the same as
5330
Tim Peters8bb5ad22003-01-24 02:44:45 +00005331 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005332
5333By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5334Substituting that into [3],
5335
Tim Peters8bb5ad22003-01-24 02:44:45 +00005336 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5337 k - (y+k).s - (y+k).d = 0; rearranging,
5338 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5339 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005340
Tim Peters8bb5ad22003-01-24 02:44:45 +00005341On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5342approximate k by ignoring the (y+k).d term at first. Note that k can't be
5343very large, since all offset-returning methods return a duration of magnitude
5344less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5345be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005346
5347In any case, the new value is
5348
Tim Peters8bb5ad22003-01-24 02:44:45 +00005349 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005350
Tim Peters8bb5ad22003-01-24 02:44:45 +00005351It's helpful to step back at look at [4] from a higher level: it's simply
5352mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005353
5354At this point, if
5355
Tim Peters8bb5ad22003-01-24 02:44:45 +00005356 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005357
5358we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005359at the start of daylight time. Picture US Eastern for concreteness. The wall
5360time 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 +00005361sense then. The docs ask that an Eastern tzinfo class consider such a time to
5362be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5363on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005364the only spelling that makes sense on the local wall clock.
5365
Tim Petersc5dc4da2003-01-02 17:55:03 +00005366In fact, if [5] holds at this point, we do have the standard-time spelling,
5367but that takes a bit of proof. We first prove a stronger result. What's the
5368difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005369
Tim Peters8bb5ad22003-01-24 02:44:45 +00005370 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005371
Tim Petersc5dc4da2003-01-02 17:55:03 +00005372Now
5373 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005374 (y + y.s).n = by #5
5375 y.n + y.s = since y.n = x.n
5376 x.n + y.s = since z and y are have the same tzinfo member,
5377 y.s = z.s by #2
5378 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005379
Tim Petersc5dc4da2003-01-02 17:55:03 +00005380Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005381
Tim Petersc5dc4da2003-01-02 17:55:03 +00005382 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005383 x.n - ((x.n + z.s) - z.o) = expanding
5384 x.n - x.n - z.s + z.o = cancelling
5385 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005386 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005387
Tim Petersc5dc4da2003-01-02 17:55:03 +00005388So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005389
Tim Petersc5dc4da2003-01-02 17:55:03 +00005390If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005391spelling we wanted in the endcase described above. We're done. Contrarily,
5392if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005393
Tim Petersc5dc4da2003-01-02 17:55:03 +00005394If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5395add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005396local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005397
Tim Petersc5dc4da2003-01-02 17:55:03 +00005398Let
Tim Petersf3615152003-01-01 21:51:37 +00005399
Tim Peters4fede1a2003-01-04 00:26:59 +00005400 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005401
Tim Peters4fede1a2003-01-04 00:26:59 +00005402and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005403
Tim Peters8bb5ad22003-01-24 02:44:45 +00005404 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005405
Tim Peters8bb5ad22003-01-24 02:44:45 +00005406If so, we're done. If not, the tzinfo class is insane, according to the
5407assumptions we've made. This also requires a bit of proof. As before, let's
5408compute the difference between the LHS and RHS of [8] (and skipping some of
5409the justifications for the kinds of substitutions we've done several times
5410already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005411
Tim Peters8bb5ad22003-01-24 02:44:45 +00005412 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005413 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5414 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5415 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5416 - z.n + z.n - z.o + z'.o = cancel z.n
5417 - z.o + z'.o = #1 twice
5418 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5419 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005420
5421So 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 +00005422we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5423return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005424
Tim Peters8bb5ad22003-01-24 02:44:45 +00005425How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5426a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5427would have to change the result dst() returns: we start in DST, and moving
5428a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005429
Tim Peters8bb5ad22003-01-24 02:44:45 +00005430There isn't a sane case where this can happen. The closest it gets is at
5431the end of DST, where there's an hour in UTC with no spelling in a hybrid
5432tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5433that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5434UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5435time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5436clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5437standard time. Since that's what the local clock *does*, we want to map both
5438UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005439in local time, but so it goes -- it's the way the local clock works.
5440
Tim Peters8bb5ad22003-01-24 02:44:45 +00005441When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5442so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5443z' = 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 +00005444(correctly) concludes that z' is not UTC-equivalent to x.
5445
5446Because we know z.d said z was in daylight time (else [5] would have held and
5447we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005448and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005449return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5450but the reasoning doesn't depend on the example -- it depends on there being
5451two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005452z' must be in standard time, and is the spelling we want in this case.
5453
5454Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5455concerned (because it takes z' as being in standard time rather than the
5456daylight time we intend here), but returning it gives the real-life "local
5457clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5458tz.
5459
5460When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5461the 1:MM standard time spelling we want.
5462
5463So how can this break? One of the assumptions must be violated. Two
5464possibilities:
5465
54661) [2] effectively says that y.s is invariant across all y belong to a given
5467 time zone. This isn't true if, for political reasons or continental drift,
5468 a region decides to change its base offset from UTC.
5469
54702) There may be versions of "double daylight" time where the tail end of
5471 the analysis gives up a step too early. I haven't thought about that
5472 enough to say.
5473
5474In any case, it's clear that the default fromutc() is strong enough to handle
5475"almost all" time zones: so long as the standard offset is invariant, it
5476doesn't matter if daylight time transition points change from year to year, or
5477if daylight time is skipped in some years; it doesn't matter how large or
5478small dst() may get within its bounds; and it doesn't even matter if some
5479perverse time zone returns a negative dst()). So a breaking case must be
5480pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005481--------------------------------------------------------------------------- */