blob: ed045205fe795bdd250e1c860feb2a6be0b5bf61 [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"
6#include "modsupport.h"
7#include "structmember.h"
8
9#include <time.h>
10
Tim Peters1b6f7a92004-06-20 02:50:16 +000011#include "timefuncs.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000012
13/* Differentiate between building the core module and building extension
14 * modules.
15 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000016#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000017#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000018#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000019#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000020#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000021
22/* We require that C int be at least 32 bits, and use int virtually
23 * everywhere. In just a few cases we use a temp long, where a Python
24 * API returns a C long. In such cases, we have to ensure that the
25 * final result fits in a C int (this can be an issue on 64-bit boxes).
26 */
27#if SIZEOF_INT < 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028# error "datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000029#endif
30
31#define MINYEAR 1
32#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000033#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000034
35/* Nine decimal digits is easy to communicate, and leaves enough room
36 * so that two delta days can be added w/o fear of overflowing a signed
37 * 32-bit int, and with plenty of room left over to absorb any possible
38 * carries from adding seconds.
39 */
40#define MAX_DELTA_DAYS 999999999
41
42/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043#define GET_YEAR PyDateTime_GET_YEAR
44#define GET_MONTH PyDateTime_GET_MONTH
45#define GET_DAY PyDateTime_GET_DAY
46#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
47#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
48#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
49#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000050
51/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
53 ((o)->data[1] = ((v) & 0x00ff)))
54#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
55#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000056
57/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
59#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
60#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
61#define DATE_SET_MICROSECOND(o, v) \
62 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
63 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
64 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000065
66/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
68#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
69#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
70#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
71#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
72#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
73#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
74#define TIME_SET_MICROSECOND(o, v) \
75 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
76 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
77 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000078
79/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
81#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
82#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084#define SET_TD_DAYS(o, v) ((o)->days = (v))
85#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000086#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
87
Tim Petersa032d2e2003-01-11 00:15:54 +000088/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
89 * p->hastzinfo.
90 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
Tim Petersa032d2e2003-01-11 00:15:54 +000092
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
241 * can see is 0 (this can happen in some normalization endcases),
242 * so we'll just special-case that.
243 */
244 assert (year >= 0);
245 if (y >= 0)
246 return y*365 + y/4 - y/100 + y/400;
247 else {
248 assert(y == -1);
249 return -366;
250 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000251}
252
253/* Number of days in 4, 100, and 400 year cycles. That these have
254 * the correct values is asserted in the module init function.
255 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256#define DI4Y 1461 /* days_before_year(5); days in 4 years */
257#define DI100Y 36524 /* days_before_year(101); days in 100 years */
258#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000259
260/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
261static void
262ord_to_ymd(int ordinal, int *year, int *month, int *day)
263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
267 * leap years repeats exactly every 400 years. The basic strategy is
268 * to find the closest 400-year boundary at or before ordinal, then
269 * work with the offset from that boundary to ordinal. Life is much
270 * clearer if we subtract 1 from ordinal first -- then the values
271 * of ordinal at 400-year boundaries are exactly those divisible
272 * by DI400Y:
273 *
274 * D M Y n n-1
275 * -- --- ---- ---------- ----------------
276 * 31 Dec -400 -DI400Y -DI400Y -1
277 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
278 * ...
279 * 30 Dec 000 -1 -2
280 * 31 Dec 000 0 -1
281 * 1 Jan 001 1 0 400-year boundary
282 * 2 Jan 001 2 1
283 * 3 Jan 001 3 2
284 * ...
285 * 31 Dec 400 DI400Y DI400Y -1
286 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
287 */
288 assert(ordinal >= 1);
289 --ordinal;
290 n400 = ordinal / DI400Y;
291 n = ordinal % DI400Y;
292 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 /* Now n is the (non-negative) offset, in days, from January 1 of
295 * year, to the desired date. Now compute how many 100-year cycles
296 * precede n.
297 * Note that it's possible for n100 to equal 4! In that case 4 full
298 * 100-year cycles precede the desired day, which implies the
299 * desired day is December 31 at the end of a 400-year cycle.
300 */
301 n100 = n / DI100Y;
302 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 /* Now compute how many 4-year cycles precede it. */
305 n4 = n / DI4Y;
306 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 /* And now how many single years. Again n1 can be 4, and again
309 * meaning that the desired day is December 31 at the end of the
310 * 4-year cycle.
311 */
312 n1 = n / 365;
313 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 *year += n100 * 100 + n4 * 4 + n1;
316 if (n1 == 4 || n100 == 4) {
317 assert(n == 0);
318 *year -= 1;
319 *month = 12;
320 *day = 31;
321 return;
322 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 /* Now the year is correct, and n is the offset from January 1. We
325 * find the month via an estimate that's either exact or one too
326 * large.
327 */
328 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
329 assert(leapyear == is_leap(*year));
330 *month = (n + 50) >> 5;
331 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
332 if (preceding > n) {
333 /* estimate is too large */
334 *month -= 1;
335 preceding -= days_in_month(*year, *month);
336 }
337 n -= preceding;
338 assert(0 <= n);
339 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000342}
343
344/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
345static int
346ymd_to_ord(int year, int month, int day)
347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000349}
350
351/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
352static int
353weekday(int year, int month, int day)
354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000356}
357
358/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
359 * first calendar week containing a Thursday.
360 */
361static int
362iso_week1_monday(int year)
363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
365 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
366 int first_weekday = (first_day + 6) % 7;
367 /* ordinal of closest Monday at or before 1/1 */
368 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
371 week1_monday += 7;
372 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000373}
374
375/* ---------------------------------------------------------------------------
376 * Range checkers.
377 */
378
379/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
380 * If not, raise OverflowError and return -1.
381 */
382static int
383check_delta_day_range(int days)
384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
386 return 0;
387 PyErr_Format(PyExc_OverflowError,
388 "days=%d; must have magnitude <= %d",
389 days, MAX_DELTA_DAYS);
390 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000391}
392
393/* Check that date arguments are in range. Return 0 if they are. If they
394 * aren't, raise ValueError and return -1.
395 */
396static int
397check_date_args(int year, int month, int day)
398{
399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 if (year < MINYEAR || year > MAXYEAR) {
401 PyErr_SetString(PyExc_ValueError,
402 "year is out of range");
403 return -1;
404 }
405 if (month < 1 || month > 12) {
406 PyErr_SetString(PyExc_ValueError,
407 "month must be in 1..12");
408 return -1;
409 }
410 if (day < 1 || day > days_in_month(year, month)) {
411 PyErr_SetString(PyExc_ValueError,
412 "day is out of range for month");
413 return -1;
414 }
415 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000416}
417
418/* Check that time arguments are in range. Return 0 if they are. If they
419 * aren't, raise ValueError and return -1.
420 */
421static int
422check_time_args(int h, int m, int s, int us)
423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 if (h < 0 || h > 23) {
425 PyErr_SetString(PyExc_ValueError,
426 "hour must be in 0..23");
427 return -1;
428 }
429 if (m < 0 || m > 59) {
430 PyErr_SetString(PyExc_ValueError,
431 "minute must be in 0..59");
432 return -1;
433 }
434 if (s < 0 || s > 59) {
435 PyErr_SetString(PyExc_ValueError,
436 "second must be in 0..59");
437 return -1;
438 }
439 if (us < 0 || us > 999999) {
440 PyErr_SetString(PyExc_ValueError,
441 "microsecond must be in 0..999999");
442 return -1;
443 }
444 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000445}
446
447/* ---------------------------------------------------------------------------
448 * Normalization utilities.
449 */
450
451/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
452 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
453 * at least factor, enough of *lo is converted into "hi" units so that
454 * 0 <= *lo < factor. The input values must be such that int overflow
455 * is impossible.
456 */
457static void
458normalize_pair(int *hi, int *lo, int factor)
459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 assert(factor > 0);
461 assert(lo != hi);
462 if (*lo < 0 || *lo >= factor) {
463 const int num_hi = divmod(*lo, factor, lo);
464 const int new_hi = *hi + num_hi;
465 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
466 *hi = new_hi;
467 }
468 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000469}
470
471/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 * 0 <= *s < 24*3600
473 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000474 * The input values must be such that the internals don't overflow.
475 * The way this routine is used, we don't get close.
476 */
477static void
478normalize_d_s_us(int *d, int *s, int *us)
479{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 if (*us < 0 || *us >= 1000000) {
481 normalize_pair(s, us, 1000000);
482 /* |s| can't be bigger than about
483 * |original s| + |original us|/1000000 now.
484 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 }
487 if (*s < 0 || *s >= 24*3600) {
488 normalize_pair(d, s, 24*3600);
489 /* |d| can't be bigger than about
490 * |original d| +
491 * (|original s| + |original us|/1000000) / (24*3600) now.
492 */
493 }
494 assert(0 <= *s && *s < 24*3600);
495 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000496}
497
498/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 * 1 <= *m <= 12
500 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000501 * The input values must be such that the internals don't overflow.
502 * The way this routine is used, we don't get close.
503 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000504static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000505normalize_y_m_d(int *y, int *m, int *d)
506{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 /* This gets muddy: the proper range for day can't be determined
510 * without knowing the correct month and year, but if day is, e.g.,
511 * plus or minus a million, the current month and year values make
512 * no sense (and may also be out of bounds themselves).
513 * Saying 12 months == 1 year should be non-controversial.
514 */
515 if (*m < 1 || *m > 12) {
516 --*m;
517 normalize_pair(y, m, 12);
518 ++*m;
519 /* |y| can't be bigger than about
520 * |original y| + |original m|/12 now.
521 */
522 }
523 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 /* Now only day can be out of bounds (year may also be out of bounds
526 * for a datetime object, but we don't care about that here).
527 * If day is out of bounds, what to do is arguable, but at least the
528 * method here is principled and explainable.
529 */
530 dim = days_in_month(*y, *m);
531 if (*d < 1 || *d > dim) {
532 /* Move day-1 days from the first of the month. First try to
533 * get off cheap if we're only one day out of range
534 * (adjustments for timezone alone can't be worse than that).
535 */
536 if (*d == 0) {
537 --*m;
538 if (*m > 0)
539 *d = days_in_month(*y, *m);
540 else {
541 --*y;
542 *m = 12;
543 *d = 31;
544 }
545 }
546 else if (*d == dim + 1) {
547 /* move forward a day */
548 ++*m;
549 *d = 1;
550 if (*m > 12) {
551 *m = 1;
552 ++*y;
553 }
554 }
555 else {
556 int ordinal = ymd_to_ord(*y, *m, 1) +
557 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000558 if (ordinal < 1 || ordinal > MAXORDINAL) {
559 goto error;
560 } else {
561 ord_to_ymd(ordinal, y, m, d);
562 return 0;
563 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 }
565 }
566 assert(*m > 0);
567 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000568 if (MINYEAR <= *y && *y <= MAXYEAR)
569 return 0;
570 error:
571 PyErr_SetString(PyExc_OverflowError,
572 "date value out of range");
573 return -1;
574
Tim Peters2a799bf2002-12-16 20:18:38 +0000575}
576
577/* Fiddle out-of-bounds months and days so that the result makes some kind
578 * of sense. The parameters are both inputs and outputs. Returns < 0 on
579 * failure, where failure means the adjusted year is out of bounds.
580 */
581static int
582normalize_date(int *year, int *month, int *day)
583{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000584 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000585}
586
587/* Force all the datetime fields into range. The parameters are both
588 * inputs and outputs. Returns < 0 on error.
589 */
590static int
591normalize_datetime(int *year, int *month, int *day,
592 int *hour, int *minute, int *second,
593 int *microsecond)
594{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 normalize_pair(second, microsecond, 1000000);
596 normalize_pair(minute, second, 60);
597 normalize_pair(hour, minute, 60);
598 normalize_pair(day, hour, 24);
599 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000600}
601
602/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000603 * Basic object allocation: tp_alloc implementations. These allocate
604 * Python objects of the right size and type, and do the Python object-
605 * initialization bit. If there's not enough memory, they return NULL after
606 * setting MemoryError. All data members remain uninitialized trash.
607 *
608 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000609 * member is needed. This is ugly, imprecise, and possibly insecure.
610 * tp_basicsize for the time and datetime types is set to the size of the
611 * struct that has room for the tzinfo member, so subclasses in Python will
612 * allocate enough space for a tzinfo member whether or not one is actually
613 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
614 * part is that PyType_GenericAlloc() (which subclasses in Python end up
615 * using) just happens today to effectively ignore the nitems argument
616 * when tp_itemsize is 0, which it is for these type objects. If that
617 * changes, perhaps the callers of tp_alloc slots in this file should
618 * be changed to force a 0 nitems argument unless the type being allocated
619 * is a base type implemented in this file (so that tp_alloc is time_alloc
620 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000621 */
622
623static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000624time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 self = (PyObject *)
629 PyObject_MALLOC(aware ?
630 sizeof(PyDateTime_Time) :
631 sizeof(_PyDateTime_BaseTime));
632 if (self == NULL)
633 return (PyObject *)PyErr_NoMemory();
634 PyObject_INIT(self, type);
635 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000636}
637
638static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000639datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 self = (PyObject *)
644 PyObject_MALLOC(aware ?
645 sizeof(PyDateTime_DateTime) :
646 sizeof(_PyDateTime_BaseDateTime));
647 if (self == NULL)
648 return (PyObject *)PyErr_NoMemory();
649 PyObject_INIT(self, type);
650 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000651}
652
653/* ---------------------------------------------------------------------------
654 * Helpers for setting object fields. These work on pointers to the
655 * appropriate base class.
656 */
657
658/* For date and datetime. */
659static void
660set_date_fields(PyDateTime_Date *self, int y, int m, int d)
661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 self->hashcode = -1;
663 SET_YEAR(self, y);
664 SET_MONTH(self, m);
665 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000666}
667
668/* ---------------------------------------------------------------------------
669 * Create various objects, mostly without range checking.
670 */
671
672/* Create a date instance with no range checking. */
673static PyObject *
674new_date_ex(int year, int month, int day, PyTypeObject *type)
675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
679 if (self != NULL)
680 set_date_fields(self, year, month, day);
681 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000682}
683
684#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000686
687/* Create a datetime instance with no range checking. */
688static PyObject *
689new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 PyDateTime_DateTime *self;
693 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
696 if (self != NULL) {
697 self->hastzinfo = aware;
698 set_date_fields((PyDateTime_Date *)self, year, month, day);
699 DATE_SET_HOUR(self, hour);
700 DATE_SET_MINUTE(self, minute);
701 DATE_SET_SECOND(self, second);
702 DATE_SET_MICROSECOND(self, usecond);
703 if (aware) {
704 Py_INCREF(tzinfo);
705 self->tzinfo = tzinfo;
706 }
707 }
708 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000709}
710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
712 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
713 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000714
715/* Create a time instance with no range checking. */
716static PyObject *
717new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 PyDateTime_Time *self;
721 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
724 if (self != NULL) {
725 self->hastzinfo = aware;
726 self->hashcode = -1;
727 TIME_SET_HOUR(self, hour);
728 TIME_SET_MINUTE(self, minute);
729 TIME_SET_SECOND(self, second);
730 TIME_SET_MICROSECOND(self, usecond);
731 if (aware) {
732 Py_INCREF(tzinfo);
733 self->tzinfo = tzinfo;
734 }
735 }
736 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000737}
738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739#define new_time(hh, mm, ss, us, tzinfo) \
740 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000741
742/* Create a timedelta instance. Normalize the members iff normalize is
743 * true. Passing false is a speed optimization, if you know for sure
744 * that seconds and microseconds are already in their proper ranges. In any
745 * case, raises OverflowError and returns NULL if the normalized days is out
746 * of range).
747 */
748static PyObject *
749new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 if (normalize)
755 normalize_d_s_us(&days, &seconds, &microseconds);
756 assert(0 <= seconds && seconds < 24*3600);
757 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 if (check_delta_day_range(days) < 0)
760 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
763 if (self != NULL) {
764 self->hashcode = -1;
765 SET_TD_DAYS(self, days);
766 SET_TD_SECONDS(self, seconds);
767 SET_TD_MICROSECONDS(self, microseconds);
768 }
769 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000770}
771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772#define new_delta(d, s, us, normalize) \
773 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000774
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000775
776typedef struct
777{
778 PyObject_HEAD
779 PyObject *offset;
780 PyObject *name;
781} PyDateTime_TimeZone;
782
783/* Create new timezone instance checking offset range. This
784 function does not check the name argument. Caller must assure
785 that offset is a timedelta instance and name is either NULL
786 or a unicode object. */
787static PyObject *
788new_timezone(PyObject *offset, PyObject *name)
789{
790 PyDateTime_TimeZone *self;
791 PyTypeObject *type = &PyDateTime_TimeZoneType;
792
793 assert(offset != NULL);
794 assert(PyDelta_Check(offset));
795 assert(name == NULL || PyUnicode_Check(name));
796
797 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
798 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
799 " representing a whole number of minutes");
800 return NULL;
801 }
802 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
803 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
804 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
805 " strictly between -timedelta(hours=24) and"
806 " timedelta(hours=24).");
807 return NULL;
808 }
809
810 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
811 if (self == NULL) {
812 return NULL;
813 }
814 Py_INCREF(offset);
815 self->offset = offset;
816 Py_XINCREF(name);
817 self->name = name;
818 return (PyObject *)self;
819}
820
Tim Petersb0c854d2003-05-17 15:57:00 +0000821/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000822 * tzinfo helpers.
823 */
824
Tim Peters855fe882002-12-22 03:43:39 +0000825/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
826 * raise TypeError and return -1.
827 */
828static int
829check_tzinfo_subclass(PyObject *p)
830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 if (p == Py_None || PyTZInfo_Check(p))
832 return 0;
833 PyErr_Format(PyExc_TypeError,
834 "tzinfo argument must be None or of a tzinfo subclass, "
835 "not type '%s'",
836 Py_TYPE(p)->tp_name);
837 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000838}
839
Tim Petersbad8ff02002-12-30 20:52:32 +0000840/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000841 * If tzinfo is None, returns None.
842 */
843static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000844call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 assert(tzinfo && methname && tzinfoarg);
849 assert(check_tzinfo_subclass(tzinfo) >= 0);
850 if (tzinfo == Py_None) {
851 result = Py_None;
852 Py_INCREF(result);
853 }
854 else
855 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
856 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000857}
858
Tim Peters2a799bf2002-12-16 20:18:38 +0000859/* If self has a tzinfo member, return a BORROWED reference to it. Else
860 * return NULL, which is NOT AN ERROR. There are no error returns here,
861 * and the caller must not decref the result.
862 */
863static PyObject *
864get_tzinfo_member(PyObject *self)
865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 if (PyDateTime_Check(self) && HASTZINFO(self))
869 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
870 else if (PyTime_Check(self) && HASTZINFO(self))
871 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000874}
875
Tim Petersbad8ff02002-12-30 20:52:32 +0000876/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000877 * result. tzinfo must be an instance of the tzinfo class. If the method
878 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000879 * return None or timedelta, TypeError is raised and this returns -1. If it
880 * returnsa timedelta and the value is out of range or isn't a whole number
881 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000882 * Else *none is set to 0 and the integer method result is returned.
883 */
884static int
885call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 int *none)
Tim Peters2a799bf2002-12-16 20:18:38 +0000887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 PyObject *u;
889 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 assert(tzinfo != NULL);
892 assert(PyTZInfo_Check(tzinfo));
893 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 *none = 0;
896 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
897 if (u == NULL)
898 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 else if (u == Py_None) {
901 result = 0;
902 *none = 1;
903 }
904 else if (PyDelta_Check(u)) {
905 const int days = GET_TD_DAYS(u);
906 if (days < -1 || days > 0)
907 result = 24*60; /* trigger ValueError below */
908 else {
909 /* next line can't overflow because we know days
910 * is -1 or 0 now
911 */
912 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
913 result = divmod(ss, 60, &ss);
914 if (ss || GET_TD_MICROSECONDS(u)) {
915 PyErr_Format(PyExc_ValueError,
916 "tzinfo.%s() must return a "
917 "whole number of minutes",
918 name);
919 result = -1;
920 }
921 }
922 }
923 else {
924 PyErr_Format(PyExc_TypeError,
925 "tzinfo.%s() must return None or "
926 "timedelta, not '%s'",
927 name, Py_TYPE(u)->tp_name);
928 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 Py_DECREF(u);
931 if (result < -1439 || result > 1439) {
932 PyErr_Format(PyExc_ValueError,
933 "tzinfo.%s() returned %d; must be in "
934 "-1439 .. 1439",
935 name, result);
936 result = -1;
937 }
938 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000939}
940
941/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
942 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
943 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000944 * doesn't return None or timedelta, TypeError is raised and this returns -1.
945 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
946 * # of minutes), ValueError is raised and this returns -1. Else *none is
947 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000948 */
949static int
950call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000953}
954
Tim Petersbad8ff02002-12-30 20:52:32 +0000955/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
956 */
Tim Peters855fe882002-12-22 03:43:39 +0000957static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000958offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 assert(tzinfo && name && tzinfoarg);
962 if (tzinfo == Py_None) {
963 result = Py_None;
964 Py_INCREF(result);
965 }
966 else {
967 int none;
968 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
969 &none);
970 if (offset < 0 && PyErr_Occurred())
971 return NULL;
972 if (none) {
973 result = Py_None;
974 Py_INCREF(result);
975 }
976 else
977 result = new_delta(0, offset * 60, 0, 1);
978 }
979 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000980}
981
Tim Peters2a799bf2002-12-16 20:18:38 +0000982/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
983 * result. tzinfo must be an instance of the tzinfo class. If dst()
984 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000985 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000986 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000987 * ValueError is raised and this returns -1. Else *none is set to 0 and
988 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000989 */
990static int
991call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000994}
995
Tim Petersbad8ff02002-12-30 20:52:32 +0000996/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000997 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000998 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000999 * returns NULL. If the result is a string, we ensure it is a Unicode
1000 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001001 */
1002static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001003call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 assert(tzinfo != NULL);
1008 assert(check_tzinfo_subclass(tzinfo) >= 0);
1009 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 if (tzinfo == Py_None) {
1012 result = Py_None;
1013 Py_INCREF(result);
1014 }
1015 else
1016 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 if (result != NULL && result != Py_None) {
1019 if (!PyUnicode_Check(result)) {
1020 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1021 "return None or a string, not '%s'",
1022 Py_TYPE(result)->tp_name);
1023 Py_DECREF(result);
1024 result = NULL;
1025 }
1026 else if (!PyUnicode_Check(result)) {
1027 PyObject *temp = PyUnicode_FromObject(result);
1028 Py_DECREF(result);
1029 result = temp;
1030 }
1031 }
1032 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001033}
1034
1035typedef enum {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 /* an exception has been set; the caller should pass it on */
1037 OFFSET_ERROR,
Tim Peters2a799bf2002-12-16 20:18:38 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 /* type isn't date, datetime, or time subclass */
1040 OFFSET_UNKNOWN,
Tim Peters2a799bf2002-12-16 20:18:38 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 /* date,
1043 * datetime with !hastzinfo
1044 * datetime with None tzinfo,
1045 * datetime where utcoffset() returns None
1046 * time with !hastzinfo
1047 * time with None tzinfo,
1048 * time where utcoffset() returns None
1049 */
1050 OFFSET_NAIVE,
Tim Peters2a799bf2002-12-16 20:18:38 +00001051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 /* time or datetime where utcoffset() doesn't return None */
1053 OFFSET_AWARE
Tim Peters2a799bf2002-12-16 20:18:38 +00001054} naivety;
1055
Tim Peters14b69412002-12-22 18:10:22 +00001056/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +00001057 * the "naivety" typedef for details. If the type is aware, *offset is set
1058 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +00001059 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +00001060 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +00001061 */
1062static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +00001063classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +00001064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 int none;
1066 PyObject *tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 assert(tzinfoarg != NULL);
1069 *offset = 0;
1070 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
1071 if (tzinfo == Py_None)
1072 return OFFSET_NAIVE;
1073 if (tzinfo == NULL) {
1074 /* note that a datetime passes the PyDate_Check test */
1075 return (PyTime_Check(op) || PyDate_Check(op)) ?
1076 OFFSET_NAIVE : OFFSET_UNKNOWN;
1077 }
1078 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1079 if (*offset == -1 && PyErr_Occurred())
1080 return OFFSET_ERROR;
1081 return none ? OFFSET_NAIVE : OFFSET_AWARE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001082}
1083
Tim Peters00237032002-12-27 02:21:51 +00001084/* Classify two objects as to whether they're naive or offset-aware.
1085 * This isn't quite the same as calling classify_utcoffset() twice: for
1086 * binary operations (comparison and subtraction), we generally want to
1087 * ignore the tzinfo members if they're identical. This is by design,
1088 * so that results match "naive" expectations when mixing objects from a
1089 * single timezone. So in that case, this sets both offsets to 0 and
1090 * both naiveties to OFFSET_NAIVE.
1091 * The function returns 0 if everything's OK, and -1 on error.
1092 */
1093static int
1094classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 PyObject *tzinfoarg1,
1096 PyObject *o2, int *offset2, naivety *n2,
1097 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1100 *offset1 = *offset2 = 0;
1101 *n1 = *n2 = OFFSET_NAIVE;
1102 }
1103 else {
1104 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1105 if (*n1 == OFFSET_ERROR)
1106 return -1;
1107 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1108 if (*n2 == OFFSET_ERROR)
1109 return -1;
1110 }
1111 return 0;
Tim Peters00237032002-12-27 02:21:51 +00001112}
1113
Tim Peters2a799bf2002-12-16 20:18:38 +00001114/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1115 * stuff
1116 * ", tzinfo=" + repr(tzinfo)
1117 * before the closing ")".
1118 */
1119static PyObject *
1120append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 assert(PyUnicode_Check(repr));
1125 assert(tzinfo);
1126 if (tzinfo == Py_None)
1127 return repr;
1128 /* Get rid of the trailing ')'. */
1129 assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
1130 temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
1131 PyUnicode_GET_SIZE(repr) - 1);
1132 Py_DECREF(repr);
1133 if (temp == NULL)
1134 return NULL;
1135 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1136 Py_DECREF(temp);
1137 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001138}
1139
1140/* ---------------------------------------------------------------------------
1141 * String format helpers.
1142 */
1143
1144static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001145format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 static const char *DayNames[] = {
1148 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1149 };
1150 static const char *MonthNames[] = {
1151 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1152 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1153 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1158 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1159 GET_DAY(date), hours, minutes, seconds,
1160 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001161}
1162
1163/* Add an hours & minutes UTC offset string to buf. buf has no more than
1164 * buflen bytes remaining. The UTC offset is gotten by calling
1165 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1166 * *buf, and that's all. Else the returned value is checked for sanity (an
1167 * integer in range), and if that's OK it's converted to an hours & minutes
1168 * string of the form
1169 * sign HH sep MM
1170 * Returns 0 if everything is OK. If the return value from utcoffset() is
1171 * bogus, an appropriate exception is set and -1 is returned.
1172 */
1173static int
Tim Peters328fff72002-12-20 01:31:27 +00001174format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 int offset;
1178 int hours;
1179 int minutes;
1180 char sign;
1181 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00001182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1186 if (offset == -1 && PyErr_Occurred())
1187 return -1;
1188 if (none) {
1189 *buf = '\0';
1190 return 0;
1191 }
1192 sign = '+';
1193 if (offset < 0) {
1194 sign = '-';
1195 offset = - offset;
1196 }
1197 hours = divmod(offset, 60, &minutes);
1198 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1199 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001200}
1201
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001202static PyObject *
1203make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 PyObject *temp;
1206 PyObject *tzinfo = get_tzinfo_member(object);
1207 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1208 if (Zreplacement == NULL)
1209 return NULL;
1210 if (tzinfo == Py_None || tzinfo == NULL)
1211 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 assert(tzinfoarg != NULL);
1214 temp = call_tzname(tzinfo, tzinfoarg);
1215 if (temp == NULL)
1216 goto Error;
1217 if (temp == Py_None) {
1218 Py_DECREF(temp);
1219 return Zreplacement;
1220 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 assert(PyUnicode_Check(temp));
1223 /* Since the tzname is getting stuffed into the
1224 * format, we have to double any % signs so that
1225 * strftime doesn't treat them as format codes.
1226 */
1227 Py_DECREF(Zreplacement);
1228 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1229 Py_DECREF(temp);
1230 if (Zreplacement == NULL)
1231 return NULL;
1232 if (!PyUnicode_Check(Zreplacement)) {
1233 PyErr_SetString(PyExc_TypeError,
1234 "tzname.replace() did not return a string");
1235 goto Error;
1236 }
1237 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001238
1239 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 Py_DECREF(Zreplacement);
1241 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001242}
1243
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001244static PyObject *
1245make_freplacement(PyObject *object)
1246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 char freplacement[64];
1248 if (PyTime_Check(object))
1249 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1250 else if (PyDateTime_Check(object))
1251 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1252 else
1253 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001256}
1257
Tim Peters2a799bf2002-12-16 20:18:38 +00001258/* I sure don't want to reproduce the strftime code from the time module,
1259 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001260 * giving special meanings to the %z, %Z and %f format codes via a
1261 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001262 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1263 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001264 */
1265static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001266wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1272 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1273 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 const char *pin; /* pointer to next char in input format */
1276 Py_ssize_t flen; /* length of input format */
1277 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 PyObject *newfmt = NULL; /* py string, the output format */
1280 char *pnew; /* pointer to available byte in output format */
1281 size_t totalnew; /* number bytes total in output format buffer,
1282 exclusive of trailing \0 */
1283 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 const char *ptoappend; /* ptr to string to append to output buffer */
1286 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 assert(object && format && timetuple);
1289 assert(PyUnicode_Check(format));
1290 /* Convert the input format to a C string and size */
1291 pin = _PyUnicode_AsStringAndSize(format, &flen);
1292 if (!pin)
1293 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 /* Give up if the year is before 1900.
1296 * Python strftime() plays games with the year, and different
1297 * games depending on whether envar PYTHON2K is set. This makes
1298 * years before 1900 a nightmare, even if the platform strftime
1299 * supports them (and not all do).
1300 * We could get a lot farther here by avoiding Python's strftime
1301 * wrapper and calling the C strftime() directly, but that isn't
1302 * an option in the Python implementation of this module.
1303 */
1304 {
1305 long year;
1306 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1307 if (pyyear == NULL) return NULL;
1308 assert(PyLong_Check(pyyear));
1309 year = PyLong_AsLong(pyyear);
1310 Py_DECREF(pyyear);
1311 if (year < 1900) {
1312 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1313 "1900; the datetime strftime() "
1314 "methods require year >= 1900",
1315 year);
1316 return NULL;
1317 }
1318 }
Tim Petersd6844152002-12-22 20:58:42 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 /* Scan the input format, looking for %z/%Z/%f escapes, building
1321 * a new format. Since computing the replacements for those codes
1322 * is expensive, don't unless they're actually used.
1323 */
1324 if (flen > INT_MAX - 1) {
1325 PyErr_NoMemory();
1326 goto Done;
1327 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 totalnew = flen + 1; /* realistic if no %z/%Z */
1330 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1331 if (newfmt == NULL) goto Done;
1332 pnew = PyBytes_AsString(newfmt);
1333 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 while ((ch = *pin++) != '\0') {
1336 if (ch != '%') {
1337 ptoappend = pin - 1;
1338 ntoappend = 1;
1339 }
1340 else if ((ch = *pin++) == '\0') {
1341 /* There's a lone trailing %; doesn't make sense. */
1342 PyErr_SetString(PyExc_ValueError, "strftime format "
1343 "ends with raw %");
1344 goto Done;
1345 }
1346 /* A % has been seen and ch is the character after it. */
1347 else if (ch == 'z') {
1348 if (zreplacement == NULL) {
1349 /* format utcoffset */
1350 char buf[100];
1351 PyObject *tzinfo = get_tzinfo_member(object);
1352 zreplacement = PyBytes_FromStringAndSize("", 0);
1353 if (zreplacement == NULL) goto Done;
1354 if (tzinfo != Py_None && tzinfo != NULL) {
1355 assert(tzinfoarg != NULL);
1356 if (format_utcoffset(buf,
1357 sizeof(buf),
1358 "",
1359 tzinfo,
1360 tzinfoarg) < 0)
1361 goto Done;
1362 Py_DECREF(zreplacement);
1363 zreplacement =
1364 PyBytes_FromStringAndSize(buf,
1365 strlen(buf));
1366 if (zreplacement == NULL)
1367 goto Done;
1368 }
1369 }
1370 assert(zreplacement != NULL);
1371 ptoappend = PyBytes_AS_STRING(zreplacement);
1372 ntoappend = PyBytes_GET_SIZE(zreplacement);
1373 }
1374 else if (ch == 'Z') {
1375 /* format tzname */
1376 if (Zreplacement == NULL) {
1377 Zreplacement = make_Zreplacement(object,
1378 tzinfoarg);
1379 if (Zreplacement == NULL)
1380 goto Done;
1381 }
1382 assert(Zreplacement != NULL);
1383 assert(PyUnicode_Check(Zreplacement));
1384 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1385 &ntoappend);
1386 ntoappend = Py_SIZE(Zreplacement);
1387 }
1388 else if (ch == 'f') {
1389 /* format microseconds */
1390 if (freplacement == NULL) {
1391 freplacement = make_freplacement(object);
1392 if (freplacement == NULL)
1393 goto Done;
1394 }
1395 assert(freplacement != NULL);
1396 assert(PyBytes_Check(freplacement));
1397 ptoappend = PyBytes_AS_STRING(freplacement);
1398 ntoappend = PyBytes_GET_SIZE(freplacement);
1399 }
1400 else {
1401 /* percent followed by neither z nor Z */
1402 ptoappend = pin - 2;
1403 ntoappend = 2;
1404 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 /* Append the ntoappend chars starting at ptoappend to
1407 * the new format.
1408 */
1409 if (ntoappend == 0)
1410 continue;
1411 assert(ptoappend != NULL);
1412 assert(ntoappend > 0);
1413 while (usednew + ntoappend > totalnew) {
1414 size_t bigger = totalnew << 1;
1415 if ((bigger >> 1) != totalnew) { /* overflow */
1416 PyErr_NoMemory();
1417 goto Done;
1418 }
1419 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1420 goto Done;
1421 totalnew = bigger;
1422 pnew = PyBytes_AsString(newfmt) + usednew;
1423 }
1424 memcpy(pnew, ptoappend, ntoappend);
1425 pnew += ntoappend;
1426 usednew += ntoappend;
1427 assert(usednew <= totalnew);
1428 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1431 goto Done;
1432 {
1433 PyObject *format;
1434 PyObject *time = PyImport_ImportModuleNoBlock("time");
1435 if (time == NULL)
1436 goto Done;
1437 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1438 if (format != NULL) {
1439 result = PyObject_CallMethod(time, "strftime", "OO",
1440 format, timetuple);
1441 Py_DECREF(format);
1442 }
1443 Py_DECREF(time);
1444 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001445 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 Py_XDECREF(freplacement);
1447 Py_XDECREF(zreplacement);
1448 Py_XDECREF(Zreplacement);
1449 Py_XDECREF(newfmt);
1450 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001451}
1452
Tim Peters2a799bf2002-12-16 20:18:38 +00001453/* ---------------------------------------------------------------------------
1454 * Wrap functions from the time module. These aren't directly available
1455 * from C. Perhaps they should be.
1456 */
1457
1458/* Call time.time() and return its result (a Python float). */
1459static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001460time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 PyObject *result = NULL;
1463 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 if (time != NULL) {
1466 result = PyObject_CallMethod(time, "time", "()");
1467 Py_DECREF(time);
1468 }
1469 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001470}
1471
1472/* Build a time.struct_time. The weekday and day number are automatically
1473 * computed from the y,m,d args.
1474 */
1475static PyObject *
1476build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 PyObject *time;
1479 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 time = PyImport_ImportModuleNoBlock("time");
1482 if (time != NULL) {
1483 result = PyObject_CallMethod(time, "struct_time",
1484 "((iiiiiiiii))",
1485 y, m, d,
1486 hh, mm, ss,
1487 weekday(y, m, d),
1488 days_before_month(y, m) + d,
1489 dstflag);
1490 Py_DECREF(time);
1491 }
1492 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001493}
1494
1495/* ---------------------------------------------------------------------------
1496 * Miscellaneous helpers.
1497 */
1498
Mark Dickinsone94c6792009-02-02 20:36:42 +00001499/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001500 * The comparisons here all most naturally compute a cmp()-like result.
1501 * This little helper turns that into a bool result for rich comparisons.
1502 */
1503static PyObject *
1504diff_to_bool(int diff, int op)
1505{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 PyObject *result;
1507 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 switch (op) {
1510 case Py_EQ: istrue = diff == 0; break;
1511 case Py_NE: istrue = diff != 0; break;
1512 case Py_LE: istrue = diff <= 0; break;
1513 case Py_GE: istrue = diff >= 0; break;
1514 case Py_LT: istrue = diff < 0; break;
1515 case Py_GT: istrue = diff > 0; break;
1516 default:
1517 assert(! "op unknown");
1518 istrue = 0; /* To shut up compiler */
1519 }
1520 result = istrue ? Py_True : Py_False;
1521 Py_INCREF(result);
1522 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001523}
1524
Tim Peters07534a62003-02-07 22:50:28 +00001525/* Raises a "can't compare" TypeError and returns NULL. */
1526static PyObject *
1527cmperror(PyObject *a, PyObject *b)
1528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 PyErr_Format(PyExc_TypeError,
1530 "can't compare %s to %s",
1531 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1532 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001533}
1534
Tim Peters2a799bf2002-12-16 20:18:38 +00001535/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001536 * Cached Python objects; these are set by the module init function.
1537 */
1538
1539/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540static PyObject *us_per_us = NULL; /* 1 */
1541static PyObject *us_per_ms = NULL; /* 1000 */
1542static PyObject *us_per_second = NULL; /* 1000000 */
1543static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1544static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1545static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1546static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001547static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1548
Tim Peters2a799bf2002-12-16 20:18:38 +00001549/* ---------------------------------------------------------------------------
1550 * Class implementations.
1551 */
1552
1553/*
1554 * PyDateTime_Delta implementation.
1555 */
1556
1557/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001559 * as a Python int or long.
1560 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1561 * due to ubiquitous overflow possibilities.
1562 */
1563static PyObject *
1564delta_to_microseconds(PyDateTime_Delta *self)
1565{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 PyObject *x1 = NULL;
1567 PyObject *x2 = NULL;
1568 PyObject *x3 = NULL;
1569 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1572 if (x1 == NULL)
1573 goto Done;
1574 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1575 if (x2 == NULL)
1576 goto Done;
1577 Py_DECREF(x1);
1578 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 /* x2 has days in seconds */
1581 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1582 if (x1 == NULL)
1583 goto Done;
1584 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1585 if (x3 == NULL)
1586 goto Done;
1587 Py_DECREF(x1);
1588 Py_DECREF(x2);
1589 x1 = x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 /* x3 has days+seconds in seconds */
1592 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1593 if (x1 == NULL)
1594 goto Done;
1595 Py_DECREF(x3);
1596 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 /* x1 has days+seconds in us */
1599 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1600 if (x2 == NULL)
1601 goto Done;
1602 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001603
1604Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 Py_XDECREF(x1);
1606 Py_XDECREF(x2);
1607 Py_XDECREF(x3);
1608 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001609}
1610
1611/* Convert a number of us (as a Python int or long) to a timedelta.
1612 */
1613static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001614microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 int us;
1617 int s;
1618 int d;
1619 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyObject *tuple = NULL;
1622 PyObject *num = NULL;
1623 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 tuple = PyNumber_Divmod(pyus, us_per_second);
1626 if (tuple == NULL)
1627 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 num = PyTuple_GetItem(tuple, 1); /* us */
1630 if (num == NULL)
1631 goto Done;
1632 temp = PyLong_AsLong(num);
1633 num = NULL;
1634 if (temp == -1 && PyErr_Occurred())
1635 goto Done;
1636 assert(0 <= temp && temp < 1000000);
1637 us = (int)temp;
1638 if (us < 0) {
1639 /* The divisor was positive, so this must be an error. */
1640 assert(PyErr_Occurred());
1641 goto Done;
1642 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1645 if (num == NULL)
1646 goto Done;
1647 Py_INCREF(num);
1648 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 tuple = PyNumber_Divmod(num, seconds_per_day);
1651 if (tuple == NULL)
1652 goto Done;
1653 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 num = PyTuple_GetItem(tuple, 1); /* seconds */
1656 if (num == NULL)
1657 goto Done;
1658 temp = PyLong_AsLong(num);
1659 num = NULL;
1660 if (temp == -1 && PyErr_Occurred())
1661 goto Done;
1662 assert(0 <= temp && temp < 24*3600);
1663 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 if (s < 0) {
1666 /* The divisor was positive, so this must be an error. */
1667 assert(PyErr_Occurred());
1668 goto Done;
1669 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1672 if (num == NULL)
1673 goto Done;
1674 Py_INCREF(num);
1675 temp = PyLong_AsLong(num);
1676 if (temp == -1 && PyErr_Occurred())
1677 goto Done;
1678 d = (int)temp;
1679 if ((long)d != temp) {
1680 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1681 "large to fit in a C int");
1682 goto Done;
1683 }
1684 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001685
1686Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 Py_XDECREF(tuple);
1688 Py_XDECREF(num);
1689 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001690}
1691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692#define microseconds_to_delta(pymicros) \
1693 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001694
Tim Peters2a799bf2002-12-16 20:18:38 +00001695static PyObject *
1696multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1697{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 PyObject *pyus_in;
1699 PyObject *pyus_out;
1700 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 pyus_in = delta_to_microseconds(delta);
1703 if (pyus_in == NULL)
1704 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1707 Py_DECREF(pyus_in);
1708 if (pyus_out == NULL)
1709 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 result = microseconds_to_delta(pyus_out);
1712 Py_DECREF(pyus_out);
1713 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001714}
1715
1716static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001717multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1718{
1719 PyObject *result = NULL;
1720 PyObject *pyus_in = NULL, *temp, *pyus_out;
1721 PyObject *ratio = NULL;
1722
1723 pyus_in = delta_to_microseconds(delta);
1724 if (pyus_in == NULL)
1725 return NULL;
1726 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1727 if (ratio == NULL)
1728 goto error;
1729 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1730 Py_DECREF(pyus_in);
1731 pyus_in = NULL;
1732 if (temp == NULL)
1733 goto error;
1734 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1735 Py_DECREF(temp);
1736 if (pyus_out == NULL)
1737 goto error;
1738 result = microseconds_to_delta(pyus_out);
1739 Py_DECREF(pyus_out);
1740 error:
1741 Py_XDECREF(pyus_in);
1742 Py_XDECREF(ratio);
1743
1744 return result;
1745}
1746
1747static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001748divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 PyObject *pyus_in;
1751 PyObject *pyus_out;
1752 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 pyus_in = delta_to_microseconds(delta);
1755 if (pyus_in == NULL)
1756 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1759 Py_DECREF(pyus_in);
1760 if (pyus_out == NULL)
1761 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 result = microseconds_to_delta(pyus_out);
1764 Py_DECREF(pyus_out);
1765 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001766}
1767
1768static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001769divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 PyObject *pyus_left;
1772 PyObject *pyus_right;
1773 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 pyus_left = delta_to_microseconds(left);
1776 if (pyus_left == NULL)
1777 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 pyus_right = delta_to_microseconds(right);
1780 if (pyus_right == NULL) {
1781 Py_DECREF(pyus_left);
1782 return NULL;
1783 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001784
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1786 Py_DECREF(pyus_left);
1787 Py_DECREF(pyus_right);
1788 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001789}
1790
1791static PyObject *
1792truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 PyObject *pyus_left;
1795 PyObject *pyus_right;
1796 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 pyus_left = delta_to_microseconds(left);
1799 if (pyus_left == NULL)
1800 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 pyus_right = delta_to_microseconds(right);
1803 if (pyus_right == NULL) {
1804 Py_DECREF(pyus_left);
1805 return NULL;
1806 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1809 Py_DECREF(pyus_left);
1810 Py_DECREF(pyus_right);
1811 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001812}
1813
1814static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001815truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1816{
1817 PyObject *result = NULL;
1818 PyObject *pyus_in = NULL, *temp, *pyus_out;
1819 PyObject *ratio = NULL;
1820
1821 pyus_in = delta_to_microseconds(delta);
1822 if (pyus_in == NULL)
1823 return NULL;
1824 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1825 if (ratio == NULL)
1826 goto error;
1827 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1828 Py_DECREF(pyus_in);
1829 pyus_in = NULL;
1830 if (temp == NULL)
1831 goto error;
1832 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1833 Py_DECREF(temp);
1834 if (pyus_out == NULL)
1835 goto error;
1836 result = microseconds_to_delta(pyus_out);
1837 Py_DECREF(pyus_out);
1838 error:
1839 Py_XDECREF(pyus_in);
1840 Py_XDECREF(ratio);
1841
1842 return result;
1843}
1844
1845static PyObject *
1846truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1847{
1848 PyObject *result;
1849 PyObject *pyus_in, *pyus_out;
1850 pyus_in = delta_to_microseconds(delta);
1851 if (pyus_in == NULL)
1852 return NULL;
1853 pyus_out = divide_nearest(pyus_in, i);
1854 Py_DECREF(pyus_in);
1855 if (pyus_out == NULL)
1856 return NULL;
1857 result = microseconds_to_delta(pyus_out);
1858 Py_DECREF(pyus_out);
1859
1860 return result;
1861}
1862
1863static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001864delta_add(PyObject *left, PyObject *right)
1865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1869 /* delta + delta */
1870 /* The C-level additions can't overflow because of the
1871 * invariant bounds.
1872 */
1873 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1874 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1875 int microseconds = GET_TD_MICROSECONDS(left) +
1876 GET_TD_MICROSECONDS(right);
1877 result = new_delta(days, seconds, microseconds, 1);
1878 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 if (result == Py_NotImplemented)
1881 Py_INCREF(result);
1882 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001883}
1884
1885static PyObject *
1886delta_negative(PyDateTime_Delta *self)
1887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 return new_delta(-GET_TD_DAYS(self),
1889 -GET_TD_SECONDS(self),
1890 -GET_TD_MICROSECONDS(self),
1891 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001892}
1893
1894static PyObject *
1895delta_positive(PyDateTime_Delta *self)
1896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 /* Could optimize this (by returning self) if this isn't a
1898 * subclass -- but who uses unary + ? Approximately nobody.
1899 */
1900 return new_delta(GET_TD_DAYS(self),
1901 GET_TD_SECONDS(self),
1902 GET_TD_MICROSECONDS(self),
1903 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001904}
1905
1906static PyObject *
1907delta_abs(PyDateTime_Delta *self)
1908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 assert(GET_TD_MICROSECONDS(self) >= 0);
1912 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 if (GET_TD_DAYS(self) < 0)
1915 result = delta_negative(self);
1916 else
1917 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001920}
1921
1922static PyObject *
1923delta_subtract(PyObject *left, PyObject *right)
1924{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1928 /* delta - delta */
1929 PyObject *minus_right = PyNumber_Negative(right);
1930 if (minus_right) {
1931 result = delta_add(left, minus_right);
1932 Py_DECREF(minus_right);
1933 }
1934 else
1935 result = NULL;
1936 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 if (result == Py_NotImplemented)
1939 Py_INCREF(result);
1940 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001941}
1942
Tim Peters2a799bf2002-12-16 20:18:38 +00001943static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001944delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 if (PyDelta_Check(other)) {
1947 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1948 if (diff == 0) {
1949 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1950 if (diff == 0)
1951 diff = GET_TD_MICROSECONDS(self) -
1952 GET_TD_MICROSECONDS(other);
1953 }
1954 return diff_to_bool(diff, op);
1955 }
1956 else {
1957 Py_INCREF(Py_NotImplemented);
1958 return Py_NotImplemented;
1959 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001960}
1961
1962static PyObject *delta_getstate(PyDateTime_Delta *self);
1963
1964static long
1965delta_hash(PyDateTime_Delta *self)
1966{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 if (self->hashcode == -1) {
1968 PyObject *temp = delta_getstate(self);
1969 if (temp != NULL) {
1970 self->hashcode = PyObject_Hash(temp);
1971 Py_DECREF(temp);
1972 }
1973 }
1974 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001975}
1976
1977static PyObject *
1978delta_multiply(PyObject *left, PyObject *right)
1979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 if (PyDelta_Check(left)) {
1983 /* delta * ??? */
1984 if (PyLong_Check(right))
1985 result = multiply_int_timedelta(right,
1986 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001987 else if (PyFloat_Check(right))
1988 result = multiply_float_timedelta(right,
1989 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 }
1991 else if (PyLong_Check(left))
1992 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001993 (PyDateTime_Delta *) right);
1994 else if (PyFloat_Check(left))
1995 result = multiply_float_timedelta(left,
1996 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 if (result == Py_NotImplemented)
1999 Py_INCREF(result);
2000 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002001}
2002
2003static PyObject *
2004delta_divide(PyObject *left, PyObject *right)
2005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 if (PyDelta_Check(left)) {
2009 /* delta * ??? */
2010 if (PyLong_Check(right))
2011 result = divide_timedelta_int(
2012 (PyDateTime_Delta *)left,
2013 right);
2014 else if (PyDelta_Check(right))
2015 result = divide_timedelta_timedelta(
2016 (PyDateTime_Delta *)left,
2017 (PyDateTime_Delta *)right);
2018 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 if (result == Py_NotImplemented)
2021 Py_INCREF(result);
2022 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002023}
2024
Mark Dickinson7c186e22010-04-20 22:32:49 +00002025static PyObject *
2026delta_truedivide(PyObject *left, PyObject *right)
2027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 if (PyDelta_Check(left)) {
2031 if (PyDelta_Check(right))
2032 result = truedivide_timedelta_timedelta(
2033 (PyDateTime_Delta *)left,
2034 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002035 else if (PyFloat_Check(right))
2036 result = truedivide_timedelta_float(
2037 (PyDateTime_Delta *)left, right);
2038 else if (PyLong_Check(right))
2039 result = truedivide_timedelta_int(
2040 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 if (result == Py_NotImplemented)
2044 Py_INCREF(result);
2045 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002046}
2047
2048static PyObject *
2049delta_remainder(PyObject *left, PyObject *right)
2050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 PyObject *pyus_left;
2052 PyObject *pyus_right;
2053 PyObject *pyus_remainder;
2054 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
2057 Py_INCREF(Py_NotImplemented);
2058 return Py_NotImplemented;
2059 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2062 if (pyus_left == NULL)
2063 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2066 if (pyus_right == NULL) {
2067 Py_DECREF(pyus_left);
2068 return NULL;
2069 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2072 Py_DECREF(pyus_left);
2073 Py_DECREF(pyus_right);
2074 if (pyus_remainder == NULL)
2075 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 remainder = microseconds_to_delta(pyus_remainder);
2078 Py_DECREF(pyus_remainder);
2079 if (remainder == NULL)
2080 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002083}
2084
2085static PyObject *
2086delta_divmod(PyObject *left, PyObject *right)
2087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 PyObject *pyus_left;
2089 PyObject *pyus_right;
2090 PyObject *divmod;
2091 PyObject *delta;
2092 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
2095 Py_INCREF(Py_NotImplemented);
2096 return Py_NotImplemented;
2097 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2100 if (pyus_left == NULL)
2101 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2104 if (pyus_right == NULL) {
2105 Py_DECREF(pyus_left);
2106 return NULL;
2107 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2110 Py_DECREF(pyus_left);
2111 Py_DECREF(pyus_right);
2112 if (divmod == NULL)
2113 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 assert(PyTuple_Size(divmod) == 2);
2116 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2117 if (delta == NULL) {
2118 Py_DECREF(divmod);
2119 return NULL;
2120 }
2121 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2122 Py_DECREF(delta);
2123 Py_DECREF(divmod);
2124 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002125}
2126
Tim Peters2a799bf2002-12-16 20:18:38 +00002127/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2128 * timedelta constructor. sofar is the # of microseconds accounted for
2129 * so far, and there are factor microseconds per current unit, the number
2130 * of which is given by num. num * factor is added to sofar in a
2131 * numerically careful way, and that's the result. Any fractional
2132 * microseconds left over (this can happen if num is a float type) are
2133 * added into *leftover.
2134 * Note that there are many ways this can give an error (NULL) return.
2135 */
2136static PyObject *
2137accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2138 double *leftover)
2139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 PyObject *prod;
2141 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002145 if (PyLong_Check(num)) {
2146 prod = PyNumber_Multiply(num, factor);
2147 if (prod == NULL)
2148 return NULL;
2149 sum = PyNumber_Add(sofar, prod);
2150 Py_DECREF(prod);
2151 return sum;
2152 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002154 if (PyFloat_Check(num)) {
2155 double dnum;
2156 double fracpart;
2157 double intpart;
2158 PyObject *x;
2159 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 /* The Plan: decompose num into an integer part and a
2162 * fractional part, num = intpart + fracpart.
2163 * Then num * factor ==
2164 * intpart * factor + fracpart * factor
2165 * and the LHS can be computed exactly in long arithmetic.
2166 * The RHS is again broken into an int part and frac part.
2167 * and the frac part is added into *leftover.
2168 */
2169 dnum = PyFloat_AsDouble(num);
2170 if (dnum == -1.0 && PyErr_Occurred())
2171 return NULL;
2172 fracpart = modf(dnum, &intpart);
2173 x = PyLong_FromDouble(intpart);
2174 if (x == NULL)
2175 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 prod = PyNumber_Multiply(x, factor);
2178 Py_DECREF(x);
2179 if (prod == NULL)
2180 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 sum = PyNumber_Add(sofar, prod);
2183 Py_DECREF(prod);
2184 if (sum == NULL)
2185 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 if (fracpart == 0.0)
2188 return sum;
2189 /* So far we've lost no information. Dealing with the
2190 * fractional part requires float arithmetic, and may
2191 * lose a little info.
2192 */
2193 assert(PyLong_Check(factor));
2194 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 dnum *= fracpart;
2197 fracpart = modf(dnum, &intpart);
2198 x = PyLong_FromDouble(intpart);
2199 if (x == NULL) {
2200 Py_DECREF(sum);
2201 return NULL;
2202 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 y = PyNumber_Add(sum, x);
2205 Py_DECREF(sum);
2206 Py_DECREF(x);
2207 *leftover += fracpart;
2208 return y;
2209 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002211 PyErr_Format(PyExc_TypeError,
2212 "unsupported type for timedelta %s component: %s",
2213 tag, Py_TYPE(num)->tp_name);
2214 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002215}
2216
2217static PyObject *
2218delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 /* Argument objects. */
2223 PyObject *day = NULL;
2224 PyObject *second = NULL;
2225 PyObject *us = NULL;
2226 PyObject *ms = NULL;
2227 PyObject *minute = NULL;
2228 PyObject *hour = NULL;
2229 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 PyObject *x = NULL; /* running sum of microseconds */
2232 PyObject *y = NULL; /* temp sum of microseconds */
2233 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 static char *keywords[] = {
2236 "days", "seconds", "microseconds", "milliseconds",
2237 "minutes", "hours", "weeks", NULL
2238 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2241 keywords,
2242 &day, &second, &us,
2243 &ms, &minute, &hour, &week) == 0)
2244 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 x = PyLong_FromLong(0);
2247 if (x == NULL)
2248 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250#define CLEANUP \
2251 Py_DECREF(x); \
2252 x = y; \
2253 if (x == NULL) \
2254 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 if (us) {
2257 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2258 CLEANUP;
2259 }
2260 if (ms) {
2261 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2262 CLEANUP;
2263 }
2264 if (second) {
2265 y = accum("seconds", x, second, us_per_second, &leftover_us);
2266 CLEANUP;
2267 }
2268 if (minute) {
2269 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2270 CLEANUP;
2271 }
2272 if (hour) {
2273 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2274 CLEANUP;
2275 }
2276 if (day) {
2277 y = accum("days", x, day, us_per_day, &leftover_us);
2278 CLEANUP;
2279 }
2280 if (week) {
2281 y = accum("weeks", x, week, us_per_week, &leftover_us);
2282 CLEANUP;
2283 }
2284 if (leftover_us) {
2285 /* Round to nearest whole # of us, and add into x. */
2286 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2287 if (temp == NULL) {
2288 Py_DECREF(x);
2289 goto Done;
2290 }
2291 y = PyNumber_Add(x, temp);
2292 Py_DECREF(temp);
2293 CLEANUP;
2294 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 self = microseconds_to_delta_ex(x, type);
2297 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002298Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002300
2301#undef CLEANUP
2302}
2303
2304static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002305delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 return (GET_TD_DAYS(self) != 0
2308 || GET_TD_SECONDS(self) != 0
2309 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002310}
2311
2312static PyObject *
2313delta_repr(PyDateTime_Delta *self)
2314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 if (GET_TD_MICROSECONDS(self) != 0)
2316 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2317 Py_TYPE(self)->tp_name,
2318 GET_TD_DAYS(self),
2319 GET_TD_SECONDS(self),
2320 GET_TD_MICROSECONDS(self));
2321 if (GET_TD_SECONDS(self) != 0)
2322 return PyUnicode_FromFormat("%s(%d, %d)",
2323 Py_TYPE(self)->tp_name,
2324 GET_TD_DAYS(self),
2325 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002327 return PyUnicode_FromFormat("%s(%d)",
2328 Py_TYPE(self)->tp_name,
2329 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002330}
2331
2332static PyObject *
2333delta_str(PyDateTime_Delta *self)
2334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 int us = GET_TD_MICROSECONDS(self);
2336 int seconds = GET_TD_SECONDS(self);
2337 int minutes = divmod(seconds, 60, &seconds);
2338 int hours = divmod(minutes, 60, &minutes);
2339 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 if (days) {
2342 if (us)
2343 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2344 days, (days == 1 || days == -1) ? "" : "s",
2345 hours, minutes, seconds, us);
2346 else
2347 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2348 days, (days == 1 || days == -1) ? "" : "s",
2349 hours, minutes, seconds);
2350 } else {
2351 if (us)
2352 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2353 hours, minutes, seconds, us);
2354 else
2355 return PyUnicode_FromFormat("%d:%02d:%02d",
2356 hours, minutes, seconds);
2357 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002358
Tim Peters2a799bf2002-12-16 20:18:38 +00002359}
2360
Tim Peters371935f2003-02-01 01:52:50 +00002361/* Pickle support, a simple use of __reduce__. */
2362
Tim Petersb57f8f02003-02-01 02:54:15 +00002363/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002364static PyObject *
2365delta_getstate(PyDateTime_Delta *self)
2366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002367 return Py_BuildValue("iii", GET_TD_DAYS(self),
2368 GET_TD_SECONDS(self),
2369 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002370}
2371
Tim Peters2a799bf2002-12-16 20:18:38 +00002372static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002373delta_total_seconds(PyObject *self)
2374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 PyObject *total_seconds;
2376 PyObject *total_microseconds;
2377 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2380 if (total_microseconds == NULL)
2381 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002383 one_million = PyLong_FromLong(1000000L);
2384 if (one_million == NULL) {
2385 Py_DECREF(total_microseconds);
2386 return NULL;
2387 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 Py_DECREF(total_microseconds);
2392 Py_DECREF(one_million);
2393 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002394}
2395
2396static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002397delta_reduce(PyDateTime_Delta* self)
2398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002400}
2401
2402#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2403
2404static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 {"days", T_INT, OFFSET(days), READONLY,
2407 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 {"seconds", T_INT, OFFSET(seconds), READONLY,
2410 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2413 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2414 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002415};
2416
2417static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2419 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2422 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002425};
2426
2427static char delta_doc[] =
2428PyDoc_STR("Difference between two datetime values.");
2429
2430static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 delta_add, /* nb_add */
2432 delta_subtract, /* nb_subtract */
2433 delta_multiply, /* nb_multiply */
2434 delta_remainder, /* nb_remainder */
2435 delta_divmod, /* nb_divmod */
2436 0, /* nb_power */
2437 (unaryfunc)delta_negative, /* nb_negative */
2438 (unaryfunc)delta_positive, /* nb_positive */
2439 (unaryfunc)delta_abs, /* nb_absolute */
2440 (inquiry)delta_bool, /* nb_bool */
2441 0, /*nb_invert*/
2442 0, /*nb_lshift*/
2443 0, /*nb_rshift*/
2444 0, /*nb_and*/
2445 0, /*nb_xor*/
2446 0, /*nb_or*/
2447 0, /*nb_int*/
2448 0, /*nb_reserved*/
2449 0, /*nb_float*/
2450 0, /*nb_inplace_add*/
2451 0, /*nb_inplace_subtract*/
2452 0, /*nb_inplace_multiply*/
2453 0, /*nb_inplace_remainder*/
2454 0, /*nb_inplace_power*/
2455 0, /*nb_inplace_lshift*/
2456 0, /*nb_inplace_rshift*/
2457 0, /*nb_inplace_and*/
2458 0, /*nb_inplace_xor*/
2459 0, /*nb_inplace_or*/
2460 delta_divide, /* nb_floor_divide */
2461 delta_truedivide, /* nb_true_divide */
2462 0, /* nb_inplace_floor_divide */
2463 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002464};
2465
2466static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 PyVarObject_HEAD_INIT(NULL, 0)
2468 "datetime.timedelta", /* tp_name */
2469 sizeof(PyDateTime_Delta), /* tp_basicsize */
2470 0, /* tp_itemsize */
2471 0, /* tp_dealloc */
2472 0, /* tp_print */
2473 0, /* tp_getattr */
2474 0, /* tp_setattr */
2475 0, /* tp_reserved */
2476 (reprfunc)delta_repr, /* tp_repr */
2477 &delta_as_number, /* tp_as_number */
2478 0, /* tp_as_sequence */
2479 0, /* tp_as_mapping */
2480 (hashfunc)delta_hash, /* tp_hash */
2481 0, /* tp_call */
2482 (reprfunc)delta_str, /* tp_str */
2483 PyObject_GenericGetAttr, /* tp_getattro */
2484 0, /* tp_setattro */
2485 0, /* tp_as_buffer */
2486 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2487 delta_doc, /* tp_doc */
2488 0, /* tp_traverse */
2489 0, /* tp_clear */
2490 delta_richcompare, /* tp_richcompare */
2491 0, /* tp_weaklistoffset */
2492 0, /* tp_iter */
2493 0, /* tp_iternext */
2494 delta_methods, /* tp_methods */
2495 delta_members, /* tp_members */
2496 0, /* tp_getset */
2497 0, /* tp_base */
2498 0, /* tp_dict */
2499 0, /* tp_descr_get */
2500 0, /* tp_descr_set */
2501 0, /* tp_dictoffset */
2502 0, /* tp_init */
2503 0, /* tp_alloc */
2504 delta_new, /* tp_new */
2505 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002506};
2507
2508/*
2509 * PyDateTime_Date implementation.
2510 */
2511
2512/* Accessor properties. */
2513
2514static PyObject *
2515date_year(PyDateTime_Date *self, void *unused)
2516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002518}
2519
2520static PyObject *
2521date_month(PyDateTime_Date *self, void *unused)
2522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002524}
2525
2526static PyObject *
2527date_day(PyDateTime_Date *self, void *unused)
2528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002530}
2531
2532static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002533 {"year", (getter)date_year},
2534 {"month", (getter)date_month},
2535 {"day", (getter)date_day},
2536 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002537};
2538
2539/* Constructors. */
2540
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002541static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002542
Tim Peters2a799bf2002-12-16 20:18:38 +00002543static PyObject *
2544date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002546 PyObject *self = NULL;
2547 PyObject *state;
2548 int year;
2549 int month;
2550 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002552 /* Check for invocation from pickle with __getstate__ state */
2553 if (PyTuple_GET_SIZE(args) == 1 &&
2554 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2555 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2556 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2557 {
2558 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2561 if (me != NULL) {
2562 char *pdata = PyBytes_AS_STRING(state);
2563 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2564 me->hashcode = -1;
2565 }
2566 return (PyObject *)me;
2567 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002569 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2570 &year, &month, &day)) {
2571 if (check_date_args(year, month, day) < 0)
2572 return NULL;
2573 self = new_date_ex(year, month, day, type);
2574 }
2575 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002576}
2577
2578/* Return new date from localtime(t). */
2579static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002580date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002581{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002582 struct tm *tm;
2583 time_t t;
2584 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 t = _PyTime_DoubleToTimet(ts);
2587 if (t == (time_t)-1 && PyErr_Occurred())
2588 return NULL;
2589 tm = localtime(&t);
2590 if (tm)
2591 result = PyObject_CallFunction(cls, "iii",
2592 tm->tm_year + 1900,
2593 tm->tm_mon + 1,
2594 tm->tm_mday);
2595 else
2596 PyErr_SetString(PyExc_ValueError,
2597 "timestamp out of range for "
2598 "platform localtime() function");
2599 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002600}
2601
2602/* Return new date from current time.
2603 * We say this is equivalent to fromtimestamp(time.time()), and the
2604 * only way to be sure of that is to *call* time.time(). That's not
2605 * generally the same as calling C's time.
2606 */
2607static PyObject *
2608date_today(PyObject *cls, PyObject *dummy)
2609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002610 PyObject *time;
2611 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 time = time_time();
2614 if (time == NULL)
2615 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617 /* Note well: today() is a class method, so this may not call
2618 * date.fromtimestamp. For example, it may call
2619 * datetime.fromtimestamp. That's why we need all the accuracy
2620 * time.time() delivers; if someone were gonzo about optimization,
2621 * date.today() could get away with plain C time().
2622 */
2623 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2624 Py_DECREF(time);
2625 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002626}
2627
2628/* Return new date from given timestamp (Python timestamp -- a double). */
2629static PyObject *
2630date_fromtimestamp(PyObject *cls, PyObject *args)
2631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002632 double timestamp;
2633 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002635 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2636 result = date_local_from_time_t(cls, timestamp);
2637 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002638}
2639
2640/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2641 * the ordinal is out of range.
2642 */
2643static PyObject *
2644date_fromordinal(PyObject *cls, PyObject *args)
2645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 PyObject *result = NULL;
2647 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002649 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2650 int year;
2651 int month;
2652 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 if (ordinal < 1)
2655 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2656 ">= 1");
2657 else {
2658 ord_to_ymd(ordinal, &year, &month, &day);
2659 result = PyObject_CallFunction(cls, "iii",
2660 year, month, day);
2661 }
2662 }
2663 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002664}
2665
2666/*
2667 * Date arithmetic.
2668 */
2669
2670/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2671 * instead.
2672 */
2673static PyObject *
2674add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002676 PyObject *result = NULL;
2677 int year = GET_YEAR(date);
2678 int month = GET_MONTH(date);
2679 int deltadays = GET_TD_DAYS(delta);
2680 /* C-level overflow is impossible because |deltadays| < 1e9. */
2681 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002683 if (normalize_date(&year, &month, &day) >= 0)
2684 result = new_date(year, month, day);
2685 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002686}
2687
2688static PyObject *
2689date_add(PyObject *left, PyObject *right)
2690{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002691 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2692 Py_INCREF(Py_NotImplemented);
2693 return Py_NotImplemented;
2694 }
2695 if (PyDate_Check(left)) {
2696 /* date + ??? */
2697 if (PyDelta_Check(right))
2698 /* date + delta */
2699 return add_date_timedelta((PyDateTime_Date *) left,
2700 (PyDateTime_Delta *) right,
2701 0);
2702 }
2703 else {
2704 /* ??? + date
2705 * 'right' must be one of us, or we wouldn't have been called
2706 */
2707 if (PyDelta_Check(left))
2708 /* delta + date */
2709 return add_date_timedelta((PyDateTime_Date *) right,
2710 (PyDateTime_Delta *) left,
2711 0);
2712 }
2713 Py_INCREF(Py_NotImplemented);
2714 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002715}
2716
2717static PyObject *
2718date_subtract(PyObject *left, PyObject *right)
2719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2721 Py_INCREF(Py_NotImplemented);
2722 return Py_NotImplemented;
2723 }
2724 if (PyDate_Check(left)) {
2725 if (PyDate_Check(right)) {
2726 /* date - date */
2727 int left_ord = ymd_to_ord(GET_YEAR(left),
2728 GET_MONTH(left),
2729 GET_DAY(left));
2730 int right_ord = ymd_to_ord(GET_YEAR(right),
2731 GET_MONTH(right),
2732 GET_DAY(right));
2733 return new_delta(left_ord - right_ord, 0, 0, 0);
2734 }
2735 if (PyDelta_Check(right)) {
2736 /* date - delta */
2737 return add_date_timedelta((PyDateTime_Date *) left,
2738 (PyDateTime_Delta *) right,
2739 1);
2740 }
2741 }
2742 Py_INCREF(Py_NotImplemented);
2743 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002744}
2745
2746
2747/* Various ways to turn a date into a string. */
2748
2749static PyObject *
2750date_repr(PyDateTime_Date *self)
2751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002752 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2753 Py_TYPE(self)->tp_name,
2754 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002755}
2756
2757static PyObject *
2758date_isoformat(PyDateTime_Date *self)
2759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002760 return PyUnicode_FromFormat("%04d-%02d-%02d",
2761 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002762}
2763
Tim Peterse2df5ff2003-05-02 18:39:55 +00002764/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002765static PyObject *
2766date_str(PyDateTime_Date *self)
2767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002768 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002769}
2770
2771
2772static PyObject *
2773date_ctime(PyDateTime_Date *self)
2774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002775 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002776}
2777
2778static PyObject *
2779date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2780{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002781 /* This method can be inherited, and needs to call the
2782 * timetuple() method appropriate to self's class.
2783 */
2784 PyObject *result;
2785 PyObject *tuple;
2786 PyObject *format;
2787 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002789 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2790 &format))
2791 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002793 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2794 if (tuple == NULL)
2795 return NULL;
2796 result = wrap_strftime((PyObject *)self, format, tuple,
2797 (PyObject *)self);
2798 Py_DECREF(tuple);
2799 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002800}
2801
Eric Smith1ba31142007-09-11 18:06:02 +00002802static PyObject *
2803date_format(PyDateTime_Date *self, PyObject *args)
2804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002807 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2808 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 /* if the format is zero length, return str(self) */
2811 if (PyUnicode_GetSize(format) == 0)
2812 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002815}
2816
Tim Peters2a799bf2002-12-16 20:18:38 +00002817/* ISO methods. */
2818
2819static PyObject *
2820date_isoweekday(PyDateTime_Date *self)
2821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002824 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002825}
2826
2827static PyObject *
2828date_isocalendar(PyDateTime_Date *self)
2829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002830 int year = GET_YEAR(self);
2831 int week1_monday = iso_week1_monday(year);
2832 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2833 int week;
2834 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 week = divmod(today - week1_monday, 7, &day);
2837 if (week < 0) {
2838 --year;
2839 week1_monday = iso_week1_monday(year);
2840 week = divmod(today - week1_monday, 7, &day);
2841 }
2842 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2843 ++year;
2844 week = 0;
2845 }
2846 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002847}
2848
2849/* Miscellaneous methods. */
2850
Tim Peters2a799bf2002-12-16 20:18:38 +00002851static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002852date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 if (PyDate_Check(other)) {
2855 int diff = memcmp(((PyDateTime_Date *)self)->data,
2856 ((PyDateTime_Date *)other)->data,
2857 _PyDateTime_DATE_DATASIZE);
2858 return diff_to_bool(diff, op);
2859 }
2860 else {
2861 Py_INCREF(Py_NotImplemented);
2862 return Py_NotImplemented;
2863 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002864}
2865
2866static PyObject *
2867date_timetuple(PyDateTime_Date *self)
2868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002869 return build_struct_time(GET_YEAR(self),
2870 GET_MONTH(self),
2871 GET_DAY(self),
2872 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002873}
2874
Tim Peters12bf3392002-12-24 05:41:27 +00002875static PyObject *
2876date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2877{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 PyObject *clone;
2879 PyObject *tuple;
2880 int year = GET_YEAR(self);
2881 int month = GET_MONTH(self);
2882 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2885 &year, &month, &day))
2886 return NULL;
2887 tuple = Py_BuildValue("iii", year, month, day);
2888 if (tuple == NULL)
2889 return NULL;
2890 clone = date_new(Py_TYPE(self), tuple, NULL);
2891 Py_DECREF(tuple);
2892 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002893}
2894
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002895/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002896 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002897*/
2898static long
2899generic_hash(unsigned char *data, int len)
2900{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002901 register unsigned char *p;
2902 register long x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002904 p = (unsigned char *) data;
2905 x = *p << 7;
2906 while (--len >= 0)
2907 x = (1000003*x) ^ *p++;
2908 x ^= len;
2909 if (x == -1)
2910 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002912 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002913}
2914
2915
2916static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002917
2918static long
2919date_hash(PyDateTime_Date *self)
2920{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002921 if (self->hashcode == -1)
2922 self->hashcode = generic_hash(
2923 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002925 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002926}
2927
2928static PyObject *
2929date_toordinal(PyDateTime_Date *self)
2930{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002931 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2932 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002933}
2934
2935static PyObject *
2936date_weekday(PyDateTime_Date *self)
2937{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002938 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002940 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002941}
2942
Tim Peters371935f2003-02-01 01:52:50 +00002943/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002944
Tim Petersb57f8f02003-02-01 02:54:15 +00002945/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002946static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002947date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002949 PyObject* field;
2950 field = PyBytes_FromStringAndSize((char*)self->data,
2951 _PyDateTime_DATE_DATASIZE);
2952 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002953}
2954
2955static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002956date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002958 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002959}
2960
2961static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002963 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002965 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2966 METH_CLASS,
2967 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2968 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002970 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2971 METH_CLASS,
2972 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2973 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002975 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2976 PyDoc_STR("Current date or datetime: same as "
2977 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002979 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002981 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2982 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002984 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2985 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002987 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2988 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002990 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2991 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002993 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2994 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2995 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002997 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2998 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003000 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3001 PyDoc_STR("Return the day of the week represented by the date.\n"
3002 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003004 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3005 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3006 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003008 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3009 PyDoc_STR("Return the day of the week represented by the date.\n"
3010 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003012 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3013 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3016 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003018 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003019};
3020
3021static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003022PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003023
3024static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003025 date_add, /* nb_add */
3026 date_subtract, /* nb_subtract */
3027 0, /* nb_multiply */
3028 0, /* nb_remainder */
3029 0, /* nb_divmod */
3030 0, /* nb_power */
3031 0, /* nb_negative */
3032 0, /* nb_positive */
3033 0, /* nb_absolute */
3034 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003035};
3036
3037static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 PyVarObject_HEAD_INIT(NULL, 0)
3039 "datetime.date", /* tp_name */
3040 sizeof(PyDateTime_Date), /* tp_basicsize */
3041 0, /* tp_itemsize */
3042 0, /* tp_dealloc */
3043 0, /* tp_print */
3044 0, /* tp_getattr */
3045 0, /* tp_setattr */
3046 0, /* tp_reserved */
3047 (reprfunc)date_repr, /* tp_repr */
3048 &date_as_number, /* tp_as_number */
3049 0, /* tp_as_sequence */
3050 0, /* tp_as_mapping */
3051 (hashfunc)date_hash, /* tp_hash */
3052 0, /* tp_call */
3053 (reprfunc)date_str, /* tp_str */
3054 PyObject_GenericGetAttr, /* tp_getattro */
3055 0, /* tp_setattro */
3056 0, /* tp_as_buffer */
3057 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3058 date_doc, /* tp_doc */
3059 0, /* tp_traverse */
3060 0, /* tp_clear */
3061 date_richcompare, /* tp_richcompare */
3062 0, /* tp_weaklistoffset */
3063 0, /* tp_iter */
3064 0, /* tp_iternext */
3065 date_methods, /* tp_methods */
3066 0, /* tp_members */
3067 date_getset, /* tp_getset */
3068 0, /* tp_base */
3069 0, /* tp_dict */
3070 0, /* tp_descr_get */
3071 0, /* tp_descr_set */
3072 0, /* tp_dictoffset */
3073 0, /* tp_init */
3074 0, /* tp_alloc */
3075 date_new, /* tp_new */
3076 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003077};
3078
3079/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003080 * PyDateTime_TZInfo implementation.
3081 */
3082
3083/* This is a pure abstract base class, so doesn't do anything beyond
3084 * raising NotImplemented exceptions. Real tzinfo classes need
3085 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003086 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003087 * be subclasses of this tzinfo class, which is easy and quick to check).
3088 *
3089 * Note: For reasons having to do with pickling of subclasses, we have
3090 * to allow tzinfo objects to be instantiated. This wasn't an issue
3091 * in the Python implementation (__init__() could raise NotImplementedError
3092 * there without ill effect), but doing so in the C implementation hit a
3093 * brick wall.
3094 */
3095
3096static PyObject *
3097tzinfo_nogo(const char* methodname)
3098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003099 PyErr_Format(PyExc_NotImplementedError,
3100 "a tzinfo subclass must implement %s()",
3101 methodname);
3102 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003103}
3104
3105/* Methods. A subclass must implement these. */
3106
Tim Peters52dcce22003-01-23 16:36:11 +00003107static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003108tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3109{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003111}
3112
Tim Peters52dcce22003-01-23 16:36:11 +00003113static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003114tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003116 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003117}
3118
Tim Peters52dcce22003-01-23 16:36:11 +00003119static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003120tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003123}
3124
Tim Peters52dcce22003-01-23 16:36:11 +00003125static PyObject *
3126tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
3127{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 int y, m, d, hh, mm, ss, us;
Tim Peters52dcce22003-01-23 16:36:11 +00003129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003130 PyObject *result;
3131 int off, dst;
3132 int none;
3133 int delta;
Tim Peters52dcce22003-01-23 16:36:11 +00003134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003135 if (! PyDateTime_Check(dt)) {
3136 PyErr_SetString(PyExc_TypeError,
3137 "fromutc: argument must be a datetime");
3138 return NULL;
3139 }
3140 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3141 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3142 "is not self");
3143 return NULL;
3144 }
Tim Peters52dcce22003-01-23 16:36:11 +00003145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003146 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
3147 if (off == -1 && PyErr_Occurred())
3148 return NULL;
3149 if (none) {
3150 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3151 "utcoffset() result required");
3152 return NULL;
3153 }
Tim Peters52dcce22003-01-23 16:36:11 +00003154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003155 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
3156 if (dst == -1 && PyErr_Occurred())
3157 return NULL;
3158 if (none) {
3159 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3160 "dst() result required");
3161 return NULL;
3162 }
Tim Peters52dcce22003-01-23 16:36:11 +00003163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003164 y = GET_YEAR(dt);
3165 m = GET_MONTH(dt);
3166 d = GET_DAY(dt);
3167 hh = DATE_GET_HOUR(dt);
3168 mm = DATE_GET_MINUTE(dt);
3169 ss = DATE_GET_SECOND(dt);
3170 us = DATE_GET_MICROSECOND(dt);
Tim Peters52dcce22003-01-23 16:36:11 +00003171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 delta = off - dst;
3173 mm += delta;
3174 if ((mm < 0 || mm >= 60) &&
3175 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
3176 return NULL;
3177 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
3178 if (result == NULL)
3179 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003181 dst = call_dst(dt->tzinfo, result, &none);
3182 if (dst == -1 && PyErr_Occurred())
3183 goto Fail;
3184 if (none)
3185 goto Inconsistent;
3186 if (dst == 0)
3187 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003189 mm += dst;
3190 if ((mm < 0 || mm >= 60) &&
3191 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
3192 goto Fail;
3193 Py_DECREF(result);
3194 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
3195 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003196
3197Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3199 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003201 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003202Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003203 Py_DECREF(result);
3204 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003205}
3206
Tim Peters2a799bf2002-12-16 20:18:38 +00003207/*
3208 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003209 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003210 */
3211
Guido van Rossum177e41a2003-01-30 22:06:23 +00003212static PyObject *
3213tzinfo_reduce(PyObject *self)
3214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 PyObject *args, *state, *tmp;
3216 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003218 tmp = PyTuple_New(0);
3219 if (tmp == NULL)
3220 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003222 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3223 if (getinitargs != NULL) {
3224 args = PyObject_CallObject(getinitargs, tmp);
3225 Py_DECREF(getinitargs);
3226 if (args == NULL) {
3227 Py_DECREF(tmp);
3228 return NULL;
3229 }
3230 }
3231 else {
3232 PyErr_Clear();
3233 args = tmp;
3234 Py_INCREF(args);
3235 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003237 getstate = PyObject_GetAttrString(self, "__getstate__");
3238 if (getstate != NULL) {
3239 state = PyObject_CallObject(getstate, tmp);
3240 Py_DECREF(getstate);
3241 if (state == NULL) {
3242 Py_DECREF(args);
3243 Py_DECREF(tmp);
3244 return NULL;
3245 }
3246 }
3247 else {
3248 PyObject **dictptr;
3249 PyErr_Clear();
3250 state = Py_None;
3251 dictptr = _PyObject_GetDictPtr(self);
3252 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3253 state = *dictptr;
3254 Py_INCREF(state);
3255 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003257 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003259 if (state == Py_None) {
3260 Py_DECREF(state);
3261 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3262 }
3263 else
3264 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003265}
Tim Peters2a799bf2002-12-16 20:18:38 +00003266
3267static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003269 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3270 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003272 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003273 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3274 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003276 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3277 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003279 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
3280 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003282 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3283 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003285 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003286};
3287
3288static char tzinfo_doc[] =
3289PyDoc_STR("Abstract base class for time zone info objects.");
3290
Neal Norwitz227b5332006-03-22 09:28:35 +00003291static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003292 PyVarObject_HEAD_INIT(NULL, 0)
3293 "datetime.tzinfo", /* tp_name */
3294 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3295 0, /* tp_itemsize */
3296 0, /* tp_dealloc */
3297 0, /* tp_print */
3298 0, /* tp_getattr */
3299 0, /* tp_setattr */
3300 0, /* tp_reserved */
3301 0, /* tp_repr */
3302 0, /* tp_as_number */
3303 0, /* tp_as_sequence */
3304 0, /* tp_as_mapping */
3305 0, /* tp_hash */
3306 0, /* tp_call */
3307 0, /* tp_str */
3308 PyObject_GenericGetAttr, /* tp_getattro */
3309 0, /* tp_setattro */
3310 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003311 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003312 tzinfo_doc, /* tp_doc */
3313 0, /* tp_traverse */
3314 0, /* tp_clear */
3315 0, /* tp_richcompare */
3316 0, /* tp_weaklistoffset */
3317 0, /* tp_iter */
3318 0, /* tp_iternext */
3319 tzinfo_methods, /* tp_methods */
3320 0, /* tp_members */
3321 0, /* tp_getset */
3322 0, /* tp_base */
3323 0, /* tp_dict */
3324 0, /* tp_descr_get */
3325 0, /* tp_descr_set */
3326 0, /* tp_dictoffset */
3327 0, /* tp_init */
3328 0, /* tp_alloc */
3329 PyType_GenericNew, /* tp_new */
3330 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003331};
3332
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003333static char *timezone_kws[] = {"offset", "name", NULL};
3334
3335static PyObject *
3336timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3337{
3338 PyObject *offset;
3339 PyObject *name = NULL;
3340 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3341 &PyDateTime_DeltaType, &offset,
3342 &PyUnicode_Type, &name))
3343 return new_timezone(offset, name);
3344
3345 return NULL;
3346}
3347
3348static void
3349timezone_dealloc(PyDateTime_TimeZone *self)
3350{
3351 Py_CLEAR(self->offset);
3352 Py_CLEAR(self->name);
3353 Py_TYPE(self)->tp_free((PyObject *)self);
3354}
3355
3356static PyObject *
3357timezone_richcompare(PyDateTime_TimeZone *self,
3358 PyDateTime_TimeZone *other, int op)
3359{
3360 if (op != Py_EQ && op != Py_NE) {
3361 Py_INCREF(Py_NotImplemented);
3362 return Py_NotImplemented;
3363 }
3364 return delta_richcompare(self->offset, other->offset, op);
3365}
3366
3367static long
3368timezone_hash(PyDateTime_TimeZone *self)
3369{
3370 return delta_hash((PyDateTime_Delta *)self->offset);
3371}
3372
3373/* Check argument type passed to tzname, utcoffset, or dst methods.
3374 Returns 0 for good argument. Returns -1 and sets exception info
3375 otherwise.
3376 */
3377static int
3378_timezone_check_argument(PyObject *dt, const char *meth)
3379{
3380 if (dt == Py_None || PyDateTime_Check(dt))
3381 return 0;
3382 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3383 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3384 return -1;
3385}
3386
3387static PyObject *
3388timezone_str(PyDateTime_TimeZone *self)
3389{
3390 char buf[10];
3391 int hours, minutes, seconds;
3392 PyObject *offset;
3393 char sign;
3394
3395 if (self->name != NULL) {
3396 Py_INCREF(self->name);
3397 return self->name;
3398 }
3399 /* Offset is normalized, so it is negative if days < 0 */
3400 if (GET_TD_DAYS(self->offset) < 0) {
3401 sign = '-';
3402 offset = delta_negative((PyDateTime_Delta *)self->offset);
3403 if (offset == NULL)
3404 return NULL;
3405 }
3406 else {
3407 sign = '+';
3408 offset = self->offset;
3409 Py_INCREF(offset);
3410 }
3411 /* Offset is not negative here. */
3412 seconds = GET_TD_SECONDS(offset);
3413 Py_DECREF(offset);
3414 minutes = divmod(seconds, 60, &seconds);
3415 hours = divmod(minutes, 60, &minutes);
3416 assert(seconds == 0);
3417 /* XXX ignore sub-minute data, curently not allowed. */
3418 PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes);
3419
3420 return PyUnicode_FromString(buf);
3421}
3422
3423static PyObject *
3424timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3425{
3426 if (_timezone_check_argument(dt, "tzname") == -1)
3427 return NULL;
3428
3429 return timezone_str(self);
3430}
3431
3432static PyObject *
3433timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3434{
3435 if (_timezone_check_argument(dt, "utcoffset") == -1)
3436 return NULL;
3437
3438 Py_INCREF(self->offset);
3439 return self->offset;
3440}
3441
3442static PyObject *
3443timezone_dst(PyObject *self, PyObject *dt)
3444{
3445 if (_timezone_check_argument(dt, "dst") == -1)
3446 return NULL;
3447
3448 Py_RETURN_NONE;
3449}
3450
3451static PyObject *
3452add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3453 int factor);
3454
3455static PyObject *
3456timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3457{
3458 if (! PyDateTime_Check(dt)) {
3459 PyErr_SetString(PyExc_TypeError,
3460 "fromutc: argument must be a datetime");
3461 return NULL;
3462 }
3463 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3464 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3465 "is not self");
3466 return NULL;
3467 }
3468
3469 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3470}
3471
3472static PyMethodDef timezone_methods[] = {
3473 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3474 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003475 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003476
3477 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003478 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003479
3480 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003481 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003482
3483 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3484 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3485
3486 {NULL, NULL}
3487};
3488
3489static char timezone_doc[] =
3490PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3491
3492static PyTypeObject PyDateTime_TimeZoneType = {
3493 PyVarObject_HEAD_INIT(NULL, 0)
3494 "datetime.timezone", /* tp_name */
3495 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3496 0, /* tp_itemsize */
3497 (destructor)timezone_dealloc, /* tp_dealloc */
3498 0, /* tp_print */
3499 0, /* tp_getattr */
3500 0, /* tp_setattr */
3501 0, /* tp_reserved */
3502 0, /* tp_repr */
3503 0, /* tp_as_number */
3504 0, /* tp_as_sequence */
3505 0, /* tp_as_mapping */
3506 (hashfunc)timezone_hash, /* tp_hash */
3507 0, /* tp_call */
3508 (reprfunc)timezone_str, /* tp_str */
3509 0, /* tp_getattro */
3510 0, /* tp_setattro */
3511 0, /* tp_as_buffer */
3512 Py_TPFLAGS_DEFAULT, /* tp_flags */
3513 timezone_doc, /* tp_doc */
3514 0, /* tp_traverse */
3515 0, /* tp_clear */
3516 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3517 0, /* tp_weaklistoffset */
3518 0, /* tp_iter */
3519 0, /* tp_iternext */
3520 timezone_methods, /* tp_methods */
3521 0, /* tp_members */
3522 0, /* tp_getset */
3523 &PyDateTime_TZInfoType, /* tp_base */
3524 0, /* tp_dict */
3525 0, /* tp_descr_get */
3526 0, /* tp_descr_set */
3527 0, /* tp_dictoffset */
3528 0, /* tp_init */
3529 0, /* tp_alloc */
3530 timezone_new, /* tp_new */
3531};
3532
Tim Peters2a799bf2002-12-16 20:18:38 +00003533/*
Tim Peters37f39822003-01-10 03:49:02 +00003534 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003535 */
3536
Tim Peters37f39822003-01-10 03:49:02 +00003537/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003538 */
3539
3540static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003541time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003543 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003544}
3545
Tim Peters37f39822003-01-10 03:49:02 +00003546static PyObject *
3547time_minute(PyDateTime_Time *self, void *unused)
3548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003549 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003550}
3551
3552/* The name time_second conflicted with some platform header file. */
3553static PyObject *
3554py_time_second(PyDateTime_Time *self, void *unused)
3555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003556 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003557}
3558
3559static PyObject *
3560time_microsecond(PyDateTime_Time *self, void *unused)
3561{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003562 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003563}
3564
3565static PyObject *
3566time_tzinfo(PyDateTime_Time *self, void *unused)
3567{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3569 Py_INCREF(result);
3570 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003571}
3572
3573static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003574 {"hour", (getter)time_hour},
3575 {"minute", (getter)time_minute},
3576 {"second", (getter)py_time_second},
3577 {"microsecond", (getter)time_microsecond},
3578 {"tzinfo", (getter)time_tzinfo},
3579 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003580};
3581
3582/*
3583 * Constructors.
3584 */
3585
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003586static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003587 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003588
Tim Peters2a799bf2002-12-16 20:18:38 +00003589static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003590time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003591{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003592 PyObject *self = NULL;
3593 PyObject *state;
3594 int hour = 0;
3595 int minute = 0;
3596 int second = 0;
3597 int usecond = 0;
3598 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003600 /* Check for invocation from pickle with __getstate__ state */
3601 if (PyTuple_GET_SIZE(args) >= 1 &&
3602 PyTuple_GET_SIZE(args) <= 2 &&
3603 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3604 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3605 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3606 {
3607 PyDateTime_Time *me;
3608 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003610 if (PyTuple_GET_SIZE(args) == 2) {
3611 tzinfo = PyTuple_GET_ITEM(args, 1);
3612 if (check_tzinfo_subclass(tzinfo) < 0) {
3613 PyErr_SetString(PyExc_TypeError, "bad "
3614 "tzinfo state arg");
3615 return NULL;
3616 }
3617 }
3618 aware = (char)(tzinfo != Py_None);
3619 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3620 if (me != NULL) {
3621 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003623 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3624 me->hashcode = -1;
3625 me->hastzinfo = aware;
3626 if (aware) {
3627 Py_INCREF(tzinfo);
3628 me->tzinfo = tzinfo;
3629 }
3630 }
3631 return (PyObject *)me;
3632 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003634 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3635 &hour, &minute, &second, &usecond,
3636 &tzinfo)) {
3637 if (check_time_args(hour, minute, second, usecond) < 0)
3638 return NULL;
3639 if (check_tzinfo_subclass(tzinfo) < 0)
3640 return NULL;
3641 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3642 type);
3643 }
3644 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003645}
3646
3647/*
3648 * Destructor.
3649 */
3650
3651static void
Tim Peters37f39822003-01-10 03:49:02 +00003652time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003654 if (HASTZINFO(self)) {
3655 Py_XDECREF(self->tzinfo);
3656 }
3657 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003658}
3659
3660/*
Tim Peters855fe882002-12-22 03:43:39 +00003661 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003662 */
3663
Tim Peters2a799bf2002-12-16 20:18:38 +00003664/* These are all METH_NOARGS, so don't need to check the arglist. */
3665static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003666time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003667 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3668 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003669}
3670
3671static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003672time_dst(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003673 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3674 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003675}
3676
3677static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003678time_tzname(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003679 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3680 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003681}
3682
3683/*
Tim Peters37f39822003-01-10 03:49:02 +00003684 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003685 */
3686
3687static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003688time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003689{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003690 const char *type_name = Py_TYPE(self)->tp_name;
3691 int h = TIME_GET_HOUR(self);
3692 int m = TIME_GET_MINUTE(self);
3693 int s = TIME_GET_SECOND(self);
3694 int us = TIME_GET_MICROSECOND(self);
3695 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003697 if (us)
3698 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3699 type_name, h, m, s, us);
3700 else if (s)
3701 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3702 type_name, h, m, s);
3703 else
3704 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3705 if (result != NULL && HASTZINFO(self))
3706 result = append_keyword_tzinfo(result, self->tzinfo);
3707 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003708}
3709
Tim Peters37f39822003-01-10 03:49:02 +00003710static PyObject *
3711time_str(PyDateTime_Time *self)
3712{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003713 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003714}
Tim Peters2a799bf2002-12-16 20:18:38 +00003715
3716static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003717time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003719 char buf[100];
3720 PyObject *result;
3721 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003723 if (us)
3724 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3725 TIME_GET_HOUR(self),
3726 TIME_GET_MINUTE(self),
3727 TIME_GET_SECOND(self),
3728 us);
3729 else
3730 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3731 TIME_GET_HOUR(self),
3732 TIME_GET_MINUTE(self),
3733 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003735 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3736 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003738 /* We need to append the UTC offset. */
3739 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3740 Py_None) < 0) {
3741 Py_DECREF(result);
3742 return NULL;
3743 }
3744 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3745 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003746}
3747
Tim Peters37f39822003-01-10 03:49:02 +00003748static PyObject *
3749time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003751 PyObject *result;
3752 PyObject *tuple;
3753 PyObject *format;
3754 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003756 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3757 &format))
3758 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003760 /* Python's strftime does insane things with the year part of the
3761 * timetuple. The year is forced to (the otherwise nonsensical)
3762 * 1900 to worm around that.
3763 */
3764 tuple = Py_BuildValue("iiiiiiiii",
3765 1900, 1, 1, /* year, month, day */
3766 TIME_GET_HOUR(self),
3767 TIME_GET_MINUTE(self),
3768 TIME_GET_SECOND(self),
3769 0, 1, -1); /* weekday, daynum, dst */
3770 if (tuple == NULL)
3771 return NULL;
3772 assert(PyTuple_Size(tuple) == 9);
3773 result = wrap_strftime((PyObject *)self, format, tuple,
3774 Py_None);
3775 Py_DECREF(tuple);
3776 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003777}
Tim Peters2a799bf2002-12-16 20:18:38 +00003778
3779/*
3780 * Miscellaneous methods.
3781 */
3782
Tim Peters37f39822003-01-10 03:49:02 +00003783static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003784time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003786 int diff;
3787 naivety n1, n2;
3788 int offset1, offset2;
Tim Peters37f39822003-01-10 03:49:02 +00003789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003790 if (! PyTime_Check(other)) {
3791 Py_INCREF(Py_NotImplemented);
3792 return Py_NotImplemented;
3793 }
3794 if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
3795 other, &offset2, &n2, Py_None) < 0)
3796 return NULL;
3797 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3798 /* If they're both naive, or both aware and have the same offsets,
3799 * we get off cheap. Note that if they're both naive, offset1 ==
3800 * offset2 == 0 at this point.
3801 */
3802 if (n1 == n2 && offset1 == offset2) {
3803 diff = memcmp(((PyDateTime_Time *)self)->data,
3804 ((PyDateTime_Time *)other)->data,
3805 _PyDateTime_TIME_DATASIZE);
3806 return diff_to_bool(diff, op);
3807 }
Tim Peters37f39822003-01-10 03:49:02 +00003808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003809 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3810 assert(offset1 != offset2); /* else last "if" handled it */
3811 /* Convert everything except microseconds to seconds. These
3812 * can't overflow (no more than the # of seconds in 2 days).
3813 */
3814 offset1 = TIME_GET_HOUR(self) * 3600 +
3815 (TIME_GET_MINUTE(self) - offset1) * 60 +
3816 TIME_GET_SECOND(self);
3817 offset2 = TIME_GET_HOUR(other) * 3600 +
3818 (TIME_GET_MINUTE(other) - offset2) * 60 +
3819 TIME_GET_SECOND(other);
3820 diff = offset1 - offset2;
3821 if (diff == 0)
3822 diff = TIME_GET_MICROSECOND(self) -
3823 TIME_GET_MICROSECOND(other);
3824 return diff_to_bool(diff, op);
3825 }
Tim Peters37f39822003-01-10 03:49:02 +00003826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003827 assert(n1 != n2);
3828 PyErr_SetString(PyExc_TypeError,
3829 "can't compare offset-naive and "
3830 "offset-aware times");
3831 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003832}
3833
3834static long
3835time_hash(PyDateTime_Time *self)
3836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003837 if (self->hashcode == -1) {
3838 naivety n;
3839 int offset;
3840 PyObject *temp;
Tim Peters37f39822003-01-10 03:49:02 +00003841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003842 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3843 assert(n != OFFSET_UNKNOWN);
3844 if (n == OFFSET_ERROR)
3845 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003847 /* Reduce this to a hash of another object. */
3848 if (offset == 0) {
3849 self->hashcode = generic_hash(
3850 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3851 return self->hashcode;
3852 }
3853 else {
3854 int hour;
3855 int minute;
Tim Peters37f39822003-01-10 03:49:02 +00003856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003857 assert(n == OFFSET_AWARE);
3858 assert(HASTZINFO(self));
3859 hour = divmod(TIME_GET_HOUR(self) * 60 +
3860 TIME_GET_MINUTE(self) - offset,
3861 60,
3862 &minute);
3863 if (0 <= hour && hour < 24)
3864 temp = new_time(hour, minute,
3865 TIME_GET_SECOND(self),
3866 TIME_GET_MICROSECOND(self),
3867 Py_None);
3868 else
3869 temp = Py_BuildValue("iiii",
3870 hour, minute,
3871 TIME_GET_SECOND(self),
3872 TIME_GET_MICROSECOND(self));
3873 }
3874 if (temp != NULL) {
3875 self->hashcode = PyObject_Hash(temp);
3876 Py_DECREF(temp);
3877 }
3878 }
3879 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003880}
Tim Peters2a799bf2002-12-16 20:18:38 +00003881
Tim Peters12bf3392002-12-24 05:41:27 +00003882static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003883time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003885 PyObject *clone;
3886 PyObject *tuple;
3887 int hh = TIME_GET_HOUR(self);
3888 int mm = TIME_GET_MINUTE(self);
3889 int ss = TIME_GET_SECOND(self);
3890 int us = TIME_GET_MICROSECOND(self);
3891 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003893 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3894 time_kws,
3895 &hh, &mm, &ss, &us, &tzinfo))
3896 return NULL;
3897 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3898 if (tuple == NULL)
3899 return NULL;
3900 clone = time_new(Py_TYPE(self), tuple, NULL);
3901 Py_DECREF(tuple);
3902 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003903}
3904
Tim Peters2a799bf2002-12-16 20:18:38 +00003905static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00003906time_bool(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003908 int offset;
3909 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00003910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003911 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3912 /* Since utcoffset is in whole minutes, nothing can
3913 * alter the conclusion that this is nonzero.
3914 */
3915 return 1;
3916 }
3917 offset = 0;
3918 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3919 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3920 if (offset == -1 && PyErr_Occurred())
3921 return -1;
3922 }
3923 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003924}
3925
Tim Peters371935f2003-02-01 01:52:50 +00003926/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003927
Tim Peters33e0f382003-01-10 02:05:14 +00003928/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003929 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3930 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003931 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003932 */
3933static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003934time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003936 PyObject *basestate;
3937 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003939 basestate = PyBytes_FromStringAndSize((char *)self->data,
3940 _PyDateTime_TIME_DATASIZE);
3941 if (basestate != NULL) {
3942 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3943 result = PyTuple_Pack(1, basestate);
3944 else
3945 result = PyTuple_Pack(2, basestate, self->tzinfo);
3946 Py_DECREF(basestate);
3947 }
3948 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003949}
3950
3951static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003952time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003954 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003955}
3956
Tim Peters37f39822003-01-10 03:49:02 +00003957static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003959 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3960 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3961 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003963 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3964 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003966 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3967 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003969 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3970 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003972 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3973 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003975 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3976 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3979 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003981 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3982 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003984 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003985};
3986
Tim Peters37f39822003-01-10 03:49:02 +00003987static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003988PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3989\n\
3990All arguments are optional. tzinfo may be None, or an instance of\n\
3991a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003992
Tim Peters37f39822003-01-10 03:49:02 +00003993static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003994 0, /* nb_add */
3995 0, /* nb_subtract */
3996 0, /* nb_multiply */
3997 0, /* nb_remainder */
3998 0, /* nb_divmod */
3999 0, /* nb_power */
4000 0, /* nb_negative */
4001 0, /* nb_positive */
4002 0, /* nb_absolute */
4003 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004004};
4005
Neal Norwitz227b5332006-03-22 09:28:35 +00004006static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004007 PyVarObject_HEAD_INIT(NULL, 0)
4008 "datetime.time", /* tp_name */
4009 sizeof(PyDateTime_Time), /* tp_basicsize */
4010 0, /* tp_itemsize */
4011 (destructor)time_dealloc, /* tp_dealloc */
4012 0, /* tp_print */
4013 0, /* tp_getattr */
4014 0, /* tp_setattr */
4015 0, /* tp_reserved */
4016 (reprfunc)time_repr, /* tp_repr */
4017 &time_as_number, /* tp_as_number */
4018 0, /* tp_as_sequence */
4019 0, /* tp_as_mapping */
4020 (hashfunc)time_hash, /* tp_hash */
4021 0, /* tp_call */
4022 (reprfunc)time_str, /* tp_str */
4023 PyObject_GenericGetAttr, /* tp_getattro */
4024 0, /* tp_setattro */
4025 0, /* tp_as_buffer */
4026 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4027 time_doc, /* tp_doc */
4028 0, /* tp_traverse */
4029 0, /* tp_clear */
4030 time_richcompare, /* tp_richcompare */
4031 0, /* tp_weaklistoffset */
4032 0, /* tp_iter */
4033 0, /* tp_iternext */
4034 time_methods, /* tp_methods */
4035 0, /* tp_members */
4036 time_getset, /* tp_getset */
4037 0, /* tp_base */
4038 0, /* tp_dict */
4039 0, /* tp_descr_get */
4040 0, /* tp_descr_set */
4041 0, /* tp_dictoffset */
4042 0, /* tp_init */
4043 time_alloc, /* tp_alloc */
4044 time_new, /* tp_new */
4045 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004046};
4047
4048/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004049 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004050 */
4051
Tim Petersa9bc1682003-01-11 03:39:11 +00004052/* Accessor properties. Properties for day, month, and year are inherited
4053 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004054 */
4055
4056static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004057datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004059 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004060}
4061
Tim Petersa9bc1682003-01-11 03:39:11 +00004062static PyObject *
4063datetime_minute(PyDateTime_DateTime *self, void *unused)
4064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004065 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004066}
4067
4068static PyObject *
4069datetime_second(PyDateTime_DateTime *self, void *unused)
4070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004071 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004072}
4073
4074static PyObject *
4075datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004077 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004078}
4079
4080static PyObject *
4081datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004083 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4084 Py_INCREF(result);
4085 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004086}
4087
4088static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004089 {"hour", (getter)datetime_hour},
4090 {"minute", (getter)datetime_minute},
4091 {"second", (getter)datetime_second},
4092 {"microsecond", (getter)datetime_microsecond},
4093 {"tzinfo", (getter)datetime_tzinfo},
4094 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004095};
4096
4097/*
4098 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004099 */
4100
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004101static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 "year", "month", "day", "hour", "minute", "second",
4103 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004104};
4105
Tim Peters2a799bf2002-12-16 20:18:38 +00004106static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004107datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004109 PyObject *self = NULL;
4110 PyObject *state;
4111 int year;
4112 int month;
4113 int day;
4114 int hour = 0;
4115 int minute = 0;
4116 int second = 0;
4117 int usecond = 0;
4118 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004120 /* Check for invocation from pickle with __getstate__ state */
4121 if (PyTuple_GET_SIZE(args) >= 1 &&
4122 PyTuple_GET_SIZE(args) <= 2 &&
4123 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4124 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4125 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4126 {
4127 PyDateTime_DateTime *me;
4128 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 if (PyTuple_GET_SIZE(args) == 2) {
4131 tzinfo = PyTuple_GET_ITEM(args, 1);
4132 if (check_tzinfo_subclass(tzinfo) < 0) {
4133 PyErr_SetString(PyExc_TypeError, "bad "
4134 "tzinfo state arg");
4135 return NULL;
4136 }
4137 }
4138 aware = (char)(tzinfo != Py_None);
4139 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4140 if (me != NULL) {
4141 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004143 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4144 me->hashcode = -1;
4145 me->hastzinfo = aware;
4146 if (aware) {
4147 Py_INCREF(tzinfo);
4148 me->tzinfo = tzinfo;
4149 }
4150 }
4151 return (PyObject *)me;
4152 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004154 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4155 &year, &month, &day, &hour, &minute,
4156 &second, &usecond, &tzinfo)) {
4157 if (check_date_args(year, month, day) < 0)
4158 return NULL;
4159 if (check_time_args(hour, minute, second, usecond) < 0)
4160 return NULL;
4161 if (check_tzinfo_subclass(tzinfo) < 0)
4162 return NULL;
4163 self = new_datetime_ex(year, month, day,
4164 hour, minute, second, usecond,
4165 tzinfo, type);
4166 }
4167 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004168}
4169
Tim Petersa9bc1682003-01-11 03:39:11 +00004170/* TM_FUNC is the shared type of localtime() and gmtime(). */
4171typedef struct tm *(*TM_FUNC)(const time_t *timer);
4172
4173/* Internal helper.
4174 * Build datetime from a time_t and a distinct count of microseconds.
4175 * Pass localtime or gmtime for f, to control the interpretation of timet.
4176 */
4177static PyObject *
4178datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004179 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004181 struct tm *tm;
4182 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004184 tm = f(&timet);
4185 if (tm) {
4186 /* The platform localtime/gmtime may insert leap seconds,
4187 * indicated by tm->tm_sec > 59. We don't care about them,
4188 * except to the extent that passing them on to the datetime
4189 * constructor would raise ValueError for a reason that
4190 * made no sense to the user.
4191 */
4192 if (tm->tm_sec > 59)
4193 tm->tm_sec = 59;
4194 result = PyObject_CallFunction(cls, "iiiiiiiO",
4195 tm->tm_year + 1900,
4196 tm->tm_mon + 1,
4197 tm->tm_mday,
4198 tm->tm_hour,
4199 tm->tm_min,
4200 tm->tm_sec,
4201 us,
4202 tzinfo);
4203 }
4204 else
4205 PyErr_SetString(PyExc_ValueError,
4206 "timestamp out of range for "
4207 "platform localtime()/gmtime() function");
4208 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004209}
4210
4211/* Internal helper.
4212 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4213 * to control the interpretation of the timestamp. Since a double doesn't
4214 * have enough bits to cover a datetime's full range of precision, it's
4215 * better to call datetime_from_timet_and_us provided you have a way
4216 * to get that much precision (e.g., C time() isn't good enough).
4217 */
4218static PyObject *
4219datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004220 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004222 time_t timet;
4223 double fraction;
4224 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 timet = _PyTime_DoubleToTimet(timestamp);
4227 if (timet == (time_t)-1 && PyErr_Occurred())
4228 return NULL;
4229 fraction = timestamp - (double)timet;
4230 us = (int)round_to_long(fraction * 1e6);
4231 if (us < 0) {
4232 /* Truncation towards zero is not what we wanted
4233 for negative numbers (Python's mod semantics) */
4234 timet -= 1;
4235 us += 1000000;
4236 }
4237 /* If timestamp is less than one microsecond smaller than a
4238 * full second, round up. Otherwise, ValueErrors are raised
4239 * for some floats. */
4240 if (us == 1000000) {
4241 timet += 1;
4242 us = 0;
4243 }
4244 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004245}
4246
4247/* Internal helper.
4248 * Build most accurate possible datetime for current time. Pass localtime or
4249 * gmtime for f as appropriate.
4250 */
4251static PyObject *
4252datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4253{
4254#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004255 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00004256
4257#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004258 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00004259#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004260 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00004261#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004262 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4263 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004265#else /* ! HAVE_GETTIMEOFDAY */
4266 /* No flavor of gettimeofday exists on this platform. Python's
4267 * time.time() does a lot of other platform tricks to get the
4268 * best time it can on the platform, and we're not going to do
4269 * better than that (if we could, the better code would belong
4270 * in time.time()!) We're limited by the precision of a double,
4271 * though.
4272 */
4273 PyObject *time;
4274 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00004275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004276 time = time_time();
4277 if (time == NULL)
4278 return NULL;
4279 dtime = PyFloat_AsDouble(time);
4280 Py_DECREF(time);
4281 if (dtime == -1.0 && PyErr_Occurred())
4282 return NULL;
4283 return datetime_from_timestamp(cls, f, dtime, tzinfo);
4284#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00004285}
4286
Tim Peters2a799bf2002-12-16 20:18:38 +00004287/* Return best possible local time -- this isn't constrained by the
4288 * precision of a timestamp.
4289 */
4290static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004291datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004293 PyObject *self;
4294 PyObject *tzinfo = Py_None;
4295 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004297 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4298 &tzinfo))
4299 return NULL;
4300 if (check_tzinfo_subclass(tzinfo) < 0)
4301 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 self = datetime_best_possible(cls,
4304 tzinfo == Py_None ? localtime : gmtime,
4305 tzinfo);
4306 if (self != NULL && tzinfo != Py_None) {
4307 /* Convert UTC to tzinfo's zone. */
4308 PyObject *temp = self;
4309 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4310 Py_DECREF(temp);
4311 }
4312 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004313}
4314
Tim Petersa9bc1682003-01-11 03:39:11 +00004315/* Return best possible UTC time -- this isn't constrained by the
4316 * precision of a timestamp.
4317 */
4318static PyObject *
4319datetime_utcnow(PyObject *cls, PyObject *dummy)
4320{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004321 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004322}
4323
Tim Peters2a799bf2002-12-16 20:18:38 +00004324/* Return new local datetime from timestamp (Python timestamp -- a double). */
4325static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004326datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004328 PyObject *self;
4329 double timestamp;
4330 PyObject *tzinfo = Py_None;
4331 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004333 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4334 keywords, &timestamp, &tzinfo))
4335 return NULL;
4336 if (check_tzinfo_subclass(tzinfo) < 0)
4337 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004339 self = datetime_from_timestamp(cls,
4340 tzinfo == Py_None ? localtime : gmtime,
4341 timestamp,
4342 tzinfo);
4343 if (self != NULL && tzinfo != Py_None) {
4344 /* Convert UTC to tzinfo's zone. */
4345 PyObject *temp = self;
4346 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4347 Py_DECREF(temp);
4348 }
4349 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004350}
4351
Tim Petersa9bc1682003-01-11 03:39:11 +00004352/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4353static PyObject *
4354datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004356 double timestamp;
4357 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004359 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4360 result = datetime_from_timestamp(cls, gmtime, timestamp,
4361 Py_None);
4362 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004363}
4364
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004365/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004366static PyObject *
4367datetime_strptime(PyObject *cls, PyObject *args)
4368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004369 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004370 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004372 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4373 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004374
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004375 if (module == NULL) {
4376 module = PyImport_ImportModuleNoBlock("_strptime");
4377 if(module == NULL)
4378 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004379 }
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004380 return PyObject_CallMethod(module, "_strptime_datetime", "uu",
4381 string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004382}
4383
Tim Petersa9bc1682003-01-11 03:39:11 +00004384/* Return new datetime from date/datetime and time arguments. */
4385static PyObject *
4386datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004388 static char *keywords[] = {"date", "time", NULL};
4389 PyObject *date;
4390 PyObject *time;
4391 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004393 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4394 &PyDateTime_DateType, &date,
4395 &PyDateTime_TimeType, &time)) {
4396 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004398 if (HASTZINFO(time))
4399 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4400 result = PyObject_CallFunction(cls, "iiiiiiiO",
4401 GET_YEAR(date),
4402 GET_MONTH(date),
4403 GET_DAY(date),
4404 TIME_GET_HOUR(time),
4405 TIME_GET_MINUTE(time),
4406 TIME_GET_SECOND(time),
4407 TIME_GET_MICROSECOND(time),
4408 tzinfo);
4409 }
4410 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004411}
Tim Peters2a799bf2002-12-16 20:18:38 +00004412
4413/*
4414 * Destructor.
4415 */
4416
4417static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004418datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004419{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004420 if (HASTZINFO(self)) {
4421 Py_XDECREF(self->tzinfo);
4422 }
4423 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004424}
4425
4426/*
4427 * Indirect access to tzinfo methods.
4428 */
4429
Tim Peters2a799bf2002-12-16 20:18:38 +00004430/* These are all METH_NOARGS, so don't need to check the arglist. */
4431static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004432datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004433 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4434 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004435}
4436
4437static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004438datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004439 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4440 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004441}
4442
4443static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004444datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004445 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4446 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004447}
4448
4449/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004450 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004451 */
4452
Tim Petersa9bc1682003-01-11 03:39:11 +00004453/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4454 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004455 */
4456static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004457add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004458 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004460 /* Note that the C-level additions can't overflow, because of
4461 * invariant bounds on the member values.
4462 */
4463 int year = GET_YEAR(date);
4464 int month = GET_MONTH(date);
4465 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4466 int hour = DATE_GET_HOUR(date);
4467 int minute = DATE_GET_MINUTE(date);
4468 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4469 int microsecond = DATE_GET_MICROSECOND(date) +
4470 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004472 assert(factor == 1 || factor == -1);
4473 if (normalize_datetime(&year, &month, &day,
4474 &hour, &minute, &second, &microsecond) < 0)
4475 return NULL;
4476 else
4477 return new_datetime(year, month, day,
4478 hour, minute, second, microsecond,
4479 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004480}
4481
4482static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004483datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004485 if (PyDateTime_Check(left)) {
4486 /* datetime + ??? */
4487 if (PyDelta_Check(right))
4488 /* datetime + delta */
4489 return add_datetime_timedelta(
4490 (PyDateTime_DateTime *)left,
4491 (PyDateTime_Delta *)right,
4492 1);
4493 }
4494 else if (PyDelta_Check(left)) {
4495 /* delta + datetime */
4496 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4497 (PyDateTime_Delta *) left,
4498 1);
4499 }
4500 Py_INCREF(Py_NotImplemented);
4501 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004502}
4503
4504static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004505datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004506{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004507 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004509 if (PyDateTime_Check(left)) {
4510 /* datetime - ??? */
4511 if (PyDateTime_Check(right)) {
4512 /* datetime - datetime */
4513 naivety n1, n2;
4514 int offset1, offset2;
4515 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004517 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4518 right, &offset2, &n2,
4519 right) < 0)
4520 return NULL;
4521 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4522 if (n1 != n2) {
4523 PyErr_SetString(PyExc_TypeError,
4524 "can't subtract offset-naive and "
4525 "offset-aware datetimes");
4526 return NULL;
4527 }
4528 delta_d = ymd_to_ord(GET_YEAR(left),
4529 GET_MONTH(left),
4530 GET_DAY(left)) -
4531 ymd_to_ord(GET_YEAR(right),
4532 GET_MONTH(right),
4533 GET_DAY(right));
4534 /* These can't overflow, since the values are
4535 * normalized. At most this gives the number of
4536 * seconds in one day.
4537 */
4538 delta_s = (DATE_GET_HOUR(left) -
4539 DATE_GET_HOUR(right)) * 3600 +
4540 (DATE_GET_MINUTE(left) -
4541 DATE_GET_MINUTE(right)) * 60 +
4542 (DATE_GET_SECOND(left) -
4543 DATE_GET_SECOND(right));
4544 delta_us = DATE_GET_MICROSECOND(left) -
4545 DATE_GET_MICROSECOND(right);
4546 /* (left - offset1) - (right - offset2) =
4547 * (left - right) + (offset2 - offset1)
4548 */
4549 delta_s += (offset2 - offset1) * 60;
4550 result = new_delta(delta_d, delta_s, delta_us, 1);
4551 }
4552 else if (PyDelta_Check(right)) {
4553 /* datetime - delta */
4554 result = add_datetime_timedelta(
4555 (PyDateTime_DateTime *)left,
4556 (PyDateTime_Delta *)right,
4557 -1);
4558 }
4559 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004561 if (result == Py_NotImplemented)
4562 Py_INCREF(result);
4563 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004564}
4565
4566/* Various ways to turn a datetime into a string. */
4567
4568static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004569datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004570{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004571 const char *type_name = Py_TYPE(self)->tp_name;
4572 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004574 if (DATE_GET_MICROSECOND(self)) {
4575 baserepr = PyUnicode_FromFormat(
4576 "%s(%d, %d, %d, %d, %d, %d, %d)",
4577 type_name,
4578 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4579 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4580 DATE_GET_SECOND(self),
4581 DATE_GET_MICROSECOND(self));
4582 }
4583 else if (DATE_GET_SECOND(self)) {
4584 baserepr = PyUnicode_FromFormat(
4585 "%s(%d, %d, %d, %d, %d, %d)",
4586 type_name,
4587 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4588 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4589 DATE_GET_SECOND(self));
4590 }
4591 else {
4592 baserepr = PyUnicode_FromFormat(
4593 "%s(%d, %d, %d, %d, %d)",
4594 type_name,
4595 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4596 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4597 }
4598 if (baserepr == NULL || ! HASTZINFO(self))
4599 return baserepr;
4600 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004601}
4602
Tim Petersa9bc1682003-01-11 03:39:11 +00004603static PyObject *
4604datetime_str(PyDateTime_DateTime *self)
4605{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004606 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004607}
Tim Peters2a799bf2002-12-16 20:18:38 +00004608
4609static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004610datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004612 int sep = 'T';
4613 static char *keywords[] = {"sep", NULL};
4614 char buffer[100];
4615 PyObject *result;
4616 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004618 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4619 return NULL;
4620 if (us)
4621 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4622 GET_YEAR(self), GET_MONTH(self),
4623 GET_DAY(self), (int)sep,
4624 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4625 DATE_GET_SECOND(self), us);
4626 else
4627 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4628 GET_YEAR(self), GET_MONTH(self),
4629 GET_DAY(self), (int)sep,
4630 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4631 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004633 if (!result || !HASTZINFO(self))
4634 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004636 /* We need to append the UTC offset. */
4637 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4638 (PyObject *)self) < 0) {
4639 Py_DECREF(result);
4640 return NULL;
4641 }
4642 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4643 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004644}
4645
Tim Petersa9bc1682003-01-11 03:39:11 +00004646static PyObject *
4647datetime_ctime(PyDateTime_DateTime *self)
4648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004649 return format_ctime((PyDateTime_Date *)self,
4650 DATE_GET_HOUR(self),
4651 DATE_GET_MINUTE(self),
4652 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004653}
4654
Tim Peters2a799bf2002-12-16 20:18:38 +00004655/* Miscellaneous methods. */
4656
Tim Petersa9bc1682003-01-11 03:39:11 +00004657static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004658datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004660 int diff;
4661 naivety n1, n2;
4662 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004664 if (! PyDateTime_Check(other)) {
4665 if (PyDate_Check(other)) {
4666 /* Prevent invocation of date_richcompare. We want to
4667 return NotImplemented here to give the other object
4668 a chance. But since DateTime is a subclass of
4669 Date, if the other object is a Date, it would
4670 compute an ordering based on the date part alone,
4671 and we don't want that. So force unequal or
4672 uncomparable here in that case. */
4673 if (op == Py_EQ)
4674 Py_RETURN_FALSE;
4675 if (op == Py_NE)
4676 Py_RETURN_TRUE;
4677 return cmperror(self, other);
4678 }
4679 Py_INCREF(Py_NotImplemented);
4680 return Py_NotImplemented;
4681 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 if (classify_two_utcoffsets(self, &offset1, &n1, self,
4684 other, &offset2, &n2, other) < 0)
4685 return NULL;
4686 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4687 /* If they're both naive, or both aware and have the same offsets,
4688 * we get off cheap. Note that if they're both naive, offset1 ==
4689 * offset2 == 0 at this point.
4690 */
4691 if (n1 == n2 && offset1 == offset2) {
4692 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4693 ((PyDateTime_DateTime *)other)->data,
4694 _PyDateTime_DATETIME_DATASIZE);
4695 return diff_to_bool(diff, op);
4696 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004698 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4699 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004701 assert(offset1 != offset2); /* else last "if" handled it */
4702 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4703 other);
4704 if (delta == NULL)
4705 return NULL;
4706 diff = GET_TD_DAYS(delta);
4707 if (diff == 0)
4708 diff = GET_TD_SECONDS(delta) |
4709 GET_TD_MICROSECONDS(delta);
4710 Py_DECREF(delta);
4711 return diff_to_bool(diff, op);
4712 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004714 assert(n1 != n2);
4715 PyErr_SetString(PyExc_TypeError,
4716 "can't compare offset-naive and "
4717 "offset-aware datetimes");
4718 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004719}
4720
4721static long
4722datetime_hash(PyDateTime_DateTime *self)
4723{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004724 if (self->hashcode == -1) {
4725 naivety n;
4726 int offset;
4727 PyObject *temp;
Tim Petersa9bc1682003-01-11 03:39:11 +00004728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004729 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4730 &offset);
4731 assert(n != OFFSET_UNKNOWN);
4732 if (n == OFFSET_ERROR)
4733 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004735 /* Reduce this to a hash of another object. */
4736 if (n == OFFSET_NAIVE) {
4737 self->hashcode = generic_hash(
4738 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
4739 return self->hashcode;
4740 }
4741 else {
4742 int days;
4743 int seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004745 assert(n == OFFSET_AWARE);
4746 assert(HASTZINFO(self));
4747 days = ymd_to_ord(GET_YEAR(self),
4748 GET_MONTH(self),
4749 GET_DAY(self));
4750 seconds = DATE_GET_HOUR(self) * 3600 +
4751 (DATE_GET_MINUTE(self) - offset) * 60 +
4752 DATE_GET_SECOND(self);
4753 temp = new_delta(days,
4754 seconds,
4755 DATE_GET_MICROSECOND(self),
4756 1);
4757 }
4758 if (temp != NULL) {
4759 self->hashcode = PyObject_Hash(temp);
4760 Py_DECREF(temp);
4761 }
4762 }
4763 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004764}
Tim Peters2a799bf2002-12-16 20:18:38 +00004765
4766static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004767datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004768{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004769 PyObject *clone;
4770 PyObject *tuple;
4771 int y = GET_YEAR(self);
4772 int m = GET_MONTH(self);
4773 int d = GET_DAY(self);
4774 int hh = DATE_GET_HOUR(self);
4775 int mm = DATE_GET_MINUTE(self);
4776 int ss = DATE_GET_SECOND(self);
4777 int us = DATE_GET_MICROSECOND(self);
4778 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004780 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4781 datetime_kws,
4782 &y, &m, &d, &hh, &mm, &ss, &us,
4783 &tzinfo))
4784 return NULL;
4785 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4786 if (tuple == NULL)
4787 return NULL;
4788 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4789 Py_DECREF(tuple);
4790 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004791}
4792
4793static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004794datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004796 int y, m, d, hh, mm, ss, us;
4797 PyObject *result;
4798 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004800 PyObject *tzinfo;
4801 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004803 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4804 &PyDateTime_TZInfoType, &tzinfo))
4805 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004807 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4808 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004810 /* Conversion to self's own time zone is a NOP. */
4811 if (self->tzinfo == tzinfo) {
4812 Py_INCREF(self);
4813 return (PyObject *)self;
4814 }
Tim Peters521fc152002-12-31 17:36:56 +00004815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004816 /* Convert self to UTC. */
4817 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4818 if (offset == -1 && PyErr_Occurred())
4819 return NULL;
4820 if (none)
4821 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004822
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004823 y = GET_YEAR(self);
4824 m = GET_MONTH(self);
4825 d = GET_DAY(self);
4826 hh = DATE_GET_HOUR(self);
4827 mm = DATE_GET_MINUTE(self);
4828 ss = DATE_GET_SECOND(self);
4829 us = DATE_GET_MICROSECOND(self);
Tim Peters52dcce22003-01-23 16:36:11 +00004830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004831 mm -= offset;
4832 if ((mm < 0 || mm >= 60) &&
4833 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4834 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004836 /* Attach new tzinfo and let fromutc() do the rest. */
4837 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4838 if (result != NULL) {
4839 PyObject *temp = result;
Tim Peters52dcce22003-01-23 16:36:11 +00004840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004841 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4842 Py_DECREF(temp);
4843 }
4844 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004845
Tim Peters52dcce22003-01-23 16:36:11 +00004846NeedAware:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004847 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4848 "a naive datetime");
4849 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004850}
4851
4852static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004853datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004854{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004855 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004857 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4858 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004860 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4861 if (dstflag == -1 && PyErr_Occurred())
4862 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004864 if (none)
4865 dstflag = -1;
4866 else if (dstflag != 0)
4867 dstflag = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004869 }
4870 return build_struct_time(GET_YEAR(self),
4871 GET_MONTH(self),
4872 GET_DAY(self),
4873 DATE_GET_HOUR(self),
4874 DATE_GET_MINUTE(self),
4875 DATE_GET_SECOND(self),
4876 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004877}
4878
4879static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004880datetime_getdate(PyDateTime_DateTime *self)
4881{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 return new_date(GET_YEAR(self),
4883 GET_MONTH(self),
4884 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004885}
4886
4887static PyObject *
4888datetime_gettime(PyDateTime_DateTime *self)
4889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 return new_time(DATE_GET_HOUR(self),
4891 DATE_GET_MINUTE(self),
4892 DATE_GET_SECOND(self),
4893 DATE_GET_MICROSECOND(self),
4894 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004895}
4896
4897static PyObject *
4898datetime_gettimetz(PyDateTime_DateTime *self)
4899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004900 return new_time(DATE_GET_HOUR(self),
4901 DATE_GET_MINUTE(self),
4902 DATE_GET_SECOND(self),
4903 DATE_GET_MICROSECOND(self),
4904 HASTZINFO(self) ? self->tzinfo : Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004905}
4906
4907static PyObject *
4908datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004910 int y = GET_YEAR(self);
4911 int m = GET_MONTH(self);
4912 int d = GET_DAY(self);
4913 int hh = DATE_GET_HOUR(self);
4914 int mm = DATE_GET_MINUTE(self);
4915 int ss = DATE_GET_SECOND(self);
4916 int us = 0; /* microseconds are ignored in a timetuple */
4917 int offset = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004919 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4920 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004922 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4923 if (offset == -1 && PyErr_Occurred())
4924 return NULL;
4925 }
4926 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4927 * 0 in a UTC timetuple regardless of what dst() says.
4928 */
4929 if (offset) {
4930 /* Subtract offset minutes & normalize. */
4931 int stat;
Tim Peters2a799bf2002-12-16 20:18:38 +00004932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004933 mm -= offset;
4934 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4935 if (stat < 0) {
4936 /* At the edges, it's possible we overflowed
4937 * beyond MINYEAR or MAXYEAR.
4938 */
4939 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4940 PyErr_Clear();
4941 else
4942 return NULL;
4943 }
4944 }
4945 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004946}
4947
Tim Peters371935f2003-02-01 01:52:50 +00004948/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004949
Tim Petersa9bc1682003-01-11 03:39:11 +00004950/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004951 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4952 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004953 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004954 */
4955static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004956datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004958 PyObject *basestate;
4959 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004961 basestate = PyBytes_FromStringAndSize((char *)self->data,
4962 _PyDateTime_DATETIME_DATASIZE);
4963 if (basestate != NULL) {
4964 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4965 result = PyTuple_Pack(1, basestate);
4966 else
4967 result = PyTuple_Pack(2, basestate, self->tzinfo);
4968 Py_DECREF(basestate);
4969 }
4970 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004971}
4972
4973static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004974datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004976 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004977}
4978
Tim Petersa9bc1682003-01-11 03:39:11 +00004979static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004981 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004983 {"now", (PyCFunction)datetime_now,
4984 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4985 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004987 {"utcnow", (PyCFunction)datetime_utcnow,
4988 METH_NOARGS | METH_CLASS,
4989 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004991 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4992 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4993 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004995 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4996 METH_VARARGS | METH_CLASS,
4997 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4998 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005000 {"strptime", (PyCFunction)datetime_strptime,
5001 METH_VARARGS | METH_CLASS,
5002 PyDoc_STR("string, format -> new datetime parsed from a string "
5003 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005005 {"combine", (PyCFunction)datetime_combine,
5006 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5007 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005009 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005011 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5012 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005014 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5015 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005017 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5018 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005020 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5021 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005023 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5024 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005026 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5027 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005029 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5030 PyDoc_STR("[sep] -> string in ISO 8601 format, "
5031 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
5032 "sep is used to separate the year from the time, and "
5033 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5036 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005038 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5039 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005041 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5042 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005044 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5045 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005047 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5048 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005050 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5051 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005053 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005054};
5055
Tim Petersa9bc1682003-01-11 03:39:11 +00005056static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005057PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5058\n\
5059The year, month and day arguments are required. tzinfo may be None, or an\n\
5060instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005061
Tim Petersa9bc1682003-01-11 03:39:11 +00005062static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005063 datetime_add, /* nb_add */
5064 datetime_subtract, /* nb_subtract */
5065 0, /* nb_multiply */
5066 0, /* nb_remainder */
5067 0, /* nb_divmod */
5068 0, /* nb_power */
5069 0, /* nb_negative */
5070 0, /* nb_positive */
5071 0, /* nb_absolute */
5072 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005073};
5074
Neal Norwitz227b5332006-03-22 09:28:35 +00005075static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005076 PyVarObject_HEAD_INIT(NULL, 0)
5077 "datetime.datetime", /* tp_name */
5078 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5079 0, /* tp_itemsize */
5080 (destructor)datetime_dealloc, /* tp_dealloc */
5081 0, /* tp_print */
5082 0, /* tp_getattr */
5083 0, /* tp_setattr */
5084 0, /* tp_reserved */
5085 (reprfunc)datetime_repr, /* tp_repr */
5086 &datetime_as_number, /* tp_as_number */
5087 0, /* tp_as_sequence */
5088 0, /* tp_as_mapping */
5089 (hashfunc)datetime_hash, /* tp_hash */
5090 0, /* tp_call */
5091 (reprfunc)datetime_str, /* tp_str */
5092 PyObject_GenericGetAttr, /* tp_getattro */
5093 0, /* tp_setattro */
5094 0, /* tp_as_buffer */
5095 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5096 datetime_doc, /* tp_doc */
5097 0, /* tp_traverse */
5098 0, /* tp_clear */
5099 datetime_richcompare, /* tp_richcompare */
5100 0, /* tp_weaklistoffset */
5101 0, /* tp_iter */
5102 0, /* tp_iternext */
5103 datetime_methods, /* tp_methods */
5104 0, /* tp_members */
5105 datetime_getset, /* tp_getset */
5106 &PyDateTime_DateType, /* tp_base */
5107 0, /* tp_dict */
5108 0, /* tp_descr_get */
5109 0, /* tp_descr_set */
5110 0, /* tp_dictoffset */
5111 0, /* tp_init */
5112 datetime_alloc, /* tp_alloc */
5113 datetime_new, /* tp_new */
5114 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005115};
5116
5117/* ---------------------------------------------------------------------------
5118 * Module methods and initialization.
5119 */
5120
5121static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005122 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005123};
5124
Tim Peters9ddf40b2004-06-20 22:41:32 +00005125/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5126 * datetime.h.
5127 */
5128static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005129 &PyDateTime_DateType,
5130 &PyDateTime_DateTimeType,
5131 &PyDateTime_TimeType,
5132 &PyDateTime_DeltaType,
5133 &PyDateTime_TZInfoType,
5134 new_date_ex,
5135 new_datetime_ex,
5136 new_time_ex,
5137 new_delta_ex,
5138 datetime_fromtimestamp,
5139 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005140};
5141
5142
Martin v. Löwis1a214512008-06-11 05:26:20 +00005143
5144static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005145 PyModuleDef_HEAD_INIT,
5146 "datetime",
5147 "Fast implementation of the datetime type.",
5148 -1,
5149 module_methods,
5150 NULL,
5151 NULL,
5152 NULL,
5153 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005154};
5155
Tim Peters2a799bf2002-12-16 20:18:38 +00005156PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00005157PyInit_datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005159 PyObject *m; /* a module object */
5160 PyObject *d; /* its dict */
5161 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005162 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005164 m = PyModule_Create(&datetimemodule);
5165 if (m == NULL)
5166 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005168 if (PyType_Ready(&PyDateTime_DateType) < 0)
5169 return NULL;
5170 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5171 return NULL;
5172 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5173 return NULL;
5174 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5175 return NULL;
5176 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5177 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005178 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5179 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005181 /* timedelta values */
5182 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005184 x = new_delta(0, 0, 1, 0);
5185 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5186 return NULL;
5187 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005189 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5190 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5191 return NULL;
5192 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005194 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5195 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5196 return NULL;
5197 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005199 /* date values */
5200 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005202 x = new_date(1, 1, 1);
5203 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5204 return NULL;
5205 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005207 x = new_date(MAXYEAR, 12, 31);
5208 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5209 return NULL;
5210 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005212 x = new_delta(1, 0, 0, 0);
5213 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5214 return NULL;
5215 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005217 /* time values */
5218 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005220 x = new_time(0, 0, 0, 0, Py_None);
5221 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5222 return NULL;
5223 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005225 x = new_time(23, 59, 59, 999999, Py_None);
5226 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5227 return NULL;
5228 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005230 x = new_delta(0, 0, 1, 0);
5231 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5232 return NULL;
5233 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005235 /* datetime values */
5236 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005238 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5239 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5240 return NULL;
5241 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5244 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5245 return NULL;
5246 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005248 x = new_delta(0, 0, 1, 0);
5249 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5250 return NULL;
5251 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005252
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005253 /* timezone values */
5254 d = PyDateTime_TimeZoneType.tp_dict;
5255
5256 delta = new_delta(0, 0, 0, 0);
5257 if (delta == NULL)
5258 return NULL;
5259 x = new_timezone(delta, NULL);
5260 Py_DECREF(delta);
5261 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5262 return NULL;
5263 Py_DECREF(x);
5264
5265 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5266 if (delta == NULL)
5267 return NULL;
5268 x = new_timezone(delta, NULL);
5269 Py_DECREF(delta);
5270 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5271 return NULL;
5272 Py_DECREF(x);
5273
5274 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5275 if (delta == NULL)
5276 return NULL;
5277 x = new_timezone(delta, NULL);
5278 Py_DECREF(delta);
5279 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5280 return NULL;
5281 Py_DECREF(x);
5282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005283 /* module initialization */
5284 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5285 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005287 Py_INCREF(&PyDateTime_DateType);
5288 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005290 Py_INCREF(&PyDateTime_DateTimeType);
5291 PyModule_AddObject(m, "datetime",
5292 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005294 Py_INCREF(&PyDateTime_TimeType);
5295 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005297 Py_INCREF(&PyDateTime_DeltaType);
5298 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005300 Py_INCREF(&PyDateTime_TZInfoType);
5301 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005302
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005303 Py_INCREF(&PyDateTime_TimeZoneType);
5304 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005306 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5307 if (x == NULL)
5308 return NULL;
5309 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005311 /* A 4-year cycle has an extra leap day over what we'd get from
5312 * pasting together 4 single years.
5313 */
5314 assert(DI4Y == 4 * 365 + 1);
5315 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005317 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5318 * get from pasting together 4 100-year cycles.
5319 */
5320 assert(DI400Y == 4 * DI100Y + 1);
5321 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005323 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5324 * pasting together 25 4-year cycles.
5325 */
5326 assert(DI100Y == 25 * DI4Y - 1);
5327 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005329 us_per_us = PyLong_FromLong(1);
5330 us_per_ms = PyLong_FromLong(1000);
5331 us_per_second = PyLong_FromLong(1000000);
5332 us_per_minute = PyLong_FromLong(60000000);
5333 seconds_per_day = PyLong_FromLong(24 * 3600);
5334 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5335 us_per_minute == NULL || seconds_per_day == NULL)
5336 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005338 /* The rest are too big for 32-bit ints, but even
5339 * us_per_week fits in 40 bits, so doubles should be exact.
5340 */
5341 us_per_hour = PyLong_FromDouble(3600000000.0);
5342 us_per_day = PyLong_FromDouble(86400000000.0);
5343 us_per_week = PyLong_FromDouble(604800000000.0);
5344 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5345 return NULL;
5346 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005347}
Tim Petersf3615152003-01-01 21:51:37 +00005348
5349/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005350Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005351 x.n = x stripped of its timezone -- its naive time.
5352 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005353 return None
Tim Petersf3615152003-01-01 21:51:37 +00005354 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005355 return None
Tim Petersf3615152003-01-01 21:51:37 +00005356 x.s = x's standard offset, x.o - x.d
5357
5358Now some derived rules, where k is a duration (timedelta).
5359
53601. x.o = x.s + x.d
5361 This follows from the definition of x.s.
5362
Tim Petersc5dc4da2003-01-02 17:55:03 +000053632. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005364 This is actually a requirement, an assumption we need to make about
5365 sane tzinfo classes.
5366
53673. The naive UTC time corresponding to x is x.n - x.o.
5368 This is again a requirement for a sane tzinfo class.
5369
53704. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005371 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005372
Tim Petersc5dc4da2003-01-02 17:55:03 +000053735. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005374 Again follows from how arithmetic is defined.
5375
Tim Peters8bb5ad22003-01-24 02:44:45 +00005376Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005377(meaning that the various tzinfo methods exist, and don't blow up or return
5378None when called).
5379
Tim Petersa9bc1682003-01-11 03:39:11 +00005380The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005381x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005382
5383By #3, we want
5384
Tim Peters8bb5ad22003-01-24 02:44:45 +00005385 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005386
5387The algorithm starts by attaching tz to x.n, and calling that y. So
5388x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5389becomes true; in effect, we want to solve [2] for k:
5390
Tim Peters8bb5ad22003-01-24 02:44:45 +00005391 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005392
5393By #1, this is the same as
5394
Tim Peters8bb5ad22003-01-24 02:44:45 +00005395 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005396
5397By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5398Substituting that into [3],
5399
Tim Peters8bb5ad22003-01-24 02:44:45 +00005400 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5401 k - (y+k).s - (y+k).d = 0; rearranging,
5402 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5403 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005404
Tim Peters8bb5ad22003-01-24 02:44:45 +00005405On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5406approximate k by ignoring the (y+k).d term at first. Note that k can't be
5407very large, since all offset-returning methods return a duration of magnitude
5408less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5409be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005410
5411In any case, the new value is
5412
Tim Peters8bb5ad22003-01-24 02:44:45 +00005413 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005414
Tim Peters8bb5ad22003-01-24 02:44:45 +00005415It's helpful to step back at look at [4] from a higher level: it's simply
5416mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005417
5418At this point, if
5419
Tim Peters8bb5ad22003-01-24 02:44:45 +00005420 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005421
5422we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005423at the start of daylight time. Picture US Eastern for concreteness. The wall
5424time 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 +00005425sense then. The docs ask that an Eastern tzinfo class consider such a time to
5426be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5427on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005428the only spelling that makes sense on the local wall clock.
5429
Tim Petersc5dc4da2003-01-02 17:55:03 +00005430In fact, if [5] holds at this point, we do have the standard-time spelling,
5431but that takes a bit of proof. We first prove a stronger result. What's the
5432difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005433
Tim Peters8bb5ad22003-01-24 02:44:45 +00005434 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005435
Tim Petersc5dc4da2003-01-02 17:55:03 +00005436Now
5437 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005438 (y + y.s).n = by #5
5439 y.n + y.s = since y.n = x.n
5440 x.n + y.s = since z and y are have the same tzinfo member,
5441 y.s = z.s by #2
5442 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005443
Tim Petersc5dc4da2003-01-02 17:55:03 +00005444Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005445
Tim Petersc5dc4da2003-01-02 17:55:03 +00005446 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005447 x.n - ((x.n + z.s) - z.o) = expanding
5448 x.n - x.n - z.s + z.o = cancelling
5449 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005450 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005451
Tim Petersc5dc4da2003-01-02 17:55:03 +00005452So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005453
Tim Petersc5dc4da2003-01-02 17:55:03 +00005454If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005455spelling we wanted in the endcase described above. We're done. Contrarily,
5456if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005457
Tim Petersc5dc4da2003-01-02 17:55:03 +00005458If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5459add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005460local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005461
Tim Petersc5dc4da2003-01-02 17:55:03 +00005462Let
Tim Petersf3615152003-01-01 21:51:37 +00005463
Tim Peters4fede1a2003-01-04 00:26:59 +00005464 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005465
Tim Peters4fede1a2003-01-04 00:26:59 +00005466and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005467
Tim Peters8bb5ad22003-01-24 02:44:45 +00005468 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005469
Tim Peters8bb5ad22003-01-24 02:44:45 +00005470If so, we're done. If not, the tzinfo class is insane, according to the
5471assumptions we've made. This also requires a bit of proof. As before, let's
5472compute the difference between the LHS and RHS of [8] (and skipping some of
5473the justifications for the kinds of substitutions we've done several times
5474already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005475
Tim Peters8bb5ad22003-01-24 02:44:45 +00005476 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005477 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5478 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5479 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5480 - z.n + z.n - z.o + z'.o = cancel z.n
5481 - z.o + z'.o = #1 twice
5482 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5483 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005484
5485So 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 +00005486we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5487return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005488
Tim Peters8bb5ad22003-01-24 02:44:45 +00005489How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5490a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5491would have to change the result dst() returns: we start in DST, and moving
5492a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005493
Tim Peters8bb5ad22003-01-24 02:44:45 +00005494There isn't a sane case where this can happen. The closest it gets is at
5495the end of DST, where there's an hour in UTC with no spelling in a hybrid
5496tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5497that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5498UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5499time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5500clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5501standard time. Since that's what the local clock *does*, we want to map both
5502UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005503in local time, but so it goes -- it's the way the local clock works.
5504
Tim Peters8bb5ad22003-01-24 02:44:45 +00005505When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5506so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5507z' = 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 +00005508(correctly) concludes that z' is not UTC-equivalent to x.
5509
5510Because we know z.d said z was in daylight time (else [5] would have held and
5511we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005512and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005513return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5514but the reasoning doesn't depend on the example -- it depends on there being
5515two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005516z' must be in standard time, and is the spelling we want in this case.
5517
5518Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5519concerned (because it takes z' as being in standard time rather than the
5520daylight time we intend here), but returning it gives the real-life "local
5521clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5522tz.
5523
5524When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5525the 1:MM standard time spelling we want.
5526
5527So how can this break? One of the assumptions must be violated. Two
5528possibilities:
5529
55301) [2] effectively says that y.s is invariant across all y belong to a given
5531 time zone. This isn't true if, for political reasons or continental drift,
5532 a region decides to change its base offset from UTC.
5533
55342) There may be versions of "double daylight" time where the tail end of
5535 the analysis gives up a step too early. I haven't thought about that
5536 enough to say.
5537
5538In any case, it's clear that the default fromutc() is strong enough to handle
5539"almost all" time zones: so long as the standard offset is invariant, it
5540doesn't matter if daylight time transition points change from year to year, or
5541if daylight time is skipped in some years; it doesn't matter how large or
5542small dst() may get within its bounds; and it doesn't even matter if some
5543perverse time zone returns a negative dst()). So a breaking case must be
5544pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005545--------------------------------------------------------------------------- */