blob: b8ca247ca53420af47d43a8a404692fa1c06c7e8 [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 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 }
1027 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001028}
1029
1030typedef enum {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 /* an exception has been set; the caller should pass it on */
1032 OFFSET_ERROR,
Tim Peters2a799bf2002-12-16 20:18:38 +00001033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 /* type isn't date, datetime, or time subclass */
1035 OFFSET_UNKNOWN,
Tim Peters2a799bf2002-12-16 20:18:38 +00001036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 /* date,
1038 * datetime with !hastzinfo
1039 * datetime with None tzinfo,
1040 * datetime where utcoffset() returns None
1041 * time with !hastzinfo
1042 * time with None tzinfo,
1043 * time where utcoffset() returns None
1044 */
1045 OFFSET_NAIVE,
Tim Peters2a799bf2002-12-16 20:18:38 +00001046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 /* time or datetime where utcoffset() doesn't return None */
1048 OFFSET_AWARE
Tim Peters2a799bf2002-12-16 20:18:38 +00001049} naivety;
1050
Tim Peters14b69412002-12-22 18:10:22 +00001051/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +00001052 * the "naivety" typedef for details. If the type is aware, *offset is set
1053 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +00001054 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +00001055 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +00001056 */
1057static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +00001058classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +00001059{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 int none;
1061 PyObject *tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 assert(tzinfoarg != NULL);
1064 *offset = 0;
1065 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
1066 if (tzinfo == Py_None)
1067 return OFFSET_NAIVE;
1068 if (tzinfo == NULL) {
1069 /* note that a datetime passes the PyDate_Check test */
1070 return (PyTime_Check(op) || PyDate_Check(op)) ?
1071 OFFSET_NAIVE : OFFSET_UNKNOWN;
1072 }
1073 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1074 if (*offset == -1 && PyErr_Occurred())
1075 return OFFSET_ERROR;
1076 return none ? OFFSET_NAIVE : OFFSET_AWARE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001077}
1078
Tim Peters00237032002-12-27 02:21:51 +00001079/* Classify two objects as to whether they're naive or offset-aware.
1080 * This isn't quite the same as calling classify_utcoffset() twice: for
1081 * binary operations (comparison and subtraction), we generally want to
1082 * ignore the tzinfo members if they're identical. This is by design,
1083 * so that results match "naive" expectations when mixing objects from a
1084 * single timezone. So in that case, this sets both offsets to 0 and
1085 * both naiveties to OFFSET_NAIVE.
1086 * The function returns 0 if everything's OK, and -1 on error.
1087 */
1088static int
1089classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 PyObject *tzinfoarg1,
1091 PyObject *o2, int *offset2, naivety *n2,
1092 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1095 *offset1 = *offset2 = 0;
1096 *n1 = *n2 = OFFSET_NAIVE;
1097 }
1098 else {
1099 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1100 if (*n1 == OFFSET_ERROR)
1101 return -1;
1102 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1103 if (*n2 == OFFSET_ERROR)
1104 return -1;
1105 }
1106 return 0;
Tim Peters00237032002-12-27 02:21:51 +00001107}
1108
Tim Peters2a799bf2002-12-16 20:18:38 +00001109/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1110 * stuff
1111 * ", tzinfo=" + repr(tzinfo)
1112 * before the closing ")".
1113 */
1114static PyObject *
1115append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 assert(PyUnicode_Check(repr));
1120 assert(tzinfo);
1121 if (tzinfo == Py_None)
1122 return repr;
1123 /* Get rid of the trailing ')'. */
1124 assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
1125 temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
1126 PyUnicode_GET_SIZE(repr) - 1);
1127 Py_DECREF(repr);
1128 if (temp == NULL)
1129 return NULL;
1130 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1131 Py_DECREF(temp);
1132 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001133}
1134
1135/* ---------------------------------------------------------------------------
1136 * String format helpers.
1137 */
1138
1139static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001140format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 static const char *DayNames[] = {
1143 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1144 };
1145 static const char *MonthNames[] = {
1146 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1147 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1148 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1153 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1154 GET_DAY(date), hours, minutes, seconds,
1155 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001156}
1157
1158/* Add an hours & minutes UTC offset string to buf. buf has no more than
1159 * buflen bytes remaining. The UTC offset is gotten by calling
1160 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1161 * *buf, and that's all. Else the returned value is checked for sanity (an
1162 * integer in range), and if that's OK it's converted to an hours & minutes
1163 * string of the form
1164 * sign HH sep MM
1165 * Returns 0 if everything is OK. If the return value from utcoffset() is
1166 * bogus, an appropriate exception is set and -1 is returned.
1167 */
1168static int
Tim Peters328fff72002-12-20 01:31:27 +00001169format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 int offset;
1173 int hours;
1174 int minutes;
1175 char sign;
1176 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00001177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1181 if (offset == -1 && PyErr_Occurred())
1182 return -1;
1183 if (none) {
1184 *buf = '\0';
1185 return 0;
1186 }
1187 sign = '+';
1188 if (offset < 0) {
1189 sign = '-';
1190 offset = - offset;
1191 }
1192 hours = divmod(offset, 60, &minutes);
1193 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1194 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001195}
1196
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001197static PyObject *
1198make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 PyObject *temp;
1201 PyObject *tzinfo = get_tzinfo_member(object);
1202 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1203 if (Zreplacement == NULL)
1204 return NULL;
1205 if (tzinfo == Py_None || tzinfo == NULL)
1206 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 assert(tzinfoarg != NULL);
1209 temp = call_tzname(tzinfo, tzinfoarg);
1210 if (temp == NULL)
1211 goto Error;
1212 if (temp == Py_None) {
1213 Py_DECREF(temp);
1214 return Zreplacement;
1215 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 assert(PyUnicode_Check(temp));
1218 /* Since the tzname is getting stuffed into the
1219 * format, we have to double any % signs so that
1220 * strftime doesn't treat them as format codes.
1221 */
1222 Py_DECREF(Zreplacement);
1223 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1224 Py_DECREF(temp);
1225 if (Zreplacement == NULL)
1226 return NULL;
1227 if (!PyUnicode_Check(Zreplacement)) {
1228 PyErr_SetString(PyExc_TypeError,
1229 "tzname.replace() did not return a string");
1230 goto Error;
1231 }
1232 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001233
1234 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 Py_DECREF(Zreplacement);
1236 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001237}
1238
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001239static PyObject *
1240make_freplacement(PyObject *object)
1241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 char freplacement[64];
1243 if (PyTime_Check(object))
1244 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1245 else if (PyDateTime_Check(object))
1246 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1247 else
1248 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001251}
1252
Tim Peters2a799bf2002-12-16 20:18:38 +00001253/* I sure don't want to reproduce the strftime code from the time module,
1254 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001255 * giving special meanings to the %z, %Z and %f format codes via a
1256 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001257 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1258 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001259 */
1260static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001261wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1267 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1268 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 const char *pin; /* pointer to next char in input format */
1271 Py_ssize_t flen; /* length of input format */
1272 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 PyObject *newfmt = NULL; /* py string, the output format */
1275 char *pnew; /* pointer to available byte in output format */
1276 size_t totalnew; /* number bytes total in output format buffer,
1277 exclusive of trailing \0 */
1278 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 const char *ptoappend; /* ptr to string to append to output buffer */
1281 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 assert(object && format && timetuple);
1284 assert(PyUnicode_Check(format));
1285 /* Convert the input format to a C string and size */
1286 pin = _PyUnicode_AsStringAndSize(format, &flen);
1287 if (!pin)
1288 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 /* Give up if the year is before 1900.
1291 * Python strftime() plays games with the year, and different
1292 * games depending on whether envar PYTHON2K is set. This makes
1293 * years before 1900 a nightmare, even if the platform strftime
1294 * supports them (and not all do).
1295 * We could get a lot farther here by avoiding Python's strftime
1296 * wrapper and calling the C strftime() directly, but that isn't
1297 * an option in the Python implementation of this module.
1298 */
1299 {
1300 long year;
1301 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1302 if (pyyear == NULL) return NULL;
1303 assert(PyLong_Check(pyyear));
1304 year = PyLong_AsLong(pyyear);
1305 Py_DECREF(pyyear);
1306 if (year < 1900) {
1307 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1308 "1900; the datetime strftime() "
1309 "methods require year >= 1900",
1310 year);
1311 return NULL;
1312 }
1313 }
Tim Petersd6844152002-12-22 20:58:42 +00001314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 /* Scan the input format, looking for %z/%Z/%f escapes, building
1316 * a new format. Since computing the replacements for those codes
1317 * is expensive, don't unless they're actually used.
1318 */
1319 if (flen > INT_MAX - 1) {
1320 PyErr_NoMemory();
1321 goto Done;
1322 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 totalnew = flen + 1; /* realistic if no %z/%Z */
1325 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1326 if (newfmt == NULL) goto Done;
1327 pnew = PyBytes_AsString(newfmt);
1328 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 while ((ch = *pin++) != '\0') {
1331 if (ch != '%') {
1332 ptoappend = pin - 1;
1333 ntoappend = 1;
1334 }
1335 else if ((ch = *pin++) == '\0') {
1336 /* There's a lone trailing %; doesn't make sense. */
1337 PyErr_SetString(PyExc_ValueError, "strftime format "
1338 "ends with raw %");
1339 goto Done;
1340 }
1341 /* A % has been seen and ch is the character after it. */
1342 else if (ch == 'z') {
1343 if (zreplacement == NULL) {
1344 /* format utcoffset */
1345 char buf[100];
1346 PyObject *tzinfo = get_tzinfo_member(object);
1347 zreplacement = PyBytes_FromStringAndSize("", 0);
1348 if (zreplacement == NULL) goto Done;
1349 if (tzinfo != Py_None && tzinfo != NULL) {
1350 assert(tzinfoarg != NULL);
1351 if (format_utcoffset(buf,
1352 sizeof(buf),
1353 "",
1354 tzinfo,
1355 tzinfoarg) < 0)
1356 goto Done;
1357 Py_DECREF(zreplacement);
1358 zreplacement =
1359 PyBytes_FromStringAndSize(buf,
1360 strlen(buf));
1361 if (zreplacement == NULL)
1362 goto Done;
1363 }
1364 }
1365 assert(zreplacement != NULL);
1366 ptoappend = PyBytes_AS_STRING(zreplacement);
1367 ntoappend = PyBytes_GET_SIZE(zreplacement);
1368 }
1369 else if (ch == 'Z') {
1370 /* format tzname */
1371 if (Zreplacement == NULL) {
1372 Zreplacement = make_Zreplacement(object,
1373 tzinfoarg);
1374 if (Zreplacement == NULL)
1375 goto Done;
1376 }
1377 assert(Zreplacement != NULL);
1378 assert(PyUnicode_Check(Zreplacement));
1379 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1380 &ntoappend);
1381 ntoappend = Py_SIZE(Zreplacement);
1382 }
1383 else if (ch == 'f') {
1384 /* format microseconds */
1385 if (freplacement == NULL) {
1386 freplacement = make_freplacement(object);
1387 if (freplacement == NULL)
1388 goto Done;
1389 }
1390 assert(freplacement != NULL);
1391 assert(PyBytes_Check(freplacement));
1392 ptoappend = PyBytes_AS_STRING(freplacement);
1393 ntoappend = PyBytes_GET_SIZE(freplacement);
1394 }
1395 else {
1396 /* percent followed by neither z nor Z */
1397 ptoappend = pin - 2;
1398 ntoappend = 2;
1399 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 /* Append the ntoappend chars starting at ptoappend to
1402 * the new format.
1403 */
1404 if (ntoappend == 0)
1405 continue;
1406 assert(ptoappend != NULL);
1407 assert(ntoappend > 0);
1408 while (usednew + ntoappend > totalnew) {
1409 size_t bigger = totalnew << 1;
1410 if ((bigger >> 1) != totalnew) { /* overflow */
1411 PyErr_NoMemory();
1412 goto Done;
1413 }
1414 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1415 goto Done;
1416 totalnew = bigger;
1417 pnew = PyBytes_AsString(newfmt) + usednew;
1418 }
1419 memcpy(pnew, ptoappend, ntoappend);
1420 pnew += ntoappend;
1421 usednew += ntoappend;
1422 assert(usednew <= totalnew);
1423 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1426 goto Done;
1427 {
1428 PyObject *format;
1429 PyObject *time = PyImport_ImportModuleNoBlock("time");
1430 if (time == NULL)
1431 goto Done;
1432 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1433 if (format != NULL) {
1434 result = PyObject_CallMethod(time, "strftime", "OO",
1435 format, timetuple);
1436 Py_DECREF(format);
1437 }
1438 Py_DECREF(time);
1439 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001440 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 Py_XDECREF(freplacement);
1442 Py_XDECREF(zreplacement);
1443 Py_XDECREF(Zreplacement);
1444 Py_XDECREF(newfmt);
1445 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001446}
1447
Tim Peters2a799bf2002-12-16 20:18:38 +00001448/* ---------------------------------------------------------------------------
1449 * Wrap functions from the time module. These aren't directly available
1450 * from C. Perhaps they should be.
1451 */
1452
1453/* Call time.time() and return its result (a Python float). */
1454static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001455time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 PyObject *result = NULL;
1458 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 if (time != NULL) {
1461 result = PyObject_CallMethod(time, "time", "()");
1462 Py_DECREF(time);
1463 }
1464 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001465}
1466
1467/* Build a time.struct_time. The weekday and day number are automatically
1468 * computed from the y,m,d args.
1469 */
1470static PyObject *
1471build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1472{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 PyObject *time;
1474 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 time = PyImport_ImportModuleNoBlock("time");
1477 if (time != NULL) {
1478 result = PyObject_CallMethod(time, "struct_time",
1479 "((iiiiiiiii))",
1480 y, m, d,
1481 hh, mm, ss,
1482 weekday(y, m, d),
1483 days_before_month(y, m) + d,
1484 dstflag);
1485 Py_DECREF(time);
1486 }
1487 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001488}
1489
1490/* ---------------------------------------------------------------------------
1491 * Miscellaneous helpers.
1492 */
1493
Mark Dickinsone94c6792009-02-02 20:36:42 +00001494/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001495 * The comparisons here all most naturally compute a cmp()-like result.
1496 * This little helper turns that into a bool result for rich comparisons.
1497 */
1498static PyObject *
1499diff_to_bool(int diff, int op)
1500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 PyObject *result;
1502 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 switch (op) {
1505 case Py_EQ: istrue = diff == 0; break;
1506 case Py_NE: istrue = diff != 0; break;
1507 case Py_LE: istrue = diff <= 0; break;
1508 case Py_GE: istrue = diff >= 0; break;
1509 case Py_LT: istrue = diff < 0; break;
1510 case Py_GT: istrue = diff > 0; break;
1511 default:
1512 assert(! "op unknown");
1513 istrue = 0; /* To shut up compiler */
1514 }
1515 result = istrue ? Py_True : Py_False;
1516 Py_INCREF(result);
1517 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001518}
1519
Tim Peters07534a62003-02-07 22:50:28 +00001520/* Raises a "can't compare" TypeError and returns NULL. */
1521static PyObject *
1522cmperror(PyObject *a, PyObject *b)
1523{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 PyErr_Format(PyExc_TypeError,
1525 "can't compare %s to %s",
1526 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1527 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001528}
1529
Tim Peters2a799bf2002-12-16 20:18:38 +00001530/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001531 * Cached Python objects; these are set by the module init function.
1532 */
1533
1534/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535static PyObject *us_per_us = NULL; /* 1 */
1536static PyObject *us_per_ms = NULL; /* 1000 */
1537static PyObject *us_per_second = NULL; /* 1000000 */
1538static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1539static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1540static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1541static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001542static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1543
Tim Peters2a799bf2002-12-16 20:18:38 +00001544/* ---------------------------------------------------------------------------
1545 * Class implementations.
1546 */
1547
1548/*
1549 * PyDateTime_Delta implementation.
1550 */
1551
1552/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001554 * as a Python int or long.
1555 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1556 * due to ubiquitous overflow possibilities.
1557 */
1558static PyObject *
1559delta_to_microseconds(PyDateTime_Delta *self)
1560{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 PyObject *x1 = NULL;
1562 PyObject *x2 = NULL;
1563 PyObject *x3 = NULL;
1564 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1567 if (x1 == NULL)
1568 goto Done;
1569 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1570 if (x2 == NULL)
1571 goto Done;
1572 Py_DECREF(x1);
1573 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 /* x2 has days in seconds */
1576 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1577 if (x1 == NULL)
1578 goto Done;
1579 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1580 if (x3 == NULL)
1581 goto Done;
1582 Py_DECREF(x1);
1583 Py_DECREF(x2);
1584 x1 = x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 /* x3 has days+seconds in seconds */
1587 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1588 if (x1 == NULL)
1589 goto Done;
1590 Py_DECREF(x3);
1591 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 /* x1 has days+seconds in us */
1594 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1595 if (x2 == NULL)
1596 goto Done;
1597 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001598
1599Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 Py_XDECREF(x1);
1601 Py_XDECREF(x2);
1602 Py_XDECREF(x3);
1603 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001604}
1605
1606/* Convert a number of us (as a Python int or long) to a timedelta.
1607 */
1608static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001609microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001610{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 int us;
1612 int s;
1613 int d;
1614 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 PyObject *tuple = NULL;
1617 PyObject *num = NULL;
1618 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 tuple = PyNumber_Divmod(pyus, us_per_second);
1621 if (tuple == NULL)
1622 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 num = PyTuple_GetItem(tuple, 1); /* us */
1625 if (num == NULL)
1626 goto Done;
1627 temp = PyLong_AsLong(num);
1628 num = NULL;
1629 if (temp == -1 && PyErr_Occurred())
1630 goto Done;
1631 assert(0 <= temp && temp < 1000000);
1632 us = (int)temp;
1633 if (us < 0) {
1634 /* The divisor was positive, so this must be an error. */
1635 assert(PyErr_Occurred());
1636 goto Done;
1637 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1640 if (num == NULL)
1641 goto Done;
1642 Py_INCREF(num);
1643 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 tuple = PyNumber_Divmod(num, seconds_per_day);
1646 if (tuple == NULL)
1647 goto Done;
1648 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 num = PyTuple_GetItem(tuple, 1); /* seconds */
1651 if (num == NULL)
1652 goto Done;
1653 temp = PyLong_AsLong(num);
1654 num = NULL;
1655 if (temp == -1 && PyErr_Occurred())
1656 goto Done;
1657 assert(0 <= temp && temp < 24*3600);
1658 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001660 if (s < 0) {
1661 /* The divisor was positive, so this must be an error. */
1662 assert(PyErr_Occurred());
1663 goto Done;
1664 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1667 if (num == NULL)
1668 goto Done;
1669 Py_INCREF(num);
1670 temp = PyLong_AsLong(num);
1671 if (temp == -1 && PyErr_Occurred())
1672 goto Done;
1673 d = (int)temp;
1674 if ((long)d != temp) {
1675 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1676 "large to fit in a C int");
1677 goto Done;
1678 }
1679 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001680
1681Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001682 Py_XDECREF(tuple);
1683 Py_XDECREF(num);
1684 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001685}
1686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687#define microseconds_to_delta(pymicros) \
1688 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001689
Tim Peters2a799bf2002-12-16 20:18:38 +00001690static PyObject *
1691multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1692{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693 PyObject *pyus_in;
1694 PyObject *pyus_out;
1695 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 pyus_in = delta_to_microseconds(delta);
1698 if (pyus_in == NULL)
1699 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1702 Py_DECREF(pyus_in);
1703 if (pyus_out == NULL)
1704 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 result = microseconds_to_delta(pyus_out);
1707 Py_DECREF(pyus_out);
1708 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001709}
1710
1711static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001712multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1713{
1714 PyObject *result = NULL;
1715 PyObject *pyus_in = NULL, *temp, *pyus_out;
1716 PyObject *ratio = NULL;
1717
1718 pyus_in = delta_to_microseconds(delta);
1719 if (pyus_in == NULL)
1720 return NULL;
1721 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1722 if (ratio == NULL)
1723 goto error;
1724 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1725 Py_DECREF(pyus_in);
1726 pyus_in = NULL;
1727 if (temp == NULL)
1728 goto error;
1729 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1730 Py_DECREF(temp);
1731 if (pyus_out == NULL)
1732 goto error;
1733 result = microseconds_to_delta(pyus_out);
1734 Py_DECREF(pyus_out);
1735 error:
1736 Py_XDECREF(pyus_in);
1737 Py_XDECREF(ratio);
1738
1739 return result;
1740}
1741
1742static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001743divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1744{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 PyObject *pyus_in;
1746 PyObject *pyus_out;
1747 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 pyus_in = delta_to_microseconds(delta);
1750 if (pyus_in == NULL)
1751 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001752
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1754 Py_DECREF(pyus_in);
1755 if (pyus_out == NULL)
1756 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 result = microseconds_to_delta(pyus_out);
1759 Py_DECREF(pyus_out);
1760 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001761}
1762
1763static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001764divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 PyObject *pyus_left;
1767 PyObject *pyus_right;
1768 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 pyus_left = delta_to_microseconds(left);
1771 if (pyus_left == NULL)
1772 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 pyus_right = delta_to_microseconds(right);
1775 if (pyus_right == NULL) {
1776 Py_DECREF(pyus_left);
1777 return NULL;
1778 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1781 Py_DECREF(pyus_left);
1782 Py_DECREF(pyus_right);
1783 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001784}
1785
1786static PyObject *
1787truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 PyObject *pyus_left;
1790 PyObject *pyus_right;
1791 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 pyus_left = delta_to_microseconds(left);
1794 if (pyus_left == NULL)
1795 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001796
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 pyus_right = delta_to_microseconds(right);
1798 if (pyus_right == NULL) {
1799 Py_DECREF(pyus_left);
1800 return NULL;
1801 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1804 Py_DECREF(pyus_left);
1805 Py_DECREF(pyus_right);
1806 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001807}
1808
1809static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001810truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1811{
1812 PyObject *result = NULL;
1813 PyObject *pyus_in = NULL, *temp, *pyus_out;
1814 PyObject *ratio = NULL;
1815
1816 pyus_in = delta_to_microseconds(delta);
1817 if (pyus_in == NULL)
1818 return NULL;
1819 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1820 if (ratio == NULL)
1821 goto error;
1822 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1823 Py_DECREF(pyus_in);
1824 pyus_in = NULL;
1825 if (temp == NULL)
1826 goto error;
1827 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1828 Py_DECREF(temp);
1829 if (pyus_out == NULL)
1830 goto error;
1831 result = microseconds_to_delta(pyus_out);
1832 Py_DECREF(pyus_out);
1833 error:
1834 Py_XDECREF(pyus_in);
1835 Py_XDECREF(ratio);
1836
1837 return result;
1838}
1839
1840static PyObject *
1841truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1842{
1843 PyObject *result;
1844 PyObject *pyus_in, *pyus_out;
1845 pyus_in = delta_to_microseconds(delta);
1846 if (pyus_in == NULL)
1847 return NULL;
1848 pyus_out = divide_nearest(pyus_in, i);
1849 Py_DECREF(pyus_in);
1850 if (pyus_out == NULL)
1851 return NULL;
1852 result = microseconds_to_delta(pyus_out);
1853 Py_DECREF(pyus_out);
1854
1855 return result;
1856}
1857
1858static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001859delta_add(PyObject *left, PyObject *right)
1860{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1864 /* delta + delta */
1865 /* The C-level additions can't overflow because of the
1866 * invariant bounds.
1867 */
1868 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1869 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1870 int microseconds = GET_TD_MICROSECONDS(left) +
1871 GET_TD_MICROSECONDS(right);
1872 result = new_delta(days, seconds, microseconds, 1);
1873 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 if (result == Py_NotImplemented)
1876 Py_INCREF(result);
1877 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001878}
1879
1880static PyObject *
1881delta_negative(PyDateTime_Delta *self)
1882{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 return new_delta(-GET_TD_DAYS(self),
1884 -GET_TD_SECONDS(self),
1885 -GET_TD_MICROSECONDS(self),
1886 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001887}
1888
1889static PyObject *
1890delta_positive(PyDateTime_Delta *self)
1891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 /* Could optimize this (by returning self) if this isn't a
1893 * subclass -- but who uses unary + ? Approximately nobody.
1894 */
1895 return new_delta(GET_TD_DAYS(self),
1896 GET_TD_SECONDS(self),
1897 GET_TD_MICROSECONDS(self),
1898 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001899}
1900
1901static PyObject *
1902delta_abs(PyDateTime_Delta *self)
1903{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 assert(GET_TD_MICROSECONDS(self) >= 0);
1907 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 if (GET_TD_DAYS(self) < 0)
1910 result = delta_negative(self);
1911 else
1912 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001915}
1916
1917static PyObject *
1918delta_subtract(PyObject *left, PyObject *right)
1919{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1923 /* delta - delta */
1924 PyObject *minus_right = PyNumber_Negative(right);
1925 if (minus_right) {
1926 result = delta_add(left, minus_right);
1927 Py_DECREF(minus_right);
1928 }
1929 else
1930 result = NULL;
1931 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 if (result == Py_NotImplemented)
1934 Py_INCREF(result);
1935 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001936}
1937
Tim Peters2a799bf2002-12-16 20:18:38 +00001938static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001939delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001940{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 if (PyDelta_Check(other)) {
1942 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1943 if (diff == 0) {
1944 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1945 if (diff == 0)
1946 diff = GET_TD_MICROSECONDS(self) -
1947 GET_TD_MICROSECONDS(other);
1948 }
1949 return diff_to_bool(diff, op);
1950 }
1951 else {
1952 Py_INCREF(Py_NotImplemented);
1953 return Py_NotImplemented;
1954 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001955}
1956
1957static PyObject *delta_getstate(PyDateTime_Delta *self);
1958
1959static long
1960delta_hash(PyDateTime_Delta *self)
1961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 if (self->hashcode == -1) {
1963 PyObject *temp = delta_getstate(self);
1964 if (temp != NULL) {
1965 self->hashcode = PyObject_Hash(temp);
1966 Py_DECREF(temp);
1967 }
1968 }
1969 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001970}
1971
1972static PyObject *
1973delta_multiply(PyObject *left, PyObject *right)
1974{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 if (PyDelta_Check(left)) {
1978 /* delta * ??? */
1979 if (PyLong_Check(right))
1980 result = multiply_int_timedelta(right,
1981 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001982 else if (PyFloat_Check(right))
1983 result = multiply_float_timedelta(right,
1984 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 }
1986 else if (PyLong_Check(left))
1987 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001988 (PyDateTime_Delta *) right);
1989 else if (PyFloat_Check(left))
1990 result = multiply_float_timedelta(left,
1991 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 if (result == Py_NotImplemented)
1994 Py_INCREF(result);
1995 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001996}
1997
1998static PyObject *
1999delta_divide(PyObject *left, PyObject *right)
2000{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002001 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 if (PyDelta_Check(left)) {
2004 /* delta * ??? */
2005 if (PyLong_Check(right))
2006 result = divide_timedelta_int(
2007 (PyDateTime_Delta *)left,
2008 right);
2009 else if (PyDelta_Check(right))
2010 result = divide_timedelta_timedelta(
2011 (PyDateTime_Delta *)left,
2012 (PyDateTime_Delta *)right);
2013 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 if (result == Py_NotImplemented)
2016 Py_INCREF(result);
2017 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002018}
2019
Mark Dickinson7c186e22010-04-20 22:32:49 +00002020static PyObject *
2021delta_truedivide(PyObject *left, PyObject *right)
2022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 if (PyDelta_Check(left)) {
2026 if (PyDelta_Check(right))
2027 result = truedivide_timedelta_timedelta(
2028 (PyDateTime_Delta *)left,
2029 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002030 else if (PyFloat_Check(right))
2031 result = truedivide_timedelta_float(
2032 (PyDateTime_Delta *)left, right);
2033 else if (PyLong_Check(right))
2034 result = truedivide_timedelta_int(
2035 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002038 if (result == Py_NotImplemented)
2039 Py_INCREF(result);
2040 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002041}
2042
2043static PyObject *
2044delta_remainder(PyObject *left, PyObject *right)
2045{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002046 PyObject *pyus_left;
2047 PyObject *pyus_right;
2048 PyObject *pyus_remainder;
2049 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
2052 Py_INCREF(Py_NotImplemented);
2053 return Py_NotImplemented;
2054 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2057 if (pyus_left == NULL)
2058 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002060 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2061 if (pyus_right == NULL) {
2062 Py_DECREF(pyus_left);
2063 return NULL;
2064 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2067 Py_DECREF(pyus_left);
2068 Py_DECREF(pyus_right);
2069 if (pyus_remainder == NULL)
2070 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002072 remainder = microseconds_to_delta(pyus_remainder);
2073 Py_DECREF(pyus_remainder);
2074 if (remainder == NULL)
2075 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002078}
2079
2080static PyObject *
2081delta_divmod(PyObject *left, PyObject *right)
2082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 PyObject *pyus_left;
2084 PyObject *pyus_right;
2085 PyObject *divmod;
2086 PyObject *delta;
2087 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
2090 Py_INCREF(Py_NotImplemented);
2091 return Py_NotImplemented;
2092 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2095 if (pyus_left == NULL)
2096 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2099 if (pyus_right == NULL) {
2100 Py_DECREF(pyus_left);
2101 return NULL;
2102 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2105 Py_DECREF(pyus_left);
2106 Py_DECREF(pyus_right);
2107 if (divmod == NULL)
2108 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 assert(PyTuple_Size(divmod) == 2);
2111 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2112 if (delta == NULL) {
2113 Py_DECREF(divmod);
2114 return NULL;
2115 }
2116 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2117 Py_DECREF(delta);
2118 Py_DECREF(divmod);
2119 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002120}
2121
Tim Peters2a799bf2002-12-16 20:18:38 +00002122/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2123 * timedelta constructor. sofar is the # of microseconds accounted for
2124 * so far, and there are factor microseconds per current unit, the number
2125 * of which is given by num. num * factor is added to sofar in a
2126 * numerically careful way, and that's the result. Any fractional
2127 * microseconds left over (this can happen if num is a float type) are
2128 * added into *leftover.
2129 * Note that there are many ways this can give an error (NULL) return.
2130 */
2131static PyObject *
2132accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2133 double *leftover)
2134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 PyObject *prod;
2136 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 if (PyLong_Check(num)) {
2141 prod = PyNumber_Multiply(num, factor);
2142 if (prod == NULL)
2143 return NULL;
2144 sum = PyNumber_Add(sofar, prod);
2145 Py_DECREF(prod);
2146 return sum;
2147 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 if (PyFloat_Check(num)) {
2150 double dnum;
2151 double fracpart;
2152 double intpart;
2153 PyObject *x;
2154 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 /* The Plan: decompose num into an integer part and a
2157 * fractional part, num = intpart + fracpart.
2158 * Then num * factor ==
2159 * intpart * factor + fracpart * factor
2160 * and the LHS can be computed exactly in long arithmetic.
2161 * The RHS is again broken into an int part and frac part.
2162 * and the frac part is added into *leftover.
2163 */
2164 dnum = PyFloat_AsDouble(num);
2165 if (dnum == -1.0 && PyErr_Occurred())
2166 return NULL;
2167 fracpart = modf(dnum, &intpart);
2168 x = PyLong_FromDouble(intpart);
2169 if (x == NULL)
2170 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 prod = PyNumber_Multiply(x, factor);
2173 Py_DECREF(x);
2174 if (prod == NULL)
2175 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 sum = PyNumber_Add(sofar, prod);
2178 Py_DECREF(prod);
2179 if (sum == NULL)
2180 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 if (fracpart == 0.0)
2183 return sum;
2184 /* So far we've lost no information. Dealing with the
2185 * fractional part requires float arithmetic, and may
2186 * lose a little info.
2187 */
2188 assert(PyLong_Check(factor));
2189 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 dnum *= fracpart;
2192 fracpart = modf(dnum, &intpart);
2193 x = PyLong_FromDouble(intpart);
2194 if (x == NULL) {
2195 Py_DECREF(sum);
2196 return NULL;
2197 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 y = PyNumber_Add(sum, x);
2200 Py_DECREF(sum);
2201 Py_DECREF(x);
2202 *leftover += fracpart;
2203 return y;
2204 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 PyErr_Format(PyExc_TypeError,
2207 "unsupported type for timedelta %s component: %s",
2208 tag, Py_TYPE(num)->tp_name);
2209 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002210}
2211
2212static PyObject *
2213delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002215 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 /* Argument objects. */
2218 PyObject *day = NULL;
2219 PyObject *second = NULL;
2220 PyObject *us = NULL;
2221 PyObject *ms = NULL;
2222 PyObject *minute = NULL;
2223 PyObject *hour = NULL;
2224 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 PyObject *x = NULL; /* running sum of microseconds */
2227 PyObject *y = NULL; /* temp sum of microseconds */
2228 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002230 static char *keywords[] = {
2231 "days", "seconds", "microseconds", "milliseconds",
2232 "minutes", "hours", "weeks", NULL
2233 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2236 keywords,
2237 &day, &second, &us,
2238 &ms, &minute, &hour, &week) == 0)
2239 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 x = PyLong_FromLong(0);
2242 if (x == NULL)
2243 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002245#define CLEANUP \
2246 Py_DECREF(x); \
2247 x = y; \
2248 if (x == NULL) \
2249 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 if (us) {
2252 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2253 CLEANUP;
2254 }
2255 if (ms) {
2256 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2257 CLEANUP;
2258 }
2259 if (second) {
2260 y = accum("seconds", x, second, us_per_second, &leftover_us);
2261 CLEANUP;
2262 }
2263 if (minute) {
2264 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2265 CLEANUP;
2266 }
2267 if (hour) {
2268 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2269 CLEANUP;
2270 }
2271 if (day) {
2272 y = accum("days", x, day, us_per_day, &leftover_us);
2273 CLEANUP;
2274 }
2275 if (week) {
2276 y = accum("weeks", x, week, us_per_week, &leftover_us);
2277 CLEANUP;
2278 }
2279 if (leftover_us) {
2280 /* Round to nearest whole # of us, and add into x. */
2281 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2282 if (temp == NULL) {
2283 Py_DECREF(x);
2284 goto Done;
2285 }
2286 y = PyNumber_Add(x, temp);
2287 Py_DECREF(temp);
2288 CLEANUP;
2289 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 self = microseconds_to_delta_ex(x, type);
2292 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002293Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002295
2296#undef CLEANUP
2297}
2298
2299static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002300delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 return (GET_TD_DAYS(self) != 0
2303 || GET_TD_SECONDS(self) != 0
2304 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002305}
2306
2307static PyObject *
2308delta_repr(PyDateTime_Delta *self)
2309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002310 if (GET_TD_MICROSECONDS(self) != 0)
2311 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2312 Py_TYPE(self)->tp_name,
2313 GET_TD_DAYS(self),
2314 GET_TD_SECONDS(self),
2315 GET_TD_MICROSECONDS(self));
2316 if (GET_TD_SECONDS(self) != 0)
2317 return PyUnicode_FromFormat("%s(%d, %d)",
2318 Py_TYPE(self)->tp_name,
2319 GET_TD_DAYS(self),
2320 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 return PyUnicode_FromFormat("%s(%d)",
2323 Py_TYPE(self)->tp_name,
2324 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002325}
2326
2327static PyObject *
2328delta_str(PyDateTime_Delta *self)
2329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002330 int us = GET_TD_MICROSECONDS(self);
2331 int seconds = GET_TD_SECONDS(self);
2332 int minutes = divmod(seconds, 60, &seconds);
2333 int hours = divmod(minutes, 60, &minutes);
2334 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336 if (days) {
2337 if (us)
2338 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2339 days, (days == 1 || days == -1) ? "" : "s",
2340 hours, minutes, seconds, us);
2341 else
2342 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2343 days, (days == 1 || days == -1) ? "" : "s",
2344 hours, minutes, seconds);
2345 } else {
2346 if (us)
2347 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2348 hours, minutes, seconds, us);
2349 else
2350 return PyUnicode_FromFormat("%d:%02d:%02d",
2351 hours, minutes, seconds);
2352 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002353
Tim Peters2a799bf2002-12-16 20:18:38 +00002354}
2355
Tim Peters371935f2003-02-01 01:52:50 +00002356/* Pickle support, a simple use of __reduce__. */
2357
Tim Petersb57f8f02003-02-01 02:54:15 +00002358/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002359static PyObject *
2360delta_getstate(PyDateTime_Delta *self)
2361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 return Py_BuildValue("iii", GET_TD_DAYS(self),
2363 GET_TD_SECONDS(self),
2364 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002365}
2366
Tim Peters2a799bf2002-12-16 20:18:38 +00002367static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002368delta_total_seconds(PyObject *self)
2369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002370 PyObject *total_seconds;
2371 PyObject *total_microseconds;
2372 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2375 if (total_microseconds == NULL)
2376 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002378 one_million = PyLong_FromLong(1000000L);
2379 if (one_million == NULL) {
2380 Py_DECREF(total_microseconds);
2381 return NULL;
2382 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 Py_DECREF(total_microseconds);
2387 Py_DECREF(one_million);
2388 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002389}
2390
2391static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002392delta_reduce(PyDateTime_Delta* self)
2393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002395}
2396
2397#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2398
2399static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002401 {"days", T_INT, OFFSET(days), READONLY,
2402 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 {"seconds", T_INT, OFFSET(seconds), READONLY,
2405 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002407 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2408 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2409 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002410};
2411
2412static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2414 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2417 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002420};
2421
2422static char delta_doc[] =
2423PyDoc_STR("Difference between two datetime values.");
2424
2425static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 delta_add, /* nb_add */
2427 delta_subtract, /* nb_subtract */
2428 delta_multiply, /* nb_multiply */
2429 delta_remainder, /* nb_remainder */
2430 delta_divmod, /* nb_divmod */
2431 0, /* nb_power */
2432 (unaryfunc)delta_negative, /* nb_negative */
2433 (unaryfunc)delta_positive, /* nb_positive */
2434 (unaryfunc)delta_abs, /* nb_absolute */
2435 (inquiry)delta_bool, /* nb_bool */
2436 0, /*nb_invert*/
2437 0, /*nb_lshift*/
2438 0, /*nb_rshift*/
2439 0, /*nb_and*/
2440 0, /*nb_xor*/
2441 0, /*nb_or*/
2442 0, /*nb_int*/
2443 0, /*nb_reserved*/
2444 0, /*nb_float*/
2445 0, /*nb_inplace_add*/
2446 0, /*nb_inplace_subtract*/
2447 0, /*nb_inplace_multiply*/
2448 0, /*nb_inplace_remainder*/
2449 0, /*nb_inplace_power*/
2450 0, /*nb_inplace_lshift*/
2451 0, /*nb_inplace_rshift*/
2452 0, /*nb_inplace_and*/
2453 0, /*nb_inplace_xor*/
2454 0, /*nb_inplace_or*/
2455 delta_divide, /* nb_floor_divide */
2456 delta_truedivide, /* nb_true_divide */
2457 0, /* nb_inplace_floor_divide */
2458 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002459};
2460
2461static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 PyVarObject_HEAD_INIT(NULL, 0)
2463 "datetime.timedelta", /* tp_name */
2464 sizeof(PyDateTime_Delta), /* tp_basicsize */
2465 0, /* tp_itemsize */
2466 0, /* tp_dealloc */
2467 0, /* tp_print */
2468 0, /* tp_getattr */
2469 0, /* tp_setattr */
2470 0, /* tp_reserved */
2471 (reprfunc)delta_repr, /* tp_repr */
2472 &delta_as_number, /* tp_as_number */
2473 0, /* tp_as_sequence */
2474 0, /* tp_as_mapping */
2475 (hashfunc)delta_hash, /* tp_hash */
2476 0, /* tp_call */
2477 (reprfunc)delta_str, /* tp_str */
2478 PyObject_GenericGetAttr, /* tp_getattro */
2479 0, /* tp_setattro */
2480 0, /* tp_as_buffer */
2481 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2482 delta_doc, /* tp_doc */
2483 0, /* tp_traverse */
2484 0, /* tp_clear */
2485 delta_richcompare, /* tp_richcompare */
2486 0, /* tp_weaklistoffset */
2487 0, /* tp_iter */
2488 0, /* tp_iternext */
2489 delta_methods, /* tp_methods */
2490 delta_members, /* tp_members */
2491 0, /* tp_getset */
2492 0, /* tp_base */
2493 0, /* tp_dict */
2494 0, /* tp_descr_get */
2495 0, /* tp_descr_set */
2496 0, /* tp_dictoffset */
2497 0, /* tp_init */
2498 0, /* tp_alloc */
2499 delta_new, /* tp_new */
2500 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002501};
2502
2503/*
2504 * PyDateTime_Date implementation.
2505 */
2506
2507/* Accessor properties. */
2508
2509static PyObject *
2510date_year(PyDateTime_Date *self, void *unused)
2511{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002513}
2514
2515static PyObject *
2516date_month(PyDateTime_Date *self, void *unused)
2517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002518 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002519}
2520
2521static PyObject *
2522date_day(PyDateTime_Date *self, void *unused)
2523{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002525}
2526
2527static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 {"year", (getter)date_year},
2529 {"month", (getter)date_month},
2530 {"day", (getter)date_day},
2531 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002532};
2533
2534/* Constructors. */
2535
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002536static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002537
Tim Peters2a799bf2002-12-16 20:18:38 +00002538static PyObject *
2539date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002541 PyObject *self = NULL;
2542 PyObject *state;
2543 int year;
2544 int month;
2545 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002547 /* Check for invocation from pickle with __getstate__ state */
2548 if (PyTuple_GET_SIZE(args) == 1 &&
2549 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2550 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2551 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2552 {
2553 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002555 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2556 if (me != NULL) {
2557 char *pdata = PyBytes_AS_STRING(state);
2558 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2559 me->hashcode = -1;
2560 }
2561 return (PyObject *)me;
2562 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2565 &year, &month, &day)) {
2566 if (check_date_args(year, month, day) < 0)
2567 return NULL;
2568 self = new_date_ex(year, month, day, type);
2569 }
2570 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002571}
2572
2573/* Return new date from localtime(t). */
2574static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002575date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002577 struct tm *tm;
2578 time_t t;
2579 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 t = _PyTime_DoubleToTimet(ts);
2582 if (t == (time_t)-1 && PyErr_Occurred())
2583 return NULL;
2584 tm = localtime(&t);
2585 if (tm)
2586 result = PyObject_CallFunction(cls, "iii",
2587 tm->tm_year + 1900,
2588 tm->tm_mon + 1,
2589 tm->tm_mday);
2590 else
2591 PyErr_SetString(PyExc_ValueError,
2592 "timestamp out of range for "
2593 "platform localtime() function");
2594 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002595}
2596
2597/* Return new date from current time.
2598 * We say this is equivalent to fromtimestamp(time.time()), and the
2599 * only way to be sure of that is to *call* time.time(). That's not
2600 * generally the same as calling C's time.
2601 */
2602static PyObject *
2603date_today(PyObject *cls, PyObject *dummy)
2604{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002605 PyObject *time;
2606 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002608 time = time_time();
2609 if (time == NULL)
2610 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002612 /* Note well: today() is a class method, so this may not call
2613 * date.fromtimestamp. For example, it may call
2614 * datetime.fromtimestamp. That's why we need all the accuracy
2615 * time.time() delivers; if someone were gonzo about optimization,
2616 * date.today() could get away with plain C time().
2617 */
2618 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2619 Py_DECREF(time);
2620 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002621}
2622
2623/* Return new date from given timestamp (Python timestamp -- a double). */
2624static PyObject *
2625date_fromtimestamp(PyObject *cls, PyObject *args)
2626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002627 double timestamp;
2628 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2631 result = date_local_from_time_t(cls, timestamp);
2632 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002633}
2634
2635/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2636 * the ordinal is out of range.
2637 */
2638static PyObject *
2639date_fromordinal(PyObject *cls, PyObject *args)
2640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 PyObject *result = NULL;
2642 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002644 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2645 int year;
2646 int month;
2647 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002649 if (ordinal < 1)
2650 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2651 ">= 1");
2652 else {
2653 ord_to_ymd(ordinal, &year, &month, &day);
2654 result = PyObject_CallFunction(cls, "iii",
2655 year, month, day);
2656 }
2657 }
2658 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002659}
2660
2661/*
2662 * Date arithmetic.
2663 */
2664
2665/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2666 * instead.
2667 */
2668static PyObject *
2669add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 PyObject *result = NULL;
2672 int year = GET_YEAR(date);
2673 int month = GET_MONTH(date);
2674 int deltadays = GET_TD_DAYS(delta);
2675 /* C-level overflow is impossible because |deltadays| < 1e9. */
2676 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002678 if (normalize_date(&year, &month, &day) >= 0)
2679 result = new_date(year, month, day);
2680 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002681}
2682
2683static PyObject *
2684date_add(PyObject *left, PyObject *right)
2685{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002686 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2687 Py_INCREF(Py_NotImplemented);
2688 return Py_NotImplemented;
2689 }
2690 if (PyDate_Check(left)) {
2691 /* date + ??? */
2692 if (PyDelta_Check(right))
2693 /* date + delta */
2694 return add_date_timedelta((PyDateTime_Date *) left,
2695 (PyDateTime_Delta *) right,
2696 0);
2697 }
2698 else {
2699 /* ??? + date
2700 * 'right' must be one of us, or we wouldn't have been called
2701 */
2702 if (PyDelta_Check(left))
2703 /* delta + date */
2704 return add_date_timedelta((PyDateTime_Date *) right,
2705 (PyDateTime_Delta *) left,
2706 0);
2707 }
2708 Py_INCREF(Py_NotImplemented);
2709 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002710}
2711
2712static PyObject *
2713date_subtract(PyObject *left, PyObject *right)
2714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002715 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2716 Py_INCREF(Py_NotImplemented);
2717 return Py_NotImplemented;
2718 }
2719 if (PyDate_Check(left)) {
2720 if (PyDate_Check(right)) {
2721 /* date - date */
2722 int left_ord = ymd_to_ord(GET_YEAR(left),
2723 GET_MONTH(left),
2724 GET_DAY(left));
2725 int right_ord = ymd_to_ord(GET_YEAR(right),
2726 GET_MONTH(right),
2727 GET_DAY(right));
2728 return new_delta(left_ord - right_ord, 0, 0, 0);
2729 }
2730 if (PyDelta_Check(right)) {
2731 /* date - delta */
2732 return add_date_timedelta((PyDateTime_Date *) left,
2733 (PyDateTime_Delta *) right,
2734 1);
2735 }
2736 }
2737 Py_INCREF(Py_NotImplemented);
2738 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002739}
2740
2741
2742/* Various ways to turn a date into a string. */
2743
2744static PyObject *
2745date_repr(PyDateTime_Date *self)
2746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002747 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2748 Py_TYPE(self)->tp_name,
2749 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002750}
2751
2752static PyObject *
2753date_isoformat(PyDateTime_Date *self)
2754{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002755 return PyUnicode_FromFormat("%04d-%02d-%02d",
2756 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002757}
2758
Tim Peterse2df5ff2003-05-02 18:39:55 +00002759/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002760static PyObject *
2761date_str(PyDateTime_Date *self)
2762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002763 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002764}
2765
2766
2767static PyObject *
2768date_ctime(PyDateTime_Date *self)
2769{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002770 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002771}
2772
2773static PyObject *
2774date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002776 /* This method can be inherited, and needs to call the
2777 * timetuple() method appropriate to self's class.
2778 */
2779 PyObject *result;
2780 PyObject *tuple;
2781 PyObject *format;
2782 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002784 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2785 &format))
2786 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002788 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2789 if (tuple == NULL)
2790 return NULL;
2791 result = wrap_strftime((PyObject *)self, format, tuple,
2792 (PyObject *)self);
2793 Py_DECREF(tuple);
2794 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002795}
2796
Eric Smith1ba31142007-09-11 18:06:02 +00002797static PyObject *
2798date_format(PyDateTime_Date *self, PyObject *args)
2799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002800 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002802 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2803 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 /* if the format is zero length, return str(self) */
2806 if (PyUnicode_GetSize(format) == 0)
2807 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002809 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002810}
2811
Tim Peters2a799bf2002-12-16 20:18:38 +00002812/* ISO methods. */
2813
2814static PyObject *
2815date_isoweekday(PyDateTime_Date *self)
2816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002817 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002819 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002820}
2821
2822static PyObject *
2823date_isocalendar(PyDateTime_Date *self)
2824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002825 int year = GET_YEAR(self);
2826 int week1_monday = iso_week1_monday(year);
2827 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2828 int week;
2829 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 week = divmod(today - week1_monday, 7, &day);
2832 if (week < 0) {
2833 --year;
2834 week1_monday = iso_week1_monday(year);
2835 week = divmod(today - week1_monday, 7, &day);
2836 }
2837 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2838 ++year;
2839 week = 0;
2840 }
2841 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002842}
2843
2844/* Miscellaneous methods. */
2845
Tim Peters2a799bf2002-12-16 20:18:38 +00002846static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002847date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 if (PyDate_Check(other)) {
2850 int diff = memcmp(((PyDateTime_Date *)self)->data,
2851 ((PyDateTime_Date *)other)->data,
2852 _PyDateTime_DATE_DATASIZE);
2853 return diff_to_bool(diff, op);
2854 }
2855 else {
2856 Py_INCREF(Py_NotImplemented);
2857 return Py_NotImplemented;
2858 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002859}
2860
2861static PyObject *
2862date_timetuple(PyDateTime_Date *self)
2863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 return build_struct_time(GET_YEAR(self),
2865 GET_MONTH(self),
2866 GET_DAY(self),
2867 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002868}
2869
Tim Peters12bf3392002-12-24 05:41:27 +00002870static PyObject *
2871date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002873 PyObject *clone;
2874 PyObject *tuple;
2875 int year = GET_YEAR(self);
2876 int month = GET_MONTH(self);
2877 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002879 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2880 &year, &month, &day))
2881 return NULL;
2882 tuple = Py_BuildValue("iii", year, month, day);
2883 if (tuple == NULL)
2884 return NULL;
2885 clone = date_new(Py_TYPE(self), tuple, NULL);
2886 Py_DECREF(tuple);
2887 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002888}
2889
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002890/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002891 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002892*/
2893static long
2894generic_hash(unsigned char *data, int len)
2895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002896 register unsigned char *p;
2897 register long x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002899 p = (unsigned char *) data;
2900 x = *p << 7;
2901 while (--len >= 0)
2902 x = (1000003*x) ^ *p++;
2903 x ^= len;
2904 if (x == -1)
2905 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002907 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002908}
2909
2910
2911static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002912
2913static long
2914date_hash(PyDateTime_Date *self)
2915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002916 if (self->hashcode == -1)
2917 self->hashcode = generic_hash(
2918 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002920 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002921}
2922
2923static PyObject *
2924date_toordinal(PyDateTime_Date *self)
2925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002926 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2927 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002928}
2929
2930static PyObject *
2931date_weekday(PyDateTime_Date *self)
2932{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002933 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002935 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002936}
2937
Tim Peters371935f2003-02-01 01:52:50 +00002938/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002939
Tim Petersb57f8f02003-02-01 02:54:15 +00002940/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002941static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002942date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002943{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002944 PyObject* field;
2945 field = PyBytes_FromStringAndSize((char*)self->data,
2946 _PyDateTime_DATE_DATASIZE);
2947 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002948}
2949
2950static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002951date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002953 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002954}
2955
2956static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002958 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002960 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2961 METH_CLASS,
2962 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2963 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002965 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2966 METH_CLASS,
2967 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2968 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002970 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2971 PyDoc_STR("Current date or datetime: same as "
2972 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002974 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002976 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2977 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002979 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2980 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002982 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2983 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002985 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2986 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002988 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2989 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2990 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002992 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2993 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002995 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2996 PyDoc_STR("Return the day of the week represented by the date.\n"
2997 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002999 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3000 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3001 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003003 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3004 PyDoc_STR("Return the day of the week represented by the date.\n"
3005 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003007 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3008 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003010 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3011 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003013 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003014};
3015
3016static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003017PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003018
3019static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003020 date_add, /* nb_add */
3021 date_subtract, /* nb_subtract */
3022 0, /* nb_multiply */
3023 0, /* nb_remainder */
3024 0, /* nb_divmod */
3025 0, /* nb_power */
3026 0, /* nb_negative */
3027 0, /* nb_positive */
3028 0, /* nb_absolute */
3029 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003030};
3031
3032static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003033 PyVarObject_HEAD_INIT(NULL, 0)
3034 "datetime.date", /* tp_name */
3035 sizeof(PyDateTime_Date), /* tp_basicsize */
3036 0, /* tp_itemsize */
3037 0, /* tp_dealloc */
3038 0, /* tp_print */
3039 0, /* tp_getattr */
3040 0, /* tp_setattr */
3041 0, /* tp_reserved */
3042 (reprfunc)date_repr, /* tp_repr */
3043 &date_as_number, /* tp_as_number */
3044 0, /* tp_as_sequence */
3045 0, /* tp_as_mapping */
3046 (hashfunc)date_hash, /* tp_hash */
3047 0, /* tp_call */
3048 (reprfunc)date_str, /* tp_str */
3049 PyObject_GenericGetAttr, /* tp_getattro */
3050 0, /* tp_setattro */
3051 0, /* tp_as_buffer */
3052 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3053 date_doc, /* tp_doc */
3054 0, /* tp_traverse */
3055 0, /* tp_clear */
3056 date_richcompare, /* tp_richcompare */
3057 0, /* tp_weaklistoffset */
3058 0, /* tp_iter */
3059 0, /* tp_iternext */
3060 date_methods, /* tp_methods */
3061 0, /* tp_members */
3062 date_getset, /* tp_getset */
3063 0, /* tp_base */
3064 0, /* tp_dict */
3065 0, /* tp_descr_get */
3066 0, /* tp_descr_set */
3067 0, /* tp_dictoffset */
3068 0, /* tp_init */
3069 0, /* tp_alloc */
3070 date_new, /* tp_new */
3071 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003072};
3073
3074/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003075 * PyDateTime_TZInfo implementation.
3076 */
3077
3078/* This is a pure abstract base class, so doesn't do anything beyond
3079 * raising NotImplemented exceptions. Real tzinfo classes need
3080 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003081 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003082 * be subclasses of this tzinfo class, which is easy and quick to check).
3083 *
3084 * Note: For reasons having to do with pickling of subclasses, we have
3085 * to allow tzinfo objects to be instantiated. This wasn't an issue
3086 * in the Python implementation (__init__() could raise NotImplementedError
3087 * there without ill effect), but doing so in the C implementation hit a
3088 * brick wall.
3089 */
3090
3091static PyObject *
3092tzinfo_nogo(const char* methodname)
3093{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003094 PyErr_Format(PyExc_NotImplementedError,
3095 "a tzinfo subclass must implement %s()",
3096 methodname);
3097 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003098}
3099
3100/* Methods. A subclass must implement these. */
3101
Tim Peters52dcce22003-01-23 16:36:11 +00003102static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003103tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3104{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003105 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003106}
3107
Tim Peters52dcce22003-01-23 16:36:11 +00003108static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003109tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3110{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003111 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003112}
3113
Tim Peters52dcce22003-01-23 16:36:11 +00003114static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003115tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003117 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003118}
3119
Tim Peters52dcce22003-01-23 16:36:11 +00003120static PyObject *
3121tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
3122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003123 int y, m, d, hh, mm, ss, us;
Tim Peters52dcce22003-01-23 16:36:11 +00003124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 PyObject *result;
3126 int off, dst;
3127 int none;
3128 int delta;
Tim Peters52dcce22003-01-23 16:36:11 +00003129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003130 if (! PyDateTime_Check(dt)) {
3131 PyErr_SetString(PyExc_TypeError,
3132 "fromutc: argument must be a datetime");
3133 return NULL;
3134 }
3135 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3136 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3137 "is not self");
3138 return NULL;
3139 }
Tim Peters52dcce22003-01-23 16:36:11 +00003140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003141 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
3142 if (off == -1 && PyErr_Occurred())
3143 return NULL;
3144 if (none) {
3145 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3146 "utcoffset() result required");
3147 return NULL;
3148 }
Tim Peters52dcce22003-01-23 16:36:11 +00003149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003150 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
3151 if (dst == -1 && PyErr_Occurred())
3152 return NULL;
3153 if (none) {
3154 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3155 "dst() result required");
3156 return NULL;
3157 }
Tim Peters52dcce22003-01-23 16:36:11 +00003158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003159 y = GET_YEAR(dt);
3160 m = GET_MONTH(dt);
3161 d = GET_DAY(dt);
3162 hh = DATE_GET_HOUR(dt);
3163 mm = DATE_GET_MINUTE(dt);
3164 ss = DATE_GET_SECOND(dt);
3165 us = DATE_GET_MICROSECOND(dt);
Tim Peters52dcce22003-01-23 16:36:11 +00003166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003167 delta = off - dst;
3168 mm += delta;
3169 if ((mm < 0 || mm >= 60) &&
3170 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
3171 return NULL;
3172 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
3173 if (result == NULL)
3174 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003176 dst = call_dst(dt->tzinfo, result, &none);
3177 if (dst == -1 && PyErr_Occurred())
3178 goto Fail;
3179 if (none)
3180 goto Inconsistent;
3181 if (dst == 0)
3182 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003184 mm += dst;
3185 if ((mm < 0 || mm >= 60) &&
3186 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
3187 goto Fail;
3188 Py_DECREF(result);
3189 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
3190 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003191
3192Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003193 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3194 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003196 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003197Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 Py_DECREF(result);
3199 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003200}
3201
Tim Peters2a799bf2002-12-16 20:18:38 +00003202/*
3203 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003204 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003205 */
3206
Guido van Rossum177e41a2003-01-30 22:06:23 +00003207static PyObject *
3208tzinfo_reduce(PyObject *self)
3209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003210 PyObject *args, *state, *tmp;
3211 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003213 tmp = PyTuple_New(0);
3214 if (tmp == NULL)
3215 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003217 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3218 if (getinitargs != NULL) {
3219 args = PyObject_CallObject(getinitargs, tmp);
3220 Py_DECREF(getinitargs);
3221 if (args == NULL) {
3222 Py_DECREF(tmp);
3223 return NULL;
3224 }
3225 }
3226 else {
3227 PyErr_Clear();
3228 args = tmp;
3229 Py_INCREF(args);
3230 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003232 getstate = PyObject_GetAttrString(self, "__getstate__");
3233 if (getstate != NULL) {
3234 state = PyObject_CallObject(getstate, tmp);
3235 Py_DECREF(getstate);
3236 if (state == NULL) {
3237 Py_DECREF(args);
3238 Py_DECREF(tmp);
3239 return NULL;
3240 }
3241 }
3242 else {
3243 PyObject **dictptr;
3244 PyErr_Clear();
3245 state = Py_None;
3246 dictptr = _PyObject_GetDictPtr(self);
3247 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3248 state = *dictptr;
3249 Py_INCREF(state);
3250 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003252 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003254 if (state == Py_None) {
3255 Py_DECREF(state);
3256 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3257 }
3258 else
3259 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003260}
Tim Peters2a799bf2002-12-16 20:18:38 +00003261
3262static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003264 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3265 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003267 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003268 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3269 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003271 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3272 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003274 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003275 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003277 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3278 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003280 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003281};
3282
3283static char tzinfo_doc[] =
3284PyDoc_STR("Abstract base class for time zone info objects.");
3285
Neal Norwitz227b5332006-03-22 09:28:35 +00003286static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003287 PyVarObject_HEAD_INIT(NULL, 0)
3288 "datetime.tzinfo", /* tp_name */
3289 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3290 0, /* tp_itemsize */
3291 0, /* tp_dealloc */
3292 0, /* tp_print */
3293 0, /* tp_getattr */
3294 0, /* tp_setattr */
3295 0, /* tp_reserved */
3296 0, /* tp_repr */
3297 0, /* tp_as_number */
3298 0, /* tp_as_sequence */
3299 0, /* tp_as_mapping */
3300 0, /* tp_hash */
3301 0, /* tp_call */
3302 0, /* tp_str */
3303 PyObject_GenericGetAttr, /* tp_getattro */
3304 0, /* tp_setattro */
3305 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003306 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003307 tzinfo_doc, /* tp_doc */
3308 0, /* tp_traverse */
3309 0, /* tp_clear */
3310 0, /* tp_richcompare */
3311 0, /* tp_weaklistoffset */
3312 0, /* tp_iter */
3313 0, /* tp_iternext */
3314 tzinfo_methods, /* tp_methods */
3315 0, /* tp_members */
3316 0, /* tp_getset */
3317 0, /* tp_base */
3318 0, /* tp_dict */
3319 0, /* tp_descr_get */
3320 0, /* tp_descr_set */
3321 0, /* tp_dictoffset */
3322 0, /* tp_init */
3323 0, /* tp_alloc */
3324 PyType_GenericNew, /* tp_new */
3325 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003326};
3327
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003328static char *timezone_kws[] = {"offset", "name", NULL};
3329
3330static PyObject *
3331timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3332{
3333 PyObject *offset;
3334 PyObject *name = NULL;
3335 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3336 &PyDateTime_DeltaType, &offset,
3337 &PyUnicode_Type, &name))
3338 return new_timezone(offset, name);
3339
3340 return NULL;
3341}
3342
3343static void
3344timezone_dealloc(PyDateTime_TimeZone *self)
3345{
3346 Py_CLEAR(self->offset);
3347 Py_CLEAR(self->name);
3348 Py_TYPE(self)->tp_free((PyObject *)self);
3349}
3350
3351static PyObject *
3352timezone_richcompare(PyDateTime_TimeZone *self,
3353 PyDateTime_TimeZone *other, int op)
3354{
3355 if (op != Py_EQ && op != Py_NE) {
3356 Py_INCREF(Py_NotImplemented);
3357 return Py_NotImplemented;
3358 }
3359 return delta_richcompare(self->offset, other->offset, op);
3360}
3361
3362static long
3363timezone_hash(PyDateTime_TimeZone *self)
3364{
3365 return delta_hash((PyDateTime_Delta *)self->offset);
3366}
3367
3368/* Check argument type passed to tzname, utcoffset, or dst methods.
3369 Returns 0 for good argument. Returns -1 and sets exception info
3370 otherwise.
3371 */
3372static int
3373_timezone_check_argument(PyObject *dt, const char *meth)
3374{
3375 if (dt == Py_None || PyDateTime_Check(dt))
3376 return 0;
3377 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3378 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3379 return -1;
3380}
3381
3382static PyObject *
3383timezone_str(PyDateTime_TimeZone *self)
3384{
3385 char buf[10];
3386 int hours, minutes, seconds;
3387 PyObject *offset;
3388 char sign;
3389
3390 if (self->name != NULL) {
3391 Py_INCREF(self->name);
3392 return self->name;
3393 }
3394 /* Offset is normalized, so it is negative if days < 0 */
3395 if (GET_TD_DAYS(self->offset) < 0) {
3396 sign = '-';
3397 offset = delta_negative((PyDateTime_Delta *)self->offset);
3398 if (offset == NULL)
3399 return NULL;
3400 }
3401 else {
3402 sign = '+';
3403 offset = self->offset;
3404 Py_INCREF(offset);
3405 }
3406 /* Offset is not negative here. */
3407 seconds = GET_TD_SECONDS(offset);
3408 Py_DECREF(offset);
3409 minutes = divmod(seconds, 60, &seconds);
3410 hours = divmod(minutes, 60, &minutes);
3411 assert(seconds == 0);
3412 /* XXX ignore sub-minute data, curently not allowed. */
3413 PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes);
3414
3415 return PyUnicode_FromString(buf);
3416}
3417
3418static PyObject *
3419timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3420{
3421 if (_timezone_check_argument(dt, "tzname") == -1)
3422 return NULL;
3423
3424 return timezone_str(self);
3425}
3426
3427static PyObject *
3428timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3429{
3430 if (_timezone_check_argument(dt, "utcoffset") == -1)
3431 return NULL;
3432
3433 Py_INCREF(self->offset);
3434 return self->offset;
3435}
3436
3437static PyObject *
3438timezone_dst(PyObject *self, PyObject *dt)
3439{
3440 if (_timezone_check_argument(dt, "dst") == -1)
3441 return NULL;
3442
3443 Py_RETURN_NONE;
3444}
3445
3446static PyObject *
3447add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3448 int factor);
3449
3450static PyObject *
3451timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3452{
3453 if (! PyDateTime_Check(dt)) {
3454 PyErr_SetString(PyExc_TypeError,
3455 "fromutc: argument must be a datetime");
3456 return NULL;
3457 }
3458 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3459 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3460 "is not self");
3461 return NULL;
3462 }
3463
3464 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3465}
3466
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003467static PyObject *
3468timezone_getinitargs(PyDateTime_TimeZone *self)
3469{
3470 if (self->name == NULL)
3471 return Py_BuildValue("(O)", self->offset);
3472 return Py_BuildValue("(OO)", self->offset, self->name);
3473}
3474
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003475static PyMethodDef timezone_methods[] = {
3476 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3477 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003478 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003479
3480 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003481 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003482
3483 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003484 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003485
3486 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3487 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3488
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003489 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3490 PyDoc_STR("pickle support")},
3491
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003492 {NULL, NULL}
3493};
3494
3495static char timezone_doc[] =
3496PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3497
3498static PyTypeObject PyDateTime_TimeZoneType = {
3499 PyVarObject_HEAD_INIT(NULL, 0)
3500 "datetime.timezone", /* tp_name */
3501 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3502 0, /* tp_itemsize */
3503 (destructor)timezone_dealloc, /* tp_dealloc */
3504 0, /* tp_print */
3505 0, /* tp_getattr */
3506 0, /* tp_setattr */
3507 0, /* tp_reserved */
3508 0, /* tp_repr */
3509 0, /* tp_as_number */
3510 0, /* tp_as_sequence */
3511 0, /* tp_as_mapping */
3512 (hashfunc)timezone_hash, /* tp_hash */
3513 0, /* tp_call */
3514 (reprfunc)timezone_str, /* tp_str */
3515 0, /* tp_getattro */
3516 0, /* tp_setattro */
3517 0, /* tp_as_buffer */
3518 Py_TPFLAGS_DEFAULT, /* tp_flags */
3519 timezone_doc, /* tp_doc */
3520 0, /* tp_traverse */
3521 0, /* tp_clear */
3522 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3523 0, /* tp_weaklistoffset */
3524 0, /* tp_iter */
3525 0, /* tp_iternext */
3526 timezone_methods, /* tp_methods */
3527 0, /* tp_members */
3528 0, /* tp_getset */
3529 &PyDateTime_TZInfoType, /* tp_base */
3530 0, /* tp_dict */
3531 0, /* tp_descr_get */
3532 0, /* tp_descr_set */
3533 0, /* tp_dictoffset */
3534 0, /* tp_init */
3535 0, /* tp_alloc */
3536 timezone_new, /* tp_new */
3537};
3538
Tim Peters2a799bf2002-12-16 20:18:38 +00003539/*
Tim Peters37f39822003-01-10 03:49:02 +00003540 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003541 */
3542
Tim Peters37f39822003-01-10 03:49:02 +00003543/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003544 */
3545
3546static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003547time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003549 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003550}
3551
Tim Peters37f39822003-01-10 03:49:02 +00003552static PyObject *
3553time_minute(PyDateTime_Time *self, void *unused)
3554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003556}
3557
3558/* The name time_second conflicted with some platform header file. */
3559static PyObject *
3560py_time_second(PyDateTime_Time *self, void *unused)
3561{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003562 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003563}
3564
3565static PyObject *
3566time_microsecond(PyDateTime_Time *self, void *unused)
3567{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003569}
3570
3571static PyObject *
3572time_tzinfo(PyDateTime_Time *self, void *unused)
3573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003574 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3575 Py_INCREF(result);
3576 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003577}
3578
3579static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003580 {"hour", (getter)time_hour},
3581 {"minute", (getter)time_minute},
3582 {"second", (getter)py_time_second},
3583 {"microsecond", (getter)time_microsecond},
3584 {"tzinfo", (getter)time_tzinfo},
3585 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003586};
3587
3588/*
3589 * Constructors.
3590 */
3591
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003592static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003593 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003594
Tim Peters2a799bf2002-12-16 20:18:38 +00003595static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003596time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003598 PyObject *self = NULL;
3599 PyObject *state;
3600 int hour = 0;
3601 int minute = 0;
3602 int second = 0;
3603 int usecond = 0;
3604 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003606 /* Check for invocation from pickle with __getstate__ state */
3607 if (PyTuple_GET_SIZE(args) >= 1 &&
3608 PyTuple_GET_SIZE(args) <= 2 &&
3609 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3610 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3611 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3612 {
3613 PyDateTime_Time *me;
3614 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003616 if (PyTuple_GET_SIZE(args) == 2) {
3617 tzinfo = PyTuple_GET_ITEM(args, 1);
3618 if (check_tzinfo_subclass(tzinfo) < 0) {
3619 PyErr_SetString(PyExc_TypeError, "bad "
3620 "tzinfo state arg");
3621 return NULL;
3622 }
3623 }
3624 aware = (char)(tzinfo != Py_None);
3625 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3626 if (me != NULL) {
3627 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003629 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3630 me->hashcode = -1;
3631 me->hastzinfo = aware;
3632 if (aware) {
3633 Py_INCREF(tzinfo);
3634 me->tzinfo = tzinfo;
3635 }
3636 }
3637 return (PyObject *)me;
3638 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003640 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3641 &hour, &minute, &second, &usecond,
3642 &tzinfo)) {
3643 if (check_time_args(hour, minute, second, usecond) < 0)
3644 return NULL;
3645 if (check_tzinfo_subclass(tzinfo) < 0)
3646 return NULL;
3647 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3648 type);
3649 }
3650 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003651}
3652
3653/*
3654 * Destructor.
3655 */
3656
3657static void
Tim Peters37f39822003-01-10 03:49:02 +00003658time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003660 if (HASTZINFO(self)) {
3661 Py_XDECREF(self->tzinfo);
3662 }
3663 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003664}
3665
3666/*
Tim Peters855fe882002-12-22 03:43:39 +00003667 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003668 */
3669
Tim Peters2a799bf2002-12-16 20:18:38 +00003670/* These are all METH_NOARGS, so don't need to check the arglist. */
3671static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003672time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003673 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3674 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003675}
3676
3677static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003678time_dst(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003679 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3680 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003681}
3682
3683static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003684time_tzname(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003685 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3686 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003687}
3688
3689/*
Tim Peters37f39822003-01-10 03:49:02 +00003690 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003691 */
3692
3693static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003694time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003695{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003696 const char *type_name = Py_TYPE(self)->tp_name;
3697 int h = TIME_GET_HOUR(self);
3698 int m = TIME_GET_MINUTE(self);
3699 int s = TIME_GET_SECOND(self);
3700 int us = TIME_GET_MICROSECOND(self);
3701 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003703 if (us)
3704 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3705 type_name, h, m, s, us);
3706 else if (s)
3707 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3708 type_name, h, m, s);
3709 else
3710 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3711 if (result != NULL && HASTZINFO(self))
3712 result = append_keyword_tzinfo(result, self->tzinfo);
3713 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003714}
3715
Tim Peters37f39822003-01-10 03:49:02 +00003716static PyObject *
3717time_str(PyDateTime_Time *self)
3718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003719 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003720}
Tim Peters2a799bf2002-12-16 20:18:38 +00003721
3722static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003723time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003725 char buf[100];
3726 PyObject *result;
3727 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003729 if (us)
3730 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3731 TIME_GET_HOUR(self),
3732 TIME_GET_MINUTE(self),
3733 TIME_GET_SECOND(self),
3734 us);
3735 else
3736 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3737 TIME_GET_HOUR(self),
3738 TIME_GET_MINUTE(self),
3739 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003741 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3742 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003743
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003744 /* We need to append the UTC offset. */
3745 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3746 Py_None) < 0) {
3747 Py_DECREF(result);
3748 return NULL;
3749 }
3750 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3751 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003752}
3753
Tim Peters37f39822003-01-10 03:49:02 +00003754static PyObject *
3755time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003757 PyObject *result;
3758 PyObject *tuple;
3759 PyObject *format;
3760 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003762 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3763 &format))
3764 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003766 /* Python's strftime does insane things with the year part of the
3767 * timetuple. The year is forced to (the otherwise nonsensical)
3768 * 1900 to worm around that.
3769 */
3770 tuple = Py_BuildValue("iiiiiiiii",
3771 1900, 1, 1, /* year, month, day */
3772 TIME_GET_HOUR(self),
3773 TIME_GET_MINUTE(self),
3774 TIME_GET_SECOND(self),
3775 0, 1, -1); /* weekday, daynum, dst */
3776 if (tuple == NULL)
3777 return NULL;
3778 assert(PyTuple_Size(tuple) == 9);
3779 result = wrap_strftime((PyObject *)self, format, tuple,
3780 Py_None);
3781 Py_DECREF(tuple);
3782 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003783}
Tim Peters2a799bf2002-12-16 20:18:38 +00003784
3785/*
3786 * Miscellaneous methods.
3787 */
3788
Tim Peters37f39822003-01-10 03:49:02 +00003789static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003790time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003791{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003792 int diff;
3793 naivety n1, n2;
3794 int offset1, offset2;
Tim Peters37f39822003-01-10 03:49:02 +00003795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003796 if (! PyTime_Check(other)) {
3797 Py_INCREF(Py_NotImplemented);
3798 return Py_NotImplemented;
3799 }
3800 if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
3801 other, &offset2, &n2, Py_None) < 0)
3802 return NULL;
3803 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3804 /* If they're both naive, or both aware and have the same offsets,
3805 * we get off cheap. Note that if they're both naive, offset1 ==
3806 * offset2 == 0 at this point.
3807 */
3808 if (n1 == n2 && offset1 == offset2) {
3809 diff = memcmp(((PyDateTime_Time *)self)->data,
3810 ((PyDateTime_Time *)other)->data,
3811 _PyDateTime_TIME_DATASIZE);
3812 return diff_to_bool(diff, op);
3813 }
Tim Peters37f39822003-01-10 03:49:02 +00003814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003815 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3816 assert(offset1 != offset2); /* else last "if" handled it */
3817 /* Convert everything except microseconds to seconds. These
3818 * can't overflow (no more than the # of seconds in 2 days).
3819 */
3820 offset1 = TIME_GET_HOUR(self) * 3600 +
3821 (TIME_GET_MINUTE(self) - offset1) * 60 +
3822 TIME_GET_SECOND(self);
3823 offset2 = TIME_GET_HOUR(other) * 3600 +
3824 (TIME_GET_MINUTE(other) - offset2) * 60 +
3825 TIME_GET_SECOND(other);
3826 diff = offset1 - offset2;
3827 if (diff == 0)
3828 diff = TIME_GET_MICROSECOND(self) -
3829 TIME_GET_MICROSECOND(other);
3830 return diff_to_bool(diff, op);
3831 }
Tim Peters37f39822003-01-10 03:49:02 +00003832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003833 assert(n1 != n2);
3834 PyErr_SetString(PyExc_TypeError,
3835 "can't compare offset-naive and "
3836 "offset-aware times");
3837 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003838}
3839
3840static long
3841time_hash(PyDateTime_Time *self)
3842{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003843 if (self->hashcode == -1) {
3844 naivety n;
3845 int offset;
3846 PyObject *temp;
Tim Peters37f39822003-01-10 03:49:02 +00003847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003848 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3849 assert(n != OFFSET_UNKNOWN);
3850 if (n == OFFSET_ERROR)
3851 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003853 /* Reduce this to a hash of another object. */
3854 if (offset == 0) {
3855 self->hashcode = generic_hash(
3856 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3857 return self->hashcode;
3858 }
3859 else {
3860 int hour;
3861 int minute;
Tim Peters37f39822003-01-10 03:49:02 +00003862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003863 assert(n == OFFSET_AWARE);
3864 assert(HASTZINFO(self));
3865 hour = divmod(TIME_GET_HOUR(self) * 60 +
3866 TIME_GET_MINUTE(self) - offset,
3867 60,
3868 &minute);
3869 if (0 <= hour && hour < 24)
3870 temp = new_time(hour, minute,
3871 TIME_GET_SECOND(self),
3872 TIME_GET_MICROSECOND(self),
3873 Py_None);
3874 else
3875 temp = Py_BuildValue("iiii",
3876 hour, minute,
3877 TIME_GET_SECOND(self),
3878 TIME_GET_MICROSECOND(self));
3879 }
3880 if (temp != NULL) {
3881 self->hashcode = PyObject_Hash(temp);
3882 Py_DECREF(temp);
3883 }
3884 }
3885 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003886}
Tim Peters2a799bf2002-12-16 20:18:38 +00003887
Tim Peters12bf3392002-12-24 05:41:27 +00003888static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003889time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003890{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003891 PyObject *clone;
3892 PyObject *tuple;
3893 int hh = TIME_GET_HOUR(self);
3894 int mm = TIME_GET_MINUTE(self);
3895 int ss = TIME_GET_SECOND(self);
3896 int us = TIME_GET_MICROSECOND(self);
3897 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003899 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3900 time_kws,
3901 &hh, &mm, &ss, &us, &tzinfo))
3902 return NULL;
3903 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3904 if (tuple == NULL)
3905 return NULL;
3906 clone = time_new(Py_TYPE(self), tuple, NULL);
3907 Py_DECREF(tuple);
3908 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003909}
3910
Tim Peters2a799bf2002-12-16 20:18:38 +00003911static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00003912time_bool(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003913{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003914 int offset;
3915 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00003916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003917 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3918 /* Since utcoffset is in whole minutes, nothing can
3919 * alter the conclusion that this is nonzero.
3920 */
3921 return 1;
3922 }
3923 offset = 0;
3924 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3925 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3926 if (offset == -1 && PyErr_Occurred())
3927 return -1;
3928 }
3929 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003930}
3931
Tim Peters371935f2003-02-01 01:52:50 +00003932/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003933
Tim Peters33e0f382003-01-10 02:05:14 +00003934/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003935 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3936 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003937 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003938 */
3939static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003940time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003941{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003942 PyObject *basestate;
3943 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003945 basestate = PyBytes_FromStringAndSize((char *)self->data,
3946 _PyDateTime_TIME_DATASIZE);
3947 if (basestate != NULL) {
3948 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3949 result = PyTuple_Pack(1, basestate);
3950 else
3951 result = PyTuple_Pack(2, basestate, self->tzinfo);
3952 Py_DECREF(basestate);
3953 }
3954 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003955}
3956
3957static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003958time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003959{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003960 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003961}
3962
Tim Peters37f39822003-01-10 03:49:02 +00003963static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003965 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3966 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3967 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003969 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3970 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003972 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3973 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003975 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3976 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3979 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003981 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3982 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003984 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3985 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003987 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3988 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003990 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003991};
3992
Tim Peters37f39822003-01-10 03:49:02 +00003993static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003994PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3995\n\
3996All arguments are optional. tzinfo may be None, or an instance of\n\
3997a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003998
Tim Peters37f39822003-01-10 03:49:02 +00003999static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004000 0, /* nb_add */
4001 0, /* nb_subtract */
4002 0, /* nb_multiply */
4003 0, /* nb_remainder */
4004 0, /* nb_divmod */
4005 0, /* nb_power */
4006 0, /* nb_negative */
4007 0, /* nb_positive */
4008 0, /* nb_absolute */
4009 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004010};
4011
Neal Norwitz227b5332006-03-22 09:28:35 +00004012static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004013 PyVarObject_HEAD_INIT(NULL, 0)
4014 "datetime.time", /* tp_name */
4015 sizeof(PyDateTime_Time), /* tp_basicsize */
4016 0, /* tp_itemsize */
4017 (destructor)time_dealloc, /* tp_dealloc */
4018 0, /* tp_print */
4019 0, /* tp_getattr */
4020 0, /* tp_setattr */
4021 0, /* tp_reserved */
4022 (reprfunc)time_repr, /* tp_repr */
4023 &time_as_number, /* tp_as_number */
4024 0, /* tp_as_sequence */
4025 0, /* tp_as_mapping */
4026 (hashfunc)time_hash, /* tp_hash */
4027 0, /* tp_call */
4028 (reprfunc)time_str, /* tp_str */
4029 PyObject_GenericGetAttr, /* tp_getattro */
4030 0, /* tp_setattro */
4031 0, /* tp_as_buffer */
4032 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4033 time_doc, /* tp_doc */
4034 0, /* tp_traverse */
4035 0, /* tp_clear */
4036 time_richcompare, /* tp_richcompare */
4037 0, /* tp_weaklistoffset */
4038 0, /* tp_iter */
4039 0, /* tp_iternext */
4040 time_methods, /* tp_methods */
4041 0, /* tp_members */
4042 time_getset, /* tp_getset */
4043 0, /* tp_base */
4044 0, /* tp_dict */
4045 0, /* tp_descr_get */
4046 0, /* tp_descr_set */
4047 0, /* tp_dictoffset */
4048 0, /* tp_init */
4049 time_alloc, /* tp_alloc */
4050 time_new, /* tp_new */
4051 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004052};
4053
4054/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004055 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004056 */
4057
Tim Petersa9bc1682003-01-11 03:39:11 +00004058/* Accessor properties. Properties for day, month, and year are inherited
4059 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004060 */
4061
4062static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004063datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004065 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004066}
4067
Tim Petersa9bc1682003-01-11 03:39:11 +00004068static PyObject *
4069datetime_minute(PyDateTime_DateTime *self, void *unused)
4070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004071 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004072}
4073
4074static PyObject *
4075datetime_second(PyDateTime_DateTime *self, void *unused)
4076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004077 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004078}
4079
4080static PyObject *
4081datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004083 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004084}
4085
4086static PyObject *
4087datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4088{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004089 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4090 Py_INCREF(result);
4091 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004092}
4093
4094static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004095 {"hour", (getter)datetime_hour},
4096 {"minute", (getter)datetime_minute},
4097 {"second", (getter)datetime_second},
4098 {"microsecond", (getter)datetime_microsecond},
4099 {"tzinfo", (getter)datetime_tzinfo},
4100 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004101};
4102
4103/*
4104 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004105 */
4106
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004107static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004108 "year", "month", "day", "hour", "minute", "second",
4109 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004110};
4111
Tim Peters2a799bf2002-12-16 20:18:38 +00004112static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004113datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004115 PyObject *self = NULL;
4116 PyObject *state;
4117 int year;
4118 int month;
4119 int day;
4120 int hour = 0;
4121 int minute = 0;
4122 int second = 0;
4123 int usecond = 0;
4124 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004126 /* Check for invocation from pickle with __getstate__ state */
4127 if (PyTuple_GET_SIZE(args) >= 1 &&
4128 PyTuple_GET_SIZE(args) <= 2 &&
4129 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4130 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4131 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4132 {
4133 PyDateTime_DateTime *me;
4134 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004136 if (PyTuple_GET_SIZE(args) == 2) {
4137 tzinfo = PyTuple_GET_ITEM(args, 1);
4138 if (check_tzinfo_subclass(tzinfo) < 0) {
4139 PyErr_SetString(PyExc_TypeError, "bad "
4140 "tzinfo state arg");
4141 return NULL;
4142 }
4143 }
4144 aware = (char)(tzinfo != Py_None);
4145 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4146 if (me != NULL) {
4147 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004149 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4150 me->hashcode = -1;
4151 me->hastzinfo = aware;
4152 if (aware) {
4153 Py_INCREF(tzinfo);
4154 me->tzinfo = tzinfo;
4155 }
4156 }
4157 return (PyObject *)me;
4158 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004160 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4161 &year, &month, &day, &hour, &minute,
4162 &second, &usecond, &tzinfo)) {
4163 if (check_date_args(year, month, day) < 0)
4164 return NULL;
4165 if (check_time_args(hour, minute, second, usecond) < 0)
4166 return NULL;
4167 if (check_tzinfo_subclass(tzinfo) < 0)
4168 return NULL;
4169 self = new_datetime_ex(year, month, day,
4170 hour, minute, second, usecond,
4171 tzinfo, type);
4172 }
4173 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004174}
4175
Tim Petersa9bc1682003-01-11 03:39:11 +00004176/* TM_FUNC is the shared type of localtime() and gmtime(). */
4177typedef struct tm *(*TM_FUNC)(const time_t *timer);
4178
4179/* Internal helper.
4180 * Build datetime from a time_t and a distinct count of microseconds.
4181 * Pass localtime or gmtime for f, to control the interpretation of timet.
4182 */
4183static PyObject *
4184datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004185 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004187 struct tm *tm;
4188 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004190 tm = f(&timet);
4191 if (tm) {
4192 /* The platform localtime/gmtime may insert leap seconds,
4193 * indicated by tm->tm_sec > 59. We don't care about them,
4194 * except to the extent that passing them on to the datetime
4195 * constructor would raise ValueError for a reason that
4196 * made no sense to the user.
4197 */
4198 if (tm->tm_sec > 59)
4199 tm->tm_sec = 59;
4200 result = PyObject_CallFunction(cls, "iiiiiiiO",
4201 tm->tm_year + 1900,
4202 tm->tm_mon + 1,
4203 tm->tm_mday,
4204 tm->tm_hour,
4205 tm->tm_min,
4206 tm->tm_sec,
4207 us,
4208 tzinfo);
4209 }
4210 else
4211 PyErr_SetString(PyExc_ValueError,
4212 "timestamp out of range for "
4213 "platform localtime()/gmtime() function");
4214 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004215}
4216
4217/* Internal helper.
4218 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4219 * to control the interpretation of the timestamp. Since a double doesn't
4220 * have enough bits to cover a datetime's full range of precision, it's
4221 * better to call datetime_from_timet_and_us provided you have a way
4222 * to get that much precision (e.g., C time() isn't good enough).
4223 */
4224static PyObject *
4225datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004227{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004228 time_t timet;
4229 double fraction;
4230 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 timet = _PyTime_DoubleToTimet(timestamp);
4233 if (timet == (time_t)-1 && PyErr_Occurred())
4234 return NULL;
4235 fraction = timestamp - (double)timet;
4236 us = (int)round_to_long(fraction * 1e6);
4237 if (us < 0) {
4238 /* Truncation towards zero is not what we wanted
4239 for negative numbers (Python's mod semantics) */
4240 timet -= 1;
4241 us += 1000000;
4242 }
4243 /* If timestamp is less than one microsecond smaller than a
4244 * full second, round up. Otherwise, ValueErrors are raised
4245 * for some floats. */
4246 if (us == 1000000) {
4247 timet += 1;
4248 us = 0;
4249 }
4250 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004251}
4252
4253/* Internal helper.
4254 * Build most accurate possible datetime for current time. Pass localtime or
4255 * gmtime for f as appropriate.
4256 */
4257static PyObject *
4258datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4259{
4260#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004261 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00004262
4263#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004264 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00004265#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004266 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00004267#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004268 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4269 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004271#else /* ! HAVE_GETTIMEOFDAY */
4272 /* No flavor of gettimeofday exists on this platform. Python's
4273 * time.time() does a lot of other platform tricks to get the
4274 * best time it can on the platform, and we're not going to do
4275 * better than that (if we could, the better code would belong
4276 * in time.time()!) We're limited by the precision of a double,
4277 * though.
4278 */
4279 PyObject *time;
4280 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00004281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004282 time = time_time();
4283 if (time == NULL)
4284 return NULL;
4285 dtime = PyFloat_AsDouble(time);
4286 Py_DECREF(time);
4287 if (dtime == -1.0 && PyErr_Occurred())
4288 return NULL;
4289 return datetime_from_timestamp(cls, f, dtime, tzinfo);
4290#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00004291}
4292
Tim Peters2a799bf2002-12-16 20:18:38 +00004293/* Return best possible local time -- this isn't constrained by the
4294 * precision of a timestamp.
4295 */
4296static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004297datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004298{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004299 PyObject *self;
4300 PyObject *tzinfo = Py_None;
4301 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4304 &tzinfo))
4305 return NULL;
4306 if (check_tzinfo_subclass(tzinfo) < 0)
4307 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004309 self = datetime_best_possible(cls,
4310 tzinfo == Py_None ? localtime : gmtime,
4311 tzinfo);
4312 if (self != NULL && tzinfo != Py_None) {
4313 /* Convert UTC to tzinfo's zone. */
4314 PyObject *temp = self;
4315 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4316 Py_DECREF(temp);
4317 }
4318 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004319}
4320
Tim Petersa9bc1682003-01-11 03:39:11 +00004321/* Return best possible UTC time -- this isn't constrained by the
4322 * precision of a timestamp.
4323 */
4324static PyObject *
4325datetime_utcnow(PyObject *cls, PyObject *dummy)
4326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004327 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004328}
4329
Tim Peters2a799bf2002-12-16 20:18:38 +00004330/* Return new local datetime from timestamp (Python timestamp -- a double). */
4331static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004332datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004334 PyObject *self;
4335 double timestamp;
4336 PyObject *tzinfo = Py_None;
4337 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004339 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4340 keywords, &timestamp, &tzinfo))
4341 return NULL;
4342 if (check_tzinfo_subclass(tzinfo) < 0)
4343 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004345 self = datetime_from_timestamp(cls,
4346 tzinfo == Py_None ? localtime : gmtime,
4347 timestamp,
4348 tzinfo);
4349 if (self != NULL && tzinfo != Py_None) {
4350 /* Convert UTC to tzinfo's zone. */
4351 PyObject *temp = self;
4352 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4353 Py_DECREF(temp);
4354 }
4355 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004356}
4357
Tim Petersa9bc1682003-01-11 03:39:11 +00004358/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4359static PyObject *
4360datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004362 double timestamp;
4363 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004365 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4366 result = datetime_from_timestamp(cls, gmtime, timestamp,
4367 Py_None);
4368 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004369}
4370
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004371/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004372static PyObject *
4373datetime_strptime(PyObject *cls, PyObject *args)
4374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004375 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004376 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004378 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4379 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004380
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004381 if (module == NULL) {
4382 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004383 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004384 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004385 }
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004386 return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4387 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004388}
4389
Tim Petersa9bc1682003-01-11 03:39:11 +00004390/* Return new datetime from date/datetime and time arguments. */
4391static PyObject *
4392datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004394 static char *keywords[] = {"date", "time", NULL};
4395 PyObject *date;
4396 PyObject *time;
4397 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004399 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4400 &PyDateTime_DateType, &date,
4401 &PyDateTime_TimeType, &time)) {
4402 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004404 if (HASTZINFO(time))
4405 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4406 result = PyObject_CallFunction(cls, "iiiiiiiO",
4407 GET_YEAR(date),
4408 GET_MONTH(date),
4409 GET_DAY(date),
4410 TIME_GET_HOUR(time),
4411 TIME_GET_MINUTE(time),
4412 TIME_GET_SECOND(time),
4413 TIME_GET_MICROSECOND(time),
4414 tzinfo);
4415 }
4416 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004417}
Tim Peters2a799bf2002-12-16 20:18:38 +00004418
4419/*
4420 * Destructor.
4421 */
4422
4423static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004424datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004426 if (HASTZINFO(self)) {
4427 Py_XDECREF(self->tzinfo);
4428 }
4429 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004430}
4431
4432/*
4433 * Indirect access to tzinfo methods.
4434 */
4435
Tim Peters2a799bf2002-12-16 20:18:38 +00004436/* These are all METH_NOARGS, so don't need to check the arglist. */
4437static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004438datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004439 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4440 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004441}
4442
4443static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004444datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004445 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4446 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004447}
4448
4449static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004450datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004451 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4452 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004453}
4454
4455/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004456 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004457 */
4458
Tim Petersa9bc1682003-01-11 03:39:11 +00004459/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4460 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004461 */
4462static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004463add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004464 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004466 /* Note that the C-level additions can't overflow, because of
4467 * invariant bounds on the member values.
4468 */
4469 int year = GET_YEAR(date);
4470 int month = GET_MONTH(date);
4471 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4472 int hour = DATE_GET_HOUR(date);
4473 int minute = DATE_GET_MINUTE(date);
4474 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4475 int microsecond = DATE_GET_MICROSECOND(date) +
4476 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004478 assert(factor == 1 || factor == -1);
4479 if (normalize_datetime(&year, &month, &day,
4480 &hour, &minute, &second, &microsecond) < 0)
4481 return NULL;
4482 else
4483 return new_datetime(year, month, day,
4484 hour, minute, second, microsecond,
4485 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004486}
4487
4488static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004489datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004491 if (PyDateTime_Check(left)) {
4492 /* datetime + ??? */
4493 if (PyDelta_Check(right))
4494 /* datetime + delta */
4495 return add_datetime_timedelta(
4496 (PyDateTime_DateTime *)left,
4497 (PyDateTime_Delta *)right,
4498 1);
4499 }
4500 else if (PyDelta_Check(left)) {
4501 /* delta + datetime */
4502 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4503 (PyDateTime_Delta *) left,
4504 1);
4505 }
4506 Py_INCREF(Py_NotImplemented);
4507 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004508}
4509
4510static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004511datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004513 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004515 if (PyDateTime_Check(left)) {
4516 /* datetime - ??? */
4517 if (PyDateTime_Check(right)) {
4518 /* datetime - datetime */
4519 naivety n1, n2;
4520 int offset1, offset2;
4521 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004523 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4524 right, &offset2, &n2,
4525 right) < 0)
4526 return NULL;
4527 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4528 if (n1 != n2) {
4529 PyErr_SetString(PyExc_TypeError,
4530 "can't subtract offset-naive and "
4531 "offset-aware datetimes");
4532 return NULL;
4533 }
4534 delta_d = ymd_to_ord(GET_YEAR(left),
4535 GET_MONTH(left),
4536 GET_DAY(left)) -
4537 ymd_to_ord(GET_YEAR(right),
4538 GET_MONTH(right),
4539 GET_DAY(right));
4540 /* These can't overflow, since the values are
4541 * normalized. At most this gives the number of
4542 * seconds in one day.
4543 */
4544 delta_s = (DATE_GET_HOUR(left) -
4545 DATE_GET_HOUR(right)) * 3600 +
4546 (DATE_GET_MINUTE(left) -
4547 DATE_GET_MINUTE(right)) * 60 +
4548 (DATE_GET_SECOND(left) -
4549 DATE_GET_SECOND(right));
4550 delta_us = DATE_GET_MICROSECOND(left) -
4551 DATE_GET_MICROSECOND(right);
4552 /* (left - offset1) - (right - offset2) =
4553 * (left - right) + (offset2 - offset1)
4554 */
4555 delta_s += (offset2 - offset1) * 60;
4556 result = new_delta(delta_d, delta_s, delta_us, 1);
4557 }
4558 else if (PyDelta_Check(right)) {
4559 /* datetime - delta */
4560 result = add_datetime_timedelta(
4561 (PyDateTime_DateTime *)left,
4562 (PyDateTime_Delta *)right,
4563 -1);
4564 }
4565 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004567 if (result == Py_NotImplemented)
4568 Py_INCREF(result);
4569 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004570}
4571
4572/* Various ways to turn a datetime into a string. */
4573
4574static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004575datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004577 const char *type_name = Py_TYPE(self)->tp_name;
4578 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004580 if (DATE_GET_MICROSECOND(self)) {
4581 baserepr = PyUnicode_FromFormat(
4582 "%s(%d, %d, %d, %d, %d, %d, %d)",
4583 type_name,
4584 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4585 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4586 DATE_GET_SECOND(self),
4587 DATE_GET_MICROSECOND(self));
4588 }
4589 else if (DATE_GET_SECOND(self)) {
4590 baserepr = PyUnicode_FromFormat(
4591 "%s(%d, %d, %d, %d, %d, %d)",
4592 type_name,
4593 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4594 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4595 DATE_GET_SECOND(self));
4596 }
4597 else {
4598 baserepr = PyUnicode_FromFormat(
4599 "%s(%d, %d, %d, %d, %d)",
4600 type_name,
4601 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4602 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4603 }
4604 if (baserepr == NULL || ! HASTZINFO(self))
4605 return baserepr;
4606 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004607}
4608
Tim Petersa9bc1682003-01-11 03:39:11 +00004609static PyObject *
4610datetime_str(PyDateTime_DateTime *self)
4611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004612 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004613}
Tim Peters2a799bf2002-12-16 20:18:38 +00004614
4615static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004616datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004617{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004618 int sep = 'T';
4619 static char *keywords[] = {"sep", NULL};
4620 char buffer[100];
4621 PyObject *result;
4622 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004624 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4625 return NULL;
4626 if (us)
4627 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
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), us);
4632 else
4633 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4634 GET_YEAR(self), GET_MONTH(self),
4635 GET_DAY(self), (int)sep,
4636 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4637 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 if (!result || !HASTZINFO(self))
4640 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004642 /* We need to append the UTC offset. */
4643 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4644 (PyObject *)self) < 0) {
4645 Py_DECREF(result);
4646 return NULL;
4647 }
4648 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4649 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004650}
4651
Tim Petersa9bc1682003-01-11 03:39:11 +00004652static PyObject *
4653datetime_ctime(PyDateTime_DateTime *self)
4654{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004655 return format_ctime((PyDateTime_Date *)self,
4656 DATE_GET_HOUR(self),
4657 DATE_GET_MINUTE(self),
4658 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004659}
4660
Tim Peters2a799bf2002-12-16 20:18:38 +00004661/* Miscellaneous methods. */
4662
Tim Petersa9bc1682003-01-11 03:39:11 +00004663static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004664datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004665{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004666 int diff;
4667 naivety n1, n2;
4668 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004670 if (! PyDateTime_Check(other)) {
4671 if (PyDate_Check(other)) {
4672 /* Prevent invocation of date_richcompare. We want to
4673 return NotImplemented here to give the other object
4674 a chance. But since DateTime is a subclass of
4675 Date, if the other object is a Date, it would
4676 compute an ordering based on the date part alone,
4677 and we don't want that. So force unequal or
4678 uncomparable here in that case. */
4679 if (op == Py_EQ)
4680 Py_RETURN_FALSE;
4681 if (op == Py_NE)
4682 Py_RETURN_TRUE;
4683 return cmperror(self, other);
4684 }
4685 Py_INCREF(Py_NotImplemented);
4686 return Py_NotImplemented;
4687 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004689 if (classify_two_utcoffsets(self, &offset1, &n1, self,
4690 other, &offset2, &n2, other) < 0)
4691 return NULL;
4692 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4693 /* If they're both naive, or both aware and have the same offsets,
4694 * we get off cheap. Note that if they're both naive, offset1 ==
4695 * offset2 == 0 at this point.
4696 */
4697 if (n1 == n2 && offset1 == offset2) {
4698 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4699 ((PyDateTime_DateTime *)other)->data,
4700 _PyDateTime_DATETIME_DATASIZE);
4701 return diff_to_bool(diff, op);
4702 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004704 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4705 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004707 assert(offset1 != offset2); /* else last "if" handled it */
4708 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4709 other);
4710 if (delta == NULL)
4711 return NULL;
4712 diff = GET_TD_DAYS(delta);
4713 if (diff == 0)
4714 diff = GET_TD_SECONDS(delta) |
4715 GET_TD_MICROSECONDS(delta);
4716 Py_DECREF(delta);
4717 return diff_to_bool(diff, op);
4718 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004720 assert(n1 != n2);
4721 PyErr_SetString(PyExc_TypeError,
4722 "can't compare offset-naive and "
4723 "offset-aware datetimes");
4724 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004725}
4726
4727static long
4728datetime_hash(PyDateTime_DateTime *self)
4729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004730 if (self->hashcode == -1) {
4731 naivety n;
4732 int offset;
4733 PyObject *temp;
Tim Petersa9bc1682003-01-11 03:39:11 +00004734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004735 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4736 &offset);
4737 assert(n != OFFSET_UNKNOWN);
4738 if (n == OFFSET_ERROR)
4739 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004741 /* Reduce this to a hash of another object. */
4742 if (n == OFFSET_NAIVE) {
4743 self->hashcode = generic_hash(
4744 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
4745 return self->hashcode;
4746 }
4747 else {
4748 int days;
4749 int seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004751 assert(n == OFFSET_AWARE);
4752 assert(HASTZINFO(self));
4753 days = ymd_to_ord(GET_YEAR(self),
4754 GET_MONTH(self),
4755 GET_DAY(self));
4756 seconds = DATE_GET_HOUR(self) * 3600 +
4757 (DATE_GET_MINUTE(self) - offset) * 60 +
4758 DATE_GET_SECOND(self);
4759 temp = new_delta(days,
4760 seconds,
4761 DATE_GET_MICROSECOND(self),
4762 1);
4763 }
4764 if (temp != NULL) {
4765 self->hashcode = PyObject_Hash(temp);
4766 Py_DECREF(temp);
4767 }
4768 }
4769 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004770}
Tim Peters2a799bf2002-12-16 20:18:38 +00004771
4772static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004773datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004775 PyObject *clone;
4776 PyObject *tuple;
4777 int y = GET_YEAR(self);
4778 int m = GET_MONTH(self);
4779 int d = GET_DAY(self);
4780 int hh = DATE_GET_HOUR(self);
4781 int mm = DATE_GET_MINUTE(self);
4782 int ss = DATE_GET_SECOND(self);
4783 int us = DATE_GET_MICROSECOND(self);
4784 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004786 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4787 datetime_kws,
4788 &y, &m, &d, &hh, &mm, &ss, &us,
4789 &tzinfo))
4790 return NULL;
4791 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4792 if (tuple == NULL)
4793 return NULL;
4794 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4795 Py_DECREF(tuple);
4796 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004797}
4798
4799static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004800datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004802 int y, m, d, hh, mm, ss, us;
4803 PyObject *result;
4804 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004806 PyObject *tzinfo;
4807 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004809 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4810 &PyDateTime_TZInfoType, &tzinfo))
4811 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004813 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4814 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004816 /* Conversion to self's own time zone is a NOP. */
4817 if (self->tzinfo == tzinfo) {
4818 Py_INCREF(self);
4819 return (PyObject *)self;
4820 }
Tim Peters521fc152002-12-31 17:36:56 +00004821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004822 /* Convert self to UTC. */
4823 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4824 if (offset == -1 && PyErr_Occurred())
4825 return NULL;
4826 if (none)
4827 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004829 y = GET_YEAR(self);
4830 m = GET_MONTH(self);
4831 d = GET_DAY(self);
4832 hh = DATE_GET_HOUR(self);
4833 mm = DATE_GET_MINUTE(self);
4834 ss = DATE_GET_SECOND(self);
4835 us = DATE_GET_MICROSECOND(self);
Tim Peters52dcce22003-01-23 16:36:11 +00004836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004837 mm -= offset;
4838 if ((mm < 0 || mm >= 60) &&
4839 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4840 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004842 /* Attach new tzinfo and let fromutc() do the rest. */
4843 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4844 if (result != NULL) {
4845 PyObject *temp = result;
Tim Peters52dcce22003-01-23 16:36:11 +00004846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004847 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4848 Py_DECREF(temp);
4849 }
4850 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004851
Tim Peters52dcce22003-01-23 16:36:11 +00004852NeedAware:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004853 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4854 "a naive datetime");
4855 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004856}
4857
4858static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004859datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004860{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004861 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004863 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4864 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004866 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4867 if (dstflag == -1 && PyErr_Occurred())
4868 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004870 if (none)
4871 dstflag = -1;
4872 else if (dstflag != 0)
4873 dstflag = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004875 }
4876 return build_struct_time(GET_YEAR(self),
4877 GET_MONTH(self),
4878 GET_DAY(self),
4879 DATE_GET_HOUR(self),
4880 DATE_GET_MINUTE(self),
4881 DATE_GET_SECOND(self),
4882 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004883}
4884
4885static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004886datetime_getdate(PyDateTime_DateTime *self)
4887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004888 return new_date(GET_YEAR(self),
4889 GET_MONTH(self),
4890 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004891}
4892
4893static PyObject *
4894datetime_gettime(PyDateTime_DateTime *self)
4895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004896 return new_time(DATE_GET_HOUR(self),
4897 DATE_GET_MINUTE(self),
4898 DATE_GET_SECOND(self),
4899 DATE_GET_MICROSECOND(self),
4900 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004901}
4902
4903static PyObject *
4904datetime_gettimetz(PyDateTime_DateTime *self)
4905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004906 return new_time(DATE_GET_HOUR(self),
4907 DATE_GET_MINUTE(self),
4908 DATE_GET_SECOND(self),
4909 DATE_GET_MICROSECOND(self),
4910 HASTZINFO(self) ? self->tzinfo : Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004911}
4912
4913static PyObject *
4914datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004916 int y = GET_YEAR(self);
4917 int m = GET_MONTH(self);
4918 int d = GET_DAY(self);
4919 int hh = DATE_GET_HOUR(self);
4920 int mm = DATE_GET_MINUTE(self);
4921 int ss = DATE_GET_SECOND(self);
4922 int us = 0; /* microseconds are ignored in a timetuple */
4923 int offset = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004925 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4926 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004928 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4929 if (offset == -1 && PyErr_Occurred())
4930 return NULL;
4931 }
4932 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4933 * 0 in a UTC timetuple regardless of what dst() says.
4934 */
4935 if (offset) {
4936 /* Subtract offset minutes & normalize. */
4937 int stat;
Tim Peters2a799bf2002-12-16 20:18:38 +00004938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004939 mm -= offset;
4940 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004941 /* OverflowError may be raised in the edge cases. */
4942 if (stat < 0)
4943 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004944 }
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--------------------------------------------------------------------------- */