blob: 98848c1217a62034ecd8f1da785ef88520cf0638 [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 Pitrouc7c96a92010-05-09 15:15:40 +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 Belopolskycfd6bc02010-05-27 21:53:16 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000131 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000132
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000204 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000205
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000246 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000247
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Belopolskycfd6bc02010-05-27 21:53:16 +0000486static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000487normalize_y_m_d(int *y, int *m, int *d)
488{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000489 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000490
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Belopolskycfd6bc02010-05-27 21:53:16 +0000540 if (ordinal < 1 || ordinal > MAXORDINAL) {
541 goto error;
542 } else {
543 ord_to_ymd(ordinal, y, m, d);
544 return 0;
545 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000546 }
547 }
548 assert(*m > 0);
549 assert(*d > 0);
Alexander Belopolskycfd6bc02010-05-27 21:53:16 +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 Belopolskycfd6bc02010-05-27 21:53:16 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000608 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000609
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000623 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000624
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000658 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000659
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000672 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000673{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000674 PyDateTime_DateTime *self;
675 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000676
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000700 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000701{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000702 PyDateTime_Time *self;
703 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000704
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000732 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000733{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000734 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000735
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000741 if (check_delta_day_range(days) < 0)
742 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000743
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000782 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000783
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000802 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000803
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000822 int *none)
Tim Peters2a799bf2002-12-16 20:18:38 +0000823{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000824 PyObject *u;
825 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000826
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000827 assert(tzinfo != NULL);
828 assert(PyTZInfo_Check(tzinfo));
829 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000830
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000895 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000896
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000940 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000941
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000942 assert(tzinfo != NULL);
943 assert(check_tzinfo_subclass(tzinfo) >= 0);
944 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000945
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000964 /* an exception has been set; the caller should pass it on */
965 OFFSET_ERROR,
Tim Peters2a799bf2002-12-16 20:18:38 +0000966
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000967 /* type isn't date, datetime, or time subclass */
968 OFFSET_UNKNOWN,
Tim Peters2a799bf2002-12-16 20:18:38 +0000969
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +0000993 int none;
994 PyObject *tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000995
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001023 PyObject *tzinfoarg1,
1024 PyObject *o2, int *offset2, naivety *n2,
1025 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001026{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001050 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001051
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001065 /* Append ", tzinfo=". */
1066 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
Tim Peters2a799bf2002-12-16 20:18:38 +00001067
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001068 /* Append repr(tzinfo). */
1069 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
Tim Peters2a799bf2002-12-16 20:18:38 +00001070
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001113 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001114{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001115 int offset;
1116 int hours;
1117 int minutes;
1118 char sign;
1119 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00001120
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001121 assert(buflen >= 1);
Gregory P. Smith9d534572008-06-11 07:41:16 +00001122
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001163 PyObject *timetuple, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001164{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001165 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001166
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001183 assert(object && format && timetuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001184
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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'Arc7682d042009-12-29 22:39:49 +00001372static char *
Tim Peters2a799bf2002-12-16 20:18:38 +00001373isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1374{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001375 int x;
1376 int us = DATE_GET_MICROSECOND(dt);
Tim Peters2a799bf2002-12-16 20:18:38 +00001377
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001399 PyObject *result = NULL;
1400 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001401
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001415 PyObject *time;
1416 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001417
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001443 PyObject *result;
1444 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001445
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 x1 = x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001527
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001553 int us;
1554 int s;
1555 int d;
1556 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001557
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001558 PyObject *tuple = NULL;
1559 PyObject *num = NULL;
1560 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001561
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001562 tuple = PyNumber_Divmod(pyus, us_per_second);
1563 if (tuple == NULL)
1564 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001565
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001624 Py_XDECREF(tuple);
1625 Py_XDECREF(num);
1626 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001627}
1628
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001635 PyObject *pyus_in;
1636 PyObject *pyus_out;
1637 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001638
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001639 pyus_in = delta_to_microseconds(delta);
1640 if (pyus_in == NULL)
1641 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001642
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001656 PyObject *pyus_in;
1657 PyObject *pyus_out;
1658 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001659
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001660 pyus_in = delta_to_microseconds(delta);
1661 if (pyus_in == NULL)
1662 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001663
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001677 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001678
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001720 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001721
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001722 assert(GET_TD_MICROSECONDS(self) >= 0);
1723 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001724
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001730 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001731}
1732
1733static PyObject *
1734delta_subtract(PyObject *left, PyObject *right)
1735{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001736 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001737
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001761 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001762
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001799 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001800
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001819 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001820
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001847 PyObject *prod;
1848 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00001849
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00001850 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001851
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001930 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001931
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001945 static char *keywords[] = {
1946 "days", "seconds", "microseconds", "milliseconds",
1947 "minutes", "hours", "weeks", NULL
1948 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001949
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00001956 x = PyInt_FromLong(0);
1957 if (x == NULL)
1958 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001959
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00002006 self = microseconds_to_delta_ex(x, type);
2007 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002008Done:
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00002055 minutes = divmod(seconds, 60, &seconds);
2056 hours = divmod(minutes, 60, &minutes);
Tim Peters2a799bf2002-12-16 20:18:38 +00002057
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +00002081 return PyString_FromStringAndSize(buf, pbuf - buf);
Tim Petersba873472002-12-18 20:19:21 +00002082
2083 Fail:
Antoine Pitrouc7c96a92010-05-09 15:15:40 +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 Pitrouc7c96a92010-05-09 15:15:40 +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 *
2100delta_reduce(PyDateTime_Delta* self)
2101{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002102 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002103}
2104
2105#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2106
2107static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002108
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002109 {"days", T_INT, OFFSET(days), READONLY,
2110 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002111
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002112 {"seconds", T_INT, OFFSET(seconds), READONLY,
2113 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002114
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002115 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2116 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2117 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002118};
2119
2120static PyMethodDef delta_methods[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002121 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2122 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002123
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002124 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002125};
2126
2127static char delta_doc[] =
2128PyDoc_STR("Difference between two datetime values.");
2129
2130static PyNumberMethods delta_as_number = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002131 delta_add, /* nb_add */
2132 delta_subtract, /* nb_subtract */
2133 delta_multiply, /* nb_multiply */
2134 delta_divide, /* nb_divide */
2135 0, /* nb_remainder */
2136 0, /* nb_divmod */
2137 0, /* nb_power */
2138 (unaryfunc)delta_negative, /* nb_negative */
2139 (unaryfunc)delta_positive, /* nb_positive */
2140 (unaryfunc)delta_abs, /* nb_absolute */
2141 (inquiry)delta_nonzero, /* nb_nonzero */
2142 0, /*nb_invert*/
2143 0, /*nb_lshift*/
2144 0, /*nb_rshift*/
2145 0, /*nb_and*/
2146 0, /*nb_xor*/
2147 0, /*nb_or*/
2148 0, /*nb_coerce*/
2149 0, /*nb_int*/
2150 0, /*nb_long*/
2151 0, /*nb_float*/
2152 0, /*nb_oct*/
2153 0, /*nb_hex*/
2154 0, /*nb_inplace_add*/
2155 0, /*nb_inplace_subtract*/
2156 0, /*nb_inplace_multiply*/
2157 0, /*nb_inplace_divide*/
2158 0, /*nb_inplace_remainder*/
2159 0, /*nb_inplace_power*/
2160 0, /*nb_inplace_lshift*/
2161 0, /*nb_inplace_rshift*/
2162 0, /*nb_inplace_and*/
2163 0, /*nb_inplace_xor*/
2164 0, /*nb_inplace_or*/
2165 delta_divide, /* nb_floor_divide */
2166 0, /* nb_true_divide */
2167 0, /* nb_inplace_floor_divide */
2168 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002169};
2170
2171static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002172 PyVarObject_HEAD_INIT(NULL, 0)
2173 "datetime.timedelta", /* tp_name */
2174 sizeof(PyDateTime_Delta), /* tp_basicsize */
2175 0, /* tp_itemsize */
2176 0, /* tp_dealloc */
2177 0, /* tp_print */
2178 0, /* tp_getattr */
2179 0, /* tp_setattr */
2180 0, /* tp_compare */
2181 (reprfunc)delta_repr, /* tp_repr */
2182 &delta_as_number, /* tp_as_number */
2183 0, /* tp_as_sequence */
2184 0, /* tp_as_mapping */
2185 (hashfunc)delta_hash, /* tp_hash */
2186 0, /* tp_call */
2187 (reprfunc)delta_str, /* tp_str */
2188 PyObject_GenericGetAttr, /* tp_getattro */
2189 0, /* tp_setattro */
2190 0, /* tp_as_buffer */
2191 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2192 Py_TPFLAGS_BASETYPE, /* tp_flags */
2193 delta_doc, /* tp_doc */
2194 0, /* tp_traverse */
2195 0, /* tp_clear */
2196 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2197 0, /* tp_weaklistoffset */
2198 0, /* tp_iter */
2199 0, /* tp_iternext */
2200 delta_methods, /* tp_methods */
2201 delta_members, /* tp_members */
2202 0, /* tp_getset */
2203 0, /* tp_base */
2204 0, /* tp_dict */
2205 0, /* tp_descr_get */
2206 0, /* tp_descr_set */
2207 0, /* tp_dictoffset */
2208 0, /* tp_init */
2209 0, /* tp_alloc */
2210 delta_new, /* tp_new */
2211 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002212};
2213
2214/*
2215 * PyDateTime_Date implementation.
2216 */
2217
2218/* Accessor properties. */
2219
2220static PyObject *
2221date_year(PyDateTime_Date *self, void *unused)
2222{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002223 return PyInt_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002224}
2225
2226static PyObject *
2227date_month(PyDateTime_Date *self, void *unused)
2228{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002229 return PyInt_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002230}
2231
2232static PyObject *
2233date_day(PyDateTime_Date *self, void *unused)
2234{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002235 return PyInt_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002236}
2237
2238static PyGetSetDef date_getset[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002239 {"year", (getter)date_year},
2240 {"month", (getter)date_month},
2241 {"day", (getter)date_day},
2242 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002243};
2244
2245/* Constructors. */
2246
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002247static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002248
Tim Peters2a799bf2002-12-16 20:18:38 +00002249static PyObject *
2250date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2251{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002252 PyObject *self = NULL;
2253 PyObject *state;
2254 int year;
2255 int month;
2256 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002257
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002258 /* Check for invocation from pickle with __getstate__ state */
2259 if (PyTuple_GET_SIZE(args) == 1 &&
2260 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2261 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2262 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
2263 {
2264 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002265
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002266 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2267 if (me != NULL) {
2268 char *pdata = PyString_AS_STRING(state);
2269 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2270 me->hashcode = -1;
2271 }
2272 return (PyObject *)me;
2273 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002274
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002275 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2276 &year, &month, &day)) {
2277 if (check_date_args(year, month, day) < 0)
2278 return NULL;
2279 self = new_date_ex(year, month, day, type);
2280 }
2281 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002282}
2283
2284/* Return new date from localtime(t). */
2285static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002286date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002287{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002288 struct tm *tm;
2289 time_t t;
2290 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002291
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002292 t = _PyTime_DoubleToTimet(ts);
2293 if (t == (time_t)-1 && PyErr_Occurred())
2294 return NULL;
2295 tm = localtime(&t);
2296 if (tm)
2297 result = PyObject_CallFunction(cls, "iii",
2298 tm->tm_year + 1900,
2299 tm->tm_mon + 1,
2300 tm->tm_mday);
2301 else
2302 PyErr_SetString(PyExc_ValueError,
2303 "timestamp out of range for "
2304 "platform localtime() function");
2305 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002306}
2307
2308/* Return new date from current time.
2309 * We say this is equivalent to fromtimestamp(time.time()), and the
2310 * only way to be sure of that is to *call* time.time(). That's not
2311 * generally the same as calling C's time.
2312 */
2313static PyObject *
2314date_today(PyObject *cls, PyObject *dummy)
2315{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002316 PyObject *time;
2317 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002318
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002319 time = time_time();
2320 if (time == NULL)
2321 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002322
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002323 /* Note well: today() is a class method, so this may not call
2324 * date.fromtimestamp. For example, it may call
2325 * datetime.fromtimestamp. That's why we need all the accuracy
2326 * time.time() delivers; if someone were gonzo about optimization,
2327 * date.today() could get away with plain C time().
2328 */
2329 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2330 Py_DECREF(time);
2331 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002332}
2333
2334/* Return new date from given timestamp (Python timestamp -- a double). */
2335static PyObject *
2336date_fromtimestamp(PyObject *cls, PyObject *args)
2337{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002338 double timestamp;
2339 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002340
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002341 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2342 result = date_local_from_time_t(cls, timestamp);
2343 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002344}
2345
2346/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2347 * the ordinal is out of range.
2348 */
2349static PyObject *
2350date_fromordinal(PyObject *cls, PyObject *args)
2351{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002352 PyObject *result = NULL;
2353 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002354
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002355 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2356 int year;
2357 int month;
2358 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002359
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002360 if (ordinal < 1)
2361 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2362 ">= 1");
2363 else {
2364 ord_to_ymd(ordinal, &year, &month, &day);
2365 result = PyObject_CallFunction(cls, "iii",
2366 year, month, day);
2367 }
2368 }
2369 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002370}
2371
2372/*
2373 * Date arithmetic.
2374 */
2375
2376/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2377 * instead.
2378 */
2379static PyObject *
2380add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2381{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002382 PyObject *result = NULL;
2383 int year = GET_YEAR(date);
2384 int month = GET_MONTH(date);
2385 int deltadays = GET_TD_DAYS(delta);
2386 /* C-level overflow is impossible because |deltadays| < 1e9. */
2387 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002388
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002389 if (normalize_date(&year, &month, &day) >= 0)
2390 result = new_date(year, month, day);
2391 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002392}
2393
2394static PyObject *
2395date_add(PyObject *left, PyObject *right)
2396{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002397 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2398 Py_INCREF(Py_NotImplemented);
2399 return Py_NotImplemented;
2400 }
2401 if (PyDate_Check(left)) {
2402 /* date + ??? */
2403 if (PyDelta_Check(right))
2404 /* date + delta */
2405 return add_date_timedelta((PyDateTime_Date *) left,
2406 (PyDateTime_Delta *) right,
2407 0);
2408 }
2409 else {
2410 /* ??? + date
2411 * 'right' must be one of us, or we wouldn't have been called
2412 */
2413 if (PyDelta_Check(left))
2414 /* delta + date */
2415 return add_date_timedelta((PyDateTime_Date *) right,
2416 (PyDateTime_Delta *) left,
2417 0);
2418 }
2419 Py_INCREF(Py_NotImplemented);
2420 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002421}
2422
2423static PyObject *
2424date_subtract(PyObject *left, PyObject *right)
2425{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002426 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2427 Py_INCREF(Py_NotImplemented);
2428 return Py_NotImplemented;
2429 }
2430 if (PyDate_Check(left)) {
2431 if (PyDate_Check(right)) {
2432 /* date - date */
2433 int left_ord = ymd_to_ord(GET_YEAR(left),
2434 GET_MONTH(left),
2435 GET_DAY(left));
2436 int right_ord = ymd_to_ord(GET_YEAR(right),
2437 GET_MONTH(right),
2438 GET_DAY(right));
2439 return new_delta(left_ord - right_ord, 0, 0, 0);
2440 }
2441 if (PyDelta_Check(right)) {
2442 /* date - delta */
2443 return add_date_timedelta((PyDateTime_Date *) left,
2444 (PyDateTime_Delta *) right,
2445 1);
2446 }
2447 }
2448 Py_INCREF(Py_NotImplemented);
2449 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002450}
2451
2452
2453/* Various ways to turn a date into a string. */
2454
2455static PyObject *
2456date_repr(PyDateTime_Date *self)
2457{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002458 char buffer[1028];
2459 const char *type_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002460
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002461 type_name = Py_TYPE(self)->tp_name;
2462 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2463 type_name,
2464 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002465
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002466 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002467}
2468
2469static PyObject *
2470date_isoformat(PyDateTime_Date *self)
2471{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002472 char buffer[128];
Tim Peters2a799bf2002-12-16 20:18:38 +00002473
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002474 isoformat_date(self, buffer, sizeof(buffer));
2475 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002476}
2477
Tim Peterse2df5ff2003-05-02 18:39:55 +00002478/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002479static PyObject *
2480date_str(PyDateTime_Date *self)
2481{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002482 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002483}
2484
2485
2486static PyObject *
2487date_ctime(PyDateTime_Date *self)
2488{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002489 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002490}
2491
2492static PyObject *
2493date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2494{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002495 /* This method can be inherited, and needs to call the
2496 * timetuple() method appropriate to self's class.
2497 */
2498 PyObject *result;
2499 PyObject *tuple;
2500 const char *format;
2501 Py_ssize_t format_len;
2502 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002503
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002504 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2505 &format, &format_len))
2506 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002507
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002508 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2509 if (tuple == NULL)
2510 return NULL;
2511 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
2512 (PyObject *)self);
2513 Py_DECREF(tuple);
2514 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002515}
2516
Eric Smitha9f7d622008-02-17 19:46:49 +00002517static PyObject *
2518date_format(PyDateTime_Date *self, PyObject *args)
2519{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002520 PyObject *format;
Eric Smitha9f7d622008-02-17 19:46:49 +00002521
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002522 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2523 return NULL;
Eric Smitha9f7d622008-02-17 19:46:49 +00002524
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002525 /* Check for str or unicode */
2526 if (PyString_Check(format)) {
2527 /* If format is zero length, return str(self) */
2528 if (PyString_GET_SIZE(format) == 0)
2529 return PyObject_Str((PyObject *)self);
2530 } else if (PyUnicode_Check(format)) {
2531 /* If format is zero length, return str(self) */
2532 if (PyUnicode_GET_SIZE(format) == 0)
2533 return PyObject_Unicode((PyObject *)self);
2534 } else {
2535 PyErr_Format(PyExc_ValueError,
2536 "__format__ expects str or unicode, not %.200s",
2537 Py_TYPE(format)->tp_name);
2538 return NULL;
2539 }
2540 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smitha9f7d622008-02-17 19:46:49 +00002541}
2542
Tim Peters2a799bf2002-12-16 20:18:38 +00002543/* ISO methods. */
2544
2545static PyObject *
2546date_isoweekday(PyDateTime_Date *self)
2547{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002548 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002549
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002550 return PyInt_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002551}
2552
2553static PyObject *
2554date_isocalendar(PyDateTime_Date *self)
2555{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002556 int year = GET_YEAR(self);
2557 int week1_monday = iso_week1_monday(year);
2558 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2559 int week;
2560 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002561
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002562 week = divmod(today - week1_monday, 7, &day);
2563 if (week < 0) {
2564 --year;
2565 week1_monday = iso_week1_monday(year);
2566 week = divmod(today - week1_monday, 7, &day);
2567 }
2568 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2569 ++year;
2570 week = 0;
2571 }
2572 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002573}
2574
2575/* Miscellaneous methods. */
2576
2577/* This is more natural as a tp_compare, but doesn't work then: for whatever
2578 * reason, Python's try_3way_compare ignores tp_compare unless
2579 * PyInstance_Check returns true, but these aren't old-style classes.
2580 */
2581static PyObject *
2582date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2583{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002584 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002585
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002586 if (PyDate_Check(other))
2587 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2588 _PyDateTime_DATE_DATASIZE);
Tim Peters07534a62003-02-07 22:50:28 +00002589
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002590 else if (PyObject_HasAttrString(other, "timetuple")) {
2591 /* A hook for other kinds of date objects. */
2592 Py_INCREF(Py_NotImplemented);
2593 return Py_NotImplemented;
2594 }
2595 else if (op == Py_EQ || op == Py_NE)
2596 diff = 1; /* any non-zero value will do */
Tim Peters07534a62003-02-07 22:50:28 +00002597
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002598 else /* stop this from falling back to address comparison */
2599 return cmperror((PyObject *)self, other);
Tim Peters07534a62003-02-07 22:50:28 +00002600
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002601 return diff_to_bool(diff, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00002602}
2603
2604static PyObject *
2605date_timetuple(PyDateTime_Date *self)
2606{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002607 return build_struct_time(GET_YEAR(self),
2608 GET_MONTH(self),
2609 GET_DAY(self),
2610 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002611}
2612
Tim Peters12bf3392002-12-24 05:41:27 +00002613static PyObject *
2614date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2615{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002616 PyObject *clone;
2617 PyObject *tuple;
2618 int year = GET_YEAR(self);
2619 int month = GET_MONTH(self);
2620 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002621
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002622 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2623 &year, &month, &day))
2624 return NULL;
2625 tuple = Py_BuildValue("iii", year, month, day);
2626 if (tuple == NULL)
2627 return NULL;
2628 clone = date_new(Py_TYPE(self), tuple, NULL);
2629 Py_DECREF(tuple);
2630 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002631}
2632
Tim Peters2a799bf2002-12-16 20:18:38 +00002633static PyObject *date_getstate(PyDateTime_Date *self);
2634
2635static long
2636date_hash(PyDateTime_Date *self)
2637{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002638 if (self->hashcode == -1) {
2639 PyObject *temp = date_getstate(self);
2640 if (temp != NULL) {
2641 self->hashcode = PyObject_Hash(temp);
2642 Py_DECREF(temp);
2643 }
2644 }
2645 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002646}
2647
2648static PyObject *
2649date_toordinal(PyDateTime_Date *self)
2650{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002651 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2652 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002653}
2654
2655static PyObject *
2656date_weekday(PyDateTime_Date *self)
2657{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002658 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002659
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002660 return PyInt_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002661}
2662
Tim Peters371935f2003-02-01 01:52:50 +00002663/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002664
Tim Petersb57f8f02003-02-01 02:54:15 +00002665/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002666static PyObject *
2667date_getstate(PyDateTime_Date *self)
2668{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002669 return Py_BuildValue(
2670 "(N)",
2671 PyString_FromStringAndSize((char *)self->data,
2672 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002673}
2674
2675static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002676date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002677{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002678 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002679}
2680
2681static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002682
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002683 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002684
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002685 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2686 METH_CLASS,
2687 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2688 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002689
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002690 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2691 METH_CLASS,
2692 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2693 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002694
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002695 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2696 PyDoc_STR("Current date or datetime: same as "
2697 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002698
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002699 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002700
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002701 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2702 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002703
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002704 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2705 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002706
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002707 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2708 PyDoc_STR("Formats self with strftime.")},
Eric Smitha9f7d622008-02-17 19:46:49 +00002709
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002710 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2711 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002712
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002713 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2714 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2715 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002716
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002717 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2718 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002719
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002720 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2721 PyDoc_STR("Return the day of the week represented by the date.\n"
2722 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002723
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002724 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2725 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2726 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002727
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002728 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2729 PyDoc_STR("Return the day of the week represented by the date.\n"
2730 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002731
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002732 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2733 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002734
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002735 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2736 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002737
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002738 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002739};
2740
2741static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002742PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002743
2744static PyNumberMethods date_as_number = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002745 date_add, /* nb_add */
2746 date_subtract, /* nb_subtract */
2747 0, /* nb_multiply */
2748 0, /* nb_divide */
2749 0, /* nb_remainder */
2750 0, /* nb_divmod */
2751 0, /* nb_power */
2752 0, /* nb_negative */
2753 0, /* nb_positive */
2754 0, /* nb_absolute */
2755 0, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00002756};
2757
2758static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002759 PyVarObject_HEAD_INIT(NULL, 0)
2760 "datetime.date", /* tp_name */
2761 sizeof(PyDateTime_Date), /* tp_basicsize */
2762 0, /* tp_itemsize */
2763 0, /* tp_dealloc */
2764 0, /* tp_print */
2765 0, /* tp_getattr */
2766 0, /* tp_setattr */
2767 0, /* tp_compare */
2768 (reprfunc)date_repr, /* tp_repr */
2769 &date_as_number, /* tp_as_number */
2770 0, /* tp_as_sequence */
2771 0, /* tp_as_mapping */
2772 (hashfunc)date_hash, /* tp_hash */
2773 0, /* tp_call */
2774 (reprfunc)date_str, /* tp_str */
2775 PyObject_GenericGetAttr, /* tp_getattro */
2776 0, /* tp_setattro */
2777 0, /* tp_as_buffer */
2778 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2779 Py_TPFLAGS_BASETYPE, /* tp_flags */
2780 date_doc, /* tp_doc */
2781 0, /* tp_traverse */
2782 0, /* tp_clear */
2783 (richcmpfunc)date_richcompare, /* tp_richcompare */
2784 0, /* tp_weaklistoffset */
2785 0, /* tp_iter */
2786 0, /* tp_iternext */
2787 date_methods, /* tp_methods */
2788 0, /* tp_members */
2789 date_getset, /* tp_getset */
2790 0, /* tp_base */
2791 0, /* tp_dict */
2792 0, /* tp_descr_get */
2793 0, /* tp_descr_set */
2794 0, /* tp_dictoffset */
2795 0, /* tp_init */
2796 0, /* tp_alloc */
2797 date_new, /* tp_new */
2798 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002799};
2800
2801/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002802 * PyDateTime_TZInfo implementation.
2803 */
2804
2805/* This is a pure abstract base class, so doesn't do anything beyond
2806 * raising NotImplemented exceptions. Real tzinfo classes need
2807 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002808 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002809 * be subclasses of this tzinfo class, which is easy and quick to check).
2810 *
2811 * Note: For reasons having to do with pickling of subclasses, we have
2812 * to allow tzinfo objects to be instantiated. This wasn't an issue
2813 * in the Python implementation (__init__() could raise NotImplementedError
2814 * there without ill effect), but doing so in the C implementation hit a
2815 * brick wall.
2816 */
2817
2818static PyObject *
2819tzinfo_nogo(const char* methodname)
2820{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002821 PyErr_Format(PyExc_NotImplementedError,
2822 "a tzinfo subclass must implement %s()",
2823 methodname);
2824 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002825}
2826
2827/* Methods. A subclass must implement these. */
2828
Tim Peters52dcce22003-01-23 16:36:11 +00002829static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002830tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2831{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002832 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002833}
2834
Tim Peters52dcce22003-01-23 16:36:11 +00002835static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002836tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2837{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002838 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002839}
2840
Tim Peters52dcce22003-01-23 16:36:11 +00002841static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002842tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2843{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002844 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002845}
2846
Tim Peters52dcce22003-01-23 16:36:11 +00002847static PyObject *
2848tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2849{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002850 int y, m, d, hh, mm, ss, us;
Tim Peters52dcce22003-01-23 16:36:11 +00002851
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002852 PyObject *result;
2853 int off, dst;
2854 int none;
2855 int delta;
Tim Peters52dcce22003-01-23 16:36:11 +00002856
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002857 if (! PyDateTime_Check(dt)) {
2858 PyErr_SetString(PyExc_TypeError,
2859 "fromutc: argument must be a datetime");
2860 return NULL;
2861 }
2862 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2863 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2864 "is not self");
2865 return NULL;
2866 }
Tim Peters52dcce22003-01-23 16:36:11 +00002867
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002868 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2869 if (off == -1 && PyErr_Occurred())
2870 return NULL;
2871 if (none) {
2872 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2873 "utcoffset() result required");
2874 return NULL;
2875 }
Tim Peters52dcce22003-01-23 16:36:11 +00002876
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002877 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2878 if (dst == -1 && PyErr_Occurred())
2879 return NULL;
2880 if (none) {
2881 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2882 "dst() result required");
2883 return NULL;
2884 }
Tim Peters52dcce22003-01-23 16:36:11 +00002885
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002886 y = GET_YEAR(dt);
2887 m = GET_MONTH(dt);
2888 d = GET_DAY(dt);
2889 hh = DATE_GET_HOUR(dt);
2890 mm = DATE_GET_MINUTE(dt);
2891 ss = DATE_GET_SECOND(dt);
2892 us = DATE_GET_MICROSECOND(dt);
Tim Peters52dcce22003-01-23 16:36:11 +00002893
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002894 delta = off - dst;
2895 mm += delta;
2896 if ((mm < 0 || mm >= 60) &&
2897 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2898 return NULL;
2899 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2900 if (result == NULL)
2901 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002902
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002903 dst = call_dst(dt->tzinfo, result, &none);
2904 if (dst == -1 && PyErr_Occurred())
2905 goto Fail;
2906 if (none)
2907 goto Inconsistent;
2908 if (dst == 0)
2909 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002910
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002911 mm += dst;
2912 if ((mm < 0 || mm >= 60) &&
2913 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2914 goto Fail;
2915 Py_DECREF(result);
2916 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2917 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002918
2919Inconsistent:
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002920 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2921 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00002922
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002923 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00002924Fail:
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002925 Py_DECREF(result);
2926 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002927}
2928
Tim Peters2a799bf2002-12-16 20:18:38 +00002929/*
2930 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002931 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002932 */
2933
Guido van Rossum177e41a2003-01-30 22:06:23 +00002934static PyObject *
2935tzinfo_reduce(PyObject *self)
2936{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002937 PyObject *args, *state, *tmp;
2938 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002939
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002940 tmp = PyTuple_New(0);
2941 if (tmp == NULL)
2942 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002943
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002944 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2945 if (getinitargs != NULL) {
2946 args = PyObject_CallObject(getinitargs, tmp);
2947 Py_DECREF(getinitargs);
2948 if (args == NULL) {
2949 Py_DECREF(tmp);
2950 return NULL;
2951 }
2952 }
2953 else {
2954 PyErr_Clear();
2955 args = tmp;
2956 Py_INCREF(args);
2957 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002958
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002959 getstate = PyObject_GetAttrString(self, "__getstate__");
2960 if (getstate != NULL) {
2961 state = PyObject_CallObject(getstate, tmp);
2962 Py_DECREF(getstate);
2963 if (state == NULL) {
2964 Py_DECREF(args);
2965 Py_DECREF(tmp);
2966 return NULL;
2967 }
2968 }
2969 else {
2970 PyObject **dictptr;
2971 PyErr_Clear();
2972 state = Py_None;
2973 dictptr = _PyObject_GetDictPtr(self);
2974 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2975 state = *dictptr;
2976 Py_INCREF(state);
2977 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002978
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002979 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002980
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002981 if (state == Py_None) {
2982 Py_DECREF(state);
2983 return Py_BuildValue("(ON)", Py_TYPE(self), args);
2984 }
2985 else
2986 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002987}
Tim Peters2a799bf2002-12-16 20:18:38 +00002988
2989static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002990
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002991 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2992 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002993
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002994 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2995 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2996 "west of UTC).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002997
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00002998 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2999 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003000
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003001 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
3002 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003003
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003004 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3005 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003006
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003007 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003008};
3009
3010static char tzinfo_doc[] =
3011PyDoc_STR("Abstract base class for time zone info objects.");
3012
Neal Norwitzce3d34d2003-02-04 20:45:17 +00003013statichere PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003014 PyObject_HEAD_INIT(NULL)
3015 0, /* ob_size */
3016 "datetime.tzinfo", /* tp_name */
3017 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3018 0, /* tp_itemsize */
3019 0, /* tp_dealloc */
3020 0, /* tp_print */
3021 0, /* tp_getattr */
3022 0, /* tp_setattr */
3023 0, /* tp_compare */
3024 0, /* tp_repr */
3025 0, /* tp_as_number */
3026 0, /* tp_as_sequence */
3027 0, /* tp_as_mapping */
3028 0, /* tp_hash */
3029 0, /* tp_call */
3030 0, /* tp_str */
3031 PyObject_GenericGetAttr, /* tp_getattro */
3032 0, /* tp_setattro */
3033 0, /* tp_as_buffer */
3034 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3035 Py_TPFLAGS_BASETYPE, /* tp_flags */
3036 tzinfo_doc, /* tp_doc */
3037 0, /* tp_traverse */
3038 0, /* tp_clear */
3039 0, /* tp_richcompare */
3040 0, /* tp_weaklistoffset */
3041 0, /* tp_iter */
3042 0, /* tp_iternext */
3043 tzinfo_methods, /* tp_methods */
3044 0, /* tp_members */
3045 0, /* tp_getset */
3046 0, /* tp_base */
3047 0, /* tp_dict */
3048 0, /* tp_descr_get */
3049 0, /* tp_descr_set */
3050 0, /* tp_dictoffset */
3051 0, /* tp_init */
3052 0, /* tp_alloc */
3053 PyType_GenericNew, /* tp_new */
3054 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003055};
3056
3057/*
Tim Peters37f39822003-01-10 03:49:02 +00003058 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003059 */
3060
Tim Peters37f39822003-01-10 03:49:02 +00003061/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003062 */
3063
3064static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003065time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003066{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003067 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003068}
3069
Tim Peters37f39822003-01-10 03:49:02 +00003070static PyObject *
3071time_minute(PyDateTime_Time *self, void *unused)
3072{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003073 return PyInt_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003074}
3075
3076/* The name time_second conflicted with some platform header file. */
3077static PyObject *
3078py_time_second(PyDateTime_Time *self, void *unused)
3079{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003080 return PyInt_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003081}
3082
3083static PyObject *
3084time_microsecond(PyDateTime_Time *self, void *unused)
3085{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003086 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003087}
3088
3089static PyObject *
3090time_tzinfo(PyDateTime_Time *self, void *unused)
3091{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003092 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3093 Py_INCREF(result);
3094 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003095}
3096
3097static PyGetSetDef time_getset[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003098 {"hour", (getter)time_hour},
3099 {"minute", (getter)time_minute},
3100 {"second", (getter)py_time_second},
3101 {"microsecond", (getter)time_microsecond},
3102 {"tzinfo", (getter)time_tzinfo},
3103 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003104};
3105
3106/*
3107 * Constructors.
3108 */
3109
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003110static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003111 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003112
Tim Peters2a799bf2002-12-16 20:18:38 +00003113static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003114time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003115{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003116 PyObject *self = NULL;
3117 PyObject *state;
3118 int hour = 0;
3119 int minute = 0;
3120 int second = 0;
3121 int usecond = 0;
3122 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003123
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003124 /* Check for invocation from pickle with __getstate__ state */
3125 if (PyTuple_GET_SIZE(args) >= 1 &&
3126 PyTuple_GET_SIZE(args) <= 2 &&
3127 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3128 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3129 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
3130 {
3131 PyDateTime_Time *me;
3132 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003133
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003134 if (PyTuple_GET_SIZE(args) == 2) {
3135 tzinfo = PyTuple_GET_ITEM(args, 1);
3136 if (check_tzinfo_subclass(tzinfo) < 0) {
3137 PyErr_SetString(PyExc_TypeError, "bad "
3138 "tzinfo state arg");
3139 return NULL;
3140 }
3141 }
3142 aware = (char)(tzinfo != Py_None);
3143 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3144 if (me != NULL) {
3145 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003146
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003147 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3148 me->hashcode = -1;
3149 me->hastzinfo = aware;
3150 if (aware) {
3151 Py_INCREF(tzinfo);
3152 me->tzinfo = tzinfo;
3153 }
3154 }
3155 return (PyObject *)me;
3156 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003157
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003158 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3159 &hour, &minute, &second, &usecond,
3160 &tzinfo)) {
3161 if (check_time_args(hour, minute, second, usecond) < 0)
3162 return NULL;
3163 if (check_tzinfo_subclass(tzinfo) < 0)
3164 return NULL;
3165 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3166 type);
3167 }
3168 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003169}
3170
3171/*
3172 * Destructor.
3173 */
3174
3175static void
Tim Peters37f39822003-01-10 03:49:02 +00003176time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003177{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003178 if (HASTZINFO(self)) {
3179 Py_XDECREF(self->tzinfo);
3180 }
3181 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003182}
3183
3184/*
Tim Peters855fe882002-12-22 03:43:39 +00003185 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003186 */
3187
Tim Peters2a799bf2002-12-16 20:18:38 +00003188/* These are all METH_NOARGS, so don't need to check the arglist. */
3189static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003190time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003191 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3192 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003193}
3194
3195static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003196time_dst(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003197 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3198 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003199}
3200
3201static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003202time_tzname(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003203 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3204 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003205}
3206
3207/*
Tim Peters37f39822003-01-10 03:49:02 +00003208 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003209 */
3210
3211static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003212time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003213{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003214 char buffer[100];
3215 const char *type_name = Py_TYPE(self)->tp_name;
3216 int h = TIME_GET_HOUR(self);
3217 int m = TIME_GET_MINUTE(self);
3218 int s = TIME_GET_SECOND(self);
3219 int us = TIME_GET_MICROSECOND(self);
3220 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003221
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003222 if (us)
3223 PyOS_snprintf(buffer, sizeof(buffer),
3224 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
3225 else if (s)
3226 PyOS_snprintf(buffer, sizeof(buffer),
3227 "%s(%d, %d, %d)", type_name, h, m, s);
3228 else
3229 PyOS_snprintf(buffer, sizeof(buffer),
3230 "%s(%d, %d)", type_name, h, m);
3231 result = PyString_FromString(buffer);
3232 if (result != NULL && HASTZINFO(self))
3233 result = append_keyword_tzinfo(result, self->tzinfo);
3234 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003235}
3236
Tim Peters37f39822003-01-10 03:49:02 +00003237static PyObject *
3238time_str(PyDateTime_Time *self)
3239{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003240 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003241}
Tim Peters2a799bf2002-12-16 20:18:38 +00003242
3243static PyObject *
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003244time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003245{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003246 char buf[100];
3247 PyObject *result;
3248 /* Reuse the time format code from the datetime type. */
3249 PyDateTime_DateTime datetime;
3250 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003251
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003252 /* Copy over just the time bytes. */
3253 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3254 self->data,
3255 _PyDateTime_TIME_DATASIZE);
Tim Peters37f39822003-01-10 03:49:02 +00003256
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003257 isoformat_time(pdatetime, buf, sizeof(buf));
3258 result = PyString_FromString(buf);
3259 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3260 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003261
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003262 /* We need to append the UTC offset. */
3263 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3264 Py_None) < 0) {
3265 Py_DECREF(result);
3266 return NULL;
3267 }
3268 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3269 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003270}
3271
Tim Peters37f39822003-01-10 03:49:02 +00003272static PyObject *
3273time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3274{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003275 PyObject *result;
3276 PyObject *tuple;
3277 const char *format;
3278 Py_ssize_t format_len;
3279 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003280
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003281 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3282 &format, &format_len))
3283 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003284
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003285 /* Python's strftime does insane things with the year part of the
3286 * timetuple. The year is forced to (the otherwise nonsensical)
3287 * 1900 to worm around that.
3288 */
3289 tuple = Py_BuildValue("iiiiiiiii",
3290 1900, 1, 1, /* year, month, day */
3291 TIME_GET_HOUR(self),
3292 TIME_GET_MINUTE(self),
3293 TIME_GET_SECOND(self),
3294 0, 1, -1); /* weekday, daynum, dst */
3295 if (tuple == NULL)
3296 return NULL;
3297 assert(PyTuple_Size(tuple) == 9);
3298 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3299 Py_None);
3300 Py_DECREF(tuple);
3301 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003302}
Tim Peters2a799bf2002-12-16 20:18:38 +00003303
3304/*
3305 * Miscellaneous methods.
3306 */
3307
Tim Peters37f39822003-01-10 03:49:02 +00003308/* This is more natural as a tp_compare, but doesn't work then: for whatever
3309 * reason, Python's try_3way_compare ignores tp_compare unless
3310 * PyInstance_Check returns true, but these aren't old-style classes.
3311 */
3312static PyObject *
3313time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3314{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003315 int diff;
3316 naivety n1, n2;
3317 int offset1, offset2;
Tim Peters37f39822003-01-10 03:49:02 +00003318
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003319 if (! PyTime_Check(other)) {
3320 if (op == Py_EQ || op == Py_NE) {
3321 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3322 Py_INCREF(result);
3323 return result;
3324 }
3325 /* Stop this from falling back to address comparison. */
3326 return cmperror((PyObject *)self, other);
3327 }
3328 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3329 other, &offset2, &n2, Py_None) < 0)
3330 return NULL;
3331 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3332 /* If they're both naive, or both aware and have the same offsets,
3333 * we get off cheap. Note that if they're both naive, offset1 ==
3334 * offset2 == 0 at this point.
3335 */
3336 if (n1 == n2 && offset1 == offset2) {
3337 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3338 _PyDateTime_TIME_DATASIZE);
3339 return diff_to_bool(diff, op);
3340 }
Tim Peters37f39822003-01-10 03:49:02 +00003341
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003342 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3343 assert(offset1 != offset2); /* else last "if" handled it */
3344 /* Convert everything except microseconds to seconds. These
3345 * can't overflow (no more than the # of seconds in 2 days).
3346 */
3347 offset1 = TIME_GET_HOUR(self) * 3600 +
3348 (TIME_GET_MINUTE(self) - offset1) * 60 +
3349 TIME_GET_SECOND(self);
3350 offset2 = TIME_GET_HOUR(other) * 3600 +
3351 (TIME_GET_MINUTE(other) - offset2) * 60 +
3352 TIME_GET_SECOND(other);
3353 diff = offset1 - offset2;
3354 if (diff == 0)
3355 diff = TIME_GET_MICROSECOND(self) -
3356 TIME_GET_MICROSECOND(other);
3357 return diff_to_bool(diff, op);
3358 }
Tim Peters37f39822003-01-10 03:49:02 +00003359
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003360 assert(n1 != n2);
3361 PyErr_SetString(PyExc_TypeError,
3362 "can't compare offset-naive and "
3363 "offset-aware times");
3364 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003365}
3366
3367static long
3368time_hash(PyDateTime_Time *self)
3369{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003370 if (self->hashcode == -1) {
3371 naivety n;
3372 int offset;
3373 PyObject *temp;
Tim Peters37f39822003-01-10 03:49:02 +00003374
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003375 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3376 assert(n != OFFSET_UNKNOWN);
3377 if (n == OFFSET_ERROR)
3378 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003379
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003380 /* Reduce this to a hash of another object. */
3381 if (offset == 0)
3382 temp = PyString_FromStringAndSize((char *)self->data,
3383 _PyDateTime_TIME_DATASIZE);
3384 else {
3385 int hour;
3386 int minute;
Tim Peters37f39822003-01-10 03:49:02 +00003387
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003388 assert(n == OFFSET_AWARE);
3389 assert(HASTZINFO(self));
3390 hour = divmod(TIME_GET_HOUR(self) * 60 +
3391 TIME_GET_MINUTE(self) - offset,
3392 60,
3393 &minute);
3394 if (0 <= hour && hour < 24)
3395 temp = new_time(hour, minute,
3396 TIME_GET_SECOND(self),
3397 TIME_GET_MICROSECOND(self),
3398 Py_None);
3399 else
3400 temp = Py_BuildValue("iiii",
3401 hour, minute,
3402 TIME_GET_SECOND(self),
3403 TIME_GET_MICROSECOND(self));
3404 }
3405 if (temp != NULL) {
3406 self->hashcode = PyObject_Hash(temp);
3407 Py_DECREF(temp);
3408 }
3409 }
3410 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003411}
Tim Peters2a799bf2002-12-16 20:18:38 +00003412
Tim Peters12bf3392002-12-24 05:41:27 +00003413static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003414time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003415{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003416 PyObject *clone;
3417 PyObject *tuple;
3418 int hh = TIME_GET_HOUR(self);
3419 int mm = TIME_GET_MINUTE(self);
3420 int ss = TIME_GET_SECOND(self);
3421 int us = TIME_GET_MICROSECOND(self);
3422 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003423
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003424 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3425 time_kws,
3426 &hh, &mm, &ss, &us, &tzinfo))
3427 return NULL;
3428 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3429 if (tuple == NULL)
3430 return NULL;
3431 clone = time_new(Py_TYPE(self), tuple, NULL);
3432 Py_DECREF(tuple);
3433 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003434}
3435
Tim Peters2a799bf2002-12-16 20:18:38 +00003436static int
Tim Peters37f39822003-01-10 03:49:02 +00003437time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003438{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003439 int offset;
3440 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00003441
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003442 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3443 /* Since utcoffset is in whole minutes, nothing can
3444 * alter the conclusion that this is nonzero.
3445 */
3446 return 1;
3447 }
3448 offset = 0;
3449 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3450 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3451 if (offset == -1 && PyErr_Occurred())
3452 return -1;
3453 }
3454 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003455}
3456
Tim Peters371935f2003-02-01 01:52:50 +00003457/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003458
Tim Peters33e0f382003-01-10 02:05:14 +00003459/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003460 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3461 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003462 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003463 */
3464static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003465time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003466{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003467 PyObject *basestate;
3468 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003469
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003470 basestate = PyString_FromStringAndSize((char *)self->data,
3471 _PyDateTime_TIME_DATASIZE);
3472 if (basestate != NULL) {
3473 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3474 result = PyTuple_Pack(1, basestate);
3475 else
3476 result = PyTuple_Pack(2, basestate, self->tzinfo);
3477 Py_DECREF(basestate);
3478 }
3479 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003480}
3481
3482static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003483time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003484{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003485 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003486}
3487
Tim Peters37f39822003-01-10 03:49:02 +00003488static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003489
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003490 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3491 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3492 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003493
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003494 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3495 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003496
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003497 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3498 PyDoc_STR("Formats self with strftime.")},
Eric Smitha9f7d622008-02-17 19:46:49 +00003499
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003500 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3501 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003502
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003503 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3504 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003505
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003506 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3507 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003508
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003509 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3510 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003511
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003512 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3513 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003514
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003515 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003516};
3517
Tim Peters37f39822003-01-10 03:49:02 +00003518static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003519PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3520\n\
3521All arguments are optional. tzinfo may be None, or an instance of\n\
3522a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003523
Tim Peters37f39822003-01-10 03:49:02 +00003524static PyNumberMethods time_as_number = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003525 0, /* nb_add */
3526 0, /* nb_subtract */
3527 0, /* nb_multiply */
3528 0, /* nb_divide */
3529 0, /* nb_remainder */
3530 0, /* nb_divmod */
3531 0, /* nb_power */
3532 0, /* nb_negative */
3533 0, /* nb_positive */
3534 0, /* nb_absolute */
3535 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003536};
3537
Tim Peters37f39822003-01-10 03:49:02 +00003538statichere PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003539 PyObject_HEAD_INIT(NULL)
3540 0, /* ob_size */
3541 "datetime.time", /* tp_name */
3542 sizeof(PyDateTime_Time), /* tp_basicsize */
3543 0, /* tp_itemsize */
3544 (destructor)time_dealloc, /* tp_dealloc */
3545 0, /* tp_print */
3546 0, /* tp_getattr */
3547 0, /* tp_setattr */
3548 0, /* tp_compare */
3549 (reprfunc)time_repr, /* tp_repr */
3550 &time_as_number, /* tp_as_number */
3551 0, /* tp_as_sequence */
3552 0, /* tp_as_mapping */
3553 (hashfunc)time_hash, /* tp_hash */
3554 0, /* tp_call */
3555 (reprfunc)time_str, /* tp_str */
3556 PyObject_GenericGetAttr, /* tp_getattro */
3557 0, /* tp_setattro */
3558 0, /* tp_as_buffer */
3559 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3560 Py_TPFLAGS_BASETYPE, /* tp_flags */
3561 time_doc, /* tp_doc */
3562 0, /* tp_traverse */
3563 0, /* tp_clear */
3564 (richcmpfunc)time_richcompare, /* tp_richcompare */
3565 0, /* tp_weaklistoffset */
3566 0, /* tp_iter */
3567 0, /* tp_iternext */
3568 time_methods, /* tp_methods */
3569 0, /* tp_members */
3570 time_getset, /* tp_getset */
3571 0, /* tp_base */
3572 0, /* tp_dict */
3573 0, /* tp_descr_get */
3574 0, /* tp_descr_set */
3575 0, /* tp_dictoffset */
3576 0, /* tp_init */
3577 time_alloc, /* tp_alloc */
3578 time_new, /* tp_new */
3579 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003580};
3581
3582/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003583 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003584 */
3585
Tim Petersa9bc1682003-01-11 03:39:11 +00003586/* Accessor properties. Properties for day, month, and year are inherited
3587 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003588 */
3589
3590static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003591datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003592{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003593 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003594}
3595
Tim Petersa9bc1682003-01-11 03:39:11 +00003596static PyObject *
3597datetime_minute(PyDateTime_DateTime *self, void *unused)
3598{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003599 return PyInt_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003600}
3601
3602static PyObject *
3603datetime_second(PyDateTime_DateTime *self, void *unused)
3604{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003605 return PyInt_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003606}
3607
3608static PyObject *
3609datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3610{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003611 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003612}
3613
3614static PyObject *
3615datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3616{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003617 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3618 Py_INCREF(result);
3619 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003620}
3621
3622static PyGetSetDef datetime_getset[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003623 {"hour", (getter)datetime_hour},
3624 {"minute", (getter)datetime_minute},
3625 {"second", (getter)datetime_second},
3626 {"microsecond", (getter)datetime_microsecond},
3627 {"tzinfo", (getter)datetime_tzinfo},
3628 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003629};
3630
3631/*
3632 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003633 */
3634
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003635static char *datetime_kws[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003636 "year", "month", "day", "hour", "minute", "second",
3637 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003638};
3639
Tim Peters2a799bf2002-12-16 20:18:38 +00003640static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003641datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003642{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003643 PyObject *self = NULL;
3644 PyObject *state;
3645 int year;
3646 int month;
3647 int day;
3648 int hour = 0;
3649 int minute = 0;
3650 int second = 0;
3651 int usecond = 0;
3652 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003653
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003654 /* Check for invocation from pickle with __getstate__ state */
3655 if (PyTuple_GET_SIZE(args) >= 1 &&
3656 PyTuple_GET_SIZE(args) <= 2 &&
3657 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3658 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3659 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
3660 {
3661 PyDateTime_DateTime *me;
3662 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003663
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003664 if (PyTuple_GET_SIZE(args) == 2) {
3665 tzinfo = PyTuple_GET_ITEM(args, 1);
3666 if (check_tzinfo_subclass(tzinfo) < 0) {
3667 PyErr_SetString(PyExc_TypeError, "bad "
3668 "tzinfo state arg");
3669 return NULL;
3670 }
3671 }
3672 aware = (char)(tzinfo != Py_None);
3673 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3674 if (me != NULL) {
3675 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003676
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003677 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3678 me->hashcode = -1;
3679 me->hastzinfo = aware;
3680 if (aware) {
3681 Py_INCREF(tzinfo);
3682 me->tzinfo = tzinfo;
3683 }
3684 }
3685 return (PyObject *)me;
3686 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003687
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003688 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3689 &year, &month, &day, &hour, &minute,
3690 &second, &usecond, &tzinfo)) {
3691 if (check_date_args(year, month, day) < 0)
3692 return NULL;
3693 if (check_time_args(hour, minute, second, usecond) < 0)
3694 return NULL;
3695 if (check_tzinfo_subclass(tzinfo) < 0)
3696 return NULL;
3697 self = new_datetime_ex(year, month, day,
3698 hour, minute, second, usecond,
3699 tzinfo, type);
3700 }
3701 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003702}
3703
Tim Petersa9bc1682003-01-11 03:39:11 +00003704/* TM_FUNC is the shared type of localtime() and gmtime(). */
3705typedef struct tm *(*TM_FUNC)(const time_t *timer);
3706
3707/* Internal helper.
3708 * Build datetime from a time_t and a distinct count of microseconds.
3709 * Pass localtime or gmtime for f, to control the interpretation of timet.
3710 */
3711static PyObject *
3712datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003713 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00003714{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003715 struct tm *tm;
3716 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003717
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003718 tm = f(&timet);
3719 if (tm) {
3720 /* The platform localtime/gmtime may insert leap seconds,
3721 * indicated by tm->tm_sec > 59. We don't care about them,
3722 * except to the extent that passing them on to the datetime
3723 * constructor would raise ValueError for a reason that
3724 * made no sense to the user.
3725 */
3726 if (tm->tm_sec > 59)
3727 tm->tm_sec = 59;
3728 result = PyObject_CallFunction(cls, "iiiiiiiO",
3729 tm->tm_year + 1900,
3730 tm->tm_mon + 1,
3731 tm->tm_mday,
3732 tm->tm_hour,
3733 tm->tm_min,
3734 tm->tm_sec,
3735 us,
3736 tzinfo);
3737 }
3738 else
3739 PyErr_SetString(PyExc_ValueError,
3740 "timestamp out of range for "
3741 "platform localtime()/gmtime() function");
3742 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003743}
3744
3745/* Internal helper.
3746 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3747 * to control the interpretation of the timestamp. Since a double doesn't
3748 * have enough bits to cover a datetime's full range of precision, it's
3749 * better to call datetime_from_timet_and_us provided you have a way
3750 * to get that much precision (e.g., C time() isn't good enough).
3751 */
3752static PyObject *
3753datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003754 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00003755{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003756 time_t timet;
3757 double fraction;
3758 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00003759
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003760 timet = _PyTime_DoubleToTimet(timestamp);
3761 if (timet == (time_t)-1 && PyErr_Occurred())
3762 return NULL;
3763 fraction = timestamp - (double)timet;
3764 us = (int)round_to_long(fraction * 1e6);
3765 if (us < 0) {
3766 /* Truncation towards zero is not what we wanted
3767 for negative numbers (Python's mod semantics) */
3768 timet -= 1;
3769 us += 1000000;
3770 }
3771 /* If timestamp is less than one microsecond smaller than a
3772 * full second, round up. Otherwise, ValueErrors are raised
3773 * for some floats. */
3774 if (us == 1000000) {
3775 timet += 1;
3776 us = 0;
3777 }
3778 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003779}
3780
3781/* Internal helper.
3782 * Build most accurate possible datetime for current time. Pass localtime or
3783 * gmtime for f as appropriate.
3784 */
3785static PyObject *
3786datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3787{
3788#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003789 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00003790
3791#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003792 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00003793#else
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003794 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00003795#endif
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003796 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3797 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003798
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003799#else /* ! HAVE_GETTIMEOFDAY */
3800 /* No flavor of gettimeofday exists on this platform. Python's
3801 * time.time() does a lot of other platform tricks to get the
3802 * best time it can on the platform, and we're not going to do
3803 * better than that (if we could, the better code would belong
3804 * in time.time()!) We're limited by the precision of a double,
3805 * though.
3806 */
3807 PyObject *time;
3808 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00003809
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003810 time = time_time();
3811 if (time == NULL)
3812 return NULL;
3813 dtime = PyFloat_AsDouble(time);
3814 Py_DECREF(time);
3815 if (dtime == -1.0 && PyErr_Occurred())
3816 return NULL;
3817 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3818#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00003819}
3820
Tim Peters2a799bf2002-12-16 20:18:38 +00003821/* Return best possible local time -- this isn't constrained by the
3822 * precision of a timestamp.
3823 */
3824static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003825datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003826{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003827 PyObject *self;
3828 PyObject *tzinfo = Py_None;
3829 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003830
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003831 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3832 &tzinfo))
3833 return NULL;
3834 if (check_tzinfo_subclass(tzinfo) < 0)
3835 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00003836
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003837 self = datetime_best_possible(cls,
3838 tzinfo == Py_None ? localtime : gmtime,
3839 tzinfo);
3840 if (self != NULL && tzinfo != Py_None) {
3841 /* Convert UTC to tzinfo's zone. */
3842 PyObject *temp = self;
3843 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3844 Py_DECREF(temp);
3845 }
3846 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003847}
3848
Tim Petersa9bc1682003-01-11 03:39:11 +00003849/* Return best possible UTC time -- this isn't constrained by the
3850 * precision of a timestamp.
3851 */
3852static PyObject *
3853datetime_utcnow(PyObject *cls, PyObject *dummy)
3854{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003855 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00003856}
3857
Tim Peters2a799bf2002-12-16 20:18:38 +00003858/* Return new local datetime from timestamp (Python timestamp -- a double). */
3859static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003860datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003861{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003862 PyObject *self;
3863 double timestamp;
3864 PyObject *tzinfo = Py_None;
3865 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003866
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003867 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3868 keywords, &timestamp, &tzinfo))
3869 return NULL;
3870 if (check_tzinfo_subclass(tzinfo) < 0)
3871 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003872
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003873 self = datetime_from_timestamp(cls,
3874 tzinfo == Py_None ? localtime : gmtime,
3875 timestamp,
3876 tzinfo);
3877 if (self != NULL && tzinfo != Py_None) {
3878 /* Convert UTC to tzinfo's zone. */
3879 PyObject *temp = self;
3880 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3881 Py_DECREF(temp);
3882 }
3883 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003884}
3885
Tim Petersa9bc1682003-01-11 03:39:11 +00003886/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3887static PyObject *
3888datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3889{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003890 double timestamp;
3891 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003892
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003893 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3894 result = datetime_from_timestamp(cls, gmtime, timestamp,
3895 Py_None);
3896 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003897}
3898
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003899/* Return new datetime from time.strptime(). */
3900static PyObject *
3901datetime_strptime(PyObject *cls, PyObject *args)
3902{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003903 static PyObject *module = NULL;
3904 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3905 const char *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003906
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003907 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3908 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003909
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003910 if (module == NULL &&
3911 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3912 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003913
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003914 /* _strptime._strptime returns a two-element tuple. The first
3915 element is a time.struct_time object. The second is the
3916 microseconds (which are not defined for time.struct_time). */
3917 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
3918 if (obj != NULL) {
3919 int i, good_timetuple = 1;
3920 long int ia[7];
3921 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3922 st = PySequence_GetItem(obj, 0);
3923 frac = PySequence_GetItem(obj, 1);
3924 if (st == NULL || frac == NULL)
3925 good_timetuple = 0;
3926 /* copy y/m/d/h/m/s values out of the
3927 time.struct_time */
3928 if (good_timetuple &&
3929 PySequence_Check(st) &&
3930 PySequence_Size(st) >= 6) {
3931 for (i=0; i < 6; i++) {
3932 PyObject *p = PySequence_GetItem(st, i);
3933 if (p == NULL) {
3934 good_timetuple = 0;
3935 break;
3936 }
3937 if (PyInt_Check(p))
3938 ia[i] = PyInt_AsLong(p);
3939 else
3940 good_timetuple = 0;
3941 Py_DECREF(p);
3942 }
3943 }
3944 else
3945 good_timetuple = 0;
3946 /* follow that up with a little dose of microseconds */
3947 if (PyInt_Check(frac))
3948 ia[6] = PyInt_AsLong(frac);
3949 else
3950 good_timetuple = 0;
3951 }
3952 else
3953 good_timetuple = 0;
3954 if (good_timetuple)
3955 result = PyObject_CallFunction(cls, "iiiiiii",
3956 ia[0], ia[1], ia[2],
3957 ia[3], ia[4], ia[5],
3958 ia[6]);
3959 else
3960 PyErr_SetString(PyExc_ValueError,
3961 "unexpected value from _strptime._strptime");
3962 }
3963 Py_XDECREF(obj);
3964 Py_XDECREF(st);
3965 Py_XDECREF(frac);
3966 return result;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003967}
3968
Tim Petersa9bc1682003-01-11 03:39:11 +00003969/* Return new datetime from date/datetime and time arguments. */
3970static PyObject *
3971datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3972{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003973 static char *keywords[] = {"date", "time", NULL};
3974 PyObject *date;
3975 PyObject *time;
3976 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003977
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003978 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3979 &PyDateTime_DateType, &date,
3980 &PyDateTime_TimeType, &time)) {
3981 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00003982
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00003983 if (HASTZINFO(time))
3984 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3985 result = PyObject_CallFunction(cls, "iiiiiiiO",
3986 GET_YEAR(date),
3987 GET_MONTH(date),
3988 GET_DAY(date),
3989 TIME_GET_HOUR(time),
3990 TIME_GET_MINUTE(time),
3991 TIME_GET_SECOND(time),
3992 TIME_GET_MICROSECOND(time),
3993 tzinfo);
3994 }
3995 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003996}
Tim Peters2a799bf2002-12-16 20:18:38 +00003997
3998/*
3999 * Destructor.
4000 */
4001
4002static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004003datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004004{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004005 if (HASTZINFO(self)) {
4006 Py_XDECREF(self->tzinfo);
4007 }
4008 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004009}
4010
4011/*
4012 * Indirect access to tzinfo methods.
4013 */
4014
Tim Peters2a799bf2002-12-16 20:18:38 +00004015/* These are all METH_NOARGS, so don't need to check the arglist. */
4016static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004017datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004018 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4019 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004020}
4021
4022static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004023datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004024 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4025 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004026}
4027
4028static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004029datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004030 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4031 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004032}
4033
4034/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004035 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004036 */
4037
Tim Petersa9bc1682003-01-11 03:39:11 +00004038/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4039 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004040 */
4041static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004042add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004043 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004044{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004045 /* Note that the C-level additions can't overflow, because of
4046 * invariant bounds on the member values.
4047 */
4048 int year = GET_YEAR(date);
4049 int month = GET_MONTH(date);
4050 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4051 int hour = DATE_GET_HOUR(date);
4052 int minute = DATE_GET_MINUTE(date);
4053 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4054 int microsecond = DATE_GET_MICROSECOND(date) +
4055 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004056
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004057 assert(factor == 1 || factor == -1);
4058 if (normalize_datetime(&year, &month, &day,
4059 &hour, &minute, &second, &microsecond) < 0)
4060 return NULL;
4061 else
4062 return new_datetime(year, month, day,
4063 hour, minute, second, microsecond,
4064 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004065}
4066
4067static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004068datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004069{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004070 if (PyDateTime_Check(left)) {
4071 /* datetime + ??? */
4072 if (PyDelta_Check(right))
4073 /* datetime + delta */
4074 return add_datetime_timedelta(
4075 (PyDateTime_DateTime *)left,
4076 (PyDateTime_Delta *)right,
4077 1);
4078 }
4079 else if (PyDelta_Check(left)) {
4080 /* delta + datetime */
4081 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4082 (PyDateTime_Delta *) left,
4083 1);
4084 }
4085 Py_INCREF(Py_NotImplemented);
4086 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004087}
4088
4089static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004090datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004091{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004092 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004093
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004094 if (PyDateTime_Check(left)) {
4095 /* datetime - ??? */
4096 if (PyDateTime_Check(right)) {
4097 /* datetime - datetime */
4098 naivety n1, n2;
4099 int offset1, offset2;
4100 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004101
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004102 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4103 right, &offset2, &n2,
4104 right) < 0)
4105 return NULL;
4106 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4107 if (n1 != n2) {
4108 PyErr_SetString(PyExc_TypeError,
4109 "can't subtract offset-naive and "
4110 "offset-aware datetimes");
4111 return NULL;
4112 }
4113 delta_d = ymd_to_ord(GET_YEAR(left),
4114 GET_MONTH(left),
4115 GET_DAY(left)) -
4116 ymd_to_ord(GET_YEAR(right),
4117 GET_MONTH(right),
4118 GET_DAY(right));
4119 /* These can't overflow, since the values are
4120 * normalized. At most this gives the number of
4121 * seconds in one day.
4122 */
4123 delta_s = (DATE_GET_HOUR(left) -
4124 DATE_GET_HOUR(right)) * 3600 +
4125 (DATE_GET_MINUTE(left) -
4126 DATE_GET_MINUTE(right)) * 60 +
4127 (DATE_GET_SECOND(left) -
4128 DATE_GET_SECOND(right));
4129 delta_us = DATE_GET_MICROSECOND(left) -
4130 DATE_GET_MICROSECOND(right);
4131 /* (left - offset1) - (right - offset2) =
4132 * (left - right) + (offset2 - offset1)
4133 */
4134 delta_s += (offset2 - offset1) * 60;
4135 result = new_delta(delta_d, delta_s, delta_us, 1);
4136 }
4137 else if (PyDelta_Check(right)) {
4138 /* datetime - delta */
4139 result = add_datetime_timedelta(
4140 (PyDateTime_DateTime *)left,
4141 (PyDateTime_Delta *)right,
4142 -1);
4143 }
4144 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004145
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004146 if (result == Py_NotImplemented)
4147 Py_INCREF(result);
4148 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004149}
4150
4151/* Various ways to turn a datetime into a string. */
4152
4153static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004154datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004155{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004156 char buffer[1000];
4157 const char *type_name = Py_TYPE(self)->tp_name;
4158 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004159
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004160 if (DATE_GET_MICROSECOND(self)) {
4161 PyOS_snprintf(buffer, sizeof(buffer),
4162 "%s(%d, %d, %d, %d, %d, %d, %d)",
4163 type_name,
4164 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4165 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4166 DATE_GET_SECOND(self),
4167 DATE_GET_MICROSECOND(self));
4168 }
4169 else if (DATE_GET_SECOND(self)) {
4170 PyOS_snprintf(buffer, sizeof(buffer),
4171 "%s(%d, %d, %d, %d, %d, %d)",
4172 type_name,
4173 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4174 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4175 DATE_GET_SECOND(self));
4176 }
4177 else {
4178 PyOS_snprintf(buffer, sizeof(buffer),
4179 "%s(%d, %d, %d, %d, %d)",
4180 type_name,
4181 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4182 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4183 }
4184 baserepr = PyString_FromString(buffer);
4185 if (baserepr == NULL || ! HASTZINFO(self))
4186 return baserepr;
4187 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004188}
4189
Tim Petersa9bc1682003-01-11 03:39:11 +00004190static PyObject *
4191datetime_str(PyDateTime_DateTime *self)
4192{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004193 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004194}
Tim Peters2a799bf2002-12-16 20:18:38 +00004195
4196static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004197datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004198{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004199 char sep = 'T';
4200 static char *keywords[] = {"sep", NULL};
4201 char buffer[100];
4202 char *cp;
4203 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004204
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004205 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4206 &sep))
4207 return NULL;
4208 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4209 assert(cp != NULL);
4210 *cp++ = sep;
4211 cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4212 result = PyString_FromStringAndSize(buffer, cp - buffer);
4213 if (result == NULL || ! HASTZINFO(self))
4214 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004215
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004216 /* We need to append the UTC offset. */
4217 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4218 (PyObject *)self) < 0) {
4219 Py_DECREF(result);
4220 return NULL;
4221 }
4222 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
4223 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004224}
4225
Tim Petersa9bc1682003-01-11 03:39:11 +00004226static PyObject *
4227datetime_ctime(PyDateTime_DateTime *self)
4228{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004229 return format_ctime((PyDateTime_Date *)self,
4230 DATE_GET_HOUR(self),
4231 DATE_GET_MINUTE(self),
4232 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004233}
4234
Tim Peters2a799bf2002-12-16 20:18:38 +00004235/* Miscellaneous methods. */
4236
Tim Petersa9bc1682003-01-11 03:39:11 +00004237/* This is more natural as a tp_compare, but doesn't work then: for whatever
4238 * reason, Python's try_3way_compare ignores tp_compare unless
4239 * PyInstance_Check returns true, but these aren't old-style classes.
4240 */
4241static PyObject *
4242datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4243{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004244 int diff;
4245 naivety n1, n2;
4246 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004247
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004248 if (! PyDateTime_Check(other)) {
4249 /* If other has a "timetuple" attr, that's an advertised
4250 * hook for other classes to ask to get comparison control.
4251 * However, date instances have a timetuple attr, and we
4252 * don't want to allow that comparison. Because datetime
4253 * is a subclass of date, when mixing date and datetime
4254 * in a comparison, Python gives datetime the first shot
4255 * (it's the more specific subtype). So we can stop that
4256 * combination here reliably.
4257 */
4258 if (PyObject_HasAttrString(other, "timetuple") &&
4259 ! PyDate_Check(other)) {
4260 /* A hook for other kinds of datetime objects. */
4261 Py_INCREF(Py_NotImplemented);
4262 return Py_NotImplemented;
4263 }
4264 if (op == Py_EQ || op == Py_NE) {
4265 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4266 Py_INCREF(result);
4267 return result;
4268 }
4269 /* Stop this from falling back to address comparison. */
4270 return cmperror((PyObject *)self, other);
4271 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004272
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004273 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4274 (PyObject *)self,
4275 other, &offset2, &n2,
4276 other) < 0)
4277 return NULL;
4278 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4279 /* If they're both naive, or both aware and have the same offsets,
4280 * we get off cheap. Note that if they're both naive, offset1 ==
4281 * offset2 == 0 at this point.
4282 */
4283 if (n1 == n2 && offset1 == offset2) {
4284 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4285 _PyDateTime_DATETIME_DATASIZE);
4286 return diff_to_bool(diff, op);
4287 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004288
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004289 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4290 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004291
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004292 assert(offset1 != offset2); /* else last "if" handled it */
4293 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4294 other);
4295 if (delta == NULL)
4296 return NULL;
4297 diff = GET_TD_DAYS(delta);
4298 if (diff == 0)
4299 diff = GET_TD_SECONDS(delta) |
4300 GET_TD_MICROSECONDS(delta);
4301 Py_DECREF(delta);
4302 return diff_to_bool(diff, op);
4303 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004304
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004305 assert(n1 != n2);
4306 PyErr_SetString(PyExc_TypeError,
4307 "can't compare offset-naive and "
4308 "offset-aware datetimes");
4309 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004310}
4311
4312static long
4313datetime_hash(PyDateTime_DateTime *self)
4314{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004315 if (self->hashcode == -1) {
4316 naivety n;
4317 int offset;
4318 PyObject *temp;
Tim Petersa9bc1682003-01-11 03:39:11 +00004319
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004320 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4321 &offset);
4322 assert(n != OFFSET_UNKNOWN);
4323 if (n == OFFSET_ERROR)
4324 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004325
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004326 /* Reduce this to a hash of another object. */
4327 if (n == OFFSET_NAIVE)
4328 temp = PyString_FromStringAndSize(
4329 (char *)self->data,
4330 _PyDateTime_DATETIME_DATASIZE);
4331 else {
4332 int days;
4333 int seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004334
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004335 assert(n == OFFSET_AWARE);
4336 assert(HASTZINFO(self));
4337 days = ymd_to_ord(GET_YEAR(self),
4338 GET_MONTH(self),
4339 GET_DAY(self));
4340 seconds = DATE_GET_HOUR(self) * 3600 +
4341 (DATE_GET_MINUTE(self) - offset) * 60 +
4342 DATE_GET_SECOND(self);
4343 temp = new_delta(days,
4344 seconds,
4345 DATE_GET_MICROSECOND(self),
4346 1);
4347 }
4348 if (temp != NULL) {
4349 self->hashcode = PyObject_Hash(temp);
4350 Py_DECREF(temp);
4351 }
4352 }
4353 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004354}
Tim Peters2a799bf2002-12-16 20:18:38 +00004355
4356static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004357datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004358{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004359 PyObject *clone;
4360 PyObject *tuple;
4361 int y = GET_YEAR(self);
4362 int m = GET_MONTH(self);
4363 int d = GET_DAY(self);
4364 int hh = DATE_GET_HOUR(self);
4365 int mm = DATE_GET_MINUTE(self);
4366 int ss = DATE_GET_SECOND(self);
4367 int us = DATE_GET_MICROSECOND(self);
4368 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004369
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004370 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4371 datetime_kws,
4372 &y, &m, &d, &hh, &mm, &ss, &us,
4373 &tzinfo))
4374 return NULL;
4375 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4376 if (tuple == NULL)
4377 return NULL;
4378 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4379 Py_DECREF(tuple);
4380 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004381}
4382
4383static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004384datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004385{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004386 int y, m, d, hh, mm, ss, us;
4387 PyObject *result;
4388 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004389
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004390 PyObject *tzinfo;
4391 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004392
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004393 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4394 &PyDateTime_TZInfoType, &tzinfo))
4395 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004396
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004397 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4398 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004399
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004400 /* Conversion to self's own time zone is a NOP. */
4401 if (self->tzinfo == tzinfo) {
4402 Py_INCREF(self);
4403 return (PyObject *)self;
4404 }
Tim Peters521fc152002-12-31 17:36:56 +00004405
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004406 /* Convert self to UTC. */
4407 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4408 if (offset == -1 && PyErr_Occurred())
4409 return NULL;
4410 if (none)
4411 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004412
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004413 y = GET_YEAR(self);
4414 m = GET_MONTH(self);
4415 d = GET_DAY(self);
4416 hh = DATE_GET_HOUR(self);
4417 mm = DATE_GET_MINUTE(self);
4418 ss = DATE_GET_SECOND(self);
4419 us = DATE_GET_MICROSECOND(self);
Tim Peters52dcce22003-01-23 16:36:11 +00004420
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004421 mm -= offset;
4422 if ((mm < 0 || mm >= 60) &&
4423 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4424 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004425
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004426 /* Attach new tzinfo and let fromutc() do the rest. */
4427 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4428 if (result != NULL) {
4429 PyObject *temp = result;
Tim Peters52dcce22003-01-23 16:36:11 +00004430
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004431 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4432 Py_DECREF(temp);
4433 }
4434 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004435
Tim Peters52dcce22003-01-23 16:36:11 +00004436NeedAware:
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004437 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4438 "a naive datetime");
4439 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004440}
4441
4442static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004443datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004444{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004445 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004446
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004447 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4448 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004449
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004450 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4451 if (dstflag == -1 && PyErr_Occurred())
4452 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004453
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004454 if (none)
4455 dstflag = -1;
4456 else if (dstflag != 0)
4457 dstflag = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004458
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004459 }
4460 return build_struct_time(GET_YEAR(self),
4461 GET_MONTH(self),
4462 GET_DAY(self),
4463 DATE_GET_HOUR(self),
4464 DATE_GET_MINUTE(self),
4465 DATE_GET_SECOND(self),
4466 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004467}
4468
4469static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004470datetime_getdate(PyDateTime_DateTime *self)
4471{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004472 return new_date(GET_YEAR(self),
4473 GET_MONTH(self),
4474 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004475}
4476
4477static PyObject *
4478datetime_gettime(PyDateTime_DateTime *self)
4479{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004480 return new_time(DATE_GET_HOUR(self),
4481 DATE_GET_MINUTE(self),
4482 DATE_GET_SECOND(self),
4483 DATE_GET_MICROSECOND(self),
4484 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004485}
4486
4487static PyObject *
4488datetime_gettimetz(PyDateTime_DateTime *self)
4489{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004490 return new_time(DATE_GET_HOUR(self),
4491 DATE_GET_MINUTE(self),
4492 DATE_GET_SECOND(self),
4493 DATE_GET_MICROSECOND(self),
4494 HASTZINFO(self) ? self->tzinfo : Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004495}
4496
4497static PyObject *
4498datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004499{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004500 int y = GET_YEAR(self);
4501 int m = GET_MONTH(self);
4502 int d = GET_DAY(self);
4503 int hh = DATE_GET_HOUR(self);
4504 int mm = DATE_GET_MINUTE(self);
4505 int ss = DATE_GET_SECOND(self);
4506 int us = 0; /* microseconds are ignored in a timetuple */
4507 int offset = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004508
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004509 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4510 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004511
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004512 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4513 if (offset == -1 && PyErr_Occurred())
4514 return NULL;
4515 }
4516 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4517 * 0 in a UTC timetuple regardless of what dst() says.
4518 */
4519 if (offset) {
4520 /* Subtract offset minutes & normalize. */
4521 int stat;
Tim Peters2a799bf2002-12-16 20:18:38 +00004522
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004523 mm -= offset;
4524 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4525 if (stat < 0) {
4526 /* At the edges, it's possible we overflowed
4527 * beyond MINYEAR or MAXYEAR.
4528 */
4529 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4530 PyErr_Clear();
4531 else
4532 return NULL;
4533 }
4534 }
4535 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004536}
4537
Tim Peters371935f2003-02-01 01:52:50 +00004538/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004539
Tim Petersa9bc1682003-01-11 03:39:11 +00004540/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004541 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4542 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004543 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004544 */
4545static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004546datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004547{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004548 PyObject *basestate;
4549 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004550
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004551 basestate = PyString_FromStringAndSize((char *)self->data,
4552 _PyDateTime_DATETIME_DATASIZE);
4553 if (basestate != NULL) {
4554 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4555 result = PyTuple_Pack(1, basestate);
4556 else
4557 result = PyTuple_Pack(2, basestate, self->tzinfo);
4558 Py_DECREF(basestate);
4559 }
4560 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004561}
4562
4563static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004564datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004565{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004566 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004567}
4568
Tim Petersa9bc1682003-01-11 03:39:11 +00004569static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004570
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004571 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004572
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004573 {"now", (PyCFunction)datetime_now,
4574 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4575 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004576
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004577 {"utcnow", (PyCFunction)datetime_utcnow,
4578 METH_NOARGS | METH_CLASS,
4579 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004580
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004581 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4582 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4583 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004584
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004585 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4586 METH_VARARGS | METH_CLASS,
4587 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4588 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004589
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004590 {"strptime", (PyCFunction)datetime_strptime,
4591 METH_VARARGS | METH_CLASS,
4592 PyDoc_STR("string, format -> new datetime parsed from a string "
4593 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004594
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004595 {"combine", (PyCFunction)datetime_combine,
4596 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4597 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004598
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004599 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004600
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004601 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4602 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004603
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004604 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4605 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004606
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004607 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4608 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004609
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004610 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4611 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004612
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004613 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4614 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004615
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004616 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4617 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004618
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004619 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4620 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4621 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4622 "sep is used to separate the year from the time, and "
4623 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004624
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004625 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4626 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004627
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004628 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4629 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004630
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004631 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4632 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004633
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004634 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4635 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004636
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004637 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4638 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004639
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004640 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4641 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004642
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004643 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004644};
4645
Tim Petersa9bc1682003-01-11 03:39:11 +00004646static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004647PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4648\n\
4649The year, month and day arguments are required. tzinfo may be None, or an\n\
4650instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004651
Tim Petersa9bc1682003-01-11 03:39:11 +00004652static PyNumberMethods datetime_as_number = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004653 datetime_add, /* nb_add */
4654 datetime_subtract, /* nb_subtract */
4655 0, /* nb_multiply */
4656 0, /* nb_divide */
4657 0, /* nb_remainder */
4658 0, /* nb_divmod */
4659 0, /* nb_power */
4660 0, /* nb_negative */
4661 0, /* nb_positive */
4662 0, /* nb_absolute */
4663 0, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00004664};
4665
Tim Petersa9bc1682003-01-11 03:39:11 +00004666statichere PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004667 PyObject_HEAD_INIT(NULL)
4668 0, /* ob_size */
4669 "datetime.datetime", /* tp_name */
4670 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4671 0, /* tp_itemsize */
4672 (destructor)datetime_dealloc, /* tp_dealloc */
4673 0, /* tp_print */
4674 0, /* tp_getattr */
4675 0, /* tp_setattr */
4676 0, /* tp_compare */
4677 (reprfunc)datetime_repr, /* tp_repr */
4678 &datetime_as_number, /* tp_as_number */
4679 0, /* tp_as_sequence */
4680 0, /* tp_as_mapping */
4681 (hashfunc)datetime_hash, /* tp_hash */
4682 0, /* tp_call */
4683 (reprfunc)datetime_str, /* tp_str */
4684 PyObject_GenericGetAttr, /* tp_getattro */
4685 0, /* tp_setattro */
4686 0, /* tp_as_buffer */
4687 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4688 Py_TPFLAGS_BASETYPE, /* tp_flags */
4689 datetime_doc, /* tp_doc */
4690 0, /* tp_traverse */
4691 0, /* tp_clear */
4692 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
4693 0, /* tp_weaklistoffset */
4694 0, /* tp_iter */
4695 0, /* tp_iternext */
4696 datetime_methods, /* tp_methods */
4697 0, /* tp_members */
4698 datetime_getset, /* tp_getset */
4699 &PyDateTime_DateType, /* tp_base */
4700 0, /* tp_dict */
4701 0, /* tp_descr_get */
4702 0, /* tp_descr_set */
4703 0, /* tp_dictoffset */
4704 0, /* tp_init */
4705 datetime_alloc, /* tp_alloc */
4706 datetime_new, /* tp_new */
4707 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004708};
4709
4710/* ---------------------------------------------------------------------------
4711 * Module methods and initialization.
4712 */
4713
4714static PyMethodDef module_methods[] = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004715 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004716};
4717
Tim Peters9ddf40b2004-06-20 22:41:32 +00004718/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4719 * datetime.h.
4720 */
4721static PyDateTime_CAPI CAPI = {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004722 &PyDateTime_DateType,
4723 &PyDateTime_DateTimeType,
4724 &PyDateTime_TimeType,
4725 &PyDateTime_DeltaType,
4726 &PyDateTime_TZInfoType,
4727 new_date_ex,
4728 new_datetime_ex,
4729 new_time_ex,
4730 new_delta_ex,
4731 datetime_fromtimestamp,
4732 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00004733};
4734
4735
Tim Peters2a799bf2002-12-16 20:18:38 +00004736PyMODINIT_FUNC
4737initdatetime(void)
4738{
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004739 PyObject *m; /* a module object */
4740 PyObject *d; /* its dict */
4741 PyObject *x;
Tim Peters2a799bf2002-12-16 20:18:38 +00004742
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004743 m = Py_InitModule3("datetime", module_methods,
4744 "Fast implementation of the datetime type.");
4745 if (m == NULL)
4746 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004747
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004748 if (PyType_Ready(&PyDateTime_DateType) < 0)
4749 return;
4750 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4751 return;
4752 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4753 return;
4754 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4755 return;
4756 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4757 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004758
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004759 /* timedelta values */
4760 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004761
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004762 x = new_delta(0, 0, 1, 0);
4763 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4764 return;
4765 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004766
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004767 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4768 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4769 return;
4770 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004771
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004772 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4773 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4774 return;
4775 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004776
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004777 /* date values */
4778 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004779
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004780 x = new_date(1, 1, 1);
4781 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4782 return;
4783 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004784
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004785 x = new_date(MAXYEAR, 12, 31);
4786 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4787 return;
4788 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004789
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004790 x = new_delta(1, 0, 0, 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 Pitrouc7c96a92010-05-09 15:15:40 +00004795 /* time values */
4796 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004797
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004798 x = new_time(0, 0, 0, 0, Py_None);
4799 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4800 return;
4801 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004802
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004803 x = new_time(23, 59, 59, 999999, Py_None);
4804 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4805 return;
4806 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004807
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004808 x = new_delta(0, 0, 1, 0);
4809 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4810 return;
4811 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004812
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004813 /* datetime values */
4814 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004815
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004816 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4817 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4818 return;
4819 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004820
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004821 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4822 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4823 return;
4824 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004825
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004826 x = new_delta(0, 0, 1, 0);
4827 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4828 return;
4829 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004830
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004831 /* module initialization */
4832 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4833 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00004834
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004835 Py_INCREF(&PyDateTime_DateType);
4836 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004837
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004838 Py_INCREF(&PyDateTime_DateTimeType);
4839 PyModule_AddObject(m, "datetime",
4840 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00004841
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004842 Py_INCREF(&PyDateTime_TimeType);
4843 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00004844
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004845 Py_INCREF(&PyDateTime_DeltaType);
4846 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004847
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004848 Py_INCREF(&PyDateTime_TZInfoType);
4849 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004850
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004851 x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
4852 NULL);
4853 if (x == NULL)
4854 return;
4855 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00004856
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004857 /* A 4-year cycle has an extra leap day over what we'd get from
4858 * pasting together 4 single years.
4859 */
4860 assert(DI4Y == 4 * 365 + 1);
4861 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004862
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004863 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4864 * get from pasting together 4 100-year cycles.
4865 */
4866 assert(DI400Y == 4 * DI100Y + 1);
4867 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004868
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004869 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4870 * pasting together 25 4-year cycles.
4871 */
4872 assert(DI100Y == 25 * DI4Y - 1);
4873 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004874
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004875 us_per_us = PyInt_FromLong(1);
4876 us_per_ms = PyInt_FromLong(1000);
4877 us_per_second = PyInt_FromLong(1000000);
4878 us_per_minute = PyInt_FromLong(60000000);
4879 seconds_per_day = PyInt_FromLong(24 * 3600);
4880 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4881 us_per_minute == NULL || seconds_per_day == NULL)
4882 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004883
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004884 /* The rest are too big for 32-bit ints, but even
4885 * us_per_week fits in 40 bits, so doubles should be exact.
4886 */
4887 us_per_hour = PyLong_FromDouble(3600000000.0);
4888 us_per_day = PyLong_FromDouble(86400000000.0);
4889 us_per_week = PyLong_FromDouble(604800000000.0);
4890 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4891 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004892}
Tim Petersf3615152003-01-01 21:51:37 +00004893
4894/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004895Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004896 x.n = x stripped of its timezone -- its naive time.
4897 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004898 return None
Tim Petersf3615152003-01-01 21:51:37 +00004899 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00004900 return None
Tim Petersf3615152003-01-01 21:51:37 +00004901 x.s = x's standard offset, x.o - x.d
4902
4903Now some derived rules, where k is a duration (timedelta).
4904
49051. x.o = x.s + x.d
4906 This follows from the definition of x.s.
4907
Tim Petersc5dc4da2003-01-02 17:55:03 +000049082. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004909 This is actually a requirement, an assumption we need to make about
4910 sane tzinfo classes.
4911
49123. The naive UTC time corresponding to x is x.n - x.o.
4913 This is again a requirement for a sane tzinfo class.
4914
49154. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004916 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004917
Tim Petersc5dc4da2003-01-02 17:55:03 +000049185. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004919 Again follows from how arithmetic is defined.
4920
Tim Peters8bb5ad22003-01-24 02:44:45 +00004921Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004922(meaning that the various tzinfo methods exist, and don't blow up or return
4923None when called).
4924
Tim Petersa9bc1682003-01-11 03:39:11 +00004925The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004926x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004927
4928By #3, we want
4929
Tim Peters8bb5ad22003-01-24 02:44:45 +00004930 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004931
4932The algorithm starts by attaching tz to x.n, and calling that y. So
4933x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4934becomes true; in effect, we want to solve [2] for k:
4935
Tim Peters8bb5ad22003-01-24 02:44:45 +00004936 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004937
4938By #1, this is the same as
4939
Tim Peters8bb5ad22003-01-24 02:44:45 +00004940 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004941
4942By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4943Substituting that into [3],
4944
Tim Peters8bb5ad22003-01-24 02:44:45 +00004945 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4946 k - (y+k).s - (y+k).d = 0; rearranging,
4947 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4948 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004949
Tim Peters8bb5ad22003-01-24 02:44:45 +00004950On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4951approximate k by ignoring the (y+k).d term at first. Note that k can't be
4952very large, since all offset-returning methods return a duration of magnitude
4953less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4954be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004955
4956In any case, the new value is
4957
Tim Peters8bb5ad22003-01-24 02:44:45 +00004958 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004959
Tim Peters8bb5ad22003-01-24 02:44:45 +00004960It's helpful to step back at look at [4] from a higher level: it's simply
4961mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004962
4963At this point, if
4964
Tim Peters8bb5ad22003-01-24 02:44:45 +00004965 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004966
4967we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004968at the start of daylight time. Picture US Eastern for concreteness. The wall
4969time 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 +00004970sense then. The docs ask that an Eastern tzinfo class consider such a time to
4971be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4972on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004973the only spelling that makes sense on the local wall clock.
4974
Tim Petersc5dc4da2003-01-02 17:55:03 +00004975In fact, if [5] holds at this point, we do have the standard-time spelling,
4976but that takes a bit of proof. We first prove a stronger result. What's the
4977difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004978
Tim Peters8bb5ad22003-01-24 02:44:45 +00004979 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004980
Tim Petersc5dc4da2003-01-02 17:55:03 +00004981Now
4982 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004983 (y + y.s).n = by #5
4984 y.n + y.s = since y.n = x.n
4985 x.n + y.s = since z and y are have the same tzinfo member,
4986 y.s = z.s by #2
4987 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004988
Tim Petersc5dc4da2003-01-02 17:55:03 +00004989Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004990
Tim Petersc5dc4da2003-01-02 17:55:03 +00004991 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004992 x.n - ((x.n + z.s) - z.o) = expanding
4993 x.n - x.n - z.s + z.o = cancelling
4994 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004995 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004996
Tim Petersc5dc4da2003-01-02 17:55:03 +00004997So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004998
Tim Petersc5dc4da2003-01-02 17:55:03 +00004999If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005000spelling we wanted in the endcase described above. We're done. Contrarily,
5001if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005002
Tim Petersc5dc4da2003-01-02 17:55:03 +00005003If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5004add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005005local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005006
Tim Petersc5dc4da2003-01-02 17:55:03 +00005007Let
Tim Petersf3615152003-01-01 21:51:37 +00005008
Tim Peters4fede1a2003-01-04 00:26:59 +00005009 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005010
Tim Peters4fede1a2003-01-04 00:26:59 +00005011and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005012
Tim Peters8bb5ad22003-01-24 02:44:45 +00005013 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005014
Tim Peters8bb5ad22003-01-24 02:44:45 +00005015If so, we're done. If not, the tzinfo class is insane, according to the
5016assumptions we've made. This also requires a bit of proof. As before, let's
5017compute the difference between the LHS and RHS of [8] (and skipping some of
5018the justifications for the kinds of substitutions we've done several times
5019already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005020
Tim Peters8bb5ad22003-01-24 02:44:45 +00005021 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouc7c96a92010-05-09 15:15:40 +00005022 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5023 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5024 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5025 - z.n + z.n - z.o + z'.o = cancel z.n
5026 - z.o + z'.o = #1 twice
5027 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5028 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005029
5030So 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 +00005031we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5032return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005033
Tim Peters8bb5ad22003-01-24 02:44:45 +00005034How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5035a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5036would have to change the result dst() returns: we start in DST, and moving
5037a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005038
Tim Peters8bb5ad22003-01-24 02:44:45 +00005039There isn't a sane case where this can happen. The closest it gets is at
5040the end of DST, where there's an hour in UTC with no spelling in a hybrid
5041tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5042that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5043UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5044time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5045clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5046standard time. Since that's what the local clock *does*, we want to map both
5047UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005048in local time, but so it goes -- it's the way the local clock works.
5049
Tim Peters8bb5ad22003-01-24 02:44:45 +00005050When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5051so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5052z' = 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 +00005053(correctly) concludes that z' is not UTC-equivalent to x.
5054
5055Because we know z.d said z was in daylight time (else [5] would have held and
5056we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005057and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005058return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5059but the reasoning doesn't depend on the example -- it depends on there being
5060two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005061z' must be in standard time, and is the spelling we want in this case.
5062
5063Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5064concerned (because it takes z' as being in standard time rather than the
5065daylight time we intend here), but returning it gives the real-life "local
5066clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5067tz.
5068
5069When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5070the 1:MM standard time spelling we want.
5071
5072So how can this break? One of the assumptions must be violated. Two
5073possibilities:
5074
50751) [2] effectively says that y.s is invariant across all y belong to a given
5076 time zone. This isn't true if, for political reasons or continental drift,
5077 a region decides to change its base offset from UTC.
5078
50792) There may be versions of "double daylight" time where the tail end of
5080 the analysis gives up a step too early. I haven't thought about that
5081 enough to say.
5082
5083In any case, it's clear that the default fromutc() is strong enough to handle
5084"almost all" time zones: so long as the standard offset is invariant, it
5085doesn't matter if daylight time transition points change from year to year, or
5086if daylight time is skipped in some years; it doesn't matter how large or
5087small dst() may get within its bounds; and it doesn't even matter if some
5088perverse time zone returns a negative dst()). So a breaking case must be
5089pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005090--------------------------------------------------------------------------- */