blob: c12a7a679238c7923ecc009b61bfb387f46328f4 [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
Gregory P. Smith137d8242008-06-02 04:05:52 +00005#define PY_SSIZE_T_CLEAN
6
Tim Peters2a799bf2002-12-16 20:18:38 +00007#include "Python.h"
8#include "modsupport.h"
9#include "structmember.h"
10
11#include <time.h>
12
Tim Peters1b6f7a92004-06-20 02:50:16 +000013#include "timefuncs.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000014
15/* Differentiate between building the core module and building extension
16 * modules.
17 */
Kristján Valur Jónsson7a0da192007-04-30 15:17:46 +000018#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000019#define Py_BUILD_CORE
Kristján Valur Jónsson7a0da192007-04-30 15:17:46 +000020#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000021#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000022#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000023
24/* We require that C int be at least 32 bits, and use int virtually
25 * everywhere. In just a few cases we use a temp long, where a Python
26 * API returns a C long. In such cases, we have to ensure that the
27 * final result fits in a C int (this can be an issue on 64-bit boxes).
28 */
29#if SIZEOF_INT < 4
Antoine Pitrouc83ea132010-05-09 14:46:46 +000030# error "datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000031#endif
32
33#define MINYEAR 1
34#define MAXYEAR 9999
Alexander Belopolsky9292ee02010-05-27 20:55:27 +000035#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000036
37/* Nine decimal digits is easy to communicate, and leaves enough room
38 * so that two delta days can be added w/o fear of overflowing a signed
39 * 32-bit int, and with plenty of room left over to absorb any possible
40 * carries from adding seconds.
41 */
42#define MAX_DELTA_DAYS 999999999
43
44/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000045#define GET_YEAR PyDateTime_GET_YEAR
46#define GET_MONTH PyDateTime_GET_MONTH
47#define GET_DAY PyDateTime_GET_DAY
48#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
49#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
50#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
51#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000052
53/* Date accessors for date and datetime. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000054#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
55 ((o)->data[1] = ((v) & 0x00ff)))
56#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
57#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000058
59/* Date/Time accessors for datetime. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000060#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
61#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
62#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
63#define DATE_SET_MICROSECOND(o, v) \
64 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
65 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
66 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000067
68/* Time accessors for time. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000069#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
70#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
71#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
72#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
73#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
74#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
75#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
76#define TIME_SET_MICROSECOND(o, v) \
77 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
78 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
79 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000080
81/* Delta accessors for timedelta. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000082#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
83#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
84#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000085
Antoine Pitrouc83ea132010-05-09 14:46:46 +000086#define SET_TD_DAYS(o, v) ((o)->days = (v))
87#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000088#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
89
Tim Petersa032d2e2003-01-11 00:15:54 +000090/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
91 * p->hastzinfo.
92 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000093#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
Tim Petersa032d2e2003-01-11 00:15:54 +000094
Tim Peters3f606292004-03-21 23:38:41 +000095/* M is a char or int claiming to be a valid month. The macro is equivalent
96 * to the two-sided Python test
Antoine Pitrouc83ea132010-05-09 14:46:46 +000097 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +000098 */
99#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
100
Tim Peters2a799bf2002-12-16 20:18:38 +0000101/* Forward declarations. */
102static PyTypeObject PyDateTime_DateType;
103static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000104static PyTypeObject PyDateTime_DeltaType;
105static PyTypeObject PyDateTime_TimeType;
106static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000107
108/* ---------------------------------------------------------------------------
109 * Math utilities.
110 */
111
112/* k = i+j overflows iff k differs in sign from both inputs,
113 * iff k^i has sign bit set and k^j has sign bit set,
114 * iff (k^i)&(k^j) has sign bit set.
115 */
116#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000117 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000118
119/* Compute Python divmod(x, y), returning the quotient and storing the
120 * remainder into *r. The quotient is the floor of x/y, and that's
121 * the real point of this. C will probably truncate instead (C99
122 * requires truncation; C89 left it implementation-defined).
123 * Simplification: we *require* that y > 0 here. That's appropriate
124 * for all the uses made of it. This simplifies the code and makes
125 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
126 * overflow case).
127 */
128static int
129divmod(int x, int y, int *r)
130{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000131 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000132
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000133 assert(y > 0);
134 quo = x / y;
135 *r = x - quo * y;
136 if (*r < 0) {
137 --quo;
138 *r += y;
139 }
140 assert(0 <= *r && *r < y);
141 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000142}
143
Tim Peters5d644dd2003-01-02 16:32:54 +0000144/* Round a double to the nearest long. |x| must be small enough to fit
145 * in a C long; this is not checked.
146 */
147static long
148round_to_long(double x)
149{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000150 if (x >= 0.0)
151 x = floor(x + 0.5);
152 else
153 x = ceil(x - 0.5);
154 return (long)x;
Tim Peters5d644dd2003-01-02 16:32:54 +0000155}
156
Tim Peters2a799bf2002-12-16 20:18:38 +0000157/* ---------------------------------------------------------------------------
158 * General calendrical helper functions
159 */
160
161/* For each month ordinal in 1..12, the number of days in that month,
162 * and the number of days before that month in the same year. These
163 * are correct for non-leap years only.
164 */
165static int _days_in_month[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000166 0, /* unused; this vector uses 1-based indexing */
167 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000168};
169
170static int _days_before_month[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000171 0, /* unused; this vector uses 1-based indexing */
172 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000173};
174
175/* year -> 1 if leap year, else 0. */
176static int
177is_leap(int year)
178{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000179 /* Cast year to unsigned. The result is the same either way, but
180 * C can generate faster code for unsigned mod than for signed
181 * mod (especially for % 4 -- a good compiler should just grab
182 * the last 2 bits when the LHS is unsigned).
183 */
184 const unsigned int ayear = (unsigned int)year;
185 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000186}
187
188/* year, month -> number of days in that month in that year */
189static int
190days_in_month(int year, int month)
191{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000192 assert(month >= 1);
193 assert(month <= 12);
194 if (month == 2 && is_leap(year))
195 return 29;
196 else
197 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000198}
199
200/* year, month -> number of days in year preceeding first day of month */
201static int
202days_before_month(int year, int month)
203{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000204 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000205
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000206 assert(month >= 1);
207 assert(month <= 12);
208 days = _days_before_month[month];
209 if (month > 2 && is_leap(year))
210 ++days;
211 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000212}
213
214/* year -> number of days before January 1st of year. Remember that we
215 * start with year 1, so days_before_year(1) == 0.
216 */
217static int
218days_before_year(int year)
219{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000220 int y = year - 1;
221 /* This is incorrect if year <= 0; we really want the floor
222 * here. But so long as MINYEAR is 1, the smallest year this
223 * can see is 0 (this can happen in some normalization endcases),
224 * so we'll just special-case that.
225 */
226 assert (year >= 0);
227 if (y >= 0)
228 return y*365 + y/4 - y/100 + y/400;
229 else {
230 assert(y == -1);
231 return -366;
232 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000233}
234
235/* Number of days in 4, 100, and 400 year cycles. That these have
236 * the correct values is asserted in the module init function.
237 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000238#define DI4Y 1461 /* days_before_year(5); days in 4 years */
239#define DI100Y 36524 /* days_before_year(101); days in 100 years */
240#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000241
242/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
243static void
244ord_to_ymd(int ordinal, int *year, int *month, int *day)
245{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000246 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000247
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000248 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
249 * leap years repeats exactly every 400 years. The basic strategy is
250 * to find the closest 400-year boundary at or before ordinal, then
251 * work with the offset from that boundary to ordinal. Life is much
252 * clearer if we subtract 1 from ordinal first -- then the values
253 * of ordinal at 400-year boundaries are exactly those divisible
254 * by DI400Y:
255 *
256 * D M Y n n-1
257 * -- --- ---- ---------- ----------------
258 * 31 Dec -400 -DI400Y -DI400Y -1
259 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
260 * ...
261 * 30 Dec 000 -1 -2
262 * 31 Dec 000 0 -1
263 * 1 Jan 001 1 0 400-year boundary
264 * 2 Jan 001 2 1
265 * 3 Jan 001 3 2
266 * ...
267 * 31 Dec 400 DI400Y DI400Y -1
268 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
269 */
270 assert(ordinal >= 1);
271 --ordinal;
272 n400 = ordinal / DI400Y;
273 n = ordinal % DI400Y;
274 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000275
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000276 /* Now n is the (non-negative) offset, in days, from January 1 of
277 * year, to the desired date. Now compute how many 100-year cycles
278 * precede n.
279 * Note that it's possible for n100 to equal 4! In that case 4 full
280 * 100-year cycles precede the desired day, which implies the
281 * desired day is December 31 at the end of a 400-year cycle.
282 */
283 n100 = n / DI100Y;
284 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000285
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000286 /* Now compute how many 4-year cycles precede it. */
287 n4 = n / DI4Y;
288 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000289
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000290 /* And now how many single years. Again n1 can be 4, and again
291 * meaning that the desired day is December 31 at the end of the
292 * 4-year cycle.
293 */
294 n1 = n / 365;
295 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000296
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000297 *year += n100 * 100 + n4 * 4 + n1;
298 if (n1 == 4 || n100 == 4) {
299 assert(n == 0);
300 *year -= 1;
301 *month = 12;
302 *day = 31;
303 return;
304 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000305
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000306 /* Now the year is correct, and n is the offset from January 1. We
307 * find the month via an estimate that's either exact or one too
308 * large.
309 */
310 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
311 assert(leapyear == is_leap(*year));
312 *month = (n + 50) >> 5;
313 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
314 if (preceding > n) {
315 /* estimate is too large */
316 *month -= 1;
317 preceding -= days_in_month(*year, *month);
318 }
319 n -= preceding;
320 assert(0 <= n);
321 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000322
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000323 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000324}
325
326/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
327static int
328ymd_to_ord(int year, int month, int day)
329{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000330 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000331}
332
333/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
334static int
335weekday(int year, int month, int day)
336{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000337 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000338}
339
340/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
341 * first calendar week containing a Thursday.
342 */
343static int
344iso_week1_monday(int year)
345{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000346 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
347 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
348 int first_weekday = (first_day + 6) % 7;
349 /* ordinal of closest Monday at or before 1/1 */
350 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000351
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000352 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
353 week1_monday += 7;
354 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000355}
356
357/* ---------------------------------------------------------------------------
358 * Range checkers.
359 */
360
361/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
362 * If not, raise OverflowError and return -1.
363 */
364static int
365check_delta_day_range(int days)
366{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000367 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
368 return 0;
369 PyErr_Format(PyExc_OverflowError,
370 "days=%d; must have magnitude <= %d",
371 days, MAX_DELTA_DAYS);
372 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000373}
374
375/* Check that date arguments are in range. Return 0 if they are. If they
376 * aren't, raise ValueError and return -1.
377 */
378static int
379check_date_args(int year, int month, int day)
380{
381
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000382 if (year < MINYEAR || year > MAXYEAR) {
383 PyErr_SetString(PyExc_ValueError,
384 "year is out of range");
385 return -1;
386 }
387 if (month < 1 || month > 12) {
388 PyErr_SetString(PyExc_ValueError,
389 "month must be in 1..12");
390 return -1;
391 }
392 if (day < 1 || day > days_in_month(year, month)) {
393 PyErr_SetString(PyExc_ValueError,
394 "day is out of range for month");
395 return -1;
396 }
397 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000398}
399
400/* Check that time arguments are in range. Return 0 if they are. If they
401 * aren't, raise ValueError and return -1.
402 */
403static int
404check_time_args(int h, int m, int s, int us)
405{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000406 if (h < 0 || h > 23) {
407 PyErr_SetString(PyExc_ValueError,
408 "hour must be in 0..23");
409 return -1;
410 }
411 if (m < 0 || m > 59) {
412 PyErr_SetString(PyExc_ValueError,
413 "minute must be in 0..59");
414 return -1;
415 }
416 if (s < 0 || s > 59) {
417 PyErr_SetString(PyExc_ValueError,
418 "second must be in 0..59");
419 return -1;
420 }
421 if (us < 0 || us > 999999) {
422 PyErr_SetString(PyExc_ValueError,
423 "microsecond must be in 0..999999");
424 return -1;
425 }
426 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000427}
428
429/* ---------------------------------------------------------------------------
430 * Normalization utilities.
431 */
432
433/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
434 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
435 * at least factor, enough of *lo is converted into "hi" units so that
436 * 0 <= *lo < factor. The input values must be such that int overflow
437 * is impossible.
438 */
439static void
440normalize_pair(int *hi, int *lo, int factor)
441{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000442 assert(factor > 0);
443 assert(lo != hi);
444 if (*lo < 0 || *lo >= factor) {
445 const int num_hi = divmod(*lo, factor, lo);
446 const int new_hi = *hi + num_hi;
447 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
448 *hi = new_hi;
449 }
450 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000451}
452
453/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000454 * 0 <= *s < 24*3600
455 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000456 * The input values must be such that the internals don't overflow.
457 * The way this routine is used, we don't get close.
458 */
459static void
460normalize_d_s_us(int *d, int *s, int *us)
461{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000462 if (*us < 0 || *us >= 1000000) {
463 normalize_pair(s, us, 1000000);
464 /* |s| can't be bigger than about
465 * |original s| + |original us|/1000000 now.
466 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000467
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000468 }
469 if (*s < 0 || *s >= 24*3600) {
470 normalize_pair(d, s, 24*3600);
471 /* |d| can't be bigger than about
472 * |original d| +
473 * (|original s| + |original us|/1000000) / (24*3600) now.
474 */
475 }
476 assert(0 <= *s && *s < 24*3600);
477 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000478}
479
480/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000481 * 1 <= *m <= 12
482 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000483 * The input values must be such that the internals don't overflow.
484 * The way this routine is used, we don't get close.
485 */
Alexander Belopolsky9292ee02010-05-27 20:55:27 +0000486static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000487normalize_y_m_d(int *y, int *m, int *d)
488{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000489 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000490
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000491 /* This gets muddy: the proper range for day can't be determined
492 * without knowing the correct month and year, but if day is, e.g.,
493 * plus or minus a million, the current month and year values make
494 * no sense (and may also be out of bounds themselves).
495 * Saying 12 months == 1 year should be non-controversial.
496 */
497 if (*m < 1 || *m > 12) {
498 --*m;
499 normalize_pair(y, m, 12);
500 ++*m;
501 /* |y| can't be bigger than about
502 * |original y| + |original m|/12 now.
503 */
504 }
505 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000506
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000507 /* Now only day can be out of bounds (year may also be out of bounds
508 * for a datetime object, but we don't care about that here).
509 * If day is out of bounds, what to do is arguable, but at least the
510 * method here is principled and explainable.
511 */
512 dim = days_in_month(*y, *m);
513 if (*d < 1 || *d > dim) {
514 /* Move day-1 days from the first of the month. First try to
515 * get off cheap if we're only one day out of range
516 * (adjustments for timezone alone can't be worse than that).
517 */
518 if (*d == 0) {
519 --*m;
520 if (*m > 0)
521 *d = days_in_month(*y, *m);
522 else {
523 --*y;
524 *m = 12;
525 *d = 31;
526 }
527 }
528 else if (*d == dim + 1) {
529 /* move forward a day */
530 ++*m;
531 *d = 1;
532 if (*m > 12) {
533 *m = 1;
534 ++*y;
535 }
536 }
537 else {
538 int ordinal = ymd_to_ord(*y, *m, 1) +
539 *d - 1;
Alexander Belopolsky9292ee02010-05-27 20:55:27 +0000540 if (ordinal < 1 || ordinal > MAXORDINAL) {
541 goto error;
542 } else {
543 ord_to_ymd(ordinal, y, m, d);
544 return 0;
545 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000546 }
547 }
548 assert(*m > 0);
549 assert(*d > 0);
Alexander Belopolsky9292ee02010-05-27 20:55:27 +0000550 if (MINYEAR <= *y && *y <= MAXYEAR)
551 return 0;
552 error:
553 PyErr_SetString(PyExc_OverflowError,
554 "date value out of range");
555 return -1;
556
Tim Peters2a799bf2002-12-16 20:18:38 +0000557}
558
559/* Fiddle out-of-bounds months and days so that the result makes some kind
560 * of sense. The parameters are both inputs and outputs. Returns < 0 on
561 * failure, where failure means the adjusted year is out of bounds.
562 */
563static int
564normalize_date(int *year, int *month, int *day)
565{
Alexander Belopolsky9292ee02010-05-27 20:55:27 +0000566 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000567}
568
569/* Force all the datetime fields into range. The parameters are both
570 * inputs and outputs. Returns < 0 on error.
571 */
572static int
573normalize_datetime(int *year, int *month, int *day,
574 int *hour, int *minute, int *second,
575 int *microsecond)
576{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000577 normalize_pair(second, microsecond, 1000000);
578 normalize_pair(minute, second, 60);
579 normalize_pair(hour, minute, 60);
580 normalize_pair(day, hour, 24);
581 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000582}
583
584/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000585 * Basic object allocation: tp_alloc implementations. These allocate
586 * Python objects of the right size and type, and do the Python object-
587 * initialization bit. If there's not enough memory, they return NULL after
588 * setting MemoryError. All data members remain uninitialized trash.
589 *
590 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000591 * member is needed. This is ugly, imprecise, and possibly insecure.
592 * tp_basicsize for the time and datetime types is set to the size of the
593 * struct that has room for the tzinfo member, so subclasses in Python will
594 * allocate enough space for a tzinfo member whether or not one is actually
595 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
596 * part is that PyType_GenericAlloc() (which subclasses in Python end up
597 * using) just happens today to effectively ignore the nitems argument
598 * when tp_itemsize is 0, which it is for these type objects. If that
599 * changes, perhaps the callers of tp_alloc slots in this file should
600 * be changed to force a 0 nitems argument unless the type being allocated
601 * is a base type implemented in this file (so that tp_alloc is time_alloc
602 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000603 */
604
605static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000606time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000607{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000608 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000609
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000610 self = (PyObject *)
611 PyObject_MALLOC(aware ?
612 sizeof(PyDateTime_Time) :
613 sizeof(_PyDateTime_BaseTime));
614 if (self == NULL)
615 return (PyObject *)PyErr_NoMemory();
616 PyObject_INIT(self, type);
617 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000618}
619
620static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000621datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000622{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000623 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000624
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000625 self = (PyObject *)
626 PyObject_MALLOC(aware ?
627 sizeof(PyDateTime_DateTime) :
628 sizeof(_PyDateTime_BaseDateTime));
629 if (self == NULL)
630 return (PyObject *)PyErr_NoMemory();
631 PyObject_INIT(self, type);
632 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000633}
634
635/* ---------------------------------------------------------------------------
636 * Helpers for setting object fields. These work on pointers to the
637 * appropriate base class.
638 */
639
640/* For date and datetime. */
641static void
642set_date_fields(PyDateTime_Date *self, int y, int m, int d)
643{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000644 self->hashcode = -1;
645 SET_YEAR(self, y);
646 SET_MONTH(self, m);
647 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000648}
649
650/* ---------------------------------------------------------------------------
651 * Create various objects, mostly without range checking.
652 */
653
654/* Create a date instance with no range checking. */
655static PyObject *
656new_date_ex(int year, int month, int day, PyTypeObject *type)
657{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000658 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000659
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000660 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
661 if (self != NULL)
662 set_date_fields(self, year, month, day);
663 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000664}
665
666#define new_date(year, month, day) \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000667 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000668
669/* Create a datetime instance with no range checking. */
670static PyObject *
671new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000672 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000673{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000674 PyDateTime_DateTime *self;
675 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000676
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000677 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
678 if (self != NULL) {
679 self->hastzinfo = aware;
680 set_date_fields((PyDateTime_Date *)self, year, month, day);
681 DATE_SET_HOUR(self, hour);
682 DATE_SET_MINUTE(self, minute);
683 DATE_SET_SECOND(self, second);
684 DATE_SET_MICROSECOND(self, usecond);
685 if (aware) {
686 Py_INCREF(tzinfo);
687 self->tzinfo = tzinfo;
688 }
689 }
690 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000691}
692
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000693#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
694 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
695 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000696
697/* Create a time instance with no range checking. */
698static PyObject *
699new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000700 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000701{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000702 PyDateTime_Time *self;
703 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000704
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000705 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
706 if (self != NULL) {
707 self->hastzinfo = aware;
708 self->hashcode = -1;
709 TIME_SET_HOUR(self, hour);
710 TIME_SET_MINUTE(self, minute);
711 TIME_SET_SECOND(self, second);
712 TIME_SET_MICROSECOND(self, usecond);
713 if (aware) {
714 Py_INCREF(tzinfo);
715 self->tzinfo = tzinfo;
716 }
717 }
718 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000719}
720
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000721#define new_time(hh, mm, ss, us, tzinfo) \
722 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000723
724/* Create a timedelta instance. Normalize the members iff normalize is
725 * true. Passing false is a speed optimization, if you know for sure
726 * that seconds and microseconds are already in their proper ranges. In any
727 * case, raises OverflowError and returns NULL if the normalized days is out
728 * of range).
729 */
730static PyObject *
731new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000732 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000733{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000734 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000735
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000736 if (normalize)
737 normalize_d_s_us(&days, &seconds, &microseconds);
738 assert(0 <= seconds && seconds < 24*3600);
739 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000740
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000741 if (check_delta_day_range(days) < 0)
742 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000743
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000744 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
745 if (self != NULL) {
746 self->hashcode = -1;
747 SET_TD_DAYS(self, days);
748 SET_TD_SECONDS(self, seconds);
749 SET_TD_MICROSECONDS(self, microseconds);
750 }
751 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000752}
753
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000754#define new_delta(d, s, us, normalize) \
755 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000756
757/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000758 * tzinfo helpers.
759 */
760
Tim Peters855fe882002-12-22 03:43:39 +0000761/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
762 * raise TypeError and return -1.
763 */
764static int
765check_tzinfo_subclass(PyObject *p)
766{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000767 if (p == Py_None || PyTZInfo_Check(p))
768 return 0;
769 PyErr_Format(PyExc_TypeError,
770 "tzinfo argument must be None or of a tzinfo subclass, "
771 "not type '%s'",
772 Py_TYPE(p)->tp_name);
773 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000774}
775
Tim Petersbad8ff02002-12-30 20:52:32 +0000776/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000777 * If tzinfo is None, returns None.
778 */
779static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000780call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000781{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000782 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000783
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000784 assert(tzinfo && methname && tzinfoarg);
785 assert(check_tzinfo_subclass(tzinfo) >= 0);
786 if (tzinfo == Py_None) {
787 result = Py_None;
788 Py_INCREF(result);
789 }
790 else
791 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
792 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000793}
794
Tim Peters2a799bf2002-12-16 20:18:38 +0000795/* If self has a tzinfo member, return a BORROWED reference to it. Else
796 * return NULL, which is NOT AN ERROR. There are no error returns here,
797 * and the caller must not decref the result.
798 */
799static PyObject *
800get_tzinfo_member(PyObject *self)
801{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000802 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000803
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000804 if (PyDateTime_Check(self) && HASTZINFO(self))
805 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
806 else if (PyTime_Check(self) && HASTZINFO(self))
807 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000808
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000809 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000810}
811
Tim Petersbad8ff02002-12-30 20:52:32 +0000812/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000813 * result. tzinfo must be an instance of the tzinfo class. If the method
814 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000815 * return None or timedelta, TypeError is raised and this returns -1. If it
816 * returnsa timedelta and the value is out of range or isn't a whole number
817 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000818 * Else *none is set to 0 and the integer method result is returned.
819 */
820static int
821call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000822 int *none)
Tim Peters2a799bf2002-12-16 20:18:38 +0000823{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000824 PyObject *u;
825 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000826
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000827 assert(tzinfo != NULL);
828 assert(PyTZInfo_Check(tzinfo));
829 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000830
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000831 *none = 0;
832 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
833 if (u == NULL)
834 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000835
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000836 else if (u == Py_None) {
837 result = 0;
838 *none = 1;
839 }
840 else if (PyDelta_Check(u)) {
841 const int days = GET_TD_DAYS(u);
842 if (days < -1 || days > 0)
843 result = 24*60; /* trigger ValueError below */
844 else {
845 /* next line can't overflow because we know days
846 * is -1 or 0 now
847 */
848 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
849 result = divmod(ss, 60, &ss);
850 if (ss || GET_TD_MICROSECONDS(u)) {
851 PyErr_Format(PyExc_ValueError,
852 "tzinfo.%s() must return a "
853 "whole number of minutes",
854 name);
855 result = -1;
856 }
857 }
858 }
859 else {
860 PyErr_Format(PyExc_TypeError,
861 "tzinfo.%s() must return None or "
862 "timedelta, not '%s'",
863 name, Py_TYPE(u)->tp_name);
864 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000865
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000866 Py_DECREF(u);
867 if (result < -1439 || result > 1439) {
868 PyErr_Format(PyExc_ValueError,
869 "tzinfo.%s() returned %d; must be in "
870 "-1439 .. 1439",
871 name, result);
872 result = -1;
873 }
874 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000875}
876
877/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
878 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
879 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000880 * doesn't return None or timedelta, TypeError is raised and this returns -1.
881 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
882 * # of minutes), ValueError is raised and this returns -1. Else *none is
883 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000884 */
885static int
886call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
887{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000888 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000889}
890
Tim Petersbad8ff02002-12-30 20:52:32 +0000891/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
892 */
Tim Peters855fe882002-12-22 03:43:39 +0000893static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000894offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000895 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000896
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000897 assert(tzinfo && name && tzinfoarg);
898 if (tzinfo == Py_None) {
899 result = Py_None;
900 Py_INCREF(result);
901 }
902 else {
903 int none;
904 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
905 &none);
906 if (offset < 0 && PyErr_Occurred())
907 return NULL;
908 if (none) {
909 result = Py_None;
910 Py_INCREF(result);
911 }
912 else
913 result = new_delta(0, offset * 60, 0, 1);
914 }
915 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000916}
917
Tim Peters2a799bf2002-12-16 20:18:38 +0000918/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
919 * result. tzinfo must be an instance of the tzinfo class. If dst()
920 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000921 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000922 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000923 * ValueError is raised and this returns -1. Else *none is set to 0 and
924 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000925 */
926static int
927call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
928{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000929 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000930}
931
Tim Petersbad8ff02002-12-30 20:52:32 +0000932/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000933 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000934 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000935 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000936 */
937static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000938call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000939{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000940 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000941
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000942 assert(tzinfo != NULL);
943 assert(check_tzinfo_subclass(tzinfo) >= 0);
944 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000945
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000946 if (tzinfo == Py_None) {
947 result = Py_None;
948 Py_INCREF(result);
949 }
950 else
951 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000952
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000953 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
954 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
955 "return None or a string, not '%s'",
956 Py_TYPE(result)->tp_name);
957 Py_DECREF(result);
958 result = NULL;
959 }
960 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000961}
962
963typedef enum {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000964 /* an exception has been set; the caller should pass it on */
965 OFFSET_ERROR,
Tim Peters2a799bf2002-12-16 20:18:38 +0000966
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000967 /* type isn't date, datetime, or time subclass */
968 OFFSET_UNKNOWN,
Tim Peters2a799bf2002-12-16 20:18:38 +0000969
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000970 /* date,
971 * datetime with !hastzinfo
972 * datetime with None tzinfo,
973 * datetime where utcoffset() returns None
974 * time with !hastzinfo
975 * time with None tzinfo,
976 * time where utcoffset() returns None
977 */
978 OFFSET_NAIVE,
Tim Peters2a799bf2002-12-16 20:18:38 +0000979
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000980 /* time or datetime where utcoffset() doesn't return None */
981 OFFSET_AWARE
Tim Peters2a799bf2002-12-16 20:18:38 +0000982} naivety;
983
Tim Peters14b69412002-12-22 18:10:22 +0000984/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000985 * the "naivety" typedef for details. If the type is aware, *offset is set
986 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000987 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000988 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000989 */
990static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000991classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000992{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000993 int none;
994 PyObject *tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000995
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000996 assert(tzinfoarg != NULL);
997 *offset = 0;
998 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
999 if (tzinfo == Py_None)
1000 return OFFSET_NAIVE;
1001 if (tzinfo == NULL) {
1002 /* note that a datetime passes the PyDate_Check test */
1003 return (PyTime_Check(op) || PyDate_Check(op)) ?
1004 OFFSET_NAIVE : OFFSET_UNKNOWN;
1005 }
1006 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1007 if (*offset == -1 && PyErr_Occurred())
1008 return OFFSET_ERROR;
1009 return none ? OFFSET_NAIVE : OFFSET_AWARE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001010}
1011
Tim Peters00237032002-12-27 02:21:51 +00001012/* Classify two objects as to whether they're naive or offset-aware.
1013 * This isn't quite the same as calling classify_utcoffset() twice: for
1014 * binary operations (comparison and subtraction), we generally want to
1015 * ignore the tzinfo members if they're identical. This is by design,
1016 * so that results match "naive" expectations when mixing objects from a
1017 * single timezone. So in that case, this sets both offsets to 0 and
1018 * both naiveties to OFFSET_NAIVE.
1019 * The function returns 0 if everything's OK, and -1 on error.
1020 */
1021static int
1022classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001023 PyObject *tzinfoarg1,
1024 PyObject *o2, int *offset2, naivety *n2,
1025 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001026{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001027 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1028 *offset1 = *offset2 = 0;
1029 *n1 = *n2 = OFFSET_NAIVE;
1030 }
1031 else {
1032 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1033 if (*n1 == OFFSET_ERROR)
1034 return -1;
1035 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1036 if (*n2 == OFFSET_ERROR)
1037 return -1;
1038 }
1039 return 0;
Tim Peters00237032002-12-27 02:21:51 +00001040}
1041
Tim Peters2a799bf2002-12-16 20:18:38 +00001042/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1043 * stuff
1044 * ", tzinfo=" + repr(tzinfo)
1045 * before the closing ")".
1046 */
1047static PyObject *
1048append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1049{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001050 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001051
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001052 assert(PyString_Check(repr));
1053 assert(tzinfo);
1054 if (tzinfo == Py_None)
1055 return repr;
1056 /* Get rid of the trailing ')'. */
1057 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1058 temp = PyString_FromStringAndSize(PyString_AsString(repr),
1059 PyString_Size(repr) - 1);
1060 Py_DECREF(repr);
1061 if (temp == NULL)
1062 return NULL;
1063 repr = temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001064
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001065 /* Append ", tzinfo=". */
1066 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
Tim Peters2a799bf2002-12-16 20:18:38 +00001067
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001068 /* Append repr(tzinfo). */
1069 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
Tim Peters2a799bf2002-12-16 20:18:38 +00001070
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001071 /* Add a closing paren. */
1072 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
1073 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001074}
1075
1076/* ---------------------------------------------------------------------------
1077 * String format helpers.
1078 */
1079
1080static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001081format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001082{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001083 static const char *DayNames[] = {
1084 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1085 };
1086 static const char *MonthNames[] = {
1087 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1088 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1089 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001090
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001091 char buffer[128];
1092 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001093
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001094 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
1095 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
1096 GET_DAY(date), hours, minutes, seconds,
1097 GET_YEAR(date));
1098 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00001099}
1100
1101/* Add an hours & minutes UTC offset string to buf. buf has no more than
1102 * buflen bytes remaining. The UTC offset is gotten by calling
1103 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1104 * *buf, and that's all. Else the returned value is checked for sanity (an
1105 * integer in range), and if that's OK it's converted to an hours & minutes
1106 * string of the form
1107 * sign HH sep MM
1108 * Returns 0 if everything is OK. If the return value from utcoffset() is
1109 * bogus, an appropriate exception is set and -1 is returned.
1110 */
1111static int
Tim Peters328fff72002-12-20 01:31:27 +00001112format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001113 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001114{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001115 int offset;
1116 int hours;
1117 int minutes;
1118 char sign;
1119 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00001120
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001121 assert(buflen >= 1);
Gregory P. Smith9d534572008-06-11 07:41:16 +00001122
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001123 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1124 if (offset == -1 && PyErr_Occurred())
1125 return -1;
1126 if (none) {
1127 *buf = '\0';
1128 return 0;
1129 }
1130 sign = '+';
1131 if (offset < 0) {
1132 sign = '-';
1133 offset = - offset;
1134 }
1135 hours = divmod(offset, 60, &minutes);
1136 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1137 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001138}
1139
Skip Montanarofc070d22008-03-15 16:04:45 +00001140static PyObject *
1141make_freplacement(PyObject *object)
1142{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001143 char freplacement[64];
1144 if (PyTime_Check(object))
1145 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1146 else if (PyDateTime_Check(object))
1147 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1148 else
1149 sprintf(freplacement, "%06d", 0);
Skip Montanarofc070d22008-03-15 16:04:45 +00001150
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001151 return PyString_FromStringAndSize(freplacement, strlen(freplacement));
Skip Montanarofc070d22008-03-15 16:04:45 +00001152}
1153
Tim Peters2a799bf2002-12-16 20:18:38 +00001154/* I sure don't want to reproduce the strftime code from the time module,
1155 * so this imports the module and calls it. All the hair is due to
Skip Montanarofc070d22008-03-15 16:04:45 +00001156 * giving special meanings to the %z, %Z and %f format codes via a
1157 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001158 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1159 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001160 */
1161static PyObject *
Gregory P. Smith137d8242008-06-02 04:05:52 +00001162wrap_strftime(PyObject *object, const char *format, size_t format_len,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001163 PyObject *timetuple, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001164{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001165 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001166
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001167 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1168 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1169 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001170
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001171 const char *pin; /* pointer to next char in input format */
1172 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001173
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001174 PyObject *newfmt = NULL; /* py string, the output format */
1175 char *pnew; /* pointer to available byte in output format */
1176 size_t totalnew; /* number bytes total in output format buffer,
1177 exclusive of trailing \0 */
1178 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001179
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001180 const char *ptoappend; /* ptr to string to append to output buffer */
1181 size_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001182
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001183 assert(object && format && timetuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001184
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001185 /* Give up if the year is before 1900.
1186 * Python strftime() plays games with the year, and different
1187 * games depending on whether envar PYTHON2K is set. This makes
1188 * years before 1900 a nightmare, even if the platform strftime
1189 * supports them (and not all do).
1190 * We could get a lot farther here by avoiding Python's strftime
1191 * wrapper and calling the C strftime() directly, but that isn't
1192 * an option in the Python implementation of this module.
1193 */
1194 {
1195 long year;
1196 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1197 if (pyyear == NULL) return NULL;
1198 assert(PyInt_Check(pyyear));
1199 year = PyInt_AsLong(pyyear);
1200 Py_DECREF(pyyear);
1201 if (year < 1900) {
1202 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1203 "1900; the datetime strftime() "
1204 "methods require year >= 1900",
1205 year);
1206 return NULL;
1207 }
1208 }
Tim Petersd6844152002-12-22 20:58:42 +00001209
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001210 /* Scan the input format, looking for %z/%Z/%f escapes, building
1211 * a new format. Since computing the replacements for those codes
1212 * is expensive, don't unless they're actually used.
1213 */
1214 if (format_len > INT_MAX - 1) {
1215 PyErr_NoMemory();
1216 goto Done;
1217 }
Gregory P. Smith9d534572008-06-11 07:41:16 +00001218
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001219 totalnew = format_len + 1; /* realistic if no %z/%Z/%f */
1220 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1221 if (newfmt == NULL) goto Done;
1222 pnew = PyString_AsString(newfmt);
1223 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001224
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001225 pin = format;
1226 while ((ch = *pin++) != '\0') {
1227 if (ch != '%') {
1228 ptoappend = pin - 1;
1229 ntoappend = 1;
1230 }
1231 else if ((ch = *pin++) == '\0') {
1232 /* There's a lone trailing %; doesn't make sense. */
1233 PyErr_SetString(PyExc_ValueError, "strftime format "
1234 "ends with raw %");
1235 goto Done;
1236 }
1237 /* A % has been seen and ch is the character after it. */
1238 else if (ch == 'z') {
1239 if (zreplacement == NULL) {
1240 /* format utcoffset */
1241 char buf[100];
1242 PyObject *tzinfo = get_tzinfo_member(object);
1243 zreplacement = PyString_FromString("");
1244 if (zreplacement == NULL) goto Done;
1245 if (tzinfo != Py_None && tzinfo != NULL) {
1246 assert(tzinfoarg != NULL);
1247 if (format_utcoffset(buf,
1248 sizeof(buf),
1249 "",
1250 tzinfo,
1251 tzinfoarg) < 0)
1252 goto Done;
1253 Py_DECREF(zreplacement);
1254 zreplacement = PyString_FromString(buf);
1255 if (zreplacement == NULL) goto Done;
1256 }
1257 }
1258 assert(zreplacement != NULL);
1259 ptoappend = PyString_AS_STRING(zreplacement);
1260 ntoappend = PyString_GET_SIZE(zreplacement);
1261 }
1262 else if (ch == 'Z') {
1263 /* format tzname */
1264 if (Zreplacement == NULL) {
1265 PyObject *tzinfo = get_tzinfo_member(object);
1266 Zreplacement = PyString_FromString("");
1267 if (Zreplacement == NULL) goto Done;
1268 if (tzinfo != Py_None && tzinfo != NULL) {
1269 PyObject *temp;
1270 assert(tzinfoarg != NULL);
1271 temp = call_tzname(tzinfo, tzinfoarg);
1272 if (temp == NULL) goto Done;
1273 if (temp != Py_None) {
1274 assert(PyString_Check(temp));
1275 /* Since the tzname is getting
1276 * stuffed into the format, we
1277 * have to double any % signs
1278 * so that strftime doesn't
1279 * treat them as format codes.
1280 */
1281 Py_DECREF(Zreplacement);
1282 Zreplacement = PyObject_CallMethod(
1283 temp, "replace",
1284 "ss", "%", "%%");
1285 Py_DECREF(temp);
1286 if (Zreplacement == NULL)
1287 goto Done;
1288 if (!PyString_Check(Zreplacement)) {
1289 PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
1290 goto Done;
1291 }
1292 }
1293 else
1294 Py_DECREF(temp);
1295 }
1296 }
1297 assert(Zreplacement != NULL);
1298 ptoappend = PyString_AS_STRING(Zreplacement);
1299 ntoappend = PyString_GET_SIZE(Zreplacement);
1300 }
1301 else if (ch == 'f') {
1302 /* format microseconds */
1303 if (freplacement == NULL) {
1304 freplacement = make_freplacement(object);
1305 if (freplacement == NULL)
1306 goto Done;
1307 }
1308 assert(freplacement != NULL);
1309 assert(PyString_Check(freplacement));
1310 ptoappend = PyString_AS_STRING(freplacement);
1311 ntoappend = PyString_GET_SIZE(freplacement);
1312 }
1313 else {
1314 /* percent followed by neither z nor Z */
1315 ptoappend = pin - 2;
1316 ntoappend = 2;
1317 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001318
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001319 /* Append the ntoappend chars starting at ptoappend to
1320 * the new format.
1321 */
1322 assert(ptoappend != NULL);
1323 assert(ntoappend >= 0);
1324 if (ntoappend == 0)
1325 continue;
1326 while (usednew + ntoappend > totalnew) {
1327 size_t bigger = totalnew << 1;
1328 if ((bigger >> 1) != totalnew) { /* overflow */
1329 PyErr_NoMemory();
1330 goto Done;
1331 }
1332 if (_PyString_Resize(&newfmt, bigger) < 0)
1333 goto Done;
1334 totalnew = bigger;
1335 pnew = PyString_AsString(newfmt) + usednew;
1336 }
1337 memcpy(pnew, ptoappend, ntoappend);
1338 pnew += ntoappend;
1339 usednew += ntoappend;
1340 assert(usednew <= totalnew);
1341 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001342
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001343 if (_PyString_Resize(&newfmt, usednew) < 0)
1344 goto Done;
1345 {
1346 PyObject *time = PyImport_ImportModuleNoBlock("time");
1347 if (time == NULL)
1348 goto Done;
1349 result = PyObject_CallMethod(time, "strftime", "OO",
1350 newfmt, timetuple);
1351 Py_DECREF(time);
1352 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001353 Done:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001354 Py_XDECREF(freplacement);
1355 Py_XDECREF(zreplacement);
1356 Py_XDECREF(Zreplacement);
1357 Py_XDECREF(newfmt);
1358 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001359}
1360
1361static char *
1362isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1363{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001364 int x;
1365 x = PyOS_snprintf(buffer, bufflen,
1366 "%04d-%02d-%02d",
1367 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1368 assert(bufflen >= x);
1369 return buffer + x;
Tim Peters2a799bf2002-12-16 20:18:38 +00001370}
1371
Amaury Forgeot d'Arc8645a5c2009-12-29 22:03:38 +00001372static char *
Tim Peters2a799bf2002-12-16 20:18:38 +00001373isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1374{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001375 int x;
1376 int us = DATE_GET_MICROSECOND(dt);
Tim Peters2a799bf2002-12-16 20:18:38 +00001377
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001378 x = PyOS_snprintf(buffer, bufflen,
1379 "%02d:%02d:%02d",
1380 DATE_GET_HOUR(dt),
1381 DATE_GET_MINUTE(dt),
1382 DATE_GET_SECOND(dt));
1383 assert(bufflen >= x);
1384 if (us)
1385 x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us);
1386 assert(bufflen >= x);
1387 return buffer + x;
Tim Peters2a799bf2002-12-16 20:18:38 +00001388}
1389
1390/* ---------------------------------------------------------------------------
1391 * Wrap functions from the time module. These aren't directly available
1392 * from C. Perhaps they should be.
1393 */
1394
1395/* Call time.time() and return its result (a Python float). */
1396static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001397time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001398{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001399 PyObject *result = NULL;
1400 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001401
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001402 if (time != NULL) {
1403 result = PyObject_CallMethod(time, "time", "()");
1404 Py_DECREF(time);
1405 }
1406 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001407}
1408
1409/* Build a time.struct_time. The weekday and day number are automatically
1410 * computed from the y,m,d args.
1411 */
1412static PyObject *
1413build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1414{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001415 PyObject *time;
1416 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001417
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001418 time = PyImport_ImportModuleNoBlock("time");
1419 if (time != NULL) {
1420 result = PyObject_CallMethod(time, "struct_time",
1421 "((iiiiiiiii))",
1422 y, m, d,
1423 hh, mm, ss,
1424 weekday(y, m, d),
1425 days_before_month(y, m) + d,
1426 dstflag);
1427 Py_DECREF(time);
1428 }
1429 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001430}
1431
1432/* ---------------------------------------------------------------------------
1433 * Miscellaneous helpers.
1434 */
1435
1436/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1437 * The comparisons here all most naturally compute a cmp()-like result.
1438 * This little helper turns that into a bool result for rich comparisons.
1439 */
1440static PyObject *
1441diff_to_bool(int diff, int op)
1442{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001443 PyObject *result;
1444 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001445
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001446 switch (op) {
1447 case Py_EQ: istrue = diff == 0; break;
1448 case Py_NE: istrue = diff != 0; break;
1449 case Py_LE: istrue = diff <= 0; break;
1450 case Py_GE: istrue = diff >= 0; break;
1451 case Py_LT: istrue = diff < 0; break;
1452 case Py_GT: istrue = diff > 0; break;
1453 default:
1454 assert(! "op unknown");
1455 istrue = 0; /* To shut up compiler */
1456 }
1457 result = istrue ? Py_True : Py_False;
1458 Py_INCREF(result);
1459 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001460}
1461
Tim Peters07534a62003-02-07 22:50:28 +00001462/* Raises a "can't compare" TypeError and returns NULL. */
1463static PyObject *
1464cmperror(PyObject *a, PyObject *b)
1465{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001466 PyErr_Format(PyExc_TypeError,
1467 "can't compare %s to %s",
1468 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1469 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001470}
1471
Tim Peters2a799bf2002-12-16 20:18:38 +00001472/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001473 * Cached Python objects; these are set by the module init function.
1474 */
1475
1476/* Conversion factors. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001477static PyObject *us_per_us = NULL; /* 1 */
1478static PyObject *us_per_ms = NULL; /* 1000 */
1479static PyObject *us_per_second = NULL; /* 1000000 */
1480static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1481static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1482static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1483static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001484static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1485
Tim Peters2a799bf2002-12-16 20:18:38 +00001486/* ---------------------------------------------------------------------------
1487 * Class implementations.
1488 */
1489
1490/*
1491 * PyDateTime_Delta implementation.
1492 */
1493
1494/* Convert a timedelta to a number of us,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001495 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001496 * as a Python int or long.
1497 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1498 * due to ubiquitous overflow possibilities.
1499 */
1500static PyObject *
1501delta_to_microseconds(PyDateTime_Delta *self)
1502{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001503 PyObject *x1 = NULL;
1504 PyObject *x2 = NULL;
1505 PyObject *x3 = NULL;
1506 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001507
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001508 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1509 if (x1 == NULL)
1510 goto Done;
1511 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1512 if (x2 == NULL)
1513 goto Done;
1514 Py_DECREF(x1);
1515 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001516
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001517 /* x2 has days in seconds */
1518 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1519 if (x1 == NULL)
1520 goto Done;
1521 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1522 if (x3 == NULL)
1523 goto Done;
1524 Py_DECREF(x1);
1525 Py_DECREF(x2);
1526 x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001527
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001528 /* x3 has days+seconds in seconds */
1529 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1530 if (x1 == NULL)
1531 goto Done;
1532 Py_DECREF(x3);
1533 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001534
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001535 /* x1 has days+seconds in us */
1536 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1537 if (x2 == NULL)
1538 goto Done;
1539 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001540
1541Done:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001542 Py_XDECREF(x1);
1543 Py_XDECREF(x2);
1544 Py_XDECREF(x3);
1545 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001546}
1547
1548/* Convert a number of us (as a Python int or long) to a timedelta.
1549 */
1550static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001551microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001552{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001553 int us;
1554 int s;
1555 int d;
1556 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001557
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001558 PyObject *tuple = NULL;
1559 PyObject *num = NULL;
1560 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001561
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001562 tuple = PyNumber_Divmod(pyus, us_per_second);
1563 if (tuple == NULL)
1564 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001565
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001566 num = PyTuple_GetItem(tuple, 1); /* us */
1567 if (num == NULL)
1568 goto Done;
1569 temp = PyLong_AsLong(num);
1570 num = NULL;
1571 if (temp == -1 && PyErr_Occurred())
1572 goto Done;
1573 assert(0 <= temp && temp < 1000000);
1574 us = (int)temp;
1575 if (us < 0) {
1576 /* The divisor was positive, so this must be an error. */
1577 assert(PyErr_Occurred());
1578 goto Done;
1579 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001580
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001581 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1582 if (num == NULL)
1583 goto Done;
1584 Py_INCREF(num);
1585 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001586
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001587 tuple = PyNumber_Divmod(num, seconds_per_day);
1588 if (tuple == NULL)
1589 goto Done;
1590 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001591
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001592 num = PyTuple_GetItem(tuple, 1); /* seconds */
1593 if (num == NULL)
1594 goto Done;
1595 temp = PyLong_AsLong(num);
1596 num = NULL;
1597 if (temp == -1 && PyErr_Occurred())
1598 goto Done;
1599 assert(0 <= temp && temp < 24*3600);
1600 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001601
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001602 if (s < 0) {
1603 /* The divisor was positive, so this must be an error. */
1604 assert(PyErr_Occurred());
1605 goto Done;
1606 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001607
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001608 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1609 if (num == NULL)
1610 goto Done;
1611 Py_INCREF(num);
1612 temp = PyLong_AsLong(num);
1613 if (temp == -1 && PyErr_Occurred())
1614 goto Done;
1615 d = (int)temp;
1616 if ((long)d != temp) {
1617 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1618 "large to fit in a C int");
1619 goto Done;
1620 }
1621 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001622
1623Done:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001624 Py_XDECREF(tuple);
1625 Py_XDECREF(num);
1626 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001627}
1628
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001629#define microseconds_to_delta(pymicros) \
1630 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001631
Tim Peters2a799bf2002-12-16 20:18:38 +00001632static PyObject *
1633multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1634{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001635 PyObject *pyus_in;
1636 PyObject *pyus_out;
1637 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001638
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001639 pyus_in = delta_to_microseconds(delta);
1640 if (pyus_in == NULL)
1641 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001642
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001643 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1644 Py_DECREF(pyus_in);
1645 if (pyus_out == NULL)
1646 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001647
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001648 result = microseconds_to_delta(pyus_out);
1649 Py_DECREF(pyus_out);
1650 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001651}
1652
1653static PyObject *
1654divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1655{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001656 PyObject *pyus_in;
1657 PyObject *pyus_out;
1658 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001659
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001660 pyus_in = delta_to_microseconds(delta);
1661 if (pyus_in == NULL)
1662 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001663
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001664 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1665 Py_DECREF(pyus_in);
1666 if (pyus_out == NULL)
1667 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001668
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001669 result = microseconds_to_delta(pyus_out);
1670 Py_DECREF(pyus_out);
1671 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001672}
1673
1674static PyObject *
1675delta_add(PyObject *left, PyObject *right)
1676{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001677 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001678
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001679 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1680 /* delta + delta */
1681 /* The C-level additions can't overflow because of the
1682 * invariant bounds.
1683 */
1684 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1685 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1686 int microseconds = GET_TD_MICROSECONDS(left) +
1687 GET_TD_MICROSECONDS(right);
1688 result = new_delta(days, seconds, microseconds, 1);
1689 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001690
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001691 if (result == Py_NotImplemented)
1692 Py_INCREF(result);
1693 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001694}
1695
1696static PyObject *
1697delta_negative(PyDateTime_Delta *self)
1698{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001699 return new_delta(-GET_TD_DAYS(self),
1700 -GET_TD_SECONDS(self),
1701 -GET_TD_MICROSECONDS(self),
1702 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001703}
1704
1705static PyObject *
1706delta_positive(PyDateTime_Delta *self)
1707{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001708 /* Could optimize this (by returning self) if this isn't a
1709 * subclass -- but who uses unary + ? Approximately nobody.
1710 */
1711 return new_delta(GET_TD_DAYS(self),
1712 GET_TD_SECONDS(self),
1713 GET_TD_MICROSECONDS(self),
1714 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001715}
1716
1717static PyObject *
1718delta_abs(PyDateTime_Delta *self)
1719{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001720 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001721
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001722 assert(GET_TD_MICROSECONDS(self) >= 0);
1723 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001724
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001725 if (GET_TD_DAYS(self) < 0)
1726 result = delta_negative(self);
1727 else
1728 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001729
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001730 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001731}
1732
1733static PyObject *
1734delta_subtract(PyObject *left, PyObject *right)
1735{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001736 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001737
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001738 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1739 /* delta - delta */
1740 PyObject *minus_right = PyNumber_Negative(right);
1741 if (minus_right) {
1742 result = delta_add(left, minus_right);
1743 Py_DECREF(minus_right);
1744 }
1745 else
1746 result = NULL;
1747 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001748
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001749 if (result == Py_NotImplemented)
1750 Py_INCREF(result);
1751 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001752}
1753
1754/* This is more natural as a tp_compare, but doesn't work then: for whatever
1755 * reason, Python's try_3way_compare ignores tp_compare unless
1756 * PyInstance_Check returns true, but these aren't old-style classes.
1757 */
1758static PyObject *
1759delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1760{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001761 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001762
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001763 if (PyDelta_Check(other)) {
1764 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1765 if (diff == 0) {
1766 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1767 if (diff == 0)
1768 diff = GET_TD_MICROSECONDS(self) -
1769 GET_TD_MICROSECONDS(other);
1770 }
1771 }
1772 else if (op == Py_EQ || op == Py_NE)
1773 diff = 1; /* any non-zero value will do */
Tim Peters07534a62003-02-07 22:50:28 +00001774
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001775 else /* stop this from falling back to address comparison */
1776 return cmperror((PyObject *)self, other);
Tim Peters07534a62003-02-07 22:50:28 +00001777
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001778 return diff_to_bool(diff, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001779}
1780
1781static PyObject *delta_getstate(PyDateTime_Delta *self);
1782
1783static long
1784delta_hash(PyDateTime_Delta *self)
1785{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001786 if (self->hashcode == -1) {
1787 PyObject *temp = delta_getstate(self);
1788 if (temp != NULL) {
1789 self->hashcode = PyObject_Hash(temp);
1790 Py_DECREF(temp);
1791 }
1792 }
1793 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001794}
1795
1796static PyObject *
1797delta_multiply(PyObject *left, PyObject *right)
1798{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001799 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001800
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001801 if (PyDelta_Check(left)) {
1802 /* delta * ??? */
1803 if (PyInt_Check(right) || PyLong_Check(right))
1804 result = multiply_int_timedelta(right,
1805 (PyDateTime_Delta *) left);
1806 }
1807 else if (PyInt_Check(left) || PyLong_Check(left))
1808 result = multiply_int_timedelta(left,
1809 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001810
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001811 if (result == Py_NotImplemented)
1812 Py_INCREF(result);
1813 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001814}
1815
1816static PyObject *
1817delta_divide(PyObject *left, PyObject *right)
1818{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001819 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001820
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001821 if (PyDelta_Check(left)) {
1822 /* delta * ??? */
1823 if (PyInt_Check(right) || PyLong_Check(right))
1824 result = divide_timedelta_int(
1825 (PyDateTime_Delta *)left,
1826 right);
1827 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001828
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001829 if (result == Py_NotImplemented)
1830 Py_INCREF(result);
1831 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001832}
1833
1834/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1835 * timedelta constructor. sofar is the # of microseconds accounted for
1836 * so far, and there are factor microseconds per current unit, the number
1837 * of which is given by num. num * factor is added to sofar in a
1838 * numerically careful way, and that's the result. Any fractional
1839 * microseconds left over (this can happen if num is a float type) are
1840 * added into *leftover.
1841 * Note that there are many ways this can give an error (NULL) return.
1842 */
1843static PyObject *
1844accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1845 double *leftover)
1846{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001847 PyObject *prod;
1848 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00001849
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001850 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001851
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001852 if (PyInt_Check(num) || PyLong_Check(num)) {
1853 prod = PyNumber_Multiply(num, factor);
1854 if (prod == NULL)
1855 return NULL;
1856 sum = PyNumber_Add(sofar, prod);
1857 Py_DECREF(prod);
1858 return sum;
1859 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001860
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001861 if (PyFloat_Check(num)) {
1862 double dnum;
1863 double fracpart;
1864 double intpart;
1865 PyObject *x;
1866 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00001867
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001868 /* The Plan: decompose num into an integer part and a
1869 * fractional part, num = intpart + fracpart.
1870 * Then num * factor ==
1871 * intpart * factor + fracpart * factor
1872 * and the LHS can be computed exactly in long arithmetic.
1873 * The RHS is again broken into an int part and frac part.
1874 * and the frac part is added into *leftover.
1875 */
1876 dnum = PyFloat_AsDouble(num);
1877 if (dnum == -1.0 && PyErr_Occurred())
1878 return NULL;
1879 fracpart = modf(dnum, &intpart);
1880 x = PyLong_FromDouble(intpart);
1881 if (x == NULL)
1882 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001883
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001884 prod = PyNumber_Multiply(x, factor);
1885 Py_DECREF(x);
1886 if (prod == NULL)
1887 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001888
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001889 sum = PyNumber_Add(sofar, prod);
1890 Py_DECREF(prod);
1891 if (sum == NULL)
1892 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001893
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001894 if (fracpart == 0.0)
1895 return sum;
1896 /* So far we've lost no information. Dealing with the
1897 * fractional part requires float arithmetic, and may
1898 * lose a little info.
1899 */
1900 assert(PyInt_Check(factor) || PyLong_Check(factor));
1901 if (PyInt_Check(factor))
1902 dnum = (double)PyInt_AsLong(factor);
1903 else
1904 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00001905
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001906 dnum *= fracpart;
1907 fracpart = modf(dnum, &intpart);
1908 x = PyLong_FromDouble(intpart);
1909 if (x == NULL) {
1910 Py_DECREF(sum);
1911 return NULL;
1912 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001913
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001914 y = PyNumber_Add(sum, x);
1915 Py_DECREF(sum);
1916 Py_DECREF(x);
1917 *leftover += fracpart;
1918 return y;
1919 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001920
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001921 PyErr_Format(PyExc_TypeError,
1922 "unsupported type for timedelta %s component: %s",
1923 tag, Py_TYPE(num)->tp_name);
1924 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001925}
1926
1927static PyObject *
1928delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1929{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001930 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001931
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001932 /* Argument objects. */
1933 PyObject *day = NULL;
1934 PyObject *second = NULL;
1935 PyObject *us = NULL;
1936 PyObject *ms = NULL;
1937 PyObject *minute = NULL;
1938 PyObject *hour = NULL;
1939 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001940
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001941 PyObject *x = NULL; /* running sum of microseconds */
1942 PyObject *y = NULL; /* temp sum of microseconds */
1943 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001944
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001945 static char *keywords[] = {
1946 "days", "seconds", "microseconds", "milliseconds",
1947 "minutes", "hours", "weeks", NULL
1948 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001949
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001950 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1951 keywords,
1952 &day, &second, &us,
1953 &ms, &minute, &hour, &week) == 0)
1954 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001955
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001956 x = PyInt_FromLong(0);
1957 if (x == NULL)
1958 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001959
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001960#define CLEANUP \
1961 Py_DECREF(x); \
1962 x = y; \
1963 if (x == NULL) \
1964 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00001965
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001966 if (us) {
1967 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1968 CLEANUP;
1969 }
1970 if (ms) {
1971 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1972 CLEANUP;
1973 }
1974 if (second) {
1975 y = accum("seconds", x, second, us_per_second, &leftover_us);
1976 CLEANUP;
1977 }
1978 if (minute) {
1979 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1980 CLEANUP;
1981 }
1982 if (hour) {
1983 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1984 CLEANUP;
1985 }
1986 if (day) {
1987 y = accum("days", x, day, us_per_day, &leftover_us);
1988 CLEANUP;
1989 }
1990 if (week) {
1991 y = accum("weeks", x, week, us_per_week, &leftover_us);
1992 CLEANUP;
1993 }
1994 if (leftover_us) {
1995 /* Round to nearest whole # of us, and add into x. */
1996 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1997 if (temp == NULL) {
1998 Py_DECREF(x);
1999 goto Done;
2000 }
2001 y = PyNumber_Add(x, temp);
2002 Py_DECREF(temp);
2003 CLEANUP;
2004 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002005
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002006 self = microseconds_to_delta_ex(x, type);
2007 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002008Done:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002009 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002010
2011#undef CLEANUP
2012}
2013
2014static int
2015delta_nonzero(PyDateTime_Delta *self)
2016{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002017 return (GET_TD_DAYS(self) != 0
2018 || GET_TD_SECONDS(self) != 0
2019 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002020}
2021
2022static PyObject *
2023delta_repr(PyDateTime_Delta *self)
2024{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002025 if (GET_TD_MICROSECONDS(self) != 0)
2026 return PyString_FromFormat("%s(%d, %d, %d)",
2027 Py_TYPE(self)->tp_name,
2028 GET_TD_DAYS(self),
2029 GET_TD_SECONDS(self),
2030 GET_TD_MICROSECONDS(self));
2031 if (GET_TD_SECONDS(self) != 0)
2032 return PyString_FromFormat("%s(%d, %d)",
2033 Py_TYPE(self)->tp_name,
2034 GET_TD_DAYS(self),
2035 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002036
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002037 return PyString_FromFormat("%s(%d)",
2038 Py_TYPE(self)->tp_name,
2039 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002040}
2041
2042static PyObject *
2043delta_str(PyDateTime_Delta *self)
2044{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002045 int days = GET_TD_DAYS(self);
2046 int seconds = GET_TD_SECONDS(self);
2047 int us = GET_TD_MICROSECONDS(self);
2048 int hours;
2049 int minutes;
2050 char buf[100];
2051 char *pbuf = buf;
2052 size_t buflen = sizeof(buf);
2053 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002054
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002055 minutes = divmod(seconds, 60, &seconds);
2056 hours = divmod(minutes, 60, &minutes);
Tim Peters2a799bf2002-12-16 20:18:38 +00002057
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002058 if (days) {
2059 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2060 (days == 1 || days == -1) ? "" : "s");
2061 if (n < 0 || (size_t)n >= buflen)
2062 goto Fail;
2063 pbuf += n;
2064 buflen -= (size_t)n;
2065 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002066
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002067 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2068 hours, minutes, seconds);
2069 if (n < 0 || (size_t)n >= buflen)
2070 goto Fail;
2071 pbuf += n;
2072 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002073
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002074 if (us) {
2075 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2076 if (n < 0 || (size_t)n >= buflen)
2077 goto Fail;
2078 pbuf += n;
2079 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002080
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002081 return PyString_FromStringAndSize(buf, pbuf - buf);
Tim Petersba873472002-12-18 20:19:21 +00002082
2083 Fail:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002084 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2085 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002086}
2087
Tim Peters371935f2003-02-01 01:52:50 +00002088/* Pickle support, a simple use of __reduce__. */
2089
Tim Petersb57f8f02003-02-01 02:54:15 +00002090/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002091static PyObject *
2092delta_getstate(PyDateTime_Delta *self)
2093{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002094 return Py_BuildValue("iii", GET_TD_DAYS(self),
2095 GET_TD_SECONDS(self),
2096 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002097}
2098
Tim Peters2a799bf2002-12-16 20:18:38 +00002099static PyObject *
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002100delta_total_seconds(PyObject *self)
2101{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002102 PyObject *total_seconds;
2103 PyObject *total_microseconds;
2104 PyObject *one_million;
Mark Dickinson7000e9e2010-05-09 09:30:06 +00002105
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002106 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2107 if (total_microseconds == NULL)
2108 return NULL;
Mark Dickinson7000e9e2010-05-09 09:30:06 +00002109
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002110 one_million = PyLong_FromLong(1000000L);
2111 if (one_million == NULL) {
2112 Py_DECREF(total_microseconds);
2113 return NULL;
2114 }
Mark Dickinson7000e9e2010-05-09 09:30:06 +00002115
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002116 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson7000e9e2010-05-09 09:30:06 +00002117
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002118 Py_DECREF(total_microseconds);
2119 Py_DECREF(one_million);
2120 return total_seconds;
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002121}
2122
2123static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002124delta_reduce(PyDateTime_Delta* self)
2125{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002126 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002127}
2128
2129#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2130
2131static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002132
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002133 {"days", T_INT, OFFSET(days), READONLY,
2134 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002135
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002136 {"seconds", T_INT, OFFSET(seconds), READONLY,
2137 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002138
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002139 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2140 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2141 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002142};
2143
2144static PyMethodDef delta_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002145 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2146 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002147
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002148 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2149 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002150
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002151 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002152};
2153
2154static char delta_doc[] =
2155PyDoc_STR("Difference between two datetime values.");
2156
2157static PyNumberMethods delta_as_number = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002158 delta_add, /* nb_add */
2159 delta_subtract, /* nb_subtract */
2160 delta_multiply, /* nb_multiply */
2161 delta_divide, /* nb_divide */
2162 0, /* nb_remainder */
2163 0, /* nb_divmod */
2164 0, /* nb_power */
2165 (unaryfunc)delta_negative, /* nb_negative */
2166 (unaryfunc)delta_positive, /* nb_positive */
2167 (unaryfunc)delta_abs, /* nb_absolute */
2168 (inquiry)delta_nonzero, /* nb_nonzero */
2169 0, /*nb_invert*/
2170 0, /*nb_lshift*/
2171 0, /*nb_rshift*/
2172 0, /*nb_and*/
2173 0, /*nb_xor*/
2174 0, /*nb_or*/
2175 0, /*nb_coerce*/
2176 0, /*nb_int*/
2177 0, /*nb_long*/
2178 0, /*nb_float*/
2179 0, /*nb_oct*/
2180 0, /*nb_hex*/
2181 0, /*nb_inplace_add*/
2182 0, /*nb_inplace_subtract*/
2183 0, /*nb_inplace_multiply*/
2184 0, /*nb_inplace_divide*/
2185 0, /*nb_inplace_remainder*/
2186 0, /*nb_inplace_power*/
2187 0, /*nb_inplace_lshift*/
2188 0, /*nb_inplace_rshift*/
2189 0, /*nb_inplace_and*/
2190 0, /*nb_inplace_xor*/
2191 0, /*nb_inplace_or*/
2192 delta_divide, /* nb_floor_divide */
2193 0, /* nb_true_divide */
2194 0, /* nb_inplace_floor_divide */
2195 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002196};
2197
2198static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002199 PyVarObject_HEAD_INIT(NULL, 0)
2200 "datetime.timedelta", /* tp_name */
2201 sizeof(PyDateTime_Delta), /* tp_basicsize */
2202 0, /* tp_itemsize */
2203 0, /* tp_dealloc */
2204 0, /* tp_print */
2205 0, /* tp_getattr */
2206 0, /* tp_setattr */
2207 0, /* tp_compare */
2208 (reprfunc)delta_repr, /* tp_repr */
2209 &delta_as_number, /* tp_as_number */
2210 0, /* tp_as_sequence */
2211 0, /* tp_as_mapping */
2212 (hashfunc)delta_hash, /* tp_hash */
2213 0, /* tp_call */
2214 (reprfunc)delta_str, /* tp_str */
2215 PyObject_GenericGetAttr, /* tp_getattro */
2216 0, /* tp_setattro */
2217 0, /* tp_as_buffer */
2218 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2219 Py_TPFLAGS_BASETYPE, /* tp_flags */
2220 delta_doc, /* tp_doc */
2221 0, /* tp_traverse */
2222 0, /* tp_clear */
2223 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2224 0, /* tp_weaklistoffset */
2225 0, /* tp_iter */
2226 0, /* tp_iternext */
2227 delta_methods, /* tp_methods */
2228 delta_members, /* tp_members */
2229 0, /* tp_getset */
2230 0, /* tp_base */
2231 0, /* tp_dict */
2232 0, /* tp_descr_get */
2233 0, /* tp_descr_set */
2234 0, /* tp_dictoffset */
2235 0, /* tp_init */
2236 0, /* tp_alloc */
2237 delta_new, /* tp_new */
2238 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002239};
2240
2241/*
2242 * PyDateTime_Date implementation.
2243 */
2244
2245/* Accessor properties. */
2246
2247static PyObject *
2248date_year(PyDateTime_Date *self, void *unused)
2249{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002250 return PyInt_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002251}
2252
2253static PyObject *
2254date_month(PyDateTime_Date *self, void *unused)
2255{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002256 return PyInt_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002257}
2258
2259static PyObject *
2260date_day(PyDateTime_Date *self, void *unused)
2261{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002262 return PyInt_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002263}
2264
2265static PyGetSetDef date_getset[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002266 {"year", (getter)date_year},
2267 {"month", (getter)date_month},
2268 {"day", (getter)date_day},
2269 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002270};
2271
2272/* Constructors. */
2273
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002274static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002275
Tim Peters2a799bf2002-12-16 20:18:38 +00002276static PyObject *
2277date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2278{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002279 PyObject *self = NULL;
2280 PyObject *state;
2281 int year;
2282 int month;
2283 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002284
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002285 /* Check for invocation from pickle with __getstate__ state */
2286 if (PyTuple_GET_SIZE(args) == 1 &&
2287 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2288 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2289 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
2290 {
2291 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002292
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002293 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2294 if (me != NULL) {
2295 char *pdata = PyString_AS_STRING(state);
2296 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2297 me->hashcode = -1;
2298 }
2299 return (PyObject *)me;
2300 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002301
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002302 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2303 &year, &month, &day)) {
2304 if (check_date_args(year, month, day) < 0)
2305 return NULL;
2306 self = new_date_ex(year, month, day, type);
2307 }
2308 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002309}
2310
2311/* Return new date from localtime(t). */
2312static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002313date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002314{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002315 struct tm *tm;
2316 time_t t;
2317 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002318
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002319 t = _PyTime_DoubleToTimet(ts);
2320 if (t == (time_t)-1 && PyErr_Occurred())
2321 return NULL;
2322 tm = localtime(&t);
2323 if (tm)
2324 result = PyObject_CallFunction(cls, "iii",
2325 tm->tm_year + 1900,
2326 tm->tm_mon + 1,
2327 tm->tm_mday);
2328 else
2329 PyErr_SetString(PyExc_ValueError,
2330 "timestamp out of range for "
2331 "platform localtime() function");
2332 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002333}
2334
2335/* Return new date from current time.
2336 * We say this is equivalent to fromtimestamp(time.time()), and the
2337 * only way to be sure of that is to *call* time.time(). That's not
2338 * generally the same as calling C's time.
2339 */
2340static PyObject *
2341date_today(PyObject *cls, PyObject *dummy)
2342{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002343 PyObject *time;
2344 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002345
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002346 time = time_time();
2347 if (time == NULL)
2348 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002349
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002350 /* Note well: today() is a class method, so this may not call
2351 * date.fromtimestamp. For example, it may call
2352 * datetime.fromtimestamp. That's why we need all the accuracy
2353 * time.time() delivers; if someone were gonzo about optimization,
2354 * date.today() could get away with plain C time().
2355 */
2356 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2357 Py_DECREF(time);
2358 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002359}
2360
2361/* Return new date from given timestamp (Python timestamp -- a double). */
2362static PyObject *
2363date_fromtimestamp(PyObject *cls, PyObject *args)
2364{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002365 double timestamp;
2366 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002367
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002368 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2369 result = date_local_from_time_t(cls, timestamp);
2370 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002371}
2372
2373/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2374 * the ordinal is out of range.
2375 */
2376static PyObject *
2377date_fromordinal(PyObject *cls, PyObject *args)
2378{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002379 PyObject *result = NULL;
2380 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002381
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002382 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2383 int year;
2384 int month;
2385 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002386
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002387 if (ordinal < 1)
2388 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2389 ">= 1");
2390 else {
2391 ord_to_ymd(ordinal, &year, &month, &day);
2392 result = PyObject_CallFunction(cls, "iii",
2393 year, month, day);
2394 }
2395 }
2396 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002397}
2398
2399/*
2400 * Date arithmetic.
2401 */
2402
2403/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2404 * instead.
2405 */
2406static PyObject *
2407add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2408{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002409 PyObject *result = NULL;
2410 int year = GET_YEAR(date);
2411 int month = GET_MONTH(date);
2412 int deltadays = GET_TD_DAYS(delta);
2413 /* C-level overflow is impossible because |deltadays| < 1e9. */
2414 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002415
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002416 if (normalize_date(&year, &month, &day) >= 0)
2417 result = new_date(year, month, day);
2418 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002419}
2420
2421static PyObject *
2422date_add(PyObject *left, PyObject *right)
2423{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002424 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2425 Py_INCREF(Py_NotImplemented);
2426 return Py_NotImplemented;
2427 }
2428 if (PyDate_Check(left)) {
2429 /* date + ??? */
2430 if (PyDelta_Check(right))
2431 /* date + delta */
2432 return add_date_timedelta((PyDateTime_Date *) left,
2433 (PyDateTime_Delta *) right,
2434 0);
2435 }
2436 else {
2437 /* ??? + date
2438 * 'right' must be one of us, or we wouldn't have been called
2439 */
2440 if (PyDelta_Check(left))
2441 /* delta + date */
2442 return add_date_timedelta((PyDateTime_Date *) right,
2443 (PyDateTime_Delta *) left,
2444 0);
2445 }
2446 Py_INCREF(Py_NotImplemented);
2447 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002448}
2449
2450static PyObject *
2451date_subtract(PyObject *left, PyObject *right)
2452{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002453 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2454 Py_INCREF(Py_NotImplemented);
2455 return Py_NotImplemented;
2456 }
2457 if (PyDate_Check(left)) {
2458 if (PyDate_Check(right)) {
2459 /* date - date */
2460 int left_ord = ymd_to_ord(GET_YEAR(left),
2461 GET_MONTH(left),
2462 GET_DAY(left));
2463 int right_ord = ymd_to_ord(GET_YEAR(right),
2464 GET_MONTH(right),
2465 GET_DAY(right));
2466 return new_delta(left_ord - right_ord, 0, 0, 0);
2467 }
2468 if (PyDelta_Check(right)) {
2469 /* date - delta */
2470 return add_date_timedelta((PyDateTime_Date *) left,
2471 (PyDateTime_Delta *) right,
2472 1);
2473 }
2474 }
2475 Py_INCREF(Py_NotImplemented);
2476 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002477}
2478
2479
2480/* Various ways to turn a date into a string. */
2481
2482static PyObject *
2483date_repr(PyDateTime_Date *self)
2484{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002485 char buffer[1028];
2486 const char *type_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002487
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002488 type_name = Py_TYPE(self)->tp_name;
2489 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2490 type_name,
2491 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002492
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002493 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002494}
2495
2496static PyObject *
2497date_isoformat(PyDateTime_Date *self)
2498{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002499 char buffer[128];
Tim Peters2a799bf2002-12-16 20:18:38 +00002500
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002501 isoformat_date(self, buffer, sizeof(buffer));
2502 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002503}
2504
Tim Peterse2df5ff2003-05-02 18:39:55 +00002505/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002506static PyObject *
2507date_str(PyDateTime_Date *self)
2508{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002509 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002510}
2511
2512
2513static PyObject *
2514date_ctime(PyDateTime_Date *self)
2515{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002516 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002517}
2518
2519static PyObject *
2520date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2521{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002522 /* This method can be inherited, and needs to call the
2523 * timetuple() method appropriate to self's class.
2524 */
2525 PyObject *result;
2526 PyObject *tuple;
2527 const char *format;
2528 Py_ssize_t format_len;
2529 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002530
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002531 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2532 &format, &format_len))
2533 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002534
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002535 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2536 if (tuple == NULL)
2537 return NULL;
2538 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
2539 (PyObject *)self);
2540 Py_DECREF(tuple);
2541 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002542}
2543
Eric Smitha9f7d622008-02-17 19:46:49 +00002544static PyObject *
2545date_format(PyDateTime_Date *self, PyObject *args)
2546{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002547 PyObject *format;
Eric Smitha9f7d622008-02-17 19:46:49 +00002548
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002549 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2550 return NULL;
Eric Smitha9f7d622008-02-17 19:46:49 +00002551
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002552 /* Check for str or unicode */
2553 if (PyString_Check(format)) {
2554 /* If format is zero length, return str(self) */
2555 if (PyString_GET_SIZE(format) == 0)
2556 return PyObject_Str((PyObject *)self);
2557 } else if (PyUnicode_Check(format)) {
2558 /* If format is zero length, return str(self) */
2559 if (PyUnicode_GET_SIZE(format) == 0)
2560 return PyObject_Unicode((PyObject *)self);
2561 } else {
2562 PyErr_Format(PyExc_ValueError,
2563 "__format__ expects str or unicode, not %.200s",
2564 Py_TYPE(format)->tp_name);
2565 return NULL;
2566 }
2567 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smitha9f7d622008-02-17 19:46:49 +00002568}
2569
Tim Peters2a799bf2002-12-16 20:18:38 +00002570/* ISO methods. */
2571
2572static PyObject *
2573date_isoweekday(PyDateTime_Date *self)
2574{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002575 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002576
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002577 return PyInt_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002578}
2579
2580static PyObject *
2581date_isocalendar(PyDateTime_Date *self)
2582{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002583 int year = GET_YEAR(self);
2584 int week1_monday = iso_week1_monday(year);
2585 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2586 int week;
2587 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002588
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002589 week = divmod(today - week1_monday, 7, &day);
2590 if (week < 0) {
2591 --year;
2592 week1_monday = iso_week1_monday(year);
2593 week = divmod(today - week1_monday, 7, &day);
2594 }
2595 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2596 ++year;
2597 week = 0;
2598 }
2599 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002600}
2601
2602/* Miscellaneous methods. */
2603
2604/* This is more natural as a tp_compare, but doesn't work then: for whatever
2605 * reason, Python's try_3way_compare ignores tp_compare unless
2606 * PyInstance_Check returns true, but these aren't old-style classes.
2607 */
2608static PyObject *
2609date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2610{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002611 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002612
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002613 if (PyDate_Check(other))
2614 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2615 _PyDateTime_DATE_DATASIZE);
Tim Peters07534a62003-02-07 22:50:28 +00002616
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002617 else if (PyObject_HasAttrString(other, "timetuple")) {
2618 /* A hook for other kinds of date objects. */
2619 Py_INCREF(Py_NotImplemented);
2620 return Py_NotImplemented;
2621 }
2622 else if (op == Py_EQ || op == Py_NE)
2623 diff = 1; /* any non-zero value will do */
Tim Peters07534a62003-02-07 22:50:28 +00002624
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002625 else /* stop this from falling back to address comparison */
2626 return cmperror((PyObject *)self, other);
Tim Peters07534a62003-02-07 22:50:28 +00002627
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002628 return diff_to_bool(diff, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00002629}
2630
2631static PyObject *
2632date_timetuple(PyDateTime_Date *self)
2633{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002634 return build_struct_time(GET_YEAR(self),
2635 GET_MONTH(self),
2636 GET_DAY(self),
2637 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002638}
2639
Tim Peters12bf3392002-12-24 05:41:27 +00002640static PyObject *
2641date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2642{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002643 PyObject *clone;
2644 PyObject *tuple;
2645 int year = GET_YEAR(self);
2646 int month = GET_MONTH(self);
2647 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002648
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002649 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2650 &year, &month, &day))
2651 return NULL;
2652 tuple = Py_BuildValue("iii", year, month, day);
2653 if (tuple == NULL)
2654 return NULL;
2655 clone = date_new(Py_TYPE(self), tuple, NULL);
2656 Py_DECREF(tuple);
2657 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002658}
2659
Tim Peters2a799bf2002-12-16 20:18:38 +00002660static PyObject *date_getstate(PyDateTime_Date *self);
2661
2662static long
2663date_hash(PyDateTime_Date *self)
2664{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002665 if (self->hashcode == -1) {
2666 PyObject *temp = date_getstate(self);
2667 if (temp != NULL) {
2668 self->hashcode = PyObject_Hash(temp);
2669 Py_DECREF(temp);
2670 }
2671 }
2672 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002673}
2674
2675static PyObject *
2676date_toordinal(PyDateTime_Date *self)
2677{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002678 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2679 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002680}
2681
2682static PyObject *
2683date_weekday(PyDateTime_Date *self)
2684{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002685 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002686
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002687 return PyInt_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002688}
2689
Tim Peters371935f2003-02-01 01:52:50 +00002690/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002691
Tim Petersb57f8f02003-02-01 02:54:15 +00002692/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002693static PyObject *
2694date_getstate(PyDateTime_Date *self)
2695{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002696 return Py_BuildValue(
2697 "(N)",
2698 PyString_FromStringAndSize((char *)self->data,
2699 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002700}
2701
2702static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002703date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002704{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002705 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002706}
2707
2708static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002709
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002710 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002711
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002712 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2713 METH_CLASS,
2714 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2715 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002716
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002717 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2718 METH_CLASS,
2719 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2720 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002721
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002722 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2723 PyDoc_STR("Current date or datetime: same as "
2724 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002725
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002726 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002727
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002728 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2729 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002730
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002731 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2732 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002733
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002734 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2735 PyDoc_STR("Formats self with strftime.")},
Eric Smitha9f7d622008-02-17 19:46:49 +00002736
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002737 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2738 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002739
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002740 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2741 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2742 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002743
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002744 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2745 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002746
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002747 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2748 PyDoc_STR("Return the day of the week represented by the date.\n"
2749 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002750
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002751 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2752 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2753 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002754
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002755 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2756 PyDoc_STR("Return the day of the week represented by the date.\n"
2757 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002758
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002759 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2760 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002761
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002762 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2763 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002764
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002765 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002766};
2767
2768static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002769PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002770
2771static PyNumberMethods date_as_number = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002772 date_add, /* nb_add */
2773 date_subtract, /* nb_subtract */
2774 0, /* nb_multiply */
2775 0, /* nb_divide */
2776 0, /* nb_remainder */
2777 0, /* nb_divmod */
2778 0, /* nb_power */
2779 0, /* nb_negative */
2780 0, /* nb_positive */
2781 0, /* nb_absolute */
2782 0, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00002783};
2784
2785static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002786 PyVarObject_HEAD_INIT(NULL, 0)
2787 "datetime.date", /* tp_name */
2788 sizeof(PyDateTime_Date), /* tp_basicsize */
2789 0, /* tp_itemsize */
2790 0, /* tp_dealloc */
2791 0, /* tp_print */
2792 0, /* tp_getattr */
2793 0, /* tp_setattr */
2794 0, /* tp_compare */
2795 (reprfunc)date_repr, /* tp_repr */
2796 &date_as_number, /* tp_as_number */
2797 0, /* tp_as_sequence */
2798 0, /* tp_as_mapping */
2799 (hashfunc)date_hash, /* tp_hash */
2800 0, /* tp_call */
2801 (reprfunc)date_str, /* tp_str */
2802 PyObject_GenericGetAttr, /* tp_getattro */
2803 0, /* tp_setattro */
2804 0, /* tp_as_buffer */
2805 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2806 Py_TPFLAGS_BASETYPE, /* tp_flags */
2807 date_doc, /* tp_doc */
2808 0, /* tp_traverse */
2809 0, /* tp_clear */
2810 (richcmpfunc)date_richcompare, /* tp_richcompare */
2811 0, /* tp_weaklistoffset */
2812 0, /* tp_iter */
2813 0, /* tp_iternext */
2814 date_methods, /* tp_methods */
2815 0, /* tp_members */
2816 date_getset, /* tp_getset */
2817 0, /* tp_base */
2818 0, /* tp_dict */
2819 0, /* tp_descr_get */
2820 0, /* tp_descr_set */
2821 0, /* tp_dictoffset */
2822 0, /* tp_init */
2823 0, /* tp_alloc */
2824 date_new, /* tp_new */
2825 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002826};
2827
2828/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002829 * PyDateTime_TZInfo implementation.
2830 */
2831
2832/* This is a pure abstract base class, so doesn't do anything beyond
2833 * raising NotImplemented exceptions. Real tzinfo classes need
2834 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002835 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002836 * be subclasses of this tzinfo class, which is easy and quick to check).
2837 *
2838 * Note: For reasons having to do with pickling of subclasses, we have
2839 * to allow tzinfo objects to be instantiated. This wasn't an issue
2840 * in the Python implementation (__init__() could raise NotImplementedError
2841 * there without ill effect), but doing so in the C implementation hit a
2842 * brick wall.
2843 */
2844
2845static PyObject *
2846tzinfo_nogo(const char* methodname)
2847{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002848 PyErr_Format(PyExc_NotImplementedError,
2849 "a tzinfo subclass must implement %s()",
2850 methodname);
2851 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002852}
2853
2854/* Methods. A subclass must implement these. */
2855
Tim Peters52dcce22003-01-23 16:36:11 +00002856static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002857tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2858{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002859 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002860}
2861
Tim Peters52dcce22003-01-23 16:36:11 +00002862static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002863tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2864{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002865 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002866}
2867
Tim Peters52dcce22003-01-23 16:36:11 +00002868static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002869tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2870{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002871 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002872}
2873
Tim Peters52dcce22003-01-23 16:36:11 +00002874static PyObject *
2875tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2876{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002877 int y, m, d, hh, mm, ss, us;
Tim Peters52dcce22003-01-23 16:36:11 +00002878
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002879 PyObject *result;
2880 int off, dst;
2881 int none;
2882 int delta;
Tim Peters52dcce22003-01-23 16:36:11 +00002883
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002884 if (! PyDateTime_Check(dt)) {
2885 PyErr_SetString(PyExc_TypeError,
2886 "fromutc: argument must be a datetime");
2887 return NULL;
2888 }
2889 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2890 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2891 "is not self");
2892 return NULL;
2893 }
Tim Peters52dcce22003-01-23 16:36:11 +00002894
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002895 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2896 if (off == -1 && PyErr_Occurred())
2897 return NULL;
2898 if (none) {
2899 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2900 "utcoffset() result required");
2901 return NULL;
2902 }
Tim Peters52dcce22003-01-23 16:36:11 +00002903
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002904 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2905 if (dst == -1 && PyErr_Occurred())
2906 return NULL;
2907 if (none) {
2908 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2909 "dst() result required");
2910 return NULL;
2911 }
Tim Peters52dcce22003-01-23 16:36:11 +00002912
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002913 y = GET_YEAR(dt);
2914 m = GET_MONTH(dt);
2915 d = GET_DAY(dt);
2916 hh = DATE_GET_HOUR(dt);
2917 mm = DATE_GET_MINUTE(dt);
2918 ss = DATE_GET_SECOND(dt);
2919 us = DATE_GET_MICROSECOND(dt);
Tim Peters52dcce22003-01-23 16:36:11 +00002920
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002921 delta = off - dst;
2922 mm += delta;
2923 if ((mm < 0 || mm >= 60) &&
2924 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2925 return NULL;
2926 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2927 if (result == NULL)
2928 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002929
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002930 dst = call_dst(dt->tzinfo, result, &none);
2931 if (dst == -1 && PyErr_Occurred())
2932 goto Fail;
2933 if (none)
2934 goto Inconsistent;
2935 if (dst == 0)
2936 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002937
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002938 mm += dst;
2939 if ((mm < 0 || mm >= 60) &&
2940 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2941 goto Fail;
2942 Py_DECREF(result);
2943 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2944 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002945
2946Inconsistent:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002947 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2948 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00002949
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002950 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00002951Fail:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002952 Py_DECREF(result);
2953 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002954}
2955
Tim Peters2a799bf2002-12-16 20:18:38 +00002956/*
2957 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002958 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002959 */
2960
Guido van Rossum177e41a2003-01-30 22:06:23 +00002961static PyObject *
2962tzinfo_reduce(PyObject *self)
2963{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002964 PyObject *args, *state, *tmp;
2965 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002966
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002967 tmp = PyTuple_New(0);
2968 if (tmp == NULL)
2969 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002970
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002971 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2972 if (getinitargs != NULL) {
2973 args = PyObject_CallObject(getinitargs, tmp);
2974 Py_DECREF(getinitargs);
2975 if (args == NULL) {
2976 Py_DECREF(tmp);
2977 return NULL;
2978 }
2979 }
2980 else {
2981 PyErr_Clear();
2982 args = tmp;
2983 Py_INCREF(args);
2984 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002985
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002986 getstate = PyObject_GetAttrString(self, "__getstate__");
2987 if (getstate != NULL) {
2988 state = PyObject_CallObject(getstate, tmp);
2989 Py_DECREF(getstate);
2990 if (state == NULL) {
2991 Py_DECREF(args);
2992 Py_DECREF(tmp);
2993 return NULL;
2994 }
2995 }
2996 else {
2997 PyObject **dictptr;
2998 PyErr_Clear();
2999 state = Py_None;
3000 dictptr = _PyObject_GetDictPtr(self);
3001 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3002 state = *dictptr;
3003 Py_INCREF(state);
3004 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003005
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003006 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003007
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003008 if (state == Py_None) {
3009 Py_DECREF(state);
3010 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3011 }
3012 else
3013 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003014}
Tim Peters2a799bf2002-12-16 20:18:38 +00003015
3016static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003017
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003018 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3019 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003020
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003021 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
3022 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3023 "west of UTC).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003024
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003025 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3026 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003027
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003028 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Sean Reifscheider5e2b27b2010-06-04 01:51:26 +00003029 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3030 "values indicating West of UTC")},
Tim Peters52dcce22003-01-23 16:36:11 +00003031
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003032 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3033 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003034
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003035 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003036};
3037
3038static char tzinfo_doc[] =
3039PyDoc_STR("Abstract base class for time zone info objects.");
3040
Neal Norwitzce3d34d2003-02-04 20:45:17 +00003041statichere PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003042 PyObject_HEAD_INIT(NULL)
3043 0, /* ob_size */
3044 "datetime.tzinfo", /* tp_name */
3045 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3046 0, /* tp_itemsize */
3047 0, /* tp_dealloc */
3048 0, /* tp_print */
3049 0, /* tp_getattr */
3050 0, /* tp_setattr */
3051 0, /* tp_compare */
3052 0, /* tp_repr */
3053 0, /* tp_as_number */
3054 0, /* tp_as_sequence */
3055 0, /* tp_as_mapping */
3056 0, /* tp_hash */
3057 0, /* tp_call */
3058 0, /* tp_str */
3059 PyObject_GenericGetAttr, /* tp_getattro */
3060 0, /* tp_setattro */
3061 0, /* tp_as_buffer */
3062 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3063 Py_TPFLAGS_BASETYPE, /* tp_flags */
3064 tzinfo_doc, /* tp_doc */
3065 0, /* tp_traverse */
3066 0, /* tp_clear */
3067 0, /* tp_richcompare */
3068 0, /* tp_weaklistoffset */
3069 0, /* tp_iter */
3070 0, /* tp_iternext */
3071 tzinfo_methods, /* tp_methods */
3072 0, /* tp_members */
3073 0, /* tp_getset */
3074 0, /* tp_base */
3075 0, /* tp_dict */
3076 0, /* tp_descr_get */
3077 0, /* tp_descr_set */
3078 0, /* tp_dictoffset */
3079 0, /* tp_init */
3080 0, /* tp_alloc */
3081 PyType_GenericNew, /* tp_new */
3082 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003083};
3084
3085/*
Tim Peters37f39822003-01-10 03:49:02 +00003086 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003087 */
3088
Tim Peters37f39822003-01-10 03:49:02 +00003089/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003090 */
3091
3092static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003093time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003094{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003095 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003096}
3097
Tim Peters37f39822003-01-10 03:49:02 +00003098static PyObject *
3099time_minute(PyDateTime_Time *self, void *unused)
3100{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003101 return PyInt_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003102}
3103
3104/* The name time_second conflicted with some platform header file. */
3105static PyObject *
3106py_time_second(PyDateTime_Time *self, void *unused)
3107{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003108 return PyInt_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003109}
3110
3111static PyObject *
3112time_microsecond(PyDateTime_Time *self, void *unused)
3113{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003114 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003115}
3116
3117static PyObject *
3118time_tzinfo(PyDateTime_Time *self, void *unused)
3119{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003120 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3121 Py_INCREF(result);
3122 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003123}
3124
3125static PyGetSetDef time_getset[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003126 {"hour", (getter)time_hour},
3127 {"minute", (getter)time_minute},
3128 {"second", (getter)py_time_second},
3129 {"microsecond", (getter)time_microsecond},
3130 {"tzinfo", (getter)time_tzinfo},
3131 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003132};
3133
3134/*
3135 * Constructors.
3136 */
3137
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003138static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003139 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003140
Tim Peters2a799bf2002-12-16 20:18:38 +00003141static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003142time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003143{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003144 PyObject *self = NULL;
3145 PyObject *state;
3146 int hour = 0;
3147 int minute = 0;
3148 int second = 0;
3149 int usecond = 0;
3150 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003151
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003152 /* Check for invocation from pickle with __getstate__ state */
3153 if (PyTuple_GET_SIZE(args) >= 1 &&
3154 PyTuple_GET_SIZE(args) <= 2 &&
3155 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3156 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3157 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
3158 {
3159 PyDateTime_Time *me;
3160 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003161
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003162 if (PyTuple_GET_SIZE(args) == 2) {
3163 tzinfo = PyTuple_GET_ITEM(args, 1);
3164 if (check_tzinfo_subclass(tzinfo) < 0) {
3165 PyErr_SetString(PyExc_TypeError, "bad "
3166 "tzinfo state arg");
3167 return NULL;
3168 }
3169 }
3170 aware = (char)(tzinfo != Py_None);
3171 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3172 if (me != NULL) {
3173 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003174
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003175 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3176 me->hashcode = -1;
3177 me->hastzinfo = aware;
3178 if (aware) {
3179 Py_INCREF(tzinfo);
3180 me->tzinfo = tzinfo;
3181 }
3182 }
3183 return (PyObject *)me;
3184 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003185
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003186 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3187 &hour, &minute, &second, &usecond,
3188 &tzinfo)) {
3189 if (check_time_args(hour, minute, second, usecond) < 0)
3190 return NULL;
3191 if (check_tzinfo_subclass(tzinfo) < 0)
3192 return NULL;
3193 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3194 type);
3195 }
3196 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003197}
3198
3199/*
3200 * Destructor.
3201 */
3202
3203static void
Tim Peters37f39822003-01-10 03:49:02 +00003204time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003205{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003206 if (HASTZINFO(self)) {
3207 Py_XDECREF(self->tzinfo);
3208 }
3209 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003210}
3211
3212/*
Tim Peters855fe882002-12-22 03:43:39 +00003213 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003214 */
3215
Tim Peters2a799bf2002-12-16 20:18:38 +00003216/* These are all METH_NOARGS, so don't need to check the arglist. */
3217static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003218time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003219 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3220 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003221}
3222
3223static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003224time_dst(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003225 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3226 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003227}
3228
3229static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003230time_tzname(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003231 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3232 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003233}
3234
3235/*
Tim Peters37f39822003-01-10 03:49:02 +00003236 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003237 */
3238
3239static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003240time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003241{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003242 char buffer[100];
3243 const char *type_name = Py_TYPE(self)->tp_name;
3244 int h = TIME_GET_HOUR(self);
3245 int m = TIME_GET_MINUTE(self);
3246 int s = TIME_GET_SECOND(self);
3247 int us = TIME_GET_MICROSECOND(self);
3248 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003249
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003250 if (us)
3251 PyOS_snprintf(buffer, sizeof(buffer),
3252 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
3253 else if (s)
3254 PyOS_snprintf(buffer, sizeof(buffer),
3255 "%s(%d, %d, %d)", type_name, h, m, s);
3256 else
3257 PyOS_snprintf(buffer, sizeof(buffer),
3258 "%s(%d, %d)", type_name, h, m);
3259 result = PyString_FromString(buffer);
3260 if (result != NULL && HASTZINFO(self))
3261 result = append_keyword_tzinfo(result, self->tzinfo);
3262 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003263}
3264
Tim Peters37f39822003-01-10 03:49:02 +00003265static PyObject *
3266time_str(PyDateTime_Time *self)
3267{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003268 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003269}
Tim Peters2a799bf2002-12-16 20:18:38 +00003270
3271static PyObject *
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003272time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003273{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003274 char buf[100];
3275 PyObject *result;
3276 /* Reuse the time format code from the datetime type. */
3277 PyDateTime_DateTime datetime;
3278 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003279
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003280 /* Copy over just the time bytes. */
3281 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3282 self->data,
3283 _PyDateTime_TIME_DATASIZE);
Tim Peters37f39822003-01-10 03:49:02 +00003284
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003285 isoformat_time(pdatetime, buf, sizeof(buf));
3286 result = PyString_FromString(buf);
3287 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3288 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003289
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003290 /* We need to append the UTC offset. */
3291 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3292 Py_None) < 0) {
3293 Py_DECREF(result);
3294 return NULL;
3295 }
3296 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3297 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003298}
3299
Tim Peters37f39822003-01-10 03:49:02 +00003300static PyObject *
3301time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3302{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003303 PyObject *result;
3304 PyObject *tuple;
3305 const char *format;
3306 Py_ssize_t format_len;
3307 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003308
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003309 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3310 &format, &format_len))
3311 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003312
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003313 /* Python's strftime does insane things with the year part of the
3314 * timetuple. The year is forced to (the otherwise nonsensical)
3315 * 1900 to worm around that.
3316 */
3317 tuple = Py_BuildValue("iiiiiiiii",
3318 1900, 1, 1, /* year, month, day */
3319 TIME_GET_HOUR(self),
3320 TIME_GET_MINUTE(self),
3321 TIME_GET_SECOND(self),
3322 0, 1, -1); /* weekday, daynum, dst */
3323 if (tuple == NULL)
3324 return NULL;
3325 assert(PyTuple_Size(tuple) == 9);
3326 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3327 Py_None);
3328 Py_DECREF(tuple);
3329 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003330}
Tim Peters2a799bf2002-12-16 20:18:38 +00003331
3332/*
3333 * Miscellaneous methods.
3334 */
3335
Tim Peters37f39822003-01-10 03:49:02 +00003336/* This is more natural as a tp_compare, but doesn't work then: for whatever
3337 * reason, Python's try_3way_compare ignores tp_compare unless
3338 * PyInstance_Check returns true, but these aren't old-style classes.
3339 */
3340static PyObject *
3341time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3342{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003343 int diff;
3344 naivety n1, n2;
3345 int offset1, offset2;
Tim Peters37f39822003-01-10 03:49:02 +00003346
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003347 if (! PyTime_Check(other)) {
3348 if (op == Py_EQ || op == Py_NE) {
3349 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3350 Py_INCREF(result);
3351 return result;
3352 }
3353 /* Stop this from falling back to address comparison. */
3354 return cmperror((PyObject *)self, other);
3355 }
3356 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3357 other, &offset2, &n2, Py_None) < 0)
3358 return NULL;
3359 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3360 /* If they're both naive, or both aware and have the same offsets,
3361 * we get off cheap. Note that if they're both naive, offset1 ==
3362 * offset2 == 0 at this point.
3363 */
3364 if (n1 == n2 && offset1 == offset2) {
3365 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3366 _PyDateTime_TIME_DATASIZE);
3367 return diff_to_bool(diff, op);
3368 }
Tim Peters37f39822003-01-10 03:49:02 +00003369
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003370 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3371 assert(offset1 != offset2); /* else last "if" handled it */
3372 /* Convert everything except microseconds to seconds. These
3373 * can't overflow (no more than the # of seconds in 2 days).
3374 */
3375 offset1 = TIME_GET_HOUR(self) * 3600 +
3376 (TIME_GET_MINUTE(self) - offset1) * 60 +
3377 TIME_GET_SECOND(self);
3378 offset2 = TIME_GET_HOUR(other) * 3600 +
3379 (TIME_GET_MINUTE(other) - offset2) * 60 +
3380 TIME_GET_SECOND(other);
3381 diff = offset1 - offset2;
3382 if (diff == 0)
3383 diff = TIME_GET_MICROSECOND(self) -
3384 TIME_GET_MICROSECOND(other);
3385 return diff_to_bool(diff, op);
3386 }
Tim Peters37f39822003-01-10 03:49:02 +00003387
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003388 assert(n1 != n2);
3389 PyErr_SetString(PyExc_TypeError,
3390 "can't compare offset-naive and "
3391 "offset-aware times");
3392 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003393}
3394
3395static long
3396time_hash(PyDateTime_Time *self)
3397{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003398 if (self->hashcode == -1) {
3399 naivety n;
3400 int offset;
3401 PyObject *temp;
Tim Peters37f39822003-01-10 03:49:02 +00003402
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003403 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3404 assert(n != OFFSET_UNKNOWN);
3405 if (n == OFFSET_ERROR)
3406 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003407
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003408 /* Reduce this to a hash of another object. */
3409 if (offset == 0)
3410 temp = PyString_FromStringAndSize((char *)self->data,
3411 _PyDateTime_TIME_DATASIZE);
3412 else {
3413 int hour;
3414 int minute;
Tim Peters37f39822003-01-10 03:49:02 +00003415
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003416 assert(n == OFFSET_AWARE);
3417 assert(HASTZINFO(self));
3418 hour = divmod(TIME_GET_HOUR(self) * 60 +
3419 TIME_GET_MINUTE(self) - offset,
3420 60,
3421 &minute);
3422 if (0 <= hour && hour < 24)
3423 temp = new_time(hour, minute,
3424 TIME_GET_SECOND(self),
3425 TIME_GET_MICROSECOND(self),
3426 Py_None);
3427 else
3428 temp = Py_BuildValue("iiii",
3429 hour, minute,
3430 TIME_GET_SECOND(self),
3431 TIME_GET_MICROSECOND(self));
3432 }
3433 if (temp != NULL) {
3434 self->hashcode = PyObject_Hash(temp);
3435 Py_DECREF(temp);
3436 }
3437 }
3438 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003439}
Tim Peters2a799bf2002-12-16 20:18:38 +00003440
Tim Peters12bf3392002-12-24 05:41:27 +00003441static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003442time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003443{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003444 PyObject *clone;
3445 PyObject *tuple;
3446 int hh = TIME_GET_HOUR(self);
3447 int mm = TIME_GET_MINUTE(self);
3448 int ss = TIME_GET_SECOND(self);
3449 int us = TIME_GET_MICROSECOND(self);
3450 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003451
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003452 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3453 time_kws,
3454 &hh, &mm, &ss, &us, &tzinfo))
3455 return NULL;
3456 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3457 if (tuple == NULL)
3458 return NULL;
3459 clone = time_new(Py_TYPE(self), tuple, NULL);
3460 Py_DECREF(tuple);
3461 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003462}
3463
Tim Peters2a799bf2002-12-16 20:18:38 +00003464static int
Tim Peters37f39822003-01-10 03:49:02 +00003465time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003466{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003467 int offset;
3468 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00003469
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003470 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3471 /* Since utcoffset is in whole minutes, nothing can
3472 * alter the conclusion that this is nonzero.
3473 */
3474 return 1;
3475 }
3476 offset = 0;
3477 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3478 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3479 if (offset == -1 && PyErr_Occurred())
3480 return -1;
3481 }
3482 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003483}
3484
Tim Peters371935f2003-02-01 01:52:50 +00003485/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003486
Tim Peters33e0f382003-01-10 02:05:14 +00003487/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003488 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3489 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003490 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003491 */
3492static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003493time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003494{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003495 PyObject *basestate;
3496 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003497
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003498 basestate = PyString_FromStringAndSize((char *)self->data,
3499 _PyDateTime_TIME_DATASIZE);
3500 if (basestate != NULL) {
3501 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3502 result = PyTuple_Pack(1, basestate);
3503 else
3504 result = PyTuple_Pack(2, basestate, self->tzinfo);
3505 Py_DECREF(basestate);
3506 }
3507 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003508}
3509
3510static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003511time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003512{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003513 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003514}
3515
Tim Peters37f39822003-01-10 03:49:02 +00003516static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003517
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003518 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3519 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3520 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003521
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003522 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3523 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003524
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003525 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3526 PyDoc_STR("Formats self with strftime.")},
Eric Smitha9f7d622008-02-17 19:46:49 +00003527
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003528 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3529 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003530
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003531 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3532 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003533
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003534 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3535 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003536
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003537 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3538 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003539
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003540 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3541 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003542
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003543 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003544};
3545
Tim Peters37f39822003-01-10 03:49:02 +00003546static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003547PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3548\n\
3549All arguments are optional. tzinfo may be None, or an instance of\n\
3550a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003551
Tim Peters37f39822003-01-10 03:49:02 +00003552static PyNumberMethods time_as_number = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003553 0, /* nb_add */
3554 0, /* nb_subtract */
3555 0, /* nb_multiply */
3556 0, /* nb_divide */
3557 0, /* nb_remainder */
3558 0, /* nb_divmod */
3559 0, /* nb_power */
3560 0, /* nb_negative */
3561 0, /* nb_positive */
3562 0, /* nb_absolute */
3563 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003564};
3565
Tim Peters37f39822003-01-10 03:49:02 +00003566statichere PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003567 PyObject_HEAD_INIT(NULL)
3568 0, /* ob_size */
3569 "datetime.time", /* tp_name */
3570 sizeof(PyDateTime_Time), /* tp_basicsize */
3571 0, /* tp_itemsize */
3572 (destructor)time_dealloc, /* tp_dealloc */
3573 0, /* tp_print */
3574 0, /* tp_getattr */
3575 0, /* tp_setattr */
3576 0, /* tp_compare */
3577 (reprfunc)time_repr, /* tp_repr */
3578 &time_as_number, /* tp_as_number */
3579 0, /* tp_as_sequence */
3580 0, /* tp_as_mapping */
3581 (hashfunc)time_hash, /* tp_hash */
3582 0, /* tp_call */
3583 (reprfunc)time_str, /* tp_str */
3584 PyObject_GenericGetAttr, /* tp_getattro */
3585 0, /* tp_setattro */
3586 0, /* tp_as_buffer */
3587 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3588 Py_TPFLAGS_BASETYPE, /* tp_flags */
3589 time_doc, /* tp_doc */
3590 0, /* tp_traverse */
3591 0, /* tp_clear */
3592 (richcmpfunc)time_richcompare, /* tp_richcompare */
3593 0, /* tp_weaklistoffset */
3594 0, /* tp_iter */
3595 0, /* tp_iternext */
3596 time_methods, /* tp_methods */
3597 0, /* tp_members */
3598 time_getset, /* tp_getset */
3599 0, /* tp_base */
3600 0, /* tp_dict */
3601 0, /* tp_descr_get */
3602 0, /* tp_descr_set */
3603 0, /* tp_dictoffset */
3604 0, /* tp_init */
3605 time_alloc, /* tp_alloc */
3606 time_new, /* tp_new */
3607 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003608};
3609
3610/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003611 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003612 */
3613
Tim Petersa9bc1682003-01-11 03:39:11 +00003614/* Accessor properties. Properties for day, month, and year are inherited
3615 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003616 */
3617
3618static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003619datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003620{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003621 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003622}
3623
Tim Petersa9bc1682003-01-11 03:39:11 +00003624static PyObject *
3625datetime_minute(PyDateTime_DateTime *self, void *unused)
3626{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003627 return PyInt_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003628}
3629
3630static PyObject *
3631datetime_second(PyDateTime_DateTime *self, void *unused)
3632{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003633 return PyInt_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003634}
3635
3636static PyObject *
3637datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3638{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003639 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003640}
3641
3642static PyObject *
3643datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3644{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003645 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3646 Py_INCREF(result);
3647 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003648}
3649
3650static PyGetSetDef datetime_getset[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003651 {"hour", (getter)datetime_hour},
3652 {"minute", (getter)datetime_minute},
3653 {"second", (getter)datetime_second},
3654 {"microsecond", (getter)datetime_microsecond},
3655 {"tzinfo", (getter)datetime_tzinfo},
3656 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003657};
3658
3659/*
3660 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003661 */
3662
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003663static char *datetime_kws[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003664 "year", "month", "day", "hour", "minute", "second",
3665 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003666};
3667
Tim Peters2a799bf2002-12-16 20:18:38 +00003668static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003669datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003670{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003671 PyObject *self = NULL;
3672 PyObject *state;
3673 int year;
3674 int month;
3675 int day;
3676 int hour = 0;
3677 int minute = 0;
3678 int second = 0;
3679 int usecond = 0;
3680 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003681
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003682 /* Check for invocation from pickle with __getstate__ state */
3683 if (PyTuple_GET_SIZE(args) >= 1 &&
3684 PyTuple_GET_SIZE(args) <= 2 &&
3685 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3686 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3687 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
3688 {
3689 PyDateTime_DateTime *me;
3690 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003691
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003692 if (PyTuple_GET_SIZE(args) == 2) {
3693 tzinfo = PyTuple_GET_ITEM(args, 1);
3694 if (check_tzinfo_subclass(tzinfo) < 0) {
3695 PyErr_SetString(PyExc_TypeError, "bad "
3696 "tzinfo state arg");
3697 return NULL;
3698 }
3699 }
3700 aware = (char)(tzinfo != Py_None);
3701 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3702 if (me != NULL) {
3703 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003704
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003705 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3706 me->hashcode = -1;
3707 me->hastzinfo = aware;
3708 if (aware) {
3709 Py_INCREF(tzinfo);
3710 me->tzinfo = tzinfo;
3711 }
3712 }
3713 return (PyObject *)me;
3714 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003715
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003716 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3717 &year, &month, &day, &hour, &minute,
3718 &second, &usecond, &tzinfo)) {
3719 if (check_date_args(year, month, day) < 0)
3720 return NULL;
3721 if (check_time_args(hour, minute, second, usecond) < 0)
3722 return NULL;
3723 if (check_tzinfo_subclass(tzinfo) < 0)
3724 return NULL;
3725 self = new_datetime_ex(year, month, day,
3726 hour, minute, second, usecond,
3727 tzinfo, type);
3728 }
3729 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003730}
3731
Tim Petersa9bc1682003-01-11 03:39:11 +00003732/* TM_FUNC is the shared type of localtime() and gmtime(). */
3733typedef struct tm *(*TM_FUNC)(const time_t *timer);
3734
3735/* Internal helper.
3736 * Build datetime from a time_t and a distinct count of microseconds.
3737 * Pass localtime or gmtime for f, to control the interpretation of timet.
3738 */
3739static PyObject *
3740datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003741 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00003742{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003743 struct tm *tm;
3744 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003745
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003746 tm = f(&timet);
3747 if (tm) {
3748 /* The platform localtime/gmtime may insert leap seconds,
3749 * indicated by tm->tm_sec > 59. We don't care about them,
3750 * except to the extent that passing them on to the datetime
3751 * constructor would raise ValueError for a reason that
3752 * made no sense to the user.
3753 */
3754 if (tm->tm_sec > 59)
3755 tm->tm_sec = 59;
3756 result = PyObject_CallFunction(cls, "iiiiiiiO",
3757 tm->tm_year + 1900,
3758 tm->tm_mon + 1,
3759 tm->tm_mday,
3760 tm->tm_hour,
3761 tm->tm_min,
3762 tm->tm_sec,
3763 us,
3764 tzinfo);
3765 }
3766 else
3767 PyErr_SetString(PyExc_ValueError,
3768 "timestamp out of range for "
3769 "platform localtime()/gmtime() function");
3770 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003771}
3772
3773/* Internal helper.
3774 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3775 * to control the interpretation of the timestamp. Since a double doesn't
3776 * have enough bits to cover a datetime's full range of precision, it's
3777 * better to call datetime_from_timet_and_us provided you have a way
3778 * to get that much precision (e.g., C time() isn't good enough).
3779 */
3780static PyObject *
3781datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003782 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00003783{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003784 time_t timet;
3785 double fraction;
3786 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00003787
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003788 timet = _PyTime_DoubleToTimet(timestamp);
3789 if (timet == (time_t)-1 && PyErr_Occurred())
3790 return NULL;
3791 fraction = timestamp - (double)timet;
3792 us = (int)round_to_long(fraction * 1e6);
3793 if (us < 0) {
3794 /* Truncation towards zero is not what we wanted
3795 for negative numbers (Python's mod semantics) */
3796 timet -= 1;
3797 us += 1000000;
3798 }
3799 /* If timestamp is less than one microsecond smaller than a
3800 * full second, round up. Otherwise, ValueErrors are raised
3801 * for some floats. */
3802 if (us == 1000000) {
3803 timet += 1;
3804 us = 0;
3805 }
3806 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003807}
3808
3809/* Internal helper.
3810 * Build most accurate possible datetime for current time. Pass localtime or
3811 * gmtime for f as appropriate.
3812 */
3813static PyObject *
3814datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3815{
3816#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003817 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00003818
3819#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003820 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00003821#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003822 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00003823#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003824 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3825 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003826
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003827#else /* ! HAVE_GETTIMEOFDAY */
3828 /* No flavor of gettimeofday exists on this platform. Python's
3829 * time.time() does a lot of other platform tricks to get the
3830 * best time it can on the platform, and we're not going to do
3831 * better than that (if we could, the better code would belong
3832 * in time.time()!) We're limited by the precision of a double,
3833 * though.
3834 */
3835 PyObject *time;
3836 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00003837
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003838 time = time_time();
3839 if (time == NULL)
3840 return NULL;
3841 dtime = PyFloat_AsDouble(time);
3842 Py_DECREF(time);
3843 if (dtime == -1.0 && PyErr_Occurred())
3844 return NULL;
3845 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3846#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00003847}
3848
Tim Peters2a799bf2002-12-16 20:18:38 +00003849/* Return best possible local time -- this isn't constrained by the
3850 * precision of a timestamp.
3851 */
3852static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003853datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003854{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003855 PyObject *self;
3856 PyObject *tzinfo = Py_None;
3857 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003858
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003859 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3860 &tzinfo))
3861 return NULL;
3862 if (check_tzinfo_subclass(tzinfo) < 0)
3863 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00003864
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003865 self = datetime_best_possible(cls,
3866 tzinfo == Py_None ? localtime : gmtime,
3867 tzinfo);
3868 if (self != NULL && tzinfo != Py_None) {
3869 /* Convert UTC to tzinfo's zone. */
3870 PyObject *temp = self;
3871 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3872 Py_DECREF(temp);
3873 }
3874 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003875}
3876
Tim Petersa9bc1682003-01-11 03:39:11 +00003877/* Return best possible UTC time -- this isn't constrained by the
3878 * precision of a timestamp.
3879 */
3880static PyObject *
3881datetime_utcnow(PyObject *cls, PyObject *dummy)
3882{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003883 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00003884}
3885
Tim Peters2a799bf2002-12-16 20:18:38 +00003886/* Return new local datetime from timestamp (Python timestamp -- a double). */
3887static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003888datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003889{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003890 PyObject *self;
3891 double timestamp;
3892 PyObject *tzinfo = Py_None;
3893 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003894
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003895 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3896 keywords, &timestamp, &tzinfo))
3897 return NULL;
3898 if (check_tzinfo_subclass(tzinfo) < 0)
3899 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003900
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003901 self = datetime_from_timestamp(cls,
3902 tzinfo == Py_None ? localtime : gmtime,
3903 timestamp,
3904 tzinfo);
3905 if (self != NULL && tzinfo != Py_None) {
3906 /* Convert UTC to tzinfo's zone. */
3907 PyObject *temp = self;
3908 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3909 Py_DECREF(temp);
3910 }
3911 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003912}
3913
Tim Petersa9bc1682003-01-11 03:39:11 +00003914/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3915static PyObject *
3916datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3917{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003918 double timestamp;
3919 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003920
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003921 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3922 result = datetime_from_timestamp(cls, gmtime, timestamp,
3923 Py_None);
3924 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003925}
3926
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003927/* Return new datetime from time.strptime(). */
3928static PyObject *
3929datetime_strptime(PyObject *cls, PyObject *args)
3930{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003931 static PyObject *module = NULL;
3932 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3933 const char *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003934
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003935 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3936 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003937
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003938 if (module == NULL &&
3939 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3940 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003941
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003942 /* _strptime._strptime returns a two-element tuple. The first
3943 element is a time.struct_time object. The second is the
3944 microseconds (which are not defined for time.struct_time). */
3945 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
3946 if (obj != NULL) {
3947 int i, good_timetuple = 1;
3948 long int ia[7];
3949 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3950 st = PySequence_GetItem(obj, 0);
3951 frac = PySequence_GetItem(obj, 1);
3952 if (st == NULL || frac == NULL)
3953 good_timetuple = 0;
3954 /* copy y/m/d/h/m/s values out of the
3955 time.struct_time */
3956 if (good_timetuple &&
3957 PySequence_Check(st) &&
3958 PySequence_Size(st) >= 6) {
3959 for (i=0; i < 6; i++) {
3960 PyObject *p = PySequence_GetItem(st, i);
3961 if (p == NULL) {
3962 good_timetuple = 0;
3963 break;
3964 }
3965 if (PyInt_Check(p))
3966 ia[i] = PyInt_AsLong(p);
3967 else
3968 good_timetuple = 0;
3969 Py_DECREF(p);
3970 }
3971 }
3972 else
3973 good_timetuple = 0;
3974 /* follow that up with a little dose of microseconds */
3975 if (good_timetuple && PyInt_Check(frac))
3976 ia[6] = PyInt_AsLong(frac);
3977 else
3978 good_timetuple = 0;
3979 }
3980 else
3981 good_timetuple = 0;
3982 if (good_timetuple)
3983 result = PyObject_CallFunction(cls, "iiiiiii",
3984 ia[0], ia[1], ia[2],
3985 ia[3], ia[4], ia[5],
3986 ia[6]);
3987 else
3988 PyErr_SetString(PyExc_ValueError,
3989 "unexpected value from _strptime._strptime");
3990 }
3991 Py_XDECREF(obj);
3992 Py_XDECREF(st);
3993 Py_XDECREF(frac);
3994 return result;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003995}
3996
Tim Petersa9bc1682003-01-11 03:39:11 +00003997/* Return new datetime from date/datetime and time arguments. */
3998static PyObject *
3999datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4000{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004001 static char *keywords[] = {"date", "time", NULL};
4002 PyObject *date;
4003 PyObject *time;
4004 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004005
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004006 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4007 &PyDateTime_DateType, &date,
4008 &PyDateTime_TimeType, &time)) {
4009 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004010
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004011 if (HASTZINFO(time))
4012 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4013 result = PyObject_CallFunction(cls, "iiiiiiiO",
4014 GET_YEAR(date),
4015 GET_MONTH(date),
4016 GET_DAY(date),
4017 TIME_GET_HOUR(time),
4018 TIME_GET_MINUTE(time),
4019 TIME_GET_SECOND(time),
4020 TIME_GET_MICROSECOND(time),
4021 tzinfo);
4022 }
4023 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004024}
Tim Peters2a799bf2002-12-16 20:18:38 +00004025
4026/*
4027 * Destructor.
4028 */
4029
4030static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004031datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004032{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004033 if (HASTZINFO(self)) {
4034 Py_XDECREF(self->tzinfo);
4035 }
4036 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004037}
4038
4039/*
4040 * Indirect access to tzinfo methods.
4041 */
4042
Tim Peters2a799bf2002-12-16 20:18:38 +00004043/* These are all METH_NOARGS, so don't need to check the arglist. */
4044static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004045datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004046 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4047 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004048}
4049
4050static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004051datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004052 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4053 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004054}
4055
4056static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004057datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004058 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4059 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004060}
4061
4062/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004063 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004064 */
4065
Tim Petersa9bc1682003-01-11 03:39:11 +00004066/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4067 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004068 */
4069static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004070add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004071 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004072{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004073 /* Note that the C-level additions can't overflow, because of
4074 * invariant bounds on the member values.
4075 */
4076 int year = GET_YEAR(date);
4077 int month = GET_MONTH(date);
4078 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4079 int hour = DATE_GET_HOUR(date);
4080 int minute = DATE_GET_MINUTE(date);
4081 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4082 int microsecond = DATE_GET_MICROSECOND(date) +
4083 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004084
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004085 assert(factor == 1 || factor == -1);
4086 if (normalize_datetime(&year, &month, &day,
4087 &hour, &minute, &second, &microsecond) < 0)
4088 return NULL;
4089 else
4090 return new_datetime(year, month, day,
4091 hour, minute, second, microsecond,
4092 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004093}
4094
4095static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004096datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004097{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004098 if (PyDateTime_Check(left)) {
4099 /* datetime + ??? */
4100 if (PyDelta_Check(right))
4101 /* datetime + delta */
4102 return add_datetime_timedelta(
4103 (PyDateTime_DateTime *)left,
4104 (PyDateTime_Delta *)right,
4105 1);
4106 }
4107 else if (PyDelta_Check(left)) {
4108 /* delta + datetime */
4109 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4110 (PyDateTime_Delta *) left,
4111 1);
4112 }
4113 Py_INCREF(Py_NotImplemented);
4114 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004115}
4116
4117static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004118datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004119{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004120 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004121
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004122 if (PyDateTime_Check(left)) {
4123 /* datetime - ??? */
4124 if (PyDateTime_Check(right)) {
4125 /* datetime - datetime */
4126 naivety n1, n2;
4127 int offset1, offset2;
4128 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004129
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004130 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4131 right, &offset2, &n2,
4132 right) < 0)
4133 return NULL;
4134 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4135 if (n1 != n2) {
4136 PyErr_SetString(PyExc_TypeError,
4137 "can't subtract offset-naive and "
4138 "offset-aware datetimes");
4139 return NULL;
4140 }
4141 delta_d = ymd_to_ord(GET_YEAR(left),
4142 GET_MONTH(left),
4143 GET_DAY(left)) -
4144 ymd_to_ord(GET_YEAR(right),
4145 GET_MONTH(right),
4146 GET_DAY(right));
4147 /* These can't overflow, since the values are
4148 * normalized. At most this gives the number of
4149 * seconds in one day.
4150 */
4151 delta_s = (DATE_GET_HOUR(left) -
4152 DATE_GET_HOUR(right)) * 3600 +
4153 (DATE_GET_MINUTE(left) -
4154 DATE_GET_MINUTE(right)) * 60 +
4155 (DATE_GET_SECOND(left) -
4156 DATE_GET_SECOND(right));
4157 delta_us = DATE_GET_MICROSECOND(left) -
4158 DATE_GET_MICROSECOND(right);
4159 /* (left - offset1) - (right - offset2) =
4160 * (left - right) + (offset2 - offset1)
4161 */
4162 delta_s += (offset2 - offset1) * 60;
4163 result = new_delta(delta_d, delta_s, delta_us, 1);
4164 }
4165 else if (PyDelta_Check(right)) {
4166 /* datetime - delta */
4167 result = add_datetime_timedelta(
4168 (PyDateTime_DateTime *)left,
4169 (PyDateTime_Delta *)right,
4170 -1);
4171 }
4172 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004173
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004174 if (result == Py_NotImplemented)
4175 Py_INCREF(result);
4176 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004177}
4178
4179/* Various ways to turn a datetime into a string. */
4180
4181static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004182datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004183{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004184 char buffer[1000];
4185 const char *type_name = Py_TYPE(self)->tp_name;
4186 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004187
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004188 if (DATE_GET_MICROSECOND(self)) {
4189 PyOS_snprintf(buffer, sizeof(buffer),
4190 "%s(%d, %d, %d, %d, %d, %d, %d)",
4191 type_name,
4192 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4193 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4194 DATE_GET_SECOND(self),
4195 DATE_GET_MICROSECOND(self));
4196 }
4197 else if (DATE_GET_SECOND(self)) {
4198 PyOS_snprintf(buffer, sizeof(buffer),
4199 "%s(%d, %d, %d, %d, %d, %d)",
4200 type_name,
4201 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4202 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4203 DATE_GET_SECOND(self));
4204 }
4205 else {
4206 PyOS_snprintf(buffer, sizeof(buffer),
4207 "%s(%d, %d, %d, %d, %d)",
4208 type_name,
4209 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4210 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4211 }
4212 baserepr = PyString_FromString(buffer);
4213 if (baserepr == NULL || ! HASTZINFO(self))
4214 return baserepr;
4215 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004216}
4217
Tim Petersa9bc1682003-01-11 03:39:11 +00004218static PyObject *
4219datetime_str(PyDateTime_DateTime *self)
4220{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004221 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004222}
Tim Peters2a799bf2002-12-16 20:18:38 +00004223
4224static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004225datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004226{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004227 char sep = 'T';
4228 static char *keywords[] = {"sep", NULL};
4229 char buffer[100];
4230 char *cp;
4231 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004232
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004233 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4234 &sep))
4235 return NULL;
4236 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4237 assert(cp != NULL);
4238 *cp++ = sep;
4239 cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4240 result = PyString_FromStringAndSize(buffer, cp - buffer);
4241 if (result == NULL || ! HASTZINFO(self))
4242 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004243
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004244 /* We need to append the UTC offset. */
4245 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4246 (PyObject *)self) < 0) {
4247 Py_DECREF(result);
4248 return NULL;
4249 }
4250 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
4251 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004252}
4253
Tim Petersa9bc1682003-01-11 03:39:11 +00004254static PyObject *
4255datetime_ctime(PyDateTime_DateTime *self)
4256{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004257 return format_ctime((PyDateTime_Date *)self,
4258 DATE_GET_HOUR(self),
4259 DATE_GET_MINUTE(self),
4260 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004261}
4262
Tim Peters2a799bf2002-12-16 20:18:38 +00004263/* Miscellaneous methods. */
4264
Tim Petersa9bc1682003-01-11 03:39:11 +00004265/* This is more natural as a tp_compare, but doesn't work then: for whatever
4266 * reason, Python's try_3way_compare ignores tp_compare unless
4267 * PyInstance_Check returns true, but these aren't old-style classes.
4268 */
4269static PyObject *
4270datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4271{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004272 int diff;
4273 naivety n1, n2;
4274 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004275
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004276 if (! PyDateTime_Check(other)) {
4277 /* If other has a "timetuple" attr, that's an advertised
4278 * hook for other classes to ask to get comparison control.
4279 * However, date instances have a timetuple attr, and we
4280 * don't want to allow that comparison. Because datetime
4281 * is a subclass of date, when mixing date and datetime
4282 * in a comparison, Python gives datetime the first shot
4283 * (it's the more specific subtype). So we can stop that
4284 * combination here reliably.
4285 */
4286 if (PyObject_HasAttrString(other, "timetuple") &&
4287 ! PyDate_Check(other)) {
4288 /* A hook for other kinds of datetime objects. */
4289 Py_INCREF(Py_NotImplemented);
4290 return Py_NotImplemented;
4291 }
4292 if (op == Py_EQ || op == Py_NE) {
4293 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4294 Py_INCREF(result);
4295 return result;
4296 }
4297 /* Stop this from falling back to address comparison. */
4298 return cmperror((PyObject *)self, other);
4299 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004300
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004301 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4302 (PyObject *)self,
4303 other, &offset2, &n2,
4304 other) < 0)
4305 return NULL;
4306 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4307 /* If they're both naive, or both aware and have the same offsets,
4308 * we get off cheap. Note that if they're both naive, offset1 ==
4309 * offset2 == 0 at this point.
4310 */
4311 if (n1 == n2 && offset1 == offset2) {
4312 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4313 _PyDateTime_DATETIME_DATASIZE);
4314 return diff_to_bool(diff, op);
4315 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004316
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004317 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4318 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004319
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004320 assert(offset1 != offset2); /* else last "if" handled it */
4321 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4322 other);
4323 if (delta == NULL)
4324 return NULL;
4325 diff = GET_TD_DAYS(delta);
4326 if (diff == 0)
4327 diff = GET_TD_SECONDS(delta) |
4328 GET_TD_MICROSECONDS(delta);
4329 Py_DECREF(delta);
4330 return diff_to_bool(diff, op);
4331 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004332
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004333 assert(n1 != n2);
4334 PyErr_SetString(PyExc_TypeError,
4335 "can't compare offset-naive and "
4336 "offset-aware datetimes");
4337 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004338}
4339
4340static long
4341datetime_hash(PyDateTime_DateTime *self)
4342{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004343 if (self->hashcode == -1) {
4344 naivety n;
4345 int offset;
4346 PyObject *temp;
Tim Petersa9bc1682003-01-11 03:39:11 +00004347
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004348 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4349 &offset);
4350 assert(n != OFFSET_UNKNOWN);
4351 if (n == OFFSET_ERROR)
4352 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004353
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004354 /* Reduce this to a hash of another object. */
4355 if (n == OFFSET_NAIVE)
4356 temp = PyString_FromStringAndSize(
4357 (char *)self->data,
4358 _PyDateTime_DATETIME_DATASIZE);
4359 else {
4360 int days;
4361 int seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004362
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004363 assert(n == OFFSET_AWARE);
4364 assert(HASTZINFO(self));
4365 days = ymd_to_ord(GET_YEAR(self),
4366 GET_MONTH(self),
4367 GET_DAY(self));
4368 seconds = DATE_GET_HOUR(self) * 3600 +
4369 (DATE_GET_MINUTE(self) - offset) * 60 +
4370 DATE_GET_SECOND(self);
4371 temp = new_delta(days,
4372 seconds,
4373 DATE_GET_MICROSECOND(self),
4374 1);
4375 }
4376 if (temp != NULL) {
4377 self->hashcode = PyObject_Hash(temp);
4378 Py_DECREF(temp);
4379 }
4380 }
4381 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004382}
Tim Peters2a799bf2002-12-16 20:18:38 +00004383
4384static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004385datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004386{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004387 PyObject *clone;
4388 PyObject *tuple;
4389 int y = GET_YEAR(self);
4390 int m = GET_MONTH(self);
4391 int d = GET_DAY(self);
4392 int hh = DATE_GET_HOUR(self);
4393 int mm = DATE_GET_MINUTE(self);
4394 int ss = DATE_GET_SECOND(self);
4395 int us = DATE_GET_MICROSECOND(self);
4396 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004397
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004398 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4399 datetime_kws,
4400 &y, &m, &d, &hh, &mm, &ss, &us,
4401 &tzinfo))
4402 return NULL;
4403 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4404 if (tuple == NULL)
4405 return NULL;
4406 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4407 Py_DECREF(tuple);
4408 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004409}
4410
4411static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004412datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004413{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004414 int y, m, d, hh, mm, ss, us;
4415 PyObject *result;
4416 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004417
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004418 PyObject *tzinfo;
4419 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004420
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004421 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4422 &PyDateTime_TZInfoType, &tzinfo))
4423 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004424
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004425 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4426 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004427
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004428 /* Conversion to self's own time zone is a NOP. */
4429 if (self->tzinfo == tzinfo) {
4430 Py_INCREF(self);
4431 return (PyObject *)self;
4432 }
Tim Peters521fc152002-12-31 17:36:56 +00004433
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004434 /* Convert self to UTC. */
4435 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4436 if (offset == -1 && PyErr_Occurred())
4437 return NULL;
4438 if (none)
4439 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004440
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004441 y = GET_YEAR(self);
4442 m = GET_MONTH(self);
4443 d = GET_DAY(self);
4444 hh = DATE_GET_HOUR(self);
4445 mm = DATE_GET_MINUTE(self);
4446 ss = DATE_GET_SECOND(self);
4447 us = DATE_GET_MICROSECOND(self);
Tim Peters52dcce22003-01-23 16:36:11 +00004448
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004449 mm -= offset;
4450 if ((mm < 0 || mm >= 60) &&
4451 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4452 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004453
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004454 /* Attach new tzinfo and let fromutc() do the rest. */
4455 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4456 if (result != NULL) {
4457 PyObject *temp = result;
Tim Peters52dcce22003-01-23 16:36:11 +00004458
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004459 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4460 Py_DECREF(temp);
4461 }
4462 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004463
Tim Peters52dcce22003-01-23 16:36:11 +00004464NeedAware:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004465 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4466 "a naive datetime");
4467 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004468}
4469
4470static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004471datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004472{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004473 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004474
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004475 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4476 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004477
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004478 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4479 if (dstflag == -1 && PyErr_Occurred())
4480 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004481
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004482 if (none)
4483 dstflag = -1;
4484 else if (dstflag != 0)
4485 dstflag = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004486
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004487 }
4488 return build_struct_time(GET_YEAR(self),
4489 GET_MONTH(self),
4490 GET_DAY(self),
4491 DATE_GET_HOUR(self),
4492 DATE_GET_MINUTE(self),
4493 DATE_GET_SECOND(self),
4494 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004495}
4496
4497static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004498datetime_getdate(PyDateTime_DateTime *self)
4499{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004500 return new_date(GET_YEAR(self),
4501 GET_MONTH(self),
4502 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004503}
4504
4505static PyObject *
4506datetime_gettime(PyDateTime_DateTime *self)
4507{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004508 return new_time(DATE_GET_HOUR(self),
4509 DATE_GET_MINUTE(self),
4510 DATE_GET_SECOND(self),
4511 DATE_GET_MICROSECOND(self),
4512 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004513}
4514
4515static PyObject *
4516datetime_gettimetz(PyDateTime_DateTime *self)
4517{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004518 return new_time(DATE_GET_HOUR(self),
4519 DATE_GET_MINUTE(self),
4520 DATE_GET_SECOND(self),
4521 DATE_GET_MICROSECOND(self),
4522 HASTZINFO(self) ? self->tzinfo : Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004523}
4524
4525static PyObject *
4526datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004527{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004528 int y = GET_YEAR(self);
4529 int m = GET_MONTH(self);
4530 int d = GET_DAY(self);
4531 int hh = DATE_GET_HOUR(self);
4532 int mm = DATE_GET_MINUTE(self);
4533 int ss = DATE_GET_SECOND(self);
4534 int us = 0; /* microseconds are ignored in a timetuple */
4535 int offset = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004536
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004537 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4538 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004539
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004540 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4541 if (offset == -1 && PyErr_Occurred())
4542 return NULL;
4543 }
4544 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4545 * 0 in a UTC timetuple regardless of what dst() says.
4546 */
4547 if (offset) {
4548 /* Subtract offset minutes & normalize. */
4549 int stat;
Tim Peters2a799bf2002-12-16 20:18:38 +00004550
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004551 mm -= offset;
4552 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4553 if (stat < 0) {
4554 /* At the edges, it's possible we overflowed
4555 * beyond MINYEAR or MAXYEAR.
4556 */
4557 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4558 PyErr_Clear();
4559 else
4560 return NULL;
4561 }
4562 }
4563 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004564}
4565
Tim Peters371935f2003-02-01 01:52:50 +00004566/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004567
Tim Petersa9bc1682003-01-11 03:39:11 +00004568/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004569 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4570 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004571 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004572 */
4573static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004574datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004575{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004576 PyObject *basestate;
4577 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004578
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004579 basestate = PyString_FromStringAndSize((char *)self->data,
4580 _PyDateTime_DATETIME_DATASIZE);
4581 if (basestate != NULL) {
4582 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4583 result = PyTuple_Pack(1, basestate);
4584 else
4585 result = PyTuple_Pack(2, basestate, self->tzinfo);
4586 Py_DECREF(basestate);
4587 }
4588 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004589}
4590
4591static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004592datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004593{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004594 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004595}
4596
Tim Petersa9bc1682003-01-11 03:39:11 +00004597static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004598
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004599 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004600
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004601 {"now", (PyCFunction)datetime_now,
4602 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4603 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004604
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004605 {"utcnow", (PyCFunction)datetime_utcnow,
4606 METH_NOARGS | METH_CLASS,
4607 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004608
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004609 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4610 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4611 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004612
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004613 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4614 METH_VARARGS | METH_CLASS,
4615 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4616 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004617
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004618 {"strptime", (PyCFunction)datetime_strptime,
4619 METH_VARARGS | METH_CLASS,
4620 PyDoc_STR("string, format -> new datetime parsed from a string "
4621 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004622
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004623 {"combine", (PyCFunction)datetime_combine,
4624 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4625 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004626
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004627 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004628
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004629 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4630 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004631
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004632 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4633 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004634
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004635 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4636 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004637
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004638 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4639 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004640
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004641 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4642 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004643
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004644 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4645 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004646
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004647 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4648 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4649 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4650 "sep is used to separate the year from the time, and "
4651 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004652
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004653 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4654 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004655
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004656 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4657 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004658
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004659 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4660 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004661
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004662 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4663 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004664
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004665 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4666 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004667
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004668 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4669 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004670
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004671 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004672};
4673
Tim Petersa9bc1682003-01-11 03:39:11 +00004674static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004675PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4676\n\
4677The year, month and day arguments are required. tzinfo may be None, or an\n\
4678instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004679
Tim Petersa9bc1682003-01-11 03:39:11 +00004680static PyNumberMethods datetime_as_number = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004681 datetime_add, /* nb_add */
4682 datetime_subtract, /* nb_subtract */
4683 0, /* nb_multiply */
4684 0, /* nb_divide */
4685 0, /* nb_remainder */
4686 0, /* nb_divmod */
4687 0, /* nb_power */
4688 0, /* nb_negative */
4689 0, /* nb_positive */
4690 0, /* nb_absolute */
4691 0, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00004692};
4693
Tim Petersa9bc1682003-01-11 03:39:11 +00004694statichere PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004695 PyObject_HEAD_INIT(NULL)
4696 0, /* ob_size */
4697 "datetime.datetime", /* tp_name */
4698 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4699 0, /* tp_itemsize */
4700 (destructor)datetime_dealloc, /* tp_dealloc */
4701 0, /* tp_print */
4702 0, /* tp_getattr */
4703 0, /* tp_setattr */
4704 0, /* tp_compare */
4705 (reprfunc)datetime_repr, /* tp_repr */
4706 &datetime_as_number, /* tp_as_number */
4707 0, /* tp_as_sequence */
4708 0, /* tp_as_mapping */
4709 (hashfunc)datetime_hash, /* tp_hash */
4710 0, /* tp_call */
4711 (reprfunc)datetime_str, /* tp_str */
4712 PyObject_GenericGetAttr, /* tp_getattro */
4713 0, /* tp_setattro */
4714 0, /* tp_as_buffer */
4715 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4716 Py_TPFLAGS_BASETYPE, /* tp_flags */
4717 datetime_doc, /* tp_doc */
4718 0, /* tp_traverse */
4719 0, /* tp_clear */
4720 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
4721 0, /* tp_weaklistoffset */
4722 0, /* tp_iter */
4723 0, /* tp_iternext */
4724 datetime_methods, /* tp_methods */
4725 0, /* tp_members */
4726 datetime_getset, /* tp_getset */
4727 &PyDateTime_DateType, /* tp_base */
4728 0, /* tp_dict */
4729 0, /* tp_descr_get */
4730 0, /* tp_descr_set */
4731 0, /* tp_dictoffset */
4732 0, /* tp_init */
4733 datetime_alloc, /* tp_alloc */
4734 datetime_new, /* tp_new */
4735 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004736};
4737
4738/* ---------------------------------------------------------------------------
4739 * Module methods and initialization.
4740 */
4741
4742static PyMethodDef module_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004743 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004744};
4745
Tim Peters9ddf40b2004-06-20 22:41:32 +00004746/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4747 * datetime.h.
4748 */
4749static PyDateTime_CAPI CAPI = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004750 &PyDateTime_DateType,
4751 &PyDateTime_DateTimeType,
4752 &PyDateTime_TimeType,
4753 &PyDateTime_DeltaType,
4754 &PyDateTime_TZInfoType,
4755 new_date_ex,
4756 new_datetime_ex,
4757 new_time_ex,
4758 new_delta_ex,
4759 datetime_fromtimestamp,
4760 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00004761};
4762
4763
Tim Peters2a799bf2002-12-16 20:18:38 +00004764PyMODINIT_FUNC
4765initdatetime(void)
4766{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004767 PyObject *m; /* a module object */
4768 PyObject *d; /* its dict */
4769 PyObject *x;
Tim Peters2a799bf2002-12-16 20:18:38 +00004770
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004771 m = Py_InitModule3("datetime", module_methods,
4772 "Fast implementation of the datetime type.");
4773 if (m == NULL)
4774 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004775
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004776 if (PyType_Ready(&PyDateTime_DateType) < 0)
4777 return;
4778 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4779 return;
4780 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4781 return;
4782 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4783 return;
4784 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4785 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004786
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004787 /* timedelta values */
4788 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004789
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004790 x = new_delta(0, 0, 1, 0);
4791 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4792 return;
4793 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004794
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004795 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4796 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4797 return;
4798 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004799
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004800 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4801 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4802 return;
4803 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004804
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004805 /* date values */
4806 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004807
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004808 x = new_date(1, 1, 1);
4809 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4810 return;
4811 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004812
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004813 x = new_date(MAXYEAR, 12, 31);
4814 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4815 return;
4816 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004817
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004818 x = new_delta(1, 0, 0, 0);
4819 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4820 return;
4821 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004822
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004823 /* time values */
4824 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004825
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004826 x = new_time(0, 0, 0, 0, Py_None);
4827 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4828 return;
4829 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004830
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004831 x = new_time(23, 59, 59, 999999, Py_None);
4832 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4833 return;
4834 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004835
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004836 x = new_delta(0, 0, 1, 0);
4837 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4838 return;
4839 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004840
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004841 /* datetime values */
4842 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004843
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004844 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4845 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4846 return;
4847 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004848
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004849 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4850 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4851 return;
4852 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004853
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004854 x = new_delta(0, 0, 1, 0);
4855 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4856 return;
4857 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004858
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004859 /* module initialization */
4860 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4861 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00004862
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004863 Py_INCREF(&PyDateTime_DateType);
4864 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004865
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004866 Py_INCREF(&PyDateTime_DateTimeType);
4867 PyModule_AddObject(m, "datetime",
4868 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00004869
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004870 Py_INCREF(&PyDateTime_TimeType);
4871 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00004872
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004873 Py_INCREF(&PyDateTime_DeltaType);
4874 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004875
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004876 Py_INCREF(&PyDateTime_TZInfoType);
4877 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004878
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004879 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
4880 if (x == NULL)
4881 return;
4882 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00004883
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004884 /* A 4-year cycle has an extra leap day over what we'd get from
4885 * pasting together 4 single years.
4886 */
4887 assert(DI4Y == 4 * 365 + 1);
4888 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004889
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004890 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4891 * get from pasting together 4 100-year cycles.
4892 */
4893 assert(DI400Y == 4 * DI100Y + 1);
4894 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004895
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004896 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4897 * pasting together 25 4-year cycles.
4898 */
4899 assert(DI100Y == 25 * DI4Y - 1);
4900 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004901
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004902 us_per_us = PyInt_FromLong(1);
4903 us_per_ms = PyInt_FromLong(1000);
4904 us_per_second = PyInt_FromLong(1000000);
4905 us_per_minute = PyInt_FromLong(60000000);
4906 seconds_per_day = PyInt_FromLong(24 * 3600);
4907 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4908 us_per_minute == NULL || seconds_per_day == NULL)
4909 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004910
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004911 /* The rest are too big for 32-bit ints, but even
4912 * us_per_week fits in 40 bits, so doubles should be exact.
4913 */
4914 us_per_hour = PyLong_FromDouble(3600000000.0);
4915 us_per_day = PyLong_FromDouble(86400000000.0);
4916 us_per_week = PyLong_FromDouble(604800000000.0);
4917 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4918 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004919}
Tim Petersf3615152003-01-01 21:51:37 +00004920
4921/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004922Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004923 x.n = x stripped of its timezone -- its naive time.
4924 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004925 return None
Tim Petersf3615152003-01-01 21:51:37 +00004926 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004927 return None
Tim Petersf3615152003-01-01 21:51:37 +00004928 x.s = x's standard offset, x.o - x.d
4929
4930Now some derived rules, where k is a duration (timedelta).
4931
49321. x.o = x.s + x.d
4933 This follows from the definition of x.s.
4934
Tim Petersc5dc4da2003-01-02 17:55:03 +000049352. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004936 This is actually a requirement, an assumption we need to make about
4937 sane tzinfo classes.
4938
49393. The naive UTC time corresponding to x is x.n - x.o.
4940 This is again a requirement for a sane tzinfo class.
4941
49424. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004943 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004944
Tim Petersc5dc4da2003-01-02 17:55:03 +000049455. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004946 Again follows from how arithmetic is defined.
4947
Tim Peters8bb5ad22003-01-24 02:44:45 +00004948Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004949(meaning that the various tzinfo methods exist, and don't blow up or return
4950None when called).
4951
Tim Petersa9bc1682003-01-11 03:39:11 +00004952The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004953x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004954
4955By #3, we want
4956
Tim Peters8bb5ad22003-01-24 02:44:45 +00004957 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004958
4959The algorithm starts by attaching tz to x.n, and calling that y. So
4960x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4961becomes true; in effect, we want to solve [2] for k:
4962
Tim Peters8bb5ad22003-01-24 02:44:45 +00004963 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004964
4965By #1, this is the same as
4966
Tim Peters8bb5ad22003-01-24 02:44:45 +00004967 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004968
4969By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4970Substituting that into [3],
4971
Tim Peters8bb5ad22003-01-24 02:44:45 +00004972 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4973 k - (y+k).s - (y+k).d = 0; rearranging,
4974 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4975 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004976
Tim Peters8bb5ad22003-01-24 02:44:45 +00004977On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4978approximate k by ignoring the (y+k).d term at first. Note that k can't be
4979very large, since all offset-returning methods return a duration of magnitude
4980less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4981be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004982
4983In any case, the new value is
4984
Tim Peters8bb5ad22003-01-24 02:44:45 +00004985 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004986
Tim Peters8bb5ad22003-01-24 02:44:45 +00004987It's helpful to step back at look at [4] from a higher level: it's simply
4988mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004989
4990At this point, if
4991
Tim Peters8bb5ad22003-01-24 02:44:45 +00004992 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004993
4994we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004995at the start of daylight time. Picture US Eastern for concreteness. The wall
4996time 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 +00004997sense then. The docs ask that an Eastern tzinfo class consider such a time to
4998be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4999on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005000the only spelling that makes sense on the local wall clock.
5001
Tim Petersc5dc4da2003-01-02 17:55:03 +00005002In fact, if [5] holds at this point, we do have the standard-time spelling,
5003but that takes a bit of proof. We first prove a stronger result. What's the
5004difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005005
Tim Peters8bb5ad22003-01-24 02:44:45 +00005006 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005007
Tim Petersc5dc4da2003-01-02 17:55:03 +00005008Now
5009 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005010 (y + y.s).n = by #5
5011 y.n + y.s = since y.n = x.n
5012 x.n + y.s = since z and y are have the same tzinfo member,
5013 y.s = z.s by #2
5014 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005015
Tim Petersc5dc4da2003-01-02 17:55:03 +00005016Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005017
Tim Petersc5dc4da2003-01-02 17:55:03 +00005018 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005019 x.n - ((x.n + z.s) - z.o) = expanding
5020 x.n - x.n - z.s + z.o = cancelling
5021 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005022 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005023
Tim Petersc5dc4da2003-01-02 17:55:03 +00005024So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005025
Tim Petersc5dc4da2003-01-02 17:55:03 +00005026If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005027spelling we wanted in the endcase described above. We're done. Contrarily,
5028if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005029
Tim Petersc5dc4da2003-01-02 17:55:03 +00005030If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5031add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005032local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005033
Tim Petersc5dc4da2003-01-02 17:55:03 +00005034Let
Tim Petersf3615152003-01-01 21:51:37 +00005035
Tim Peters4fede1a2003-01-04 00:26:59 +00005036 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005037
Tim Peters4fede1a2003-01-04 00:26:59 +00005038and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005039
Tim Peters8bb5ad22003-01-24 02:44:45 +00005040 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005041
Tim Peters8bb5ad22003-01-24 02:44:45 +00005042If so, we're done. If not, the tzinfo class is insane, according to the
5043assumptions we've made. This also requires a bit of proof. As before, let's
5044compute the difference between the LHS and RHS of [8] (and skipping some of
5045the justifications for the kinds of substitutions we've done several times
5046already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005047
Tim Peters8bb5ad22003-01-24 02:44:45 +00005048 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005049 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5050 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5051 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5052 - z.n + z.n - z.o + z'.o = cancel z.n
5053 - z.o + z'.o = #1 twice
5054 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5055 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005056
5057So 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 +00005058we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5059return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005060
Tim Peters8bb5ad22003-01-24 02:44:45 +00005061How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5062a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5063would have to change the result dst() returns: we start in DST, and moving
5064a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005065
Tim Peters8bb5ad22003-01-24 02:44:45 +00005066There isn't a sane case where this can happen. The closest it gets is at
5067the end of DST, where there's an hour in UTC with no spelling in a hybrid
5068tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5069that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5070UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5071time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5072clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5073standard time. Since that's what the local clock *does*, we want to map both
5074UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005075in local time, but so it goes -- it's the way the local clock works.
5076
Tim Peters8bb5ad22003-01-24 02:44:45 +00005077When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5078so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5079z' = 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 +00005080(correctly) concludes that z' is not UTC-equivalent to x.
5081
5082Because we know z.d said z was in daylight time (else [5] would have held and
5083we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005084and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005085return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5086but the reasoning doesn't depend on the example -- it depends on there being
5087two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005088z' must be in standard time, and is the spelling we want in this case.
5089
5090Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5091concerned (because it takes z' as being in standard time rather than the
5092daylight time we intend here), but returning it gives the real-life "local
5093clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5094tz.
5095
5096When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5097the 1:MM standard time spelling we want.
5098
5099So how can this break? One of the assumptions must be violated. Two
5100possibilities:
5101
51021) [2] effectively says that y.s is invariant across all y belong to a given
5103 time zone. This isn't true if, for political reasons or continental drift,
5104 a region decides to change its base offset from UTC.
5105
51062) There may be versions of "double daylight" time where the tail end of
5107 the analysis gives up a step too early. I haven't thought about that
5108 enough to say.
5109
5110In any case, it's clear that the default fromutc() is strong enough to handle
5111"almost all" time zones: so long as the standard offset is invariant, it
5112doesn't matter if daylight time transition points change from year to year, or
5113if daylight time is skipped in some years; it doesn't matter how large or
5114small dst() may get within its bounds; and it doesn't even matter if some
5115perverse time zone returns a negative dst()). So a breaking case must be
5116pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005117--------------------------------------------------------------------------- */