blob: ee558ce12eb9a2bd0a39d76bf142c38951180201 [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
30# error "datetime.c requires that C int have at least 32 bits"
31#endif
32
33#define MINYEAR 1
34#define MAXYEAR 9999
35
36/* Nine decimal digits is easy to communicate, and leaves enough room
37 * so that two delta days can be added w/o fear of overflowing a signed
38 * 32-bit int, and with plenty of room left over to absorb any possible
39 * carries from adding seconds.
40 */
41#define MAX_DELTA_DAYS 999999999
42
43/* Rename the long macros in datetime.h to more reasonable short names. */
44#define GET_YEAR PyDateTime_GET_YEAR
45#define GET_MONTH PyDateTime_GET_MONTH
46#define GET_DAY PyDateTime_GET_DAY
47#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
48#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
49#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
50#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
51
52/* Date accessors for date and datetime. */
53#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
54 ((o)->data[1] = ((v) & 0x00ff)))
55#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
56#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
57
58/* Date/Time accessors for datetime. */
59#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
60#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
61#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
62#define DATE_SET_MICROSECOND(o, v) \
63 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
64 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
65 ((o)->data[9] = ((v) & 0x0000ff)))
66
67/* Time accessors for time. */
68#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
69#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
70#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
71#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
72#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
73#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
74#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
75#define TIME_SET_MICROSECOND(o, v) \
76 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
77 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
78 ((o)->data[5] = ((v) & 0x0000ff)))
79
80/* Delta accessors for timedelta. */
81#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
82#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
83#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
84
85#define SET_TD_DAYS(o, v) ((o)->days = (v))
86#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
87#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
88
Tim Petersa032d2e2003-01-11 00:15:54 +000089/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
90 * p->hastzinfo.
91 */
92#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
93
Tim Peters3f606292004-03-21 23:38:41 +000094/* M is a char or int claiming to be a valid month. The macro is equivalent
95 * to the two-sided Python test
96 * 1 <= M <= 12
97 */
98#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
99
Tim Peters2a799bf2002-12-16 20:18:38 +0000100/* Forward declarations. */
101static PyTypeObject PyDateTime_DateType;
102static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000103static PyTypeObject PyDateTime_DeltaType;
104static PyTypeObject PyDateTime_TimeType;
105static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000106
107/* ---------------------------------------------------------------------------
108 * Math utilities.
109 */
110
111/* k = i+j overflows iff k differs in sign from both inputs,
112 * iff k^i has sign bit set and k^j has sign bit set,
113 * iff (k^i)&(k^j) has sign bit set.
114 */
115#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
116 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
117
118/* Compute Python divmod(x, y), returning the quotient and storing the
119 * remainder into *r. The quotient is the floor of x/y, and that's
120 * the real point of this. C will probably truncate instead (C99
121 * requires truncation; C89 left it implementation-defined).
122 * Simplification: we *require* that y > 0 here. That's appropriate
123 * for all the uses made of it. This simplifies the code and makes
124 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
125 * overflow case).
126 */
127static int
128divmod(int x, int y, int *r)
129{
130 int quo;
131
132 assert(y > 0);
133 quo = x / y;
134 *r = x - quo * y;
135 if (*r < 0) {
136 --quo;
137 *r += y;
138 }
139 assert(0 <= *r && *r < y);
140 return quo;
141}
142
Tim Peters5d644dd2003-01-02 16:32:54 +0000143/* Round a double to the nearest long. |x| must be small enough to fit
144 * in a C long; this is not checked.
145 */
146static long
147round_to_long(double x)
148{
149 if (x >= 0.0)
150 x = floor(x + 0.5);
151 else
152 x = ceil(x - 0.5);
153 return (long)x;
154}
155
Tim Peters2a799bf2002-12-16 20:18:38 +0000156/* ---------------------------------------------------------------------------
157 * General calendrical helper functions
158 */
159
160/* For each month ordinal in 1..12, the number of days in that month,
161 * and the number of days before that month in the same year. These
162 * are correct for non-leap years only.
163 */
164static int _days_in_month[] = {
165 0, /* unused; this vector uses 1-based indexing */
166 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
167};
168
169static int _days_before_month[] = {
170 0, /* unused; this vector uses 1-based indexing */
171 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
172};
173
174/* year -> 1 if leap year, else 0. */
175static int
176is_leap(int year)
177{
178 /* Cast year to unsigned. The result is the same either way, but
179 * C can generate faster code for unsigned mod than for signed
180 * mod (especially for % 4 -- a good compiler should just grab
181 * the last 2 bits when the LHS is unsigned).
182 */
183 const unsigned int ayear = (unsigned int)year;
184 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
185}
186
187/* year, month -> number of days in that month in that year */
188static int
189days_in_month(int year, int month)
190{
191 assert(month >= 1);
192 assert(month <= 12);
193 if (month == 2 && is_leap(year))
194 return 29;
195 else
196 return _days_in_month[month];
197}
198
199/* year, month -> number of days in year preceeding first day of month */
200static int
201days_before_month(int year, int month)
202{
203 int days;
204
205 assert(month >= 1);
206 assert(month <= 12);
207 days = _days_before_month[month];
208 if (month > 2 && is_leap(year))
209 ++days;
210 return days;
211}
212
213/* year -> number of days before January 1st of year. Remember that we
214 * start with year 1, so days_before_year(1) == 0.
215 */
216static int
217days_before_year(int year)
218{
219 int y = year - 1;
220 /* This is incorrect if year <= 0; we really want the floor
221 * here. But so long as MINYEAR is 1, the smallest year this
222 * can see is 0 (this can happen in some normalization endcases),
223 * so we'll just special-case that.
224 */
225 assert (year >= 0);
226 if (y >= 0)
227 return y*365 + y/4 - y/100 + y/400;
228 else {
229 assert(y == -1);
230 return -366;
231 }
232}
233
234/* Number of days in 4, 100, and 400 year cycles. That these have
235 * the correct values is asserted in the module init function.
236 */
237#define DI4Y 1461 /* days_before_year(5); days in 4 years */
238#define DI100Y 36524 /* days_before_year(101); days in 100 years */
239#define DI400Y 146097 /* days_before_year(401); days in 400 years */
240
241/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
242static void
243ord_to_ymd(int ordinal, int *year, int *month, int *day)
244{
245 int n, n1, n4, n100, n400, leapyear, preceding;
246
247 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
248 * leap years repeats exactly every 400 years. The basic strategy is
249 * to find the closest 400-year boundary at or before ordinal, then
250 * work with the offset from that boundary to ordinal. Life is much
251 * clearer if we subtract 1 from ordinal first -- then the values
252 * of ordinal at 400-year boundaries are exactly those divisible
253 * by DI400Y:
254 *
255 * D M Y n n-1
256 * -- --- ---- ---------- ----------------
257 * 31 Dec -400 -DI400Y -DI400Y -1
258 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
259 * ...
260 * 30 Dec 000 -1 -2
261 * 31 Dec 000 0 -1
262 * 1 Jan 001 1 0 400-year boundary
263 * 2 Jan 001 2 1
264 * 3 Jan 001 3 2
265 * ...
266 * 31 Dec 400 DI400Y DI400Y -1
267 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
268 */
269 assert(ordinal >= 1);
270 --ordinal;
271 n400 = ordinal / DI400Y;
272 n = ordinal % DI400Y;
273 *year = n400 * 400 + 1;
274
275 /* Now n is the (non-negative) offset, in days, from January 1 of
276 * year, to the desired date. Now compute how many 100-year cycles
277 * precede n.
278 * Note that it's possible for n100 to equal 4! In that case 4 full
279 * 100-year cycles precede the desired day, which implies the
280 * desired day is December 31 at the end of a 400-year cycle.
281 */
282 n100 = n / DI100Y;
283 n = n % DI100Y;
284
285 /* Now compute how many 4-year cycles precede it. */
286 n4 = n / DI4Y;
287 n = n % DI4Y;
288
289 /* And now how many single years. Again n1 can be 4, and again
290 * meaning that the desired day is December 31 at the end of the
291 * 4-year cycle.
292 */
293 n1 = n / 365;
294 n = n % 365;
295
296 *year += n100 * 100 + n4 * 4 + n1;
297 if (n1 == 4 || n100 == 4) {
298 assert(n == 0);
299 *year -= 1;
300 *month = 12;
301 *day = 31;
302 return;
303 }
304
305 /* Now the year is correct, and n is the offset from January 1. We
306 * find the month via an estimate that's either exact or one too
307 * large.
308 */
309 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
310 assert(leapyear == is_leap(*year));
311 *month = (n + 50) >> 5;
312 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
313 if (preceding > n) {
314 /* estimate is too large */
315 *month -= 1;
316 preceding -= days_in_month(*year, *month);
317 }
318 n -= preceding;
319 assert(0 <= n);
320 assert(n < days_in_month(*year, *month));
321
322 *day = n + 1;
323}
324
325/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
326static int
327ymd_to_ord(int year, int month, int day)
328{
329 return days_before_year(year) + days_before_month(year, month) + day;
330}
331
332/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
333static int
334weekday(int year, int month, int day)
335{
336 return (ymd_to_ord(year, month, day) + 6) % 7;
337}
338
339/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
340 * first calendar week containing a Thursday.
341 */
342static int
343iso_week1_monday(int year)
344{
345 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
346 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
347 int first_weekday = (first_day + 6) % 7;
348 /* ordinal of closest Monday at or before 1/1 */
349 int week1_monday = first_day - first_weekday;
350
351 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
352 week1_monday += 7;
353 return week1_monday;
354}
355
356/* ---------------------------------------------------------------------------
357 * Range checkers.
358 */
359
360/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
361 * If not, raise OverflowError and return -1.
362 */
363static int
364check_delta_day_range(int days)
365{
366 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
367 return 0;
368 PyErr_Format(PyExc_OverflowError,
369 "days=%d; must have magnitude <= %d",
Guido van Rossumbd43e912002-12-16 20:34:55 +0000370 days, MAX_DELTA_DAYS);
Tim Peters2a799bf2002-12-16 20:18:38 +0000371 return -1;
372}
373
374/* Check that date arguments are in range. Return 0 if they are. If they
375 * aren't, raise ValueError and return -1.
376 */
377static int
378check_date_args(int year, int month, int day)
379{
380
381 if (year < MINYEAR || year > MAXYEAR) {
382 PyErr_SetString(PyExc_ValueError,
383 "year is out of range");
384 return -1;
385 }
386 if (month < 1 || month > 12) {
387 PyErr_SetString(PyExc_ValueError,
388 "month must be in 1..12");
389 return -1;
390 }
391 if (day < 1 || day > days_in_month(year, month)) {
392 PyErr_SetString(PyExc_ValueError,
393 "day is out of range for month");
394 return -1;
395 }
396 return 0;
397}
398
399/* Check that time arguments are in range. Return 0 if they are. If they
400 * aren't, raise ValueError and return -1.
401 */
402static int
403check_time_args(int h, int m, int s, int us)
404{
405 if (h < 0 || h > 23) {
406 PyErr_SetString(PyExc_ValueError,
407 "hour must be in 0..23");
408 return -1;
409 }
410 if (m < 0 || m > 59) {
411 PyErr_SetString(PyExc_ValueError,
412 "minute must be in 0..59");
413 return -1;
414 }
415 if (s < 0 || s > 59) {
416 PyErr_SetString(PyExc_ValueError,
417 "second must be in 0..59");
418 return -1;
419 }
420 if (us < 0 || us > 999999) {
421 PyErr_SetString(PyExc_ValueError,
422 "microsecond must be in 0..999999");
423 return -1;
424 }
425 return 0;
426}
427
428/* ---------------------------------------------------------------------------
429 * Normalization utilities.
430 */
431
432/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
433 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
434 * at least factor, enough of *lo is converted into "hi" units so that
435 * 0 <= *lo < factor. The input values must be such that int overflow
436 * is impossible.
437 */
438static void
439normalize_pair(int *hi, int *lo, int factor)
440{
441 assert(factor > 0);
442 assert(lo != hi);
443 if (*lo < 0 || *lo >= factor) {
444 const int num_hi = divmod(*lo, factor, lo);
445 const int new_hi = *hi + num_hi;
446 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
447 *hi = new_hi;
448 }
449 assert(0 <= *lo && *lo < factor);
450}
451
452/* Fiddle days (d), seconds (s), and microseconds (us) so that
453 * 0 <= *s < 24*3600
454 * 0 <= *us < 1000000
455 * The input values must be such that the internals don't overflow.
456 * The way this routine is used, we don't get close.
457 */
458static void
459normalize_d_s_us(int *d, int *s, int *us)
460{
461 if (*us < 0 || *us >= 1000000) {
462 normalize_pair(s, us, 1000000);
463 /* |s| can't be bigger than about
464 * |original s| + |original us|/1000000 now.
465 */
466
467 }
468 if (*s < 0 || *s >= 24*3600) {
469 normalize_pair(d, s, 24*3600);
470 /* |d| can't be bigger than about
471 * |original d| +
472 * (|original s| + |original us|/1000000) / (24*3600) now.
473 */
474 }
475 assert(0 <= *s && *s < 24*3600);
476 assert(0 <= *us && *us < 1000000);
477}
478
479/* Fiddle years (y), months (m), and days (d) so that
480 * 1 <= *m <= 12
481 * 1 <= *d <= days_in_month(*y, *m)
482 * The input values must be such that the internals don't overflow.
483 * The way this routine is used, we don't get close.
484 */
485static void
486normalize_y_m_d(int *y, int *m, int *d)
487{
488 int dim; /* # of days in month */
489
490 /* This gets muddy: the proper range for day can't be determined
491 * without knowing the correct month and year, but if day is, e.g.,
492 * plus or minus a million, the current month and year values make
493 * no sense (and may also be out of bounds themselves).
494 * Saying 12 months == 1 year should be non-controversial.
495 */
496 if (*m < 1 || *m > 12) {
497 --*m;
498 normalize_pair(y, m, 12);
499 ++*m;
500 /* |y| can't be bigger than about
501 * |original y| + |original m|/12 now.
502 */
503 }
504 assert(1 <= *m && *m <= 12);
505
506 /* Now only day can be out of bounds (year may also be out of bounds
507 * for a datetime object, but we don't care about that here).
508 * If day is out of bounds, what to do is arguable, but at least the
509 * method here is principled and explainable.
510 */
511 dim = days_in_month(*y, *m);
512 if (*d < 1 || *d > dim) {
513 /* Move day-1 days from the first of the month. First try to
514 * get off cheap if we're only one day out of range
515 * (adjustments for timezone alone can't be worse than that).
516 */
517 if (*d == 0) {
518 --*m;
519 if (*m > 0)
520 *d = days_in_month(*y, *m);
521 else {
522 --*y;
523 *m = 12;
524 *d = 31;
525 }
526 }
527 else if (*d == dim + 1) {
528 /* move forward a day */
529 ++*m;
530 *d = 1;
531 if (*m > 12) {
532 *m = 1;
533 ++*y;
534 }
535 }
536 else {
537 int ordinal = ymd_to_ord(*y, *m, 1) +
538 *d - 1;
539 ord_to_ymd(ordinal, y, m, d);
540 }
541 }
542 assert(*m > 0);
543 assert(*d > 0);
544}
545
546/* Fiddle out-of-bounds months and days so that the result makes some kind
547 * of sense. The parameters are both inputs and outputs. Returns < 0 on
548 * failure, where failure means the adjusted year is out of bounds.
549 */
550static int
551normalize_date(int *year, int *month, int *day)
552{
553 int result;
554
555 normalize_y_m_d(year, month, day);
556 if (MINYEAR <= *year && *year <= MAXYEAR)
557 result = 0;
558 else {
559 PyErr_SetString(PyExc_OverflowError,
560 "date value out of range");
561 result = -1;
562 }
563 return result;
564}
565
566/* Force all the datetime fields into range. The parameters are both
567 * inputs and outputs. Returns < 0 on error.
568 */
569static int
570normalize_datetime(int *year, int *month, int *day,
571 int *hour, int *minute, int *second,
572 int *microsecond)
573{
574 normalize_pair(second, microsecond, 1000000);
575 normalize_pair(minute, second, 60);
576 normalize_pair(hour, minute, 60);
577 normalize_pair(day, hour, 24);
578 return normalize_date(year, month, day);
579}
580
581/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000582 * Basic object allocation: tp_alloc implementations. These allocate
583 * Python objects of the right size and type, and do the Python object-
584 * initialization bit. If there's not enough memory, they return NULL after
585 * setting MemoryError. All data members remain uninitialized trash.
586 *
587 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000588 * member is needed. This is ugly, imprecise, and possibly insecure.
589 * tp_basicsize for the time and datetime types is set to the size of the
590 * struct that has room for the tzinfo member, so subclasses in Python will
591 * allocate enough space for a tzinfo member whether or not one is actually
592 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
593 * part is that PyType_GenericAlloc() (which subclasses in Python end up
594 * using) just happens today to effectively ignore the nitems argument
595 * when tp_itemsize is 0, which it is for these type objects. If that
596 * changes, perhaps the callers of tp_alloc slots in this file should
597 * be changed to force a 0 nitems argument unless the type being allocated
598 * is a base type implemented in this file (so that tp_alloc is time_alloc
599 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000600 */
601
602static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000603time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000604{
605 PyObject *self;
606
607 self = (PyObject *)
608 PyObject_MALLOC(aware ?
609 sizeof(PyDateTime_Time) :
610 sizeof(_PyDateTime_BaseTime));
611 if (self == NULL)
612 return (PyObject *)PyErr_NoMemory();
613 PyObject_INIT(self, type);
614 return self;
615}
616
617static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000618datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000619{
620 PyObject *self;
621
622 self = (PyObject *)
623 PyObject_MALLOC(aware ?
624 sizeof(PyDateTime_DateTime) :
625 sizeof(_PyDateTime_BaseDateTime));
626 if (self == NULL)
627 return (PyObject *)PyErr_NoMemory();
628 PyObject_INIT(self, type);
629 return self;
630}
631
632/* ---------------------------------------------------------------------------
633 * Helpers for setting object fields. These work on pointers to the
634 * appropriate base class.
635 */
636
637/* For date and datetime. */
638static void
639set_date_fields(PyDateTime_Date *self, int y, int m, int d)
640{
641 self->hashcode = -1;
642 SET_YEAR(self, y);
643 SET_MONTH(self, m);
644 SET_DAY(self, d);
645}
646
647/* ---------------------------------------------------------------------------
648 * Create various objects, mostly without range checking.
649 */
650
651/* Create a date instance with no range checking. */
652static PyObject *
653new_date_ex(int year, int month, int day, PyTypeObject *type)
654{
655 PyDateTime_Date *self;
656
657 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
658 if (self != NULL)
659 set_date_fields(self, year, month, day);
660 return (PyObject *) self;
661}
662
663#define new_date(year, month, day) \
664 new_date_ex(year, month, day, &PyDateTime_DateType)
665
666/* Create a datetime instance with no range checking. */
667static PyObject *
668new_datetime_ex(int year, int month, int day, int hour, int minute,
669 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
670{
671 PyDateTime_DateTime *self;
672 char aware = tzinfo != Py_None;
673
674 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
675 if (self != NULL) {
676 self->hastzinfo = aware;
677 set_date_fields((PyDateTime_Date *)self, year, month, day);
678 DATE_SET_HOUR(self, hour);
679 DATE_SET_MINUTE(self, minute);
680 DATE_SET_SECOND(self, second);
681 DATE_SET_MICROSECOND(self, usecond);
682 if (aware) {
683 Py_INCREF(tzinfo);
684 self->tzinfo = tzinfo;
685 }
686 }
687 return (PyObject *)self;
688}
689
690#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
691 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
692 &PyDateTime_DateTimeType)
693
694/* Create a time instance with no range checking. */
695static PyObject *
696new_time_ex(int hour, int minute, int second, int usecond,
697 PyObject *tzinfo, PyTypeObject *type)
698{
699 PyDateTime_Time *self;
700 char aware = tzinfo != Py_None;
701
702 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
703 if (self != NULL) {
704 self->hastzinfo = aware;
705 self->hashcode = -1;
706 TIME_SET_HOUR(self, hour);
707 TIME_SET_MINUTE(self, minute);
708 TIME_SET_SECOND(self, second);
709 TIME_SET_MICROSECOND(self, usecond);
710 if (aware) {
711 Py_INCREF(tzinfo);
712 self->tzinfo = tzinfo;
713 }
714 }
715 return (PyObject *)self;
716}
717
718#define new_time(hh, mm, ss, us, tzinfo) \
719 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
720
721/* Create a timedelta instance. Normalize the members iff normalize is
722 * true. Passing false is a speed optimization, if you know for sure
723 * that seconds and microseconds are already in their proper ranges. In any
724 * case, raises OverflowError and returns NULL if the normalized days is out
725 * of range).
726 */
727static PyObject *
728new_delta_ex(int days, int seconds, int microseconds, int normalize,
729 PyTypeObject *type)
730{
731 PyDateTime_Delta *self;
732
733 if (normalize)
734 normalize_d_s_us(&days, &seconds, &microseconds);
735 assert(0 <= seconds && seconds < 24*3600);
736 assert(0 <= microseconds && microseconds < 1000000);
737
738 if (check_delta_day_range(days) < 0)
739 return NULL;
740
741 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
742 if (self != NULL) {
743 self->hashcode = -1;
744 SET_TD_DAYS(self, days);
745 SET_TD_SECONDS(self, seconds);
746 SET_TD_MICROSECONDS(self, microseconds);
747 }
748 return (PyObject *) self;
749}
750
751#define new_delta(d, s, us, normalize) \
752 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
753
754/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000755 * tzinfo helpers.
756 */
757
Tim Peters855fe882002-12-22 03:43:39 +0000758/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
759 * raise TypeError and return -1.
760 */
761static int
762check_tzinfo_subclass(PyObject *p)
763{
764 if (p == Py_None || PyTZInfo_Check(p))
765 return 0;
766 PyErr_Format(PyExc_TypeError,
767 "tzinfo argument must be None or of a tzinfo subclass, "
768 "not type '%s'",
Christian Heimese93237d2007-12-19 02:37:44 +0000769 Py_TYPE(p)->tp_name);
Tim Peters855fe882002-12-22 03:43:39 +0000770 return -1;
771}
772
Tim Petersbad8ff02002-12-30 20:52:32 +0000773/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000774 * If tzinfo is None, returns None.
775 */
776static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000777call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000778{
779 PyObject *result;
780
Tim Petersbad8ff02002-12-30 20:52:32 +0000781 assert(tzinfo && methname && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000782 assert(check_tzinfo_subclass(tzinfo) >= 0);
783 if (tzinfo == Py_None) {
784 result = Py_None;
785 Py_INCREF(result);
786 }
787 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000788 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000789 return result;
790}
791
Tim Peters2a799bf2002-12-16 20:18:38 +0000792/* If self has a tzinfo member, return a BORROWED reference to it. Else
793 * return NULL, which is NOT AN ERROR. There are no error returns here,
794 * and the caller must not decref the result.
795 */
796static PyObject *
797get_tzinfo_member(PyObject *self)
798{
799 PyObject *tzinfo = NULL;
800
Tim Petersa9bc1682003-01-11 03:39:11 +0000801 if (PyDateTime_Check(self) && HASTZINFO(self))
802 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
Tim Petersa032d2e2003-01-11 00:15:54 +0000803 else if (PyTime_Check(self) && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +0000804 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000805
806 return tzinfo;
807}
808
Tim Petersbad8ff02002-12-30 20:52:32 +0000809/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000810 * result. tzinfo must be an instance of the tzinfo class. If the method
811 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000812 * return None or timedelta, TypeError is raised and this returns -1. If it
813 * returnsa timedelta and the value is out of range or isn't a whole number
814 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000815 * Else *none is set to 0 and the integer method result is returned.
816 */
817static int
818call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
819 int *none)
820{
821 PyObject *u;
Tim Peters397301e2003-01-02 21:28:08 +0000822 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000823
824 assert(tzinfo != NULL);
825 assert(PyTZInfo_Check(tzinfo));
826 assert(tzinfoarg != NULL);
827
828 *none = 0;
Tim Petersbad8ff02002-12-30 20:52:32 +0000829 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000830 if (u == NULL)
831 return -1;
832
Tim Peters27362852002-12-23 16:17:39 +0000833 else if (u == Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +0000834 result = 0;
835 *none = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000836 }
Tim Peters855fe882002-12-22 03:43:39 +0000837 else if (PyDelta_Check(u)) {
838 const int days = GET_TD_DAYS(u);
839 if (days < -1 || days > 0)
840 result = 24*60; /* trigger ValueError below */
841 else {
842 /* next line can't overflow because we know days
843 * is -1 or 0 now
844 */
845 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
846 result = divmod(ss, 60, &ss);
847 if (ss || GET_TD_MICROSECONDS(u)) {
848 PyErr_Format(PyExc_ValueError,
849 "tzinfo.%s() must return a "
850 "whole number of minutes",
851 name);
852 result = -1;
Tim Peters855fe882002-12-22 03:43:39 +0000853 }
854 }
855 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000856 else {
857 PyErr_Format(PyExc_TypeError,
Tim Peters397301e2003-01-02 21:28:08 +0000858 "tzinfo.%s() must return None or "
Tim Peters855fe882002-12-22 03:43:39 +0000859 "timedelta, not '%s'",
Christian Heimese93237d2007-12-19 02:37:44 +0000860 name, Py_TYPE(u)->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000861 }
862
Tim Peters2a799bf2002-12-16 20:18:38 +0000863 Py_DECREF(u);
864 if (result < -1439 || result > 1439) {
865 PyErr_Format(PyExc_ValueError,
Neal Norwitz506a2242003-01-04 01:02:25 +0000866 "tzinfo.%s() returned %d; must be in "
Tim Peters2a799bf2002-12-16 20:18:38 +0000867 "-1439 .. 1439",
868 name, result);
869 result = -1;
870 }
Tim Peters397301e2003-01-02 21:28:08 +0000871 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000872}
873
874/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
875 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
876 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000877 * doesn't return None or timedelta, TypeError is raised and this returns -1.
878 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
879 * # of minutes), ValueError is raised and this returns -1. Else *none is
880 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000881 */
882static int
883call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
884{
885 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
886}
887
Tim Petersbad8ff02002-12-30 20:52:32 +0000888/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
889 */
Tim Peters855fe882002-12-22 03:43:39 +0000890static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000891offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Tim Peters855fe882002-12-22 03:43:39 +0000892 PyObject *result;
893
Tim Petersbad8ff02002-12-30 20:52:32 +0000894 assert(tzinfo && name && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000895 if (tzinfo == Py_None) {
896 result = Py_None;
897 Py_INCREF(result);
898 }
899 else {
900 int none;
Tim Petersbad8ff02002-12-30 20:52:32 +0000901 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
902 &none);
Tim Peters855fe882002-12-22 03:43:39 +0000903 if (offset < 0 && PyErr_Occurred())
904 return NULL;
905 if (none) {
906 result = Py_None;
907 Py_INCREF(result);
908 }
909 else
910 result = new_delta(0, offset * 60, 0, 1);
911 }
912 return result;
913}
914
Tim Peters2a799bf2002-12-16 20:18:38 +0000915/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
916 * result. tzinfo must be an instance of the tzinfo class. If dst()
917 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000918 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000919 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000920 * ValueError is raised and this returns -1. Else *none is set to 0 and
921 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000922 */
923static int
924call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
925{
926 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
927}
928
Tim Petersbad8ff02002-12-30 20:52:32 +0000929/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000930 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000931 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000932 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000933 */
934static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000935call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000936{
937 PyObject *result;
938
939 assert(tzinfo != NULL);
Tim Peters855fe882002-12-22 03:43:39 +0000940 assert(check_tzinfo_subclass(tzinfo) >= 0);
Tim Petersbad8ff02002-12-30 20:52:32 +0000941 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000942
Tim Peters855fe882002-12-22 03:43:39 +0000943 if (tzinfo == Py_None) {
944 result = Py_None;
945 Py_INCREF(result);
946 }
947 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000948 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000949
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000950 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
Tim Peters855fe882002-12-22 03:43:39 +0000951 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
Tim Peters2a799bf2002-12-16 20:18:38 +0000952 "return None or a string, not '%s'",
Christian Heimese93237d2007-12-19 02:37:44 +0000953 Py_TYPE(result)->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000954 Py_DECREF(result);
955 result = NULL;
956 }
957 return result;
958}
959
960typedef enum {
961 /* an exception has been set; the caller should pass it on */
962 OFFSET_ERROR,
963
Tim Petersa9bc1682003-01-11 03:39:11 +0000964 /* type isn't date, datetime, or time subclass */
Tim Peters2a799bf2002-12-16 20:18:38 +0000965 OFFSET_UNKNOWN,
966
967 /* date,
Tim Petersa9bc1682003-01-11 03:39:11 +0000968 * datetime with !hastzinfo
969 * datetime with None tzinfo,
970 * datetime where utcoffset() returns None
Tim Peters37f39822003-01-10 03:49:02 +0000971 * time with !hastzinfo
972 * time with None tzinfo,
973 * time where utcoffset() returns None
Tim Peters2a799bf2002-12-16 20:18:38 +0000974 */
975 OFFSET_NAIVE,
976
Tim Petersa9bc1682003-01-11 03:39:11 +0000977 /* time or datetime where utcoffset() doesn't return None */
Georg Brandle810fe22006-02-19 15:28:47 +0000978 OFFSET_AWARE
Tim Peters2a799bf2002-12-16 20:18:38 +0000979} naivety;
980
Tim Peters14b69412002-12-22 18:10:22 +0000981/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000982 * the "naivety" typedef for details. If the type is aware, *offset is set
983 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000984 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000985 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000986 */
987static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000988classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000989{
990 int none;
991 PyObject *tzinfo;
992
Tim Peterse39a80c2002-12-30 21:28:52 +0000993 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000994 *offset = 0;
Tim Peters14b69412002-12-22 18:10:22 +0000995 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
Tim Peters2a799bf2002-12-16 20:18:38 +0000996 if (tzinfo == Py_None)
997 return OFFSET_NAIVE;
Tim Peters14b69412002-12-22 18:10:22 +0000998 if (tzinfo == NULL) {
999 /* note that a datetime passes the PyDate_Check test */
1000 return (PyTime_Check(op) || PyDate_Check(op)) ?
1001 OFFSET_NAIVE : OFFSET_UNKNOWN;
1002 }
Tim Peterse39a80c2002-12-30 21:28:52 +00001003 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00001004 if (*offset == -1 && PyErr_Occurred())
1005 return OFFSET_ERROR;
1006 return none ? OFFSET_NAIVE : OFFSET_AWARE;
1007}
1008
Tim Peters00237032002-12-27 02:21:51 +00001009/* Classify two objects as to whether they're naive or offset-aware.
1010 * This isn't quite the same as calling classify_utcoffset() twice: for
1011 * binary operations (comparison and subtraction), we generally want to
1012 * ignore the tzinfo members if they're identical. This is by design,
1013 * so that results match "naive" expectations when mixing objects from a
1014 * single timezone. So in that case, this sets both offsets to 0 and
1015 * both naiveties to OFFSET_NAIVE.
1016 * The function returns 0 if everything's OK, and -1 on error.
1017 */
1018static int
1019classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Tim Peterse39a80c2002-12-30 21:28:52 +00001020 PyObject *tzinfoarg1,
1021 PyObject *o2, int *offset2, naivety *n2,
1022 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001023{
1024 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1025 *offset1 = *offset2 = 0;
1026 *n1 = *n2 = OFFSET_NAIVE;
1027 }
1028 else {
Tim Peterse39a80c2002-12-30 21:28:52 +00001029 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
Tim Peters00237032002-12-27 02:21:51 +00001030 if (*n1 == OFFSET_ERROR)
1031 return -1;
Tim Peterse39a80c2002-12-30 21:28:52 +00001032 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
Tim Peters00237032002-12-27 02:21:51 +00001033 if (*n2 == OFFSET_ERROR)
1034 return -1;
1035 }
1036 return 0;
1037}
1038
Tim Peters2a799bf2002-12-16 20:18:38 +00001039/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1040 * stuff
1041 * ", tzinfo=" + repr(tzinfo)
1042 * before the closing ")".
1043 */
1044static PyObject *
1045append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1046{
1047 PyObject *temp;
1048
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001049 assert(PyString_Check(repr));
Tim Peters2a799bf2002-12-16 20:18:38 +00001050 assert(tzinfo);
1051 if (tzinfo == Py_None)
1052 return repr;
1053 /* Get rid of the trailing ')'. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001054 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1055 temp = PyString_FromStringAndSize(PyString_AsString(repr),
1056 PyString_Size(repr) - 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001057 Py_DECREF(repr);
1058 if (temp == NULL)
1059 return NULL;
1060 repr = temp;
1061
1062 /* Append ", tzinfo=". */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001063 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
Tim Peters2a799bf2002-12-16 20:18:38 +00001064
1065 /* Append repr(tzinfo). */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001066 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
Tim Peters2a799bf2002-12-16 20:18:38 +00001067
1068 /* Add a closing paren. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001069 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
Tim Peters2a799bf2002-12-16 20:18:38 +00001070 return repr;
1071}
1072
1073/* ---------------------------------------------------------------------------
1074 * String format helpers.
1075 */
1076
1077static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001078format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001079{
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001080 static const char *DayNames[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00001081 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1082 };
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001083 static const char *MonthNames[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00001084 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1085 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1086 };
1087
1088 char buffer[128];
1089 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1090
1091 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
1092 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
1093 GET_DAY(date), hours, minutes, seconds,
1094 GET_YEAR(date));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001095 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00001096}
1097
1098/* Add an hours & minutes UTC offset string to buf. buf has no more than
1099 * buflen bytes remaining. The UTC offset is gotten by calling
1100 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1101 * *buf, and that's all. Else the returned value is checked for sanity (an
1102 * integer in range), and if that's OK it's converted to an hours & minutes
1103 * string of the form
1104 * sign HH sep MM
1105 * Returns 0 if everything is OK. If the return value from utcoffset() is
1106 * bogus, an appropriate exception is set and -1 is returned.
1107 */
1108static int
Tim Peters328fff72002-12-20 01:31:27 +00001109format_utcoffset(char *buf, size_t buflen, const char *sep,
Tim Peters2a799bf2002-12-16 20:18:38 +00001110 PyObject *tzinfo, PyObject *tzinfoarg)
1111{
1112 int offset;
1113 int hours;
1114 int minutes;
1115 char sign;
1116 int none;
1117
Gregory P. Smith9d534572008-06-11 07:41:16 +00001118 assert(buflen >= 1);
1119
Tim Peters2a799bf2002-12-16 20:18:38 +00001120 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1121 if (offset == -1 && PyErr_Occurred())
1122 return -1;
1123 if (none) {
1124 *buf = '\0';
1125 return 0;
1126 }
1127 sign = '+';
1128 if (offset < 0) {
1129 sign = '-';
1130 offset = - offset;
1131 }
1132 hours = divmod(offset, 60, &minutes);
1133 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1134 return 0;
1135}
1136
Skip Montanarofc070d22008-03-15 16:04:45 +00001137static PyObject *
1138make_freplacement(PyObject *object)
1139{
Neal Norwitzf13572d2008-03-17 19:02:45 +00001140 char freplacement[64];
Skip Montanarofc070d22008-03-15 16:04:45 +00001141 if (PyTime_Check(object))
1142 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1143 else if (PyDateTime_Check(object))
1144 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1145 else
1146 sprintf(freplacement, "%06d", 0);
1147
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001148 return PyString_FromStringAndSize(freplacement, strlen(freplacement));
Skip Montanarofc070d22008-03-15 16:04:45 +00001149}
1150
Tim Peters2a799bf2002-12-16 20:18:38 +00001151/* I sure don't want to reproduce the strftime code from the time module,
1152 * so this imports the module and calls it. All the hair is due to
Skip Montanarofc070d22008-03-15 16:04:45 +00001153 * giving special meanings to the %z, %Z and %f format codes via a
1154 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001155 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1156 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001157 */
1158static PyObject *
Gregory P. Smith137d8242008-06-02 04:05:52 +00001159wrap_strftime(PyObject *object, const char *format, size_t format_len,
1160 PyObject *timetuple, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001161{
1162 PyObject *result = NULL; /* guilty until proved innocent */
1163
1164 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1165 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
Skip Montanarofc070d22008-03-15 16:04:45 +00001166 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001167
Gregory P. Smith137d8242008-06-02 04:05:52 +00001168 const char *pin; /* pointer to next char in input format */
1169 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001170
1171 PyObject *newfmt = NULL; /* py string, the output format */
1172 char *pnew; /* pointer to available byte in output format */
Gregory P. Smith137d8242008-06-02 04:05:52 +00001173 size_t totalnew; /* number bytes total in output format buffer,
1174 exclusive of trailing \0 */
1175 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001176
Gregory P. Smith137d8242008-06-02 04:05:52 +00001177 const char *ptoappend; /* ptr to string to append to output buffer */
1178 size_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001179
Tim Peters2a799bf2002-12-16 20:18:38 +00001180 assert(object && format && timetuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001181
Tim Petersd6844152002-12-22 20:58:42 +00001182 /* Give up if the year is before 1900.
1183 * Python strftime() plays games with the year, and different
1184 * games depending on whether envar PYTHON2K is set. This makes
1185 * years before 1900 a nightmare, even if the platform strftime
1186 * supports them (and not all do).
1187 * We could get a lot farther here by avoiding Python's strftime
1188 * wrapper and calling the C strftime() directly, but that isn't
1189 * an option in the Python implementation of this module.
1190 */
1191 {
1192 long year;
1193 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1194 if (pyyear == NULL) return NULL;
1195 assert(PyInt_Check(pyyear));
1196 year = PyInt_AsLong(pyyear);
1197 Py_DECREF(pyyear);
1198 if (year < 1900) {
1199 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1200 "1900; the datetime strftime() "
1201 "methods require year >= 1900",
1202 year);
1203 return NULL;
1204 }
1205 }
1206
Skip Montanarofc070d22008-03-15 16:04:45 +00001207 /* Scan the input format, looking for %z/%Z/%f escapes, building
Tim Peters328fff72002-12-20 01:31:27 +00001208 * a new format. Since computing the replacements for those codes
1209 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +00001210 */
Gregory P. Smith9d534572008-06-11 07:41:16 +00001211 if (format_len > INT_MAX - 1) {
1212 PyErr_NoMemory();
1213 goto Done;
1214 }
1215
Gregory P. Smith137d8242008-06-02 04:05:52 +00001216 totalnew = format_len + 1; /* realistic if no %z/%Z/%f */
Gregory P. Smith99a3dce2008-06-10 17:42:36 +00001217 newfmt = PyString_FromStringAndSize(NULL, totalnew);
Tim Peters2a799bf2002-12-16 20:18:38 +00001218 if (newfmt == NULL) goto Done;
Gregory P. Smith99a3dce2008-06-10 17:42:36 +00001219 pnew = PyString_AsString(newfmt);
Tim Peters2a799bf2002-12-16 20:18:38 +00001220 usednew = 0;
1221
Gregory P. Smith137d8242008-06-02 04:05:52 +00001222 pin = format;
Tim Peters2a799bf2002-12-16 20:18:38 +00001223 while ((ch = *pin++) != '\0') {
1224 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +00001225 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001226 ntoappend = 1;
1227 }
1228 else if ((ch = *pin++) == '\0') {
1229 /* There's a lone trailing %; doesn't make sense. */
1230 PyErr_SetString(PyExc_ValueError, "strftime format "
1231 "ends with raw %");
1232 goto Done;
1233 }
1234 /* A % has been seen and ch is the character after it. */
1235 else if (ch == 'z') {
1236 if (zreplacement == NULL) {
1237 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +00001238 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +00001239 PyObject *tzinfo = get_tzinfo_member(object);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001240 zreplacement = PyString_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00001241 if (zreplacement == NULL) goto Done;
1242 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001243 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001244 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001245 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001246 "",
1247 tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00001248 tzinfoarg) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001249 goto Done;
1250 Py_DECREF(zreplacement);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001251 zreplacement = PyString_FromString(buf);
Tim Peters2a799bf2002-12-16 20:18:38 +00001252 if (zreplacement == NULL) goto Done;
1253 }
1254 }
1255 assert(zreplacement != NULL);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001256 ptoappend = PyString_AS_STRING(zreplacement);
1257 ntoappend = PyString_GET_SIZE(zreplacement);
Tim Peters2a799bf2002-12-16 20:18:38 +00001258 }
1259 else if (ch == 'Z') {
1260 /* format tzname */
1261 if (Zreplacement == NULL) {
1262 PyObject *tzinfo = get_tzinfo_member(object);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001263 Zreplacement = PyString_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00001264 if (Zreplacement == NULL) goto Done;
1265 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001266 PyObject *temp;
1267 assert(tzinfoarg != NULL);
1268 temp = call_tzname(tzinfo, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001269 if (temp == NULL) goto Done;
1270 if (temp != Py_None) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001271 assert(PyString_Check(temp));
Tim Peters2a799bf2002-12-16 20:18:38 +00001272 /* Since the tzname is getting
1273 * stuffed into the format, we
1274 * have to double any % signs
1275 * so that strftime doesn't
1276 * treat them as format codes.
1277 */
1278 Py_DECREF(Zreplacement);
1279 Zreplacement = PyObject_CallMethod(
1280 temp, "replace",
1281 "ss", "%", "%%");
1282 Py_DECREF(temp);
1283 if (Zreplacement == NULL)
1284 goto Done;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001285 if (!PyString_Check(Zreplacement)) {
Neal Norwitzd5b0c9b2006-03-20 01:58:39 +00001286 PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
1287 goto Done;
1288 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001289 }
1290 else
1291 Py_DECREF(temp);
1292 }
1293 }
1294 assert(Zreplacement != NULL);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001295 ptoappend = PyString_AS_STRING(Zreplacement);
1296 ntoappend = PyString_GET_SIZE(Zreplacement);
Tim Peters2a799bf2002-12-16 20:18:38 +00001297 }
Skip Montanarofc070d22008-03-15 16:04:45 +00001298 else if (ch == 'f') {
1299 /* format microseconds */
1300 if (freplacement == NULL) {
1301 freplacement = make_freplacement(object);
1302 if (freplacement == NULL)
1303 goto Done;
1304 }
1305 assert(freplacement != NULL);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001306 assert(PyString_Check(freplacement));
1307 ptoappend = PyString_AS_STRING(freplacement);
1308 ntoappend = PyString_GET_SIZE(freplacement);
Skip Montanarofc070d22008-03-15 16:04:45 +00001309 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001310 else {
Tim Peters328fff72002-12-20 01:31:27 +00001311 /* percent followed by neither z nor Z */
1312 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001313 ntoappend = 2;
1314 }
1315
1316 /* Append the ntoappend chars starting at ptoappend to
1317 * the new format.
1318 */
Neal Norwitzd5b0c9b2006-03-20 01:58:39 +00001319 assert(ptoappend != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001320 assert(ntoappend >= 0);
1321 if (ntoappend == 0)
1322 continue;
1323 while (usednew + ntoappend > totalnew) {
Gregory P. Smith137d8242008-06-02 04:05:52 +00001324 size_t bigger = totalnew << 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001325 if ((bigger >> 1) != totalnew) { /* overflow */
1326 PyErr_NoMemory();
1327 goto Done;
1328 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001329 if (_PyString_Resize(&newfmt, bigger) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001330 goto Done;
1331 totalnew = bigger;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001332 pnew = PyString_AsString(newfmt) + usednew;
Tim Peters2a799bf2002-12-16 20:18:38 +00001333 }
1334 memcpy(pnew, ptoappend, ntoappend);
1335 pnew += ntoappend;
1336 usednew += ntoappend;
1337 assert(usednew <= totalnew);
1338 } /* end while() */
1339
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001340 if (_PyString_Resize(&newfmt, usednew) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001341 goto Done;
1342 {
Christian Heimes000a0742008-01-03 22:16:32 +00001343 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001344 if (time == NULL)
1345 goto Done;
1346 result = PyObject_CallMethod(time, "strftime", "OO",
1347 newfmt, timetuple);
1348 Py_DECREF(time);
1349 }
1350 Done:
Skip Montanarofc070d22008-03-15 16:04:45 +00001351 Py_XDECREF(freplacement);
Tim Peters2a799bf2002-12-16 20:18:38 +00001352 Py_XDECREF(zreplacement);
1353 Py_XDECREF(Zreplacement);
1354 Py_XDECREF(newfmt);
1355 return result;
1356}
1357
1358static char *
1359isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1360{
1361 int x;
1362 x = PyOS_snprintf(buffer, bufflen,
1363 "%04d-%02d-%02d",
1364 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
Amaury Forgeot d'Arc7682d042009-12-29 22:39:49 +00001365 assert(bufflen >= x);
Tim Peters2a799bf2002-12-16 20:18:38 +00001366 return buffer + x;
1367}
1368
Amaury Forgeot d'Arc7682d042009-12-29 22:39:49 +00001369static char *
Tim Peters2a799bf2002-12-16 20:18:38 +00001370isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1371{
Amaury Forgeot d'Arc7682d042009-12-29 22:39:49 +00001372 int x;
Tim Peters2a799bf2002-12-16 20:18:38 +00001373 int us = DATE_GET_MICROSECOND(dt);
1374
Amaury Forgeot d'Arc7682d042009-12-29 22:39:49 +00001375 x = PyOS_snprintf(buffer, bufflen,
1376 "%02d:%02d:%02d",
1377 DATE_GET_HOUR(dt),
1378 DATE_GET_MINUTE(dt),
1379 DATE_GET_SECOND(dt));
1380 assert(bufflen >= x);
Tim Peters2a799bf2002-12-16 20:18:38 +00001381 if (us)
Amaury Forgeot d'Arc7682d042009-12-29 22:39:49 +00001382 x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us);
1383 assert(bufflen >= x);
1384 return buffer + x;
Tim Peters2a799bf2002-12-16 20:18:38 +00001385}
1386
1387/* ---------------------------------------------------------------------------
1388 * Wrap functions from the time module. These aren't directly available
1389 * from C. Perhaps they should be.
1390 */
1391
1392/* Call time.time() and return its result (a Python float). */
1393static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001394time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001395{
1396 PyObject *result = NULL;
Christian Heimes000a0742008-01-03 22:16:32 +00001397 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001398
1399 if (time != NULL) {
1400 result = PyObject_CallMethod(time, "time", "()");
1401 Py_DECREF(time);
1402 }
1403 return result;
1404}
1405
1406/* Build a time.struct_time. The weekday and day number are automatically
1407 * computed from the y,m,d args.
1408 */
1409static PyObject *
1410build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1411{
1412 PyObject *time;
1413 PyObject *result = NULL;
1414
Christian Heimes000a0742008-01-03 22:16:32 +00001415 time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001416 if (time != NULL) {
1417 result = PyObject_CallMethod(time, "struct_time",
1418 "((iiiiiiiii))",
1419 y, m, d,
1420 hh, mm, ss,
1421 weekday(y, m, d),
1422 days_before_month(y, m) + d,
1423 dstflag);
1424 Py_DECREF(time);
1425 }
1426 return result;
1427}
1428
1429/* ---------------------------------------------------------------------------
1430 * Miscellaneous helpers.
1431 */
1432
1433/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1434 * The comparisons here all most naturally compute a cmp()-like result.
1435 * This little helper turns that into a bool result for rich comparisons.
1436 */
1437static PyObject *
1438diff_to_bool(int diff, int op)
1439{
1440 PyObject *result;
1441 int istrue;
1442
1443 switch (op) {
1444 case Py_EQ: istrue = diff == 0; break;
1445 case Py_NE: istrue = diff != 0; break;
1446 case Py_LE: istrue = diff <= 0; break;
1447 case Py_GE: istrue = diff >= 0; break;
1448 case Py_LT: istrue = diff < 0; break;
1449 case Py_GT: istrue = diff > 0; break;
1450 default:
1451 assert(! "op unknown");
1452 istrue = 0; /* To shut up compiler */
1453 }
1454 result = istrue ? Py_True : Py_False;
1455 Py_INCREF(result);
1456 return result;
1457}
1458
Tim Peters07534a62003-02-07 22:50:28 +00001459/* Raises a "can't compare" TypeError and returns NULL. */
1460static PyObject *
1461cmperror(PyObject *a, PyObject *b)
1462{
1463 PyErr_Format(PyExc_TypeError,
1464 "can't compare %s to %s",
Christian Heimese93237d2007-12-19 02:37:44 +00001465 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
Tim Peters07534a62003-02-07 22:50:28 +00001466 return NULL;
1467}
1468
Tim Peters2a799bf2002-12-16 20:18:38 +00001469/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001470 * Cached Python objects; these are set by the module init function.
1471 */
1472
1473/* Conversion factors. */
1474static PyObject *us_per_us = NULL; /* 1 */
1475static PyObject *us_per_ms = NULL; /* 1000 */
1476static PyObject *us_per_second = NULL; /* 1000000 */
1477static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1478static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1479static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1480static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1481static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1482
Tim Peters2a799bf2002-12-16 20:18:38 +00001483/* ---------------------------------------------------------------------------
1484 * Class implementations.
1485 */
1486
1487/*
1488 * PyDateTime_Delta implementation.
1489 */
1490
1491/* Convert a timedelta to a number of us,
1492 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1493 * as a Python int or long.
1494 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1495 * due to ubiquitous overflow possibilities.
1496 */
1497static PyObject *
1498delta_to_microseconds(PyDateTime_Delta *self)
1499{
1500 PyObject *x1 = NULL;
1501 PyObject *x2 = NULL;
1502 PyObject *x3 = NULL;
1503 PyObject *result = NULL;
1504
1505 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1506 if (x1 == NULL)
1507 goto Done;
1508 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1509 if (x2 == NULL)
1510 goto Done;
1511 Py_DECREF(x1);
1512 x1 = NULL;
1513
1514 /* x2 has days in seconds */
1515 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1516 if (x1 == NULL)
1517 goto Done;
1518 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1519 if (x3 == NULL)
1520 goto Done;
1521 Py_DECREF(x1);
1522 Py_DECREF(x2);
1523 x1 = x2 = NULL;
1524
1525 /* x3 has days+seconds in seconds */
1526 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1527 if (x1 == NULL)
1528 goto Done;
1529 Py_DECREF(x3);
1530 x3 = NULL;
1531
1532 /* x1 has days+seconds in us */
1533 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1534 if (x2 == NULL)
1535 goto Done;
1536 result = PyNumber_Add(x1, x2);
1537
1538Done:
1539 Py_XDECREF(x1);
1540 Py_XDECREF(x2);
1541 Py_XDECREF(x3);
1542 return result;
1543}
1544
1545/* Convert a number of us (as a Python int or long) to a timedelta.
1546 */
1547static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001548microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001549{
1550 int us;
1551 int s;
1552 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001553 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001554
1555 PyObject *tuple = NULL;
1556 PyObject *num = NULL;
1557 PyObject *result = NULL;
1558
1559 tuple = PyNumber_Divmod(pyus, us_per_second);
1560 if (tuple == NULL)
1561 goto Done;
1562
1563 num = PyTuple_GetItem(tuple, 1); /* us */
1564 if (num == NULL)
1565 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001566 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001567 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001568 if (temp == -1 && PyErr_Occurred())
1569 goto Done;
1570 assert(0 <= temp && temp < 1000000);
1571 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001572 if (us < 0) {
1573 /* The divisor was positive, so this must be an error. */
1574 assert(PyErr_Occurred());
1575 goto Done;
1576 }
1577
1578 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1579 if (num == NULL)
1580 goto Done;
1581 Py_INCREF(num);
1582 Py_DECREF(tuple);
1583
1584 tuple = PyNumber_Divmod(num, seconds_per_day);
1585 if (tuple == NULL)
1586 goto Done;
1587 Py_DECREF(num);
1588
1589 num = PyTuple_GetItem(tuple, 1); /* seconds */
1590 if (num == NULL)
1591 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001592 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001593 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001594 if (temp == -1 && PyErr_Occurred())
1595 goto Done;
1596 assert(0 <= temp && temp < 24*3600);
1597 s = (int)temp;
1598
Tim Peters2a799bf2002-12-16 20:18:38 +00001599 if (s < 0) {
1600 /* The divisor was positive, so this must be an error. */
1601 assert(PyErr_Occurred());
1602 goto Done;
1603 }
1604
1605 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1606 if (num == NULL)
1607 goto Done;
1608 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001609 temp = PyLong_AsLong(num);
1610 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001611 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001612 d = (int)temp;
1613 if ((long)d != temp) {
1614 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1615 "large to fit in a C int");
1616 goto Done;
1617 }
Tim Petersb0c854d2003-05-17 15:57:00 +00001618 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001619
1620Done:
1621 Py_XDECREF(tuple);
1622 Py_XDECREF(num);
1623 return result;
1624}
1625
Tim Petersb0c854d2003-05-17 15:57:00 +00001626#define microseconds_to_delta(pymicros) \
1627 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1628
Tim Peters2a799bf2002-12-16 20:18:38 +00001629static PyObject *
1630multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1631{
1632 PyObject *pyus_in;
1633 PyObject *pyus_out;
1634 PyObject *result;
1635
1636 pyus_in = delta_to_microseconds(delta);
1637 if (pyus_in == NULL)
1638 return NULL;
1639
1640 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1641 Py_DECREF(pyus_in);
1642 if (pyus_out == NULL)
1643 return NULL;
1644
1645 result = microseconds_to_delta(pyus_out);
1646 Py_DECREF(pyus_out);
1647 return result;
1648}
1649
1650static PyObject *
1651divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1652{
1653 PyObject *pyus_in;
1654 PyObject *pyus_out;
1655 PyObject *result;
1656
1657 pyus_in = delta_to_microseconds(delta);
1658 if (pyus_in == NULL)
1659 return NULL;
1660
1661 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1662 Py_DECREF(pyus_in);
1663 if (pyus_out == NULL)
1664 return NULL;
1665
1666 result = microseconds_to_delta(pyus_out);
1667 Py_DECREF(pyus_out);
1668 return result;
1669}
1670
1671static PyObject *
1672delta_add(PyObject *left, PyObject *right)
1673{
1674 PyObject *result = Py_NotImplemented;
1675
1676 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1677 /* delta + delta */
1678 /* The C-level additions can't overflow because of the
1679 * invariant bounds.
1680 */
1681 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1682 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1683 int microseconds = GET_TD_MICROSECONDS(left) +
1684 GET_TD_MICROSECONDS(right);
1685 result = new_delta(days, seconds, microseconds, 1);
1686 }
1687
1688 if (result == Py_NotImplemented)
1689 Py_INCREF(result);
1690 return result;
1691}
1692
1693static PyObject *
1694delta_negative(PyDateTime_Delta *self)
1695{
1696 return new_delta(-GET_TD_DAYS(self),
1697 -GET_TD_SECONDS(self),
1698 -GET_TD_MICROSECONDS(self),
1699 1);
1700}
1701
1702static PyObject *
1703delta_positive(PyDateTime_Delta *self)
1704{
1705 /* Could optimize this (by returning self) if this isn't a
1706 * subclass -- but who uses unary + ? Approximately nobody.
1707 */
1708 return new_delta(GET_TD_DAYS(self),
1709 GET_TD_SECONDS(self),
1710 GET_TD_MICROSECONDS(self),
1711 0);
1712}
1713
1714static PyObject *
1715delta_abs(PyDateTime_Delta *self)
1716{
1717 PyObject *result;
1718
1719 assert(GET_TD_MICROSECONDS(self) >= 0);
1720 assert(GET_TD_SECONDS(self) >= 0);
1721
1722 if (GET_TD_DAYS(self) < 0)
1723 result = delta_negative(self);
1724 else
1725 result = delta_positive(self);
1726
1727 return result;
1728}
1729
1730static PyObject *
1731delta_subtract(PyObject *left, PyObject *right)
1732{
1733 PyObject *result = Py_NotImplemented;
1734
1735 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1736 /* delta - delta */
1737 PyObject *minus_right = PyNumber_Negative(right);
1738 if (minus_right) {
1739 result = delta_add(left, minus_right);
1740 Py_DECREF(minus_right);
1741 }
1742 else
1743 result = NULL;
1744 }
1745
1746 if (result == Py_NotImplemented)
1747 Py_INCREF(result);
1748 return result;
1749}
1750
1751/* This is more natural as a tp_compare, but doesn't work then: for whatever
1752 * reason, Python's try_3way_compare ignores tp_compare unless
1753 * PyInstance_Check returns true, but these aren't old-style classes.
1754 */
1755static PyObject *
1756delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1757{
Tim Peters07534a62003-02-07 22:50:28 +00001758 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001759
Tim Petersaa7d8492003-02-08 03:28:59 +00001760 if (PyDelta_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00001761 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1762 if (diff == 0) {
1763 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1764 if (diff == 0)
1765 diff = GET_TD_MICROSECONDS(self) -
1766 GET_TD_MICROSECONDS(other);
1767 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001768 }
Tim Peters07534a62003-02-07 22:50:28 +00001769 else if (op == Py_EQ || op == Py_NE)
1770 diff = 1; /* any non-zero value will do */
1771
1772 else /* stop this from falling back to address comparison */
1773 return cmperror((PyObject *)self, other);
1774
Tim Peters2a799bf2002-12-16 20:18:38 +00001775 return diff_to_bool(diff, op);
1776}
1777
1778static PyObject *delta_getstate(PyDateTime_Delta *self);
1779
1780static long
1781delta_hash(PyDateTime_Delta *self)
1782{
1783 if (self->hashcode == -1) {
1784 PyObject *temp = delta_getstate(self);
1785 if (temp != NULL) {
1786 self->hashcode = PyObject_Hash(temp);
1787 Py_DECREF(temp);
1788 }
1789 }
1790 return self->hashcode;
1791}
1792
1793static PyObject *
1794delta_multiply(PyObject *left, PyObject *right)
1795{
1796 PyObject *result = Py_NotImplemented;
1797
1798 if (PyDelta_Check(left)) {
1799 /* delta * ??? */
1800 if (PyInt_Check(right) || PyLong_Check(right))
1801 result = multiply_int_timedelta(right,
1802 (PyDateTime_Delta *) left);
1803 }
1804 else if (PyInt_Check(left) || PyLong_Check(left))
1805 result = multiply_int_timedelta(left,
1806 (PyDateTime_Delta *) right);
1807
1808 if (result == Py_NotImplemented)
1809 Py_INCREF(result);
1810 return result;
1811}
1812
1813static PyObject *
1814delta_divide(PyObject *left, PyObject *right)
1815{
1816 PyObject *result = Py_NotImplemented;
1817
1818 if (PyDelta_Check(left)) {
1819 /* delta * ??? */
1820 if (PyInt_Check(right) || PyLong_Check(right))
1821 result = divide_timedelta_int(
1822 (PyDateTime_Delta *)left,
1823 right);
1824 }
1825
1826 if (result == Py_NotImplemented)
1827 Py_INCREF(result);
1828 return result;
1829}
1830
1831/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1832 * timedelta constructor. sofar is the # of microseconds accounted for
1833 * so far, and there are factor microseconds per current unit, the number
1834 * of which is given by num. num * factor is added to sofar in a
1835 * numerically careful way, and that's the result. Any fractional
1836 * microseconds left over (this can happen if num is a float type) are
1837 * added into *leftover.
1838 * Note that there are many ways this can give an error (NULL) return.
1839 */
1840static PyObject *
1841accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1842 double *leftover)
1843{
1844 PyObject *prod;
1845 PyObject *sum;
1846
1847 assert(num != NULL);
1848
1849 if (PyInt_Check(num) || PyLong_Check(num)) {
1850 prod = PyNumber_Multiply(num, factor);
1851 if (prod == NULL)
1852 return NULL;
1853 sum = PyNumber_Add(sofar, prod);
1854 Py_DECREF(prod);
1855 return sum;
1856 }
1857
1858 if (PyFloat_Check(num)) {
1859 double dnum;
1860 double fracpart;
1861 double intpart;
1862 PyObject *x;
1863 PyObject *y;
1864
1865 /* The Plan: decompose num into an integer part and a
1866 * fractional part, num = intpart + fracpart.
1867 * Then num * factor ==
1868 * intpart * factor + fracpart * factor
1869 * and the LHS can be computed exactly in long arithmetic.
1870 * The RHS is again broken into an int part and frac part.
1871 * and the frac part is added into *leftover.
1872 */
1873 dnum = PyFloat_AsDouble(num);
1874 if (dnum == -1.0 && PyErr_Occurred())
1875 return NULL;
1876 fracpart = modf(dnum, &intpart);
1877 x = PyLong_FromDouble(intpart);
1878 if (x == NULL)
1879 return NULL;
1880
1881 prod = PyNumber_Multiply(x, factor);
1882 Py_DECREF(x);
1883 if (prod == NULL)
1884 return NULL;
1885
1886 sum = PyNumber_Add(sofar, prod);
1887 Py_DECREF(prod);
1888 if (sum == NULL)
1889 return NULL;
1890
1891 if (fracpart == 0.0)
1892 return sum;
1893 /* So far we've lost no information. Dealing with the
1894 * fractional part requires float arithmetic, and may
1895 * lose a little info.
1896 */
1897 assert(PyInt_Check(factor) || PyLong_Check(factor));
1898 if (PyInt_Check(factor))
1899 dnum = (double)PyInt_AsLong(factor);
1900 else
1901 dnum = PyLong_AsDouble(factor);
1902
1903 dnum *= fracpart;
1904 fracpart = modf(dnum, &intpart);
1905 x = PyLong_FromDouble(intpart);
1906 if (x == NULL) {
1907 Py_DECREF(sum);
1908 return NULL;
1909 }
1910
1911 y = PyNumber_Add(sum, x);
1912 Py_DECREF(sum);
1913 Py_DECREF(x);
1914 *leftover += fracpart;
1915 return y;
1916 }
1917
1918 PyErr_Format(PyExc_TypeError,
1919 "unsupported type for timedelta %s component: %s",
Christian Heimese93237d2007-12-19 02:37:44 +00001920 tag, Py_TYPE(num)->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00001921 return NULL;
1922}
1923
1924static PyObject *
1925delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1926{
1927 PyObject *self = NULL;
1928
1929 /* Argument objects. */
1930 PyObject *day = NULL;
1931 PyObject *second = NULL;
1932 PyObject *us = NULL;
1933 PyObject *ms = NULL;
1934 PyObject *minute = NULL;
1935 PyObject *hour = NULL;
1936 PyObject *week = NULL;
1937
1938 PyObject *x = NULL; /* running sum of microseconds */
1939 PyObject *y = NULL; /* temp sum of microseconds */
1940 double leftover_us = 0.0;
1941
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001942 static char *keywords[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00001943 "days", "seconds", "microseconds", "milliseconds",
1944 "minutes", "hours", "weeks", NULL
1945 };
1946
1947 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1948 keywords,
1949 &day, &second, &us,
1950 &ms, &minute, &hour, &week) == 0)
1951 goto Done;
1952
1953 x = PyInt_FromLong(0);
1954 if (x == NULL)
1955 goto Done;
1956
1957#define CLEANUP \
1958 Py_DECREF(x); \
1959 x = y; \
1960 if (x == NULL) \
1961 goto Done
1962
1963 if (us) {
1964 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1965 CLEANUP;
1966 }
1967 if (ms) {
1968 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1969 CLEANUP;
1970 }
1971 if (second) {
1972 y = accum("seconds", x, second, us_per_second, &leftover_us);
1973 CLEANUP;
1974 }
1975 if (minute) {
1976 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1977 CLEANUP;
1978 }
1979 if (hour) {
1980 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1981 CLEANUP;
1982 }
1983 if (day) {
1984 y = accum("days", x, day, us_per_day, &leftover_us);
1985 CLEANUP;
1986 }
1987 if (week) {
1988 y = accum("weeks", x, week, us_per_week, &leftover_us);
1989 CLEANUP;
1990 }
1991 if (leftover_us) {
1992 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001993 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001994 if (temp == NULL) {
1995 Py_DECREF(x);
1996 goto Done;
1997 }
1998 y = PyNumber_Add(x, temp);
1999 Py_DECREF(temp);
2000 CLEANUP;
2001 }
2002
Tim Petersb0c854d2003-05-17 15:57:00 +00002003 self = microseconds_to_delta_ex(x, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00002004 Py_DECREF(x);
2005Done:
2006 return self;
2007
2008#undef CLEANUP
2009}
2010
2011static int
2012delta_nonzero(PyDateTime_Delta *self)
2013{
2014 return (GET_TD_DAYS(self) != 0
2015 || GET_TD_SECONDS(self) != 0
2016 || GET_TD_MICROSECONDS(self) != 0);
2017}
2018
2019static PyObject *
2020delta_repr(PyDateTime_Delta *self)
2021{
2022 if (GET_TD_MICROSECONDS(self) != 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002023 return PyString_FromFormat("%s(%d, %d, %d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002024 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002025 GET_TD_DAYS(self),
2026 GET_TD_SECONDS(self),
2027 GET_TD_MICROSECONDS(self));
2028 if (GET_TD_SECONDS(self) != 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002029 return PyString_FromFormat("%s(%d, %d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002030 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002031 GET_TD_DAYS(self),
2032 GET_TD_SECONDS(self));
2033
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002034 return PyString_FromFormat("%s(%d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002035 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002036 GET_TD_DAYS(self));
2037}
2038
2039static PyObject *
2040delta_str(PyDateTime_Delta *self)
2041{
2042 int days = GET_TD_DAYS(self);
2043 int seconds = GET_TD_SECONDS(self);
2044 int us = GET_TD_MICROSECONDS(self);
2045 int hours;
2046 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00002047 char buf[100];
2048 char *pbuf = buf;
2049 size_t buflen = sizeof(buf);
2050 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002051
2052 minutes = divmod(seconds, 60, &seconds);
2053 hours = divmod(minutes, 60, &minutes);
2054
2055 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00002056 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2057 (days == 1 || days == -1) ? "" : "s");
2058 if (n < 0 || (size_t)n >= buflen)
2059 goto Fail;
2060 pbuf += n;
2061 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002062 }
2063
Tim Petersba873472002-12-18 20:19:21 +00002064 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2065 hours, minutes, seconds);
2066 if (n < 0 || (size_t)n >= buflen)
2067 goto Fail;
2068 pbuf += n;
2069 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002070
2071 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00002072 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2073 if (n < 0 || (size_t)n >= buflen)
2074 goto Fail;
2075 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002076 }
2077
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002078 return PyString_FromStringAndSize(buf, pbuf - buf);
Tim Petersba873472002-12-18 20:19:21 +00002079
2080 Fail:
2081 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2082 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002083}
2084
Tim Peters371935f2003-02-01 01:52:50 +00002085/* Pickle support, a simple use of __reduce__. */
2086
Tim Petersb57f8f02003-02-01 02:54:15 +00002087/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002088static PyObject *
2089delta_getstate(PyDateTime_Delta *self)
2090{
2091 return Py_BuildValue("iii", GET_TD_DAYS(self),
2092 GET_TD_SECONDS(self),
2093 GET_TD_MICROSECONDS(self));
2094}
2095
Tim Peters2a799bf2002-12-16 20:18:38 +00002096static PyObject *
2097delta_reduce(PyDateTime_Delta* self)
2098{
Christian Heimese93237d2007-12-19 02:37:44 +00002099 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002100}
2101
2102#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2103
2104static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002105
Neal Norwitzdfb80862002-12-19 02:30:56 +00002106 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002107 PyDoc_STR("Number of days.")},
2108
Neal Norwitzdfb80862002-12-19 02:30:56 +00002109 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002110 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2111
Neal Norwitzdfb80862002-12-19 02:30:56 +00002112 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002113 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2114 {NULL}
2115};
2116
2117static PyMethodDef delta_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002118 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2119 PyDoc_STR("__reduce__() -> (cls, state)")},
2120
Tim Peters2a799bf2002-12-16 20:18:38 +00002121 {NULL, NULL},
2122};
2123
2124static char delta_doc[] =
2125PyDoc_STR("Difference between two datetime values.");
2126
2127static PyNumberMethods delta_as_number = {
2128 delta_add, /* nb_add */
2129 delta_subtract, /* nb_subtract */
2130 delta_multiply, /* nb_multiply */
2131 delta_divide, /* nb_divide */
2132 0, /* nb_remainder */
2133 0, /* nb_divmod */
2134 0, /* nb_power */
2135 (unaryfunc)delta_negative, /* nb_negative */
2136 (unaryfunc)delta_positive, /* nb_positive */
2137 (unaryfunc)delta_abs, /* nb_absolute */
2138 (inquiry)delta_nonzero, /* nb_nonzero */
2139 0, /*nb_invert*/
2140 0, /*nb_lshift*/
2141 0, /*nb_rshift*/
2142 0, /*nb_and*/
2143 0, /*nb_xor*/
2144 0, /*nb_or*/
2145 0, /*nb_coerce*/
2146 0, /*nb_int*/
2147 0, /*nb_long*/
2148 0, /*nb_float*/
2149 0, /*nb_oct*/
2150 0, /*nb_hex*/
2151 0, /*nb_inplace_add*/
2152 0, /*nb_inplace_subtract*/
2153 0, /*nb_inplace_multiply*/
2154 0, /*nb_inplace_divide*/
2155 0, /*nb_inplace_remainder*/
2156 0, /*nb_inplace_power*/
2157 0, /*nb_inplace_lshift*/
2158 0, /*nb_inplace_rshift*/
2159 0, /*nb_inplace_and*/
2160 0, /*nb_inplace_xor*/
2161 0, /*nb_inplace_or*/
2162 delta_divide, /* nb_floor_divide */
2163 0, /* nb_true_divide */
2164 0, /* nb_inplace_floor_divide */
2165 0, /* nb_inplace_true_divide */
2166};
2167
2168static PyTypeObject PyDateTime_DeltaType = {
Martin v. Löwis68192102007-07-21 06:55:02 +00002169 PyVarObject_HEAD_INIT(NULL, 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00002170 "datetime.timedelta", /* tp_name */
2171 sizeof(PyDateTime_Delta), /* tp_basicsize */
2172 0, /* tp_itemsize */
2173 0, /* tp_dealloc */
2174 0, /* tp_print */
2175 0, /* tp_getattr */
2176 0, /* tp_setattr */
2177 0, /* tp_compare */
2178 (reprfunc)delta_repr, /* tp_repr */
2179 &delta_as_number, /* tp_as_number */
2180 0, /* tp_as_sequence */
2181 0, /* tp_as_mapping */
2182 (hashfunc)delta_hash, /* tp_hash */
2183 0, /* tp_call */
2184 (reprfunc)delta_str, /* tp_str */
2185 PyObject_GenericGetAttr, /* tp_getattro */
2186 0, /* tp_setattro */
2187 0, /* tp_as_buffer */
Tim Petersb0c854d2003-05-17 15:57:00 +00002188 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2189 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters2a799bf2002-12-16 20:18:38 +00002190 delta_doc, /* tp_doc */
2191 0, /* tp_traverse */
2192 0, /* tp_clear */
2193 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2194 0, /* tp_weaklistoffset */
2195 0, /* tp_iter */
2196 0, /* tp_iternext */
2197 delta_methods, /* tp_methods */
2198 delta_members, /* tp_members */
2199 0, /* tp_getset */
2200 0, /* tp_base */
2201 0, /* tp_dict */
2202 0, /* tp_descr_get */
2203 0, /* tp_descr_set */
2204 0, /* tp_dictoffset */
2205 0, /* tp_init */
2206 0, /* tp_alloc */
2207 delta_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002208 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002209};
2210
2211/*
2212 * PyDateTime_Date implementation.
2213 */
2214
2215/* Accessor properties. */
2216
2217static PyObject *
2218date_year(PyDateTime_Date *self, void *unused)
2219{
2220 return PyInt_FromLong(GET_YEAR(self));
2221}
2222
2223static PyObject *
2224date_month(PyDateTime_Date *self, void *unused)
2225{
2226 return PyInt_FromLong(GET_MONTH(self));
2227}
2228
2229static PyObject *
2230date_day(PyDateTime_Date *self, void *unused)
2231{
2232 return PyInt_FromLong(GET_DAY(self));
2233}
2234
2235static PyGetSetDef date_getset[] = {
2236 {"year", (getter)date_year},
2237 {"month", (getter)date_month},
2238 {"day", (getter)date_day},
2239 {NULL}
2240};
2241
2242/* Constructors. */
2243
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002244static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002245
Tim Peters2a799bf2002-12-16 20:18:38 +00002246static PyObject *
2247date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2248{
2249 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002250 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002251 int year;
2252 int month;
2253 int day;
2254
Guido van Rossum177e41a2003-01-30 22:06:23 +00002255 /* Check for invocation from pickle with __getstate__ state */
2256 if (PyTuple_GET_SIZE(args) == 1 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002257 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2258 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2259 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00002260 {
Tim Peters70533e22003-02-01 04:40:04 +00002261 PyDateTime_Date *me;
2262
Tim Peters604c0132004-06-07 23:04:33 +00002263 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
Tim Peters70533e22003-02-01 04:40:04 +00002264 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002265 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00002266 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2267 me->hashcode = -1;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002268 }
Tim Peters70533e22003-02-01 04:40:04 +00002269 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002270 }
2271
Tim Peters12bf3392002-12-24 05:41:27 +00002272 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002273 &year, &month, &day)) {
2274 if (check_date_args(year, month, day) < 0)
2275 return NULL;
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002276 self = new_date_ex(year, month, day, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00002277 }
2278 return self;
2279}
2280
2281/* Return new date from localtime(t). */
2282static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002283date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002284{
2285 struct tm *tm;
Tim Peters1b6f7a92004-06-20 02:50:16 +00002286 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002287 PyObject *result = NULL;
2288
Tim Peters1b6f7a92004-06-20 02:50:16 +00002289 t = _PyTime_DoubleToTimet(ts);
2290 if (t == (time_t)-1 && PyErr_Occurred())
2291 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002292 tm = localtime(&t);
2293 if (tm)
2294 result = PyObject_CallFunction(cls, "iii",
2295 tm->tm_year + 1900,
2296 tm->tm_mon + 1,
2297 tm->tm_mday);
2298 else
2299 PyErr_SetString(PyExc_ValueError,
2300 "timestamp out of range for "
2301 "platform localtime() function");
2302 return result;
2303}
2304
2305/* Return new date from current time.
2306 * We say this is equivalent to fromtimestamp(time.time()), and the
2307 * only way to be sure of that is to *call* time.time(). That's not
2308 * generally the same as calling C's time.
2309 */
2310static PyObject *
2311date_today(PyObject *cls, PyObject *dummy)
2312{
2313 PyObject *time;
2314 PyObject *result;
2315
2316 time = time_time();
2317 if (time == NULL)
2318 return NULL;
2319
2320 /* Note well: today() is a class method, so this may not call
2321 * date.fromtimestamp. For example, it may call
2322 * datetime.fromtimestamp. That's why we need all the accuracy
2323 * time.time() delivers; if someone were gonzo about optimization,
2324 * date.today() could get away with plain C time().
2325 */
2326 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2327 Py_DECREF(time);
2328 return result;
2329}
2330
2331/* Return new date from given timestamp (Python timestamp -- a double). */
2332static PyObject *
2333date_fromtimestamp(PyObject *cls, PyObject *args)
2334{
2335 double timestamp;
2336 PyObject *result = NULL;
2337
2338 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
Tim Peters1b6f7a92004-06-20 02:50:16 +00002339 result = date_local_from_time_t(cls, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002340 return result;
2341}
2342
2343/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2344 * the ordinal is out of range.
2345 */
2346static PyObject *
2347date_fromordinal(PyObject *cls, PyObject *args)
2348{
2349 PyObject *result = NULL;
2350 int ordinal;
2351
2352 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2353 int year;
2354 int month;
2355 int day;
2356
2357 if (ordinal < 1)
2358 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2359 ">= 1");
2360 else {
2361 ord_to_ymd(ordinal, &year, &month, &day);
2362 result = PyObject_CallFunction(cls, "iii",
2363 year, month, day);
2364 }
2365 }
2366 return result;
2367}
2368
2369/*
2370 * Date arithmetic.
2371 */
2372
2373/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2374 * instead.
2375 */
2376static PyObject *
2377add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2378{
2379 PyObject *result = NULL;
2380 int year = GET_YEAR(date);
2381 int month = GET_MONTH(date);
2382 int deltadays = GET_TD_DAYS(delta);
2383 /* C-level overflow is impossible because |deltadays| < 1e9. */
2384 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2385
2386 if (normalize_date(&year, &month, &day) >= 0)
2387 result = new_date(year, month, day);
2388 return result;
2389}
2390
2391static PyObject *
2392date_add(PyObject *left, PyObject *right)
2393{
2394 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2395 Py_INCREF(Py_NotImplemented);
2396 return Py_NotImplemented;
2397 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002398 if (PyDate_Check(left)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002399 /* date + ??? */
2400 if (PyDelta_Check(right))
2401 /* date + delta */
2402 return add_date_timedelta((PyDateTime_Date *) left,
2403 (PyDateTime_Delta *) right,
2404 0);
2405 }
2406 else {
2407 /* ??? + date
2408 * 'right' must be one of us, or we wouldn't have been called
2409 */
2410 if (PyDelta_Check(left))
2411 /* delta + date */
2412 return add_date_timedelta((PyDateTime_Date *) right,
2413 (PyDateTime_Delta *) left,
2414 0);
2415 }
2416 Py_INCREF(Py_NotImplemented);
2417 return Py_NotImplemented;
2418}
2419
2420static PyObject *
2421date_subtract(PyObject *left, PyObject *right)
2422{
2423 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2424 Py_INCREF(Py_NotImplemented);
2425 return Py_NotImplemented;
2426 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002427 if (PyDate_Check(left)) {
2428 if (PyDate_Check(right)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002429 /* date - date */
2430 int left_ord = ymd_to_ord(GET_YEAR(left),
2431 GET_MONTH(left),
2432 GET_DAY(left));
2433 int right_ord = ymd_to_ord(GET_YEAR(right),
2434 GET_MONTH(right),
2435 GET_DAY(right));
2436 return new_delta(left_ord - right_ord, 0, 0, 0);
2437 }
2438 if (PyDelta_Check(right)) {
2439 /* date - delta */
2440 return add_date_timedelta((PyDateTime_Date *) left,
2441 (PyDateTime_Delta *) right,
2442 1);
2443 }
2444 }
2445 Py_INCREF(Py_NotImplemented);
2446 return Py_NotImplemented;
2447}
2448
2449
2450/* Various ways to turn a date into a string. */
2451
2452static PyObject *
2453date_repr(PyDateTime_Date *self)
2454{
2455 char buffer[1028];
Skip Montanaro14f88992006-04-18 19:35:04 +00002456 const char *type_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002457
Christian Heimese93237d2007-12-19 02:37:44 +00002458 type_name = Py_TYPE(self)->tp_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002459 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00002460 type_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002461 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2462
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002463 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002464}
2465
2466static PyObject *
2467date_isoformat(PyDateTime_Date *self)
2468{
2469 char buffer[128];
2470
2471 isoformat_date(self, buffer, sizeof(buffer));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002472 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002473}
2474
Tim Peterse2df5ff2003-05-02 18:39:55 +00002475/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002476static PyObject *
2477date_str(PyDateTime_Date *self)
2478{
2479 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2480}
2481
2482
2483static PyObject *
2484date_ctime(PyDateTime_Date *self)
2485{
2486 return format_ctime(self, 0, 0, 0);
2487}
2488
2489static PyObject *
2490date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2491{
2492 /* This method can be inherited, and needs to call the
2493 * timetuple() method appropriate to self's class.
2494 */
2495 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002496 PyObject *tuple;
Gregory P. Smith137d8242008-06-02 04:05:52 +00002497 const char *format;
2498 Py_ssize_t format_len;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002499 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002500
Gregory P. Smith137d8242008-06-02 04:05:52 +00002501 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2502 &format, &format_len))
Tim Peters2a799bf2002-12-16 20:18:38 +00002503 return NULL;
2504
2505 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2506 if (tuple == NULL)
2507 return NULL;
Gregory P. Smith137d8242008-06-02 04:05:52 +00002508 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
Tim Petersbad8ff02002-12-30 20:52:32 +00002509 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002510 Py_DECREF(tuple);
2511 return result;
2512}
2513
Eric Smitha9f7d622008-02-17 19:46:49 +00002514static PyObject *
2515date_format(PyDateTime_Date *self, PyObject *args)
2516{
2517 PyObject *format;
2518
2519 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2520 return NULL;
2521
2522 /* Check for str or unicode */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002523 if (PyString_Check(format)) {
Eric Smitha9f7d622008-02-17 19:46:49 +00002524 /* If format is zero length, return str(self) */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002525 if (PyString_GET_SIZE(format) == 0)
Eric Smitha9f7d622008-02-17 19:46:49 +00002526 return PyObject_Str((PyObject *)self);
2527 } else if (PyUnicode_Check(format)) {
2528 /* If format is zero length, return str(self) */
2529 if (PyUnicode_GET_SIZE(format) == 0)
2530 return PyObject_Unicode((PyObject *)self);
2531 } else {
2532 PyErr_Format(PyExc_ValueError,
2533 "__format__ expects str or unicode, not %.200s",
2534 Py_TYPE(format)->tp_name);
2535 return NULL;
2536 }
2537 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2538}
2539
Tim Peters2a799bf2002-12-16 20:18:38 +00002540/* ISO methods. */
2541
2542static PyObject *
2543date_isoweekday(PyDateTime_Date *self)
2544{
2545 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2546
2547 return PyInt_FromLong(dow + 1);
2548}
2549
2550static PyObject *
2551date_isocalendar(PyDateTime_Date *self)
2552{
2553 int year = GET_YEAR(self);
2554 int week1_monday = iso_week1_monday(year);
2555 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2556 int week;
2557 int day;
2558
2559 week = divmod(today - week1_monday, 7, &day);
2560 if (week < 0) {
2561 --year;
2562 week1_monday = iso_week1_monday(year);
2563 week = divmod(today - week1_monday, 7, &day);
2564 }
2565 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2566 ++year;
2567 week = 0;
2568 }
2569 return Py_BuildValue("iii", year, week + 1, day + 1);
2570}
2571
2572/* Miscellaneous methods. */
2573
2574/* This is more natural as a tp_compare, but doesn't work then: for whatever
2575 * reason, Python's try_3way_compare ignores tp_compare unless
2576 * PyInstance_Check returns true, but these aren't old-style classes.
2577 */
2578static PyObject *
2579date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2580{
Tim Peters07534a62003-02-07 22:50:28 +00002581 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002582
Tim Peters07534a62003-02-07 22:50:28 +00002583 if (PyDate_Check(other))
2584 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2585 _PyDateTime_DATE_DATASIZE);
2586
2587 else if (PyObject_HasAttrString(other, "timetuple")) {
2588 /* A hook for other kinds of date objects. */
2589 Py_INCREF(Py_NotImplemented);
2590 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002591 }
Tim Peters07534a62003-02-07 22:50:28 +00002592 else if (op == Py_EQ || op == Py_NE)
2593 diff = 1; /* any non-zero value will do */
2594
2595 else /* stop this from falling back to address comparison */
2596 return cmperror((PyObject *)self, other);
2597
Tim Peters2a799bf2002-12-16 20:18:38 +00002598 return diff_to_bool(diff, op);
2599}
2600
2601static PyObject *
2602date_timetuple(PyDateTime_Date *self)
2603{
2604 return build_struct_time(GET_YEAR(self),
2605 GET_MONTH(self),
2606 GET_DAY(self),
2607 0, 0, 0, -1);
2608}
2609
Tim Peters12bf3392002-12-24 05:41:27 +00002610static PyObject *
2611date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2612{
2613 PyObject *clone;
2614 PyObject *tuple;
2615 int year = GET_YEAR(self);
2616 int month = GET_MONTH(self);
2617 int day = GET_DAY(self);
2618
2619 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2620 &year, &month, &day))
2621 return NULL;
2622 tuple = Py_BuildValue("iii", year, month, day);
2623 if (tuple == NULL)
2624 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00002625 clone = date_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00002626 Py_DECREF(tuple);
2627 return clone;
2628}
2629
Tim Peters2a799bf2002-12-16 20:18:38 +00002630static PyObject *date_getstate(PyDateTime_Date *self);
2631
2632static long
2633date_hash(PyDateTime_Date *self)
2634{
2635 if (self->hashcode == -1) {
2636 PyObject *temp = date_getstate(self);
2637 if (temp != NULL) {
2638 self->hashcode = PyObject_Hash(temp);
2639 Py_DECREF(temp);
2640 }
2641 }
2642 return self->hashcode;
2643}
2644
2645static PyObject *
2646date_toordinal(PyDateTime_Date *self)
2647{
2648 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2649 GET_DAY(self)));
2650}
2651
2652static PyObject *
2653date_weekday(PyDateTime_Date *self)
2654{
2655 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2656
2657 return PyInt_FromLong(dow);
2658}
2659
Tim Peters371935f2003-02-01 01:52:50 +00002660/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002661
Tim Petersb57f8f02003-02-01 02:54:15 +00002662/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002663static PyObject *
2664date_getstate(PyDateTime_Date *self)
2665{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002666 return Py_BuildValue(
2667 "(N)",
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002668 PyString_FromStringAndSize((char *)self->data,
Guido van Rossum177e41a2003-01-30 22:06:23 +00002669 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002670}
2671
2672static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002673date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002674{
Christian Heimese93237d2007-12-19 02:37:44 +00002675 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002676}
2677
2678static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002679
Tim Peters2a799bf2002-12-16 20:18:38 +00002680 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002681
Tim Peters2a799bf2002-12-16 20:18:38 +00002682 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2683 METH_CLASS,
2684 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2685 "time.time()).")},
2686
2687 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2688 METH_CLASS,
2689 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2690 "ordinal.")},
2691
2692 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2693 PyDoc_STR("Current date or datetime: same as "
2694 "self.__class__.fromtimestamp(time.time()).")},
2695
2696 /* Instance methods: */
2697
2698 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2699 PyDoc_STR("Return ctime() style string.")},
2700
Neal Norwitza84dcd72007-05-22 07:16:44 +00002701 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00002702 PyDoc_STR("format -> strftime() style string.")},
2703
Eric Smitha9f7d622008-02-17 19:46:49 +00002704 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2705 PyDoc_STR("Formats self with strftime.")},
2706
Tim Peters2a799bf2002-12-16 20:18:38 +00002707 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2708 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2709
2710 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2711 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2712 "weekday.")},
2713
2714 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2715 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2716
2717 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2718 PyDoc_STR("Return the day of the week represented by the date.\n"
2719 "Monday == 1 ... Sunday == 7")},
2720
2721 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2722 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2723 "1 is day 1.")},
2724
2725 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2726 PyDoc_STR("Return the day of the week represented by the date.\n"
2727 "Monday == 0 ... Sunday == 6")},
2728
Neal Norwitza84dcd72007-05-22 07:16:44 +00002729 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
Tim Peters12bf3392002-12-24 05:41:27 +00002730 PyDoc_STR("Return date with new specified fields.")},
2731
Guido van Rossum177e41a2003-01-30 22:06:23 +00002732 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2733 PyDoc_STR("__reduce__() -> (cls, state)")},
2734
Tim Peters2a799bf2002-12-16 20:18:38 +00002735 {NULL, NULL}
2736};
2737
2738static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002739PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002740
2741static PyNumberMethods date_as_number = {
2742 date_add, /* nb_add */
2743 date_subtract, /* nb_subtract */
2744 0, /* nb_multiply */
2745 0, /* nb_divide */
2746 0, /* nb_remainder */
2747 0, /* nb_divmod */
2748 0, /* nb_power */
2749 0, /* nb_negative */
2750 0, /* nb_positive */
2751 0, /* nb_absolute */
2752 0, /* nb_nonzero */
2753};
2754
2755static PyTypeObject PyDateTime_DateType = {
Martin v. Löwis68192102007-07-21 06:55:02 +00002756 PyVarObject_HEAD_INIT(NULL, 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00002757 "datetime.date", /* tp_name */
2758 sizeof(PyDateTime_Date), /* tp_basicsize */
2759 0, /* tp_itemsize */
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002760 0, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00002761 0, /* tp_print */
2762 0, /* tp_getattr */
2763 0, /* tp_setattr */
2764 0, /* tp_compare */
2765 (reprfunc)date_repr, /* tp_repr */
2766 &date_as_number, /* tp_as_number */
2767 0, /* tp_as_sequence */
2768 0, /* tp_as_mapping */
2769 (hashfunc)date_hash, /* tp_hash */
2770 0, /* tp_call */
2771 (reprfunc)date_str, /* tp_str */
2772 PyObject_GenericGetAttr, /* tp_getattro */
2773 0, /* tp_setattro */
2774 0, /* tp_as_buffer */
2775 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2776 Py_TPFLAGS_BASETYPE, /* tp_flags */
2777 date_doc, /* tp_doc */
2778 0, /* tp_traverse */
2779 0, /* tp_clear */
2780 (richcmpfunc)date_richcompare, /* tp_richcompare */
2781 0, /* tp_weaklistoffset */
2782 0, /* tp_iter */
2783 0, /* tp_iternext */
2784 date_methods, /* tp_methods */
2785 0, /* tp_members */
2786 date_getset, /* tp_getset */
2787 0, /* tp_base */
2788 0, /* tp_dict */
2789 0, /* tp_descr_get */
2790 0, /* tp_descr_set */
2791 0, /* tp_dictoffset */
2792 0, /* tp_init */
2793 0, /* tp_alloc */
2794 date_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002795 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002796};
2797
2798/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002799 * PyDateTime_TZInfo implementation.
2800 */
2801
2802/* This is a pure abstract base class, so doesn't do anything beyond
2803 * raising NotImplemented exceptions. Real tzinfo classes need
2804 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002805 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002806 * be subclasses of this tzinfo class, which is easy and quick to check).
2807 *
2808 * Note: For reasons having to do with pickling of subclasses, we have
2809 * to allow tzinfo objects to be instantiated. This wasn't an issue
2810 * in the Python implementation (__init__() could raise NotImplementedError
2811 * there without ill effect), but doing so in the C implementation hit a
2812 * brick wall.
2813 */
2814
2815static PyObject *
2816tzinfo_nogo(const char* methodname)
2817{
2818 PyErr_Format(PyExc_NotImplementedError,
2819 "a tzinfo subclass must implement %s()",
2820 methodname);
2821 return NULL;
2822}
2823
2824/* Methods. A subclass must implement these. */
2825
Tim Peters52dcce22003-01-23 16:36:11 +00002826static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002827tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2828{
2829 return tzinfo_nogo("tzname");
2830}
2831
Tim Peters52dcce22003-01-23 16:36:11 +00002832static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002833tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2834{
2835 return tzinfo_nogo("utcoffset");
2836}
2837
Tim Peters52dcce22003-01-23 16:36:11 +00002838static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002839tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2840{
2841 return tzinfo_nogo("dst");
2842}
2843
Tim Peters52dcce22003-01-23 16:36:11 +00002844static PyObject *
2845tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2846{
2847 int y, m, d, hh, mm, ss, us;
2848
2849 PyObject *result;
2850 int off, dst;
2851 int none;
2852 int delta;
2853
2854 if (! PyDateTime_Check(dt)) {
2855 PyErr_SetString(PyExc_TypeError,
2856 "fromutc: argument must be a datetime");
2857 return NULL;
2858 }
2859 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2860 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2861 "is not self");
2862 return NULL;
2863 }
2864
2865 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2866 if (off == -1 && PyErr_Occurred())
2867 return NULL;
2868 if (none) {
2869 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2870 "utcoffset() result required");
2871 return NULL;
2872 }
2873
2874 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2875 if (dst == -1 && PyErr_Occurred())
2876 return NULL;
2877 if (none) {
2878 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2879 "dst() result required");
2880 return NULL;
2881 }
2882
2883 y = GET_YEAR(dt);
2884 m = GET_MONTH(dt);
2885 d = GET_DAY(dt);
2886 hh = DATE_GET_HOUR(dt);
2887 mm = DATE_GET_MINUTE(dt);
2888 ss = DATE_GET_SECOND(dt);
2889 us = DATE_GET_MICROSECOND(dt);
2890
2891 delta = off - dst;
2892 mm += delta;
2893 if ((mm < 0 || mm >= 60) &&
2894 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002895 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002896 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2897 if (result == NULL)
2898 return result;
2899
2900 dst = call_dst(dt->tzinfo, result, &none);
2901 if (dst == -1 && PyErr_Occurred())
2902 goto Fail;
2903 if (none)
2904 goto Inconsistent;
2905 if (dst == 0)
2906 return result;
2907
2908 mm += dst;
2909 if ((mm < 0 || mm >= 60) &&
2910 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2911 goto Fail;
2912 Py_DECREF(result);
2913 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2914 return result;
2915
2916Inconsistent:
2917 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2918 "inconsistent results; cannot convert");
2919
2920 /* fall thru to failure */
2921Fail:
2922 Py_DECREF(result);
2923 return NULL;
2924}
2925
Tim Peters2a799bf2002-12-16 20:18:38 +00002926/*
2927 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002928 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002929 */
2930
Guido van Rossum177e41a2003-01-30 22:06:23 +00002931static PyObject *
2932tzinfo_reduce(PyObject *self)
2933{
2934 PyObject *args, *state, *tmp;
2935 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002936
Guido van Rossum177e41a2003-01-30 22:06:23 +00002937 tmp = PyTuple_New(0);
2938 if (tmp == NULL)
2939 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002940
Guido van Rossum177e41a2003-01-30 22:06:23 +00002941 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2942 if (getinitargs != NULL) {
2943 args = PyObject_CallObject(getinitargs, tmp);
2944 Py_DECREF(getinitargs);
2945 if (args == NULL) {
2946 Py_DECREF(tmp);
2947 return NULL;
2948 }
2949 }
2950 else {
2951 PyErr_Clear();
2952 args = tmp;
2953 Py_INCREF(args);
2954 }
2955
2956 getstate = PyObject_GetAttrString(self, "__getstate__");
2957 if (getstate != NULL) {
2958 state = PyObject_CallObject(getstate, tmp);
2959 Py_DECREF(getstate);
2960 if (state == NULL) {
2961 Py_DECREF(args);
2962 Py_DECREF(tmp);
2963 return NULL;
2964 }
2965 }
2966 else {
2967 PyObject **dictptr;
2968 PyErr_Clear();
2969 state = Py_None;
2970 dictptr = _PyObject_GetDictPtr(self);
2971 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2972 state = *dictptr;
2973 Py_INCREF(state);
2974 }
2975
2976 Py_DECREF(tmp);
2977
2978 if (state == Py_None) {
2979 Py_DECREF(state);
Christian Heimese93237d2007-12-19 02:37:44 +00002980 return Py_BuildValue("(ON)", Py_TYPE(self), args);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002981 }
2982 else
Christian Heimese93237d2007-12-19 02:37:44 +00002983 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002984}
Tim Peters2a799bf2002-12-16 20:18:38 +00002985
2986static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002987
Tim Peters2a799bf2002-12-16 20:18:38 +00002988 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2989 PyDoc_STR("datetime -> string name of time zone.")},
2990
2991 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2992 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2993 "west of UTC).")},
2994
2995 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2996 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2997
Tim Peters52dcce22003-01-23 16:36:11 +00002998 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2999 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3000
Guido van Rossum177e41a2003-01-30 22:06:23 +00003001 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3002 PyDoc_STR("-> (cls, state)")},
3003
Tim Peters2a799bf2002-12-16 20:18:38 +00003004 {NULL, NULL}
3005};
3006
3007static char tzinfo_doc[] =
3008PyDoc_STR("Abstract base class for time zone info objects.");
3009
Neal Norwitzce3d34d2003-02-04 20:45:17 +00003010statichere PyTypeObject PyDateTime_TZInfoType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003011 PyObject_HEAD_INIT(NULL)
3012 0, /* ob_size */
3013 "datetime.tzinfo", /* tp_name */
3014 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3015 0, /* tp_itemsize */
3016 0, /* tp_dealloc */
3017 0, /* tp_print */
3018 0, /* tp_getattr */
3019 0, /* tp_setattr */
3020 0, /* tp_compare */
3021 0, /* tp_repr */
3022 0, /* tp_as_number */
3023 0, /* tp_as_sequence */
3024 0, /* tp_as_mapping */
3025 0, /* tp_hash */
3026 0, /* tp_call */
3027 0, /* tp_str */
3028 PyObject_GenericGetAttr, /* tp_getattro */
3029 0, /* tp_setattro */
3030 0, /* tp_as_buffer */
3031 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3032 Py_TPFLAGS_BASETYPE, /* tp_flags */
3033 tzinfo_doc, /* tp_doc */
3034 0, /* tp_traverse */
3035 0, /* tp_clear */
3036 0, /* tp_richcompare */
3037 0, /* tp_weaklistoffset */
3038 0, /* tp_iter */
3039 0, /* tp_iternext */
3040 tzinfo_methods, /* tp_methods */
3041 0, /* tp_members */
3042 0, /* tp_getset */
3043 0, /* tp_base */
3044 0, /* tp_dict */
3045 0, /* tp_descr_get */
3046 0, /* tp_descr_set */
3047 0, /* tp_dictoffset */
3048 0, /* tp_init */
3049 0, /* tp_alloc */
3050 PyType_GenericNew, /* tp_new */
3051 0, /* tp_free */
3052};
3053
3054/*
Tim Peters37f39822003-01-10 03:49:02 +00003055 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003056 */
3057
Tim Peters37f39822003-01-10 03:49:02 +00003058/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003059 */
3060
3061static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003062time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003063{
Tim Peters37f39822003-01-10 03:49:02 +00003064 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003065}
3066
Tim Peters37f39822003-01-10 03:49:02 +00003067static PyObject *
3068time_minute(PyDateTime_Time *self, void *unused)
3069{
3070 return PyInt_FromLong(TIME_GET_MINUTE(self));
3071}
3072
3073/* The name time_second conflicted with some platform header file. */
3074static PyObject *
3075py_time_second(PyDateTime_Time *self, void *unused)
3076{
3077 return PyInt_FromLong(TIME_GET_SECOND(self));
3078}
3079
3080static PyObject *
3081time_microsecond(PyDateTime_Time *self, void *unused)
3082{
3083 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3084}
3085
3086static PyObject *
3087time_tzinfo(PyDateTime_Time *self, void *unused)
3088{
Tim Petersa032d2e2003-01-11 00:15:54 +00003089 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00003090 Py_INCREF(result);
3091 return result;
3092}
3093
3094static PyGetSetDef time_getset[] = {
3095 {"hour", (getter)time_hour},
3096 {"minute", (getter)time_minute},
3097 {"second", (getter)py_time_second},
3098 {"microsecond", (getter)time_microsecond},
3099 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003100 {NULL}
3101};
3102
3103/*
3104 * Constructors.
3105 */
3106
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003107static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Tim Peters37f39822003-01-10 03:49:02 +00003108 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003109
Tim Peters2a799bf2002-12-16 20:18:38 +00003110static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003111time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003112{
3113 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003114 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003115 int hour = 0;
3116 int minute = 0;
3117 int second = 0;
3118 int usecond = 0;
3119 PyObject *tzinfo = Py_None;
3120
Guido van Rossum177e41a2003-01-30 22:06:23 +00003121 /* Check for invocation from pickle with __getstate__ state */
3122 if (PyTuple_GET_SIZE(args) >= 1 &&
3123 PyTuple_GET_SIZE(args) <= 2 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003124 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3125 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3126 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003127 {
Tim Peters70533e22003-02-01 04:40:04 +00003128 PyDateTime_Time *me;
3129 char aware;
3130
3131 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003132 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003133 if (check_tzinfo_subclass(tzinfo) < 0) {
3134 PyErr_SetString(PyExc_TypeError, "bad "
3135 "tzinfo state arg");
3136 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003137 }
3138 }
Tim Peters70533e22003-02-01 04:40:04 +00003139 aware = (char)(tzinfo != Py_None);
Tim Peters604c0132004-06-07 23:04:33 +00003140 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
Tim Peters70533e22003-02-01 04:40:04 +00003141 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003142 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003143
3144 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3145 me->hashcode = -1;
3146 me->hastzinfo = aware;
3147 if (aware) {
3148 Py_INCREF(tzinfo);
3149 me->tzinfo = tzinfo;
3150 }
3151 }
3152 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003153 }
3154
Tim Peters37f39822003-01-10 03:49:02 +00003155 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003156 &hour, &minute, &second, &usecond,
3157 &tzinfo)) {
3158 if (check_time_args(hour, minute, second, usecond) < 0)
3159 return NULL;
3160 if (check_tzinfo_subclass(tzinfo) < 0)
3161 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003162 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3163 type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003164 }
3165 return self;
3166}
3167
3168/*
3169 * Destructor.
3170 */
3171
3172static void
Tim Peters37f39822003-01-10 03:49:02 +00003173time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003174{
Tim Petersa032d2e2003-01-11 00:15:54 +00003175 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003176 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003177 }
Christian Heimese93237d2007-12-19 02:37:44 +00003178 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003179}
3180
3181/*
Tim Peters855fe882002-12-22 03:43:39 +00003182 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003183 */
3184
Tim Peters2a799bf2002-12-16 20:18:38 +00003185/* These are all METH_NOARGS, so don't need to check the arglist. */
3186static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003187time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003188 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003189 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003190}
3191
3192static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003193time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003194 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003195 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003196}
3197
3198static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003199time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003200 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003201 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003202}
3203
3204/*
Tim Peters37f39822003-01-10 03:49:02 +00003205 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003206 */
3207
3208static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003209time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003210{
Tim Peters37f39822003-01-10 03:49:02 +00003211 char buffer[100];
Christian Heimese93237d2007-12-19 02:37:44 +00003212 const char *type_name = Py_TYPE(self)->tp_name;
Tim Peters37f39822003-01-10 03:49:02 +00003213 int h = TIME_GET_HOUR(self);
3214 int m = TIME_GET_MINUTE(self);
3215 int s = TIME_GET_SECOND(self);
3216 int us = TIME_GET_MICROSECOND(self);
3217 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003218
Tim Peters37f39822003-01-10 03:49:02 +00003219 if (us)
3220 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003221 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
Tim Peters37f39822003-01-10 03:49:02 +00003222 else if (s)
3223 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003224 "%s(%d, %d, %d)", type_name, h, m, s);
Tim Peters37f39822003-01-10 03:49:02 +00003225 else
3226 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003227 "%s(%d, %d)", type_name, h, m);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003228 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003229 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003230 result = append_keyword_tzinfo(result, self->tzinfo);
3231 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003232}
3233
Tim Peters37f39822003-01-10 03:49:02 +00003234static PyObject *
3235time_str(PyDateTime_Time *self)
3236{
3237 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3238}
Tim Peters2a799bf2002-12-16 20:18:38 +00003239
3240static PyObject *
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003241time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003242{
3243 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003244 PyObject *result;
3245 /* Reuse the time format code from the datetime type. */
3246 PyDateTime_DateTime datetime;
3247 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003248
Tim Peters37f39822003-01-10 03:49:02 +00003249 /* Copy over just the time bytes. */
3250 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3251 self->data,
3252 _PyDateTime_TIME_DATASIZE);
3253
3254 isoformat_time(pdatetime, buf, sizeof(buf));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003255 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003256 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003257 return result;
3258
3259 /* We need to append the UTC offset. */
3260 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003261 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003262 Py_DECREF(result);
3263 return NULL;
3264 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003265 PyString_ConcatAndDel(&result, PyString_FromString(buf));
Tim Peters2a799bf2002-12-16 20:18:38 +00003266 return result;
3267}
3268
Tim Peters37f39822003-01-10 03:49:02 +00003269static PyObject *
3270time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3271{
3272 PyObject *result;
Tim Peters37f39822003-01-10 03:49:02 +00003273 PyObject *tuple;
Gregory P. Smith137d8242008-06-02 04:05:52 +00003274 const char *format;
3275 Py_ssize_t format_len;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003276 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003277
Gregory P. Smith137d8242008-06-02 04:05:52 +00003278 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3279 &format, &format_len))
Tim Peters37f39822003-01-10 03:49:02 +00003280 return NULL;
3281
3282 /* Python's strftime does insane things with the year part of the
3283 * timetuple. The year is forced to (the otherwise nonsensical)
3284 * 1900 to worm around that.
3285 */
3286 tuple = Py_BuildValue("iiiiiiiii",
Brett Cannond1080a32004-03-02 04:38:10 +00003287 1900, 1, 1, /* year, month, day */
Tim Peters37f39822003-01-10 03:49:02 +00003288 TIME_GET_HOUR(self),
3289 TIME_GET_MINUTE(self),
3290 TIME_GET_SECOND(self),
Brett Cannond1080a32004-03-02 04:38:10 +00003291 0, 1, -1); /* weekday, daynum, dst */
Tim Peters37f39822003-01-10 03:49:02 +00003292 if (tuple == NULL)
3293 return NULL;
3294 assert(PyTuple_Size(tuple) == 9);
Gregory P. Smith137d8242008-06-02 04:05:52 +00003295 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3296 Py_None);
Tim Peters37f39822003-01-10 03:49:02 +00003297 Py_DECREF(tuple);
3298 return result;
3299}
Tim Peters2a799bf2002-12-16 20:18:38 +00003300
3301/*
3302 * Miscellaneous methods.
3303 */
3304
Tim Peters37f39822003-01-10 03:49:02 +00003305/* This is more natural as a tp_compare, but doesn't work then: for whatever
3306 * reason, Python's try_3way_compare ignores tp_compare unless
3307 * PyInstance_Check returns true, but these aren't old-style classes.
3308 */
3309static PyObject *
3310time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3311{
3312 int diff;
3313 naivety n1, n2;
3314 int offset1, offset2;
3315
3316 if (! PyTime_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00003317 if (op == Py_EQ || op == Py_NE) {
3318 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3319 Py_INCREF(result);
3320 return result;
3321 }
Tim Peters37f39822003-01-10 03:49:02 +00003322 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00003323 return cmperror((PyObject *)self, other);
Tim Peters37f39822003-01-10 03:49:02 +00003324 }
3325 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3326 other, &offset2, &n2, Py_None) < 0)
3327 return NULL;
3328 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3329 /* If they're both naive, or both aware and have the same offsets,
3330 * we get off cheap. Note that if they're both naive, offset1 ==
3331 * offset2 == 0 at this point.
3332 */
3333 if (n1 == n2 && offset1 == offset2) {
3334 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3335 _PyDateTime_TIME_DATASIZE);
3336 return diff_to_bool(diff, op);
3337 }
3338
3339 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3340 assert(offset1 != offset2); /* else last "if" handled it */
3341 /* Convert everything except microseconds to seconds. These
3342 * can't overflow (no more than the # of seconds in 2 days).
3343 */
3344 offset1 = TIME_GET_HOUR(self) * 3600 +
3345 (TIME_GET_MINUTE(self) - offset1) * 60 +
3346 TIME_GET_SECOND(self);
3347 offset2 = TIME_GET_HOUR(other) * 3600 +
3348 (TIME_GET_MINUTE(other) - offset2) * 60 +
3349 TIME_GET_SECOND(other);
3350 diff = offset1 - offset2;
3351 if (diff == 0)
3352 diff = TIME_GET_MICROSECOND(self) -
3353 TIME_GET_MICROSECOND(other);
3354 return diff_to_bool(diff, op);
3355 }
3356
3357 assert(n1 != n2);
3358 PyErr_SetString(PyExc_TypeError,
3359 "can't compare offset-naive and "
3360 "offset-aware times");
3361 return NULL;
3362}
3363
3364static long
3365time_hash(PyDateTime_Time *self)
3366{
3367 if (self->hashcode == -1) {
3368 naivety n;
3369 int offset;
3370 PyObject *temp;
3371
3372 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3373 assert(n != OFFSET_UNKNOWN);
3374 if (n == OFFSET_ERROR)
3375 return -1;
3376
3377 /* Reduce this to a hash of another object. */
3378 if (offset == 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003379 temp = PyString_FromStringAndSize((char *)self->data,
Tim Peters37f39822003-01-10 03:49:02 +00003380 _PyDateTime_TIME_DATASIZE);
3381 else {
3382 int hour;
3383 int minute;
3384
3385 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003386 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003387 hour = divmod(TIME_GET_HOUR(self) * 60 +
3388 TIME_GET_MINUTE(self) - offset,
3389 60,
3390 &minute);
3391 if (0 <= hour && hour < 24)
3392 temp = new_time(hour, minute,
3393 TIME_GET_SECOND(self),
3394 TIME_GET_MICROSECOND(self),
3395 Py_None);
3396 else
3397 temp = Py_BuildValue("iiii",
3398 hour, minute,
3399 TIME_GET_SECOND(self),
3400 TIME_GET_MICROSECOND(self));
3401 }
3402 if (temp != NULL) {
3403 self->hashcode = PyObject_Hash(temp);
3404 Py_DECREF(temp);
3405 }
3406 }
3407 return self->hashcode;
3408}
Tim Peters2a799bf2002-12-16 20:18:38 +00003409
Tim Peters12bf3392002-12-24 05:41:27 +00003410static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003411time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003412{
3413 PyObject *clone;
3414 PyObject *tuple;
3415 int hh = TIME_GET_HOUR(self);
3416 int mm = TIME_GET_MINUTE(self);
3417 int ss = TIME_GET_SECOND(self);
3418 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003419 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003420
3421 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003422 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003423 &hh, &mm, &ss, &us, &tzinfo))
3424 return NULL;
3425 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3426 if (tuple == NULL)
3427 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00003428 clone = time_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003429 Py_DECREF(tuple);
3430 return clone;
3431}
3432
Tim Peters2a799bf2002-12-16 20:18:38 +00003433static int
Tim Peters37f39822003-01-10 03:49:02 +00003434time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003435{
3436 int offset;
3437 int none;
3438
3439 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3440 /* Since utcoffset is in whole minutes, nothing can
3441 * alter the conclusion that this is nonzero.
3442 */
3443 return 1;
3444 }
3445 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003446 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003447 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003448 if (offset == -1 && PyErr_Occurred())
3449 return -1;
3450 }
3451 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3452}
3453
Tim Peters371935f2003-02-01 01:52:50 +00003454/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003455
Tim Peters33e0f382003-01-10 02:05:14 +00003456/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003457 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3458 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003459 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003460 */
3461static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003462time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003463{
3464 PyObject *basestate;
3465 PyObject *result = NULL;
3466
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003467 basestate = PyString_FromStringAndSize((char *)self->data,
Tim Peters33e0f382003-01-10 02:05:14 +00003468 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003469 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003470 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003471 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00003472 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003473 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003474 Py_DECREF(basestate);
3475 }
3476 return result;
3477}
3478
3479static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003480time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003481{
Christian Heimese93237d2007-12-19 02:37:44 +00003482 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003483}
3484
Tim Peters37f39822003-01-10 03:49:02 +00003485static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003486
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003487 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003488 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3489 "[+HH:MM].")},
3490
Neal Norwitza84dcd72007-05-22 07:16:44 +00003491 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
Tim Peters37f39822003-01-10 03:49:02 +00003492 PyDoc_STR("format -> strftime() style string.")},
3493
Eric Smitha9f7d622008-02-17 19:46:49 +00003494 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3495 PyDoc_STR("Formats self with strftime.")},
3496
Tim Peters37f39822003-01-10 03:49:02 +00003497 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003498 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3499
Tim Peters37f39822003-01-10 03:49:02 +00003500 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003501 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3502
Tim Peters37f39822003-01-10 03:49:02 +00003503 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003504 PyDoc_STR("Return self.tzinfo.dst(self).")},
3505
Neal Norwitza84dcd72007-05-22 07:16:44 +00003506 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
Tim Peters37f39822003-01-10 03:49:02 +00003507 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003508
Guido van Rossum177e41a2003-01-30 22:06:23 +00003509 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3510 PyDoc_STR("__reduce__() -> (cls, state)")},
3511
Tim Peters2a799bf2002-12-16 20:18:38 +00003512 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003513};
3514
Tim Peters37f39822003-01-10 03:49:02 +00003515static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003516PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3517\n\
3518All arguments are optional. tzinfo may be None, or an instance of\n\
3519a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003520
Tim Peters37f39822003-01-10 03:49:02 +00003521static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003522 0, /* nb_add */
3523 0, /* nb_subtract */
3524 0, /* nb_multiply */
3525 0, /* nb_divide */
3526 0, /* nb_remainder */
3527 0, /* nb_divmod */
3528 0, /* nb_power */
3529 0, /* nb_negative */
3530 0, /* nb_positive */
3531 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003532 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003533};
3534
Tim Peters37f39822003-01-10 03:49:02 +00003535statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003536 PyObject_HEAD_INIT(NULL)
3537 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003538 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003539 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003540 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003541 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003542 0, /* tp_print */
3543 0, /* tp_getattr */
3544 0, /* tp_setattr */
3545 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003546 (reprfunc)time_repr, /* tp_repr */
3547 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003548 0, /* tp_as_sequence */
3549 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003550 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003551 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003552 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003553 PyObject_GenericGetAttr, /* tp_getattro */
3554 0, /* tp_setattro */
3555 0, /* tp_as_buffer */
3556 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3557 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003558 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003559 0, /* tp_traverse */
3560 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003561 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003562 0, /* tp_weaklistoffset */
3563 0, /* tp_iter */
3564 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003565 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003566 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003567 time_getset, /* tp_getset */
3568 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003569 0, /* tp_dict */
3570 0, /* tp_descr_get */
3571 0, /* tp_descr_set */
3572 0, /* tp_dictoffset */
3573 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00003574 time_alloc, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003575 time_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00003576 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003577};
3578
3579/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003580 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003581 */
3582
Tim Petersa9bc1682003-01-11 03:39:11 +00003583/* Accessor properties. Properties for day, month, and year are inherited
3584 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003585 */
3586
3587static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003588datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003589{
Tim Petersa9bc1682003-01-11 03:39:11 +00003590 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003591}
3592
Tim Petersa9bc1682003-01-11 03:39:11 +00003593static PyObject *
3594datetime_minute(PyDateTime_DateTime *self, void *unused)
3595{
3596 return PyInt_FromLong(DATE_GET_MINUTE(self));
3597}
3598
3599static PyObject *
3600datetime_second(PyDateTime_DateTime *self, void *unused)
3601{
3602 return PyInt_FromLong(DATE_GET_SECOND(self));
3603}
3604
3605static PyObject *
3606datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3607{
3608 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3609}
3610
3611static PyObject *
3612datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3613{
3614 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3615 Py_INCREF(result);
3616 return result;
3617}
3618
3619static PyGetSetDef datetime_getset[] = {
3620 {"hour", (getter)datetime_hour},
3621 {"minute", (getter)datetime_minute},
3622 {"second", (getter)datetime_second},
3623 {"microsecond", (getter)datetime_microsecond},
3624 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003625 {NULL}
3626};
3627
3628/*
3629 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003630 */
3631
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003632static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003633 "year", "month", "day", "hour", "minute", "second",
3634 "microsecond", "tzinfo", NULL
3635};
3636
Tim Peters2a799bf2002-12-16 20:18:38 +00003637static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003638datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003639{
3640 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003641 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003642 int year;
3643 int month;
3644 int day;
3645 int hour = 0;
3646 int minute = 0;
3647 int second = 0;
3648 int usecond = 0;
3649 PyObject *tzinfo = Py_None;
3650
Guido van Rossum177e41a2003-01-30 22:06:23 +00003651 /* Check for invocation from pickle with __getstate__ state */
3652 if (PyTuple_GET_SIZE(args) >= 1 &&
3653 PyTuple_GET_SIZE(args) <= 2 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003654 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3655 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3656 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003657 {
Tim Peters70533e22003-02-01 04:40:04 +00003658 PyDateTime_DateTime *me;
3659 char aware;
3660
3661 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003662 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003663 if (check_tzinfo_subclass(tzinfo) < 0) {
3664 PyErr_SetString(PyExc_TypeError, "bad "
3665 "tzinfo state arg");
3666 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003667 }
3668 }
Tim Peters70533e22003-02-01 04:40:04 +00003669 aware = (char)(tzinfo != Py_None);
Tim Peters604c0132004-06-07 23:04:33 +00003670 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
Tim Peters70533e22003-02-01 04:40:04 +00003671 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003672 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003673
3674 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3675 me->hashcode = -1;
3676 me->hastzinfo = aware;
3677 if (aware) {
3678 Py_INCREF(tzinfo);
3679 me->tzinfo = tzinfo;
3680 }
3681 }
3682 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003683 }
3684
Tim Petersa9bc1682003-01-11 03:39:11 +00003685 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003686 &year, &month, &day, &hour, &minute,
3687 &second, &usecond, &tzinfo)) {
3688 if (check_date_args(year, month, day) < 0)
3689 return NULL;
3690 if (check_time_args(hour, minute, second, usecond) < 0)
3691 return NULL;
3692 if (check_tzinfo_subclass(tzinfo) < 0)
3693 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003694 self = new_datetime_ex(year, month, day,
3695 hour, minute, second, usecond,
3696 tzinfo, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003697 }
3698 return self;
3699}
3700
Tim Petersa9bc1682003-01-11 03:39:11 +00003701/* TM_FUNC is the shared type of localtime() and gmtime(). */
3702typedef struct tm *(*TM_FUNC)(const time_t *timer);
3703
3704/* Internal helper.
3705 * Build datetime from a time_t and a distinct count of microseconds.
3706 * Pass localtime or gmtime for f, to control the interpretation of timet.
3707 */
3708static PyObject *
3709datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3710 PyObject *tzinfo)
3711{
3712 struct tm *tm;
3713 PyObject *result = NULL;
3714
3715 tm = f(&timet);
3716 if (tm) {
3717 /* The platform localtime/gmtime may insert leap seconds,
3718 * indicated by tm->tm_sec > 59. We don't care about them,
3719 * except to the extent that passing them on to the datetime
3720 * constructor would raise ValueError for a reason that
3721 * made no sense to the user.
3722 */
3723 if (tm->tm_sec > 59)
3724 tm->tm_sec = 59;
3725 result = PyObject_CallFunction(cls, "iiiiiiiO",
3726 tm->tm_year + 1900,
3727 tm->tm_mon + 1,
3728 tm->tm_mday,
3729 tm->tm_hour,
3730 tm->tm_min,
3731 tm->tm_sec,
3732 us,
3733 tzinfo);
3734 }
3735 else
3736 PyErr_SetString(PyExc_ValueError,
3737 "timestamp out of range for "
3738 "platform localtime()/gmtime() function");
3739 return result;
3740}
3741
3742/* Internal helper.
3743 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3744 * to control the interpretation of the timestamp. Since a double doesn't
3745 * have enough bits to cover a datetime's full range of precision, it's
3746 * better to call datetime_from_timet_and_us provided you have a way
3747 * to get that much precision (e.g., C time() isn't good enough).
3748 */
3749static PyObject *
3750datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3751 PyObject *tzinfo)
3752{
Tim Peters1b6f7a92004-06-20 02:50:16 +00003753 time_t timet;
3754 double fraction;
3755 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00003756
Tim Peters1b6f7a92004-06-20 02:50:16 +00003757 timet = _PyTime_DoubleToTimet(timestamp);
3758 if (timet == (time_t)-1 && PyErr_Occurred())
3759 return NULL;
3760 fraction = timestamp - (double)timet;
3761 us = (int)round_to_long(fraction * 1e6);
Guido van Rossum2054ee92007-03-06 15:50:01 +00003762 if (us < 0) {
3763 /* Truncation towards zero is not what we wanted
3764 for negative numbers (Python's mod semantics) */
3765 timet -= 1;
3766 us += 1000000;
3767 }
Georg Brandl6d78a582006-04-28 19:09:24 +00003768 /* If timestamp is less than one microsecond smaller than a
3769 * full second, round up. Otherwise, ValueErrors are raised
3770 * for some floats. */
3771 if (us == 1000000) {
3772 timet += 1;
3773 us = 0;
3774 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003775 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3776}
3777
3778/* Internal helper.
3779 * Build most accurate possible datetime for current time. Pass localtime or
3780 * gmtime for f as appropriate.
3781 */
3782static PyObject *
3783datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3784{
3785#ifdef HAVE_GETTIMEOFDAY
3786 struct timeval t;
3787
3788#ifdef GETTIMEOFDAY_NO_TZ
3789 gettimeofday(&t);
3790#else
3791 gettimeofday(&t, (struct timezone *)NULL);
3792#endif
3793 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3794 tzinfo);
3795
3796#else /* ! HAVE_GETTIMEOFDAY */
3797 /* No flavor of gettimeofday exists on this platform. Python's
3798 * time.time() does a lot of other platform tricks to get the
3799 * best time it can on the platform, and we're not going to do
3800 * better than that (if we could, the better code would belong
3801 * in time.time()!) We're limited by the precision of a double,
3802 * though.
3803 */
3804 PyObject *time;
3805 double dtime;
3806
3807 time = time_time();
3808 if (time == NULL)
3809 return NULL;
3810 dtime = PyFloat_AsDouble(time);
3811 Py_DECREF(time);
3812 if (dtime == -1.0 && PyErr_Occurred())
3813 return NULL;
3814 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3815#endif /* ! HAVE_GETTIMEOFDAY */
3816}
3817
Tim Peters2a799bf2002-12-16 20:18:38 +00003818/* Return best possible local time -- this isn't constrained by the
3819 * precision of a timestamp.
3820 */
3821static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003822datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003823{
Tim Peters10cadce2003-01-23 19:58:02 +00003824 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003825 PyObject *tzinfo = Py_None;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003826 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003827
Tim Peters10cadce2003-01-23 19:58:02 +00003828 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3829 &tzinfo))
3830 return NULL;
3831 if (check_tzinfo_subclass(tzinfo) < 0)
3832 return NULL;
3833
3834 self = datetime_best_possible(cls,
3835 tzinfo == Py_None ? localtime : gmtime,
3836 tzinfo);
3837 if (self != NULL && tzinfo != Py_None) {
3838 /* Convert UTC to tzinfo's zone. */
3839 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003840 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003841 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003842 }
3843 return self;
3844}
3845
Tim Petersa9bc1682003-01-11 03:39:11 +00003846/* Return best possible UTC time -- this isn't constrained by the
3847 * precision of a timestamp.
3848 */
3849static PyObject *
3850datetime_utcnow(PyObject *cls, PyObject *dummy)
3851{
3852 return datetime_best_possible(cls, gmtime, Py_None);
3853}
3854
Tim Peters2a799bf2002-12-16 20:18:38 +00003855/* Return new local datetime from timestamp (Python timestamp -- a double). */
3856static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003857datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003858{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003859 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003860 double timestamp;
3861 PyObject *tzinfo = Py_None;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003862 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003863
Tim Peters2a44a8d2003-01-23 20:53:10 +00003864 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3865 keywords, &timestamp, &tzinfo))
3866 return NULL;
3867 if (check_tzinfo_subclass(tzinfo) < 0)
3868 return NULL;
3869
3870 self = datetime_from_timestamp(cls,
3871 tzinfo == Py_None ? localtime : gmtime,
3872 timestamp,
3873 tzinfo);
3874 if (self != NULL && tzinfo != Py_None) {
3875 /* Convert UTC to tzinfo's zone. */
3876 PyObject *temp = self;
3877 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3878 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003879 }
3880 return self;
3881}
3882
Tim Petersa9bc1682003-01-11 03:39:11 +00003883/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3884static PyObject *
3885datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3886{
3887 double timestamp;
3888 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003889
Tim Petersa9bc1682003-01-11 03:39:11 +00003890 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3891 result = datetime_from_timestamp(cls, gmtime, timestamp,
3892 Py_None);
3893 return result;
3894}
3895
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003896/* Return new datetime from time.strptime(). */
3897static PyObject *
3898datetime_strptime(PyObject *cls, PyObject *args)
3899{
Skip Montanarofc070d22008-03-15 16:04:45 +00003900 static PyObject *module = NULL;
3901 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003902 const char *string, *format;
3903
3904 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3905 return NULL;
3906
Skip Montanarofc070d22008-03-15 16:04:45 +00003907 if (module == NULL &&
3908 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003909 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003910
Skip Montanarofc070d22008-03-15 16:04:45 +00003911 /* _strptime._strptime returns a two-element tuple. The first
3912 element is a time.struct_time object. The second is the
3913 microseconds (which are not defined for time.struct_time). */
3914 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003915 if (obj != NULL) {
3916 int i, good_timetuple = 1;
Skip Montanarofc070d22008-03-15 16:04:45 +00003917 long int ia[7];
3918 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3919 st = PySequence_GetItem(obj, 0);
3920 frac = PySequence_GetItem(obj, 1);
3921 if (st == NULL || frac == NULL)
3922 good_timetuple = 0;
3923 /* copy y/m/d/h/m/s values out of the
3924 time.struct_time */
3925 if (good_timetuple &&
3926 PySequence_Check(st) &&
3927 PySequence_Size(st) >= 6) {
3928 for (i=0; i < 6; i++) {
3929 PyObject *p = PySequence_GetItem(st, i);
3930 if (p == NULL) {
3931 good_timetuple = 0;
3932 break;
3933 }
3934 if (PyInt_Check(p))
3935 ia[i] = PyInt_AsLong(p);
3936 else
3937 good_timetuple = 0;
3938 Py_DECREF(p);
Thomas Wouters3cfea2d2006-04-14 21:23:42 +00003939 }
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003940 }
Skip Montanarofc070d22008-03-15 16:04:45 +00003941 else
3942 good_timetuple = 0;
3943 /* follow that up with a little dose of microseconds */
3944 if (PyInt_Check(frac))
3945 ia[6] = PyInt_AsLong(frac);
3946 else
3947 good_timetuple = 0;
3948 }
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003949 else
3950 good_timetuple = 0;
3951 if (good_timetuple)
Skip Montanarofc070d22008-03-15 16:04:45 +00003952 result = PyObject_CallFunction(cls, "iiiiiii",
3953 ia[0], ia[1], ia[2],
3954 ia[3], ia[4], ia[5],
3955 ia[6]);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003956 else
3957 PyErr_SetString(PyExc_ValueError,
Skip Montanarofc070d22008-03-15 16:04:45 +00003958 "unexpected value from _strptime._strptime");
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003959 }
Skip Montanarofc070d22008-03-15 16:04:45 +00003960 Py_XDECREF(obj);
3961 Py_XDECREF(st);
3962 Py_XDECREF(frac);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003963 return result;
3964}
3965
Tim Petersa9bc1682003-01-11 03:39:11 +00003966/* Return new datetime from date/datetime and time arguments. */
3967static PyObject *
3968datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3969{
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003970 static char *keywords[] = {"date", "time", NULL};
Tim Petersa9bc1682003-01-11 03:39:11 +00003971 PyObject *date;
3972 PyObject *time;
3973 PyObject *result = NULL;
3974
3975 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3976 &PyDateTime_DateType, &date,
3977 &PyDateTime_TimeType, &time)) {
3978 PyObject *tzinfo = Py_None;
3979
3980 if (HASTZINFO(time))
3981 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3982 result = PyObject_CallFunction(cls, "iiiiiiiO",
3983 GET_YEAR(date),
3984 GET_MONTH(date),
3985 GET_DAY(date),
3986 TIME_GET_HOUR(time),
3987 TIME_GET_MINUTE(time),
3988 TIME_GET_SECOND(time),
3989 TIME_GET_MICROSECOND(time),
3990 tzinfo);
3991 }
3992 return result;
3993}
Tim Peters2a799bf2002-12-16 20:18:38 +00003994
3995/*
3996 * Destructor.
3997 */
3998
3999static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004000datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004001{
Tim Petersa9bc1682003-01-11 03:39:11 +00004002 if (HASTZINFO(self)) {
4003 Py_XDECREF(self->tzinfo);
4004 }
Christian Heimese93237d2007-12-19 02:37:44 +00004005 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004006}
4007
4008/*
4009 * Indirect access to tzinfo methods.
4010 */
4011
Tim Peters2a799bf2002-12-16 20:18:38 +00004012/* These are all METH_NOARGS, so don't need to check the arglist. */
4013static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004014datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
4015 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4016 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004017}
4018
4019static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004020datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
4021 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4022 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004023}
4024
4025static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004026datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
4027 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4028 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004029}
4030
4031/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004032 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004033 */
4034
Tim Petersa9bc1682003-01-11 03:39:11 +00004035/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4036 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004037 */
4038static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004039add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4040 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004041{
Tim Petersa9bc1682003-01-11 03:39:11 +00004042 /* Note that the C-level additions can't overflow, because of
4043 * invariant bounds on the member values.
4044 */
4045 int year = GET_YEAR(date);
4046 int month = GET_MONTH(date);
4047 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4048 int hour = DATE_GET_HOUR(date);
4049 int minute = DATE_GET_MINUTE(date);
4050 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4051 int microsecond = DATE_GET_MICROSECOND(date) +
4052 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004053
Tim Petersa9bc1682003-01-11 03:39:11 +00004054 assert(factor == 1 || factor == -1);
4055 if (normalize_datetime(&year, &month, &day,
4056 &hour, &minute, &second, &microsecond) < 0)
4057 return NULL;
4058 else
4059 return new_datetime(year, month, day,
4060 hour, minute, second, microsecond,
4061 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004062}
4063
4064static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004065datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004066{
Tim Petersa9bc1682003-01-11 03:39:11 +00004067 if (PyDateTime_Check(left)) {
4068 /* datetime + ??? */
4069 if (PyDelta_Check(right))
4070 /* datetime + delta */
4071 return add_datetime_timedelta(
4072 (PyDateTime_DateTime *)left,
4073 (PyDateTime_Delta *)right,
4074 1);
4075 }
4076 else if (PyDelta_Check(left)) {
4077 /* delta + datetime */
4078 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4079 (PyDateTime_Delta *) left,
4080 1);
4081 }
4082 Py_INCREF(Py_NotImplemented);
4083 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004084}
4085
4086static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004087datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004088{
4089 PyObject *result = Py_NotImplemented;
4090
4091 if (PyDateTime_Check(left)) {
4092 /* datetime - ??? */
4093 if (PyDateTime_Check(right)) {
4094 /* datetime - datetime */
4095 naivety n1, n2;
4096 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004097 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004098
Tim Peterse39a80c2002-12-30 21:28:52 +00004099 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4100 right, &offset2, &n2,
4101 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00004102 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00004103 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00004104 if (n1 != n2) {
4105 PyErr_SetString(PyExc_TypeError,
4106 "can't subtract offset-naive and "
4107 "offset-aware datetimes");
4108 return NULL;
4109 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004110 delta_d = ymd_to_ord(GET_YEAR(left),
4111 GET_MONTH(left),
4112 GET_DAY(left)) -
4113 ymd_to_ord(GET_YEAR(right),
4114 GET_MONTH(right),
4115 GET_DAY(right));
4116 /* These can't overflow, since the values are
4117 * normalized. At most this gives the number of
4118 * seconds in one day.
4119 */
4120 delta_s = (DATE_GET_HOUR(left) -
4121 DATE_GET_HOUR(right)) * 3600 +
4122 (DATE_GET_MINUTE(left) -
4123 DATE_GET_MINUTE(right)) * 60 +
4124 (DATE_GET_SECOND(left) -
4125 DATE_GET_SECOND(right));
4126 delta_us = DATE_GET_MICROSECOND(left) -
4127 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00004128 /* (left - offset1) - (right - offset2) =
4129 * (left - right) + (offset2 - offset1)
4130 */
Tim Petersa9bc1682003-01-11 03:39:11 +00004131 delta_s += (offset2 - offset1) * 60;
4132 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004133 }
4134 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004135 /* datetime - delta */
4136 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00004137 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00004138 (PyDateTime_Delta *)right,
4139 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004140 }
4141 }
4142
4143 if (result == Py_NotImplemented)
4144 Py_INCREF(result);
4145 return result;
4146}
4147
4148/* Various ways to turn a datetime into a string. */
4149
4150static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004151datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004152{
Tim Petersa9bc1682003-01-11 03:39:11 +00004153 char buffer[1000];
Christian Heimese93237d2007-12-19 02:37:44 +00004154 const char *type_name = Py_TYPE(self)->tp_name;
Tim Petersa9bc1682003-01-11 03:39:11 +00004155 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004156
Tim Petersa9bc1682003-01-11 03:39:11 +00004157 if (DATE_GET_MICROSECOND(self)) {
4158 PyOS_snprintf(buffer, sizeof(buffer),
4159 "%s(%d, %d, %d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004160 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004161 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4162 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4163 DATE_GET_SECOND(self),
4164 DATE_GET_MICROSECOND(self));
4165 }
4166 else if (DATE_GET_SECOND(self)) {
4167 PyOS_snprintf(buffer, sizeof(buffer),
4168 "%s(%d, %d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004169 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004170 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4171 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4172 DATE_GET_SECOND(self));
4173 }
4174 else {
4175 PyOS_snprintf(buffer, sizeof(buffer),
4176 "%s(%d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004177 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004178 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4179 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4180 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004181 baserepr = PyString_FromString(buffer);
Tim Petersa9bc1682003-01-11 03:39:11 +00004182 if (baserepr == NULL || ! HASTZINFO(self))
4183 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004184 return append_keyword_tzinfo(baserepr, self->tzinfo);
4185}
4186
Tim Petersa9bc1682003-01-11 03:39:11 +00004187static PyObject *
4188datetime_str(PyDateTime_DateTime *self)
4189{
4190 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4191}
Tim Peters2a799bf2002-12-16 20:18:38 +00004192
4193static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004194datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004195{
Tim Petersa9bc1682003-01-11 03:39:11 +00004196 char sep = 'T';
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004197 static char *keywords[] = {"sep", NULL};
Tim Petersa9bc1682003-01-11 03:39:11 +00004198 char buffer[100];
4199 char *cp;
4200 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004201
Tim Petersa9bc1682003-01-11 03:39:11 +00004202 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4203 &sep))
4204 return NULL;
4205 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4206 assert(cp != NULL);
4207 *cp++ = sep;
Amaury Forgeot d'Arc7682d042009-12-29 22:39:49 +00004208 cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4209 result = PyString_FromStringAndSize(buffer, cp - buffer);
Tim Petersa9bc1682003-01-11 03:39:11 +00004210 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00004211 return result;
4212
4213 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00004214 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00004215 (PyObject *)self) < 0) {
4216 Py_DECREF(result);
4217 return NULL;
4218 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004219 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00004220 return result;
4221}
4222
Tim Petersa9bc1682003-01-11 03:39:11 +00004223static PyObject *
4224datetime_ctime(PyDateTime_DateTime *self)
4225{
4226 return format_ctime((PyDateTime_Date *)self,
4227 DATE_GET_HOUR(self),
4228 DATE_GET_MINUTE(self),
4229 DATE_GET_SECOND(self));
4230}
4231
Tim Peters2a799bf2002-12-16 20:18:38 +00004232/* Miscellaneous methods. */
4233
Tim Petersa9bc1682003-01-11 03:39:11 +00004234/* This is more natural as a tp_compare, but doesn't work then: for whatever
4235 * reason, Python's try_3way_compare ignores tp_compare unless
4236 * PyInstance_Check returns true, but these aren't old-style classes.
4237 */
4238static PyObject *
4239datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4240{
4241 int diff;
4242 naivety n1, n2;
4243 int offset1, offset2;
4244
4245 if (! PyDateTime_Check(other)) {
Tim Peters528ca532004-09-16 01:30:50 +00004246 /* If other has a "timetuple" attr, that's an advertised
4247 * hook for other classes to ask to get comparison control.
4248 * However, date instances have a timetuple attr, and we
4249 * don't want to allow that comparison. Because datetime
4250 * is a subclass of date, when mixing date and datetime
4251 * in a comparison, Python gives datetime the first shot
4252 * (it's the more specific subtype). So we can stop that
4253 * combination here reliably.
4254 */
4255 if (PyObject_HasAttrString(other, "timetuple") &&
4256 ! PyDate_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004257 /* A hook for other kinds of datetime objects. */
4258 Py_INCREF(Py_NotImplemented);
4259 return Py_NotImplemented;
4260 }
Tim Peters07534a62003-02-07 22:50:28 +00004261 if (op == Py_EQ || op == Py_NE) {
4262 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4263 Py_INCREF(result);
4264 return result;
4265 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004266 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00004267 return cmperror((PyObject *)self, other);
Tim Petersa9bc1682003-01-11 03:39:11 +00004268 }
4269
4270 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4271 (PyObject *)self,
4272 other, &offset2, &n2,
4273 other) < 0)
4274 return NULL;
4275 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4276 /* If they're both naive, or both aware and have the same offsets,
4277 * we get off cheap. Note that if they're both naive, offset1 ==
4278 * offset2 == 0 at this point.
4279 */
4280 if (n1 == n2 && offset1 == offset2) {
4281 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4282 _PyDateTime_DATETIME_DATASIZE);
4283 return diff_to_bool(diff, op);
4284 }
4285
4286 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4287 PyDateTime_Delta *delta;
4288
4289 assert(offset1 != offset2); /* else last "if" handled it */
4290 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4291 other);
4292 if (delta == NULL)
4293 return NULL;
4294 diff = GET_TD_DAYS(delta);
4295 if (diff == 0)
4296 diff = GET_TD_SECONDS(delta) |
4297 GET_TD_MICROSECONDS(delta);
4298 Py_DECREF(delta);
4299 return diff_to_bool(diff, op);
4300 }
4301
4302 assert(n1 != n2);
4303 PyErr_SetString(PyExc_TypeError,
4304 "can't compare offset-naive and "
4305 "offset-aware datetimes");
4306 return NULL;
4307}
4308
4309static long
4310datetime_hash(PyDateTime_DateTime *self)
4311{
4312 if (self->hashcode == -1) {
4313 naivety n;
4314 int offset;
4315 PyObject *temp;
4316
4317 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4318 &offset);
4319 assert(n != OFFSET_UNKNOWN);
4320 if (n == OFFSET_ERROR)
4321 return -1;
4322
4323 /* Reduce this to a hash of another object. */
4324 if (n == OFFSET_NAIVE)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004325 temp = PyString_FromStringAndSize(
Tim Petersa9bc1682003-01-11 03:39:11 +00004326 (char *)self->data,
4327 _PyDateTime_DATETIME_DATASIZE);
4328 else {
4329 int days;
4330 int seconds;
4331
4332 assert(n == OFFSET_AWARE);
4333 assert(HASTZINFO(self));
4334 days = ymd_to_ord(GET_YEAR(self),
4335 GET_MONTH(self),
4336 GET_DAY(self));
4337 seconds = DATE_GET_HOUR(self) * 3600 +
4338 (DATE_GET_MINUTE(self) - offset) * 60 +
4339 DATE_GET_SECOND(self);
4340 temp = new_delta(days,
4341 seconds,
4342 DATE_GET_MICROSECOND(self),
4343 1);
4344 }
4345 if (temp != NULL) {
4346 self->hashcode = PyObject_Hash(temp);
4347 Py_DECREF(temp);
4348 }
4349 }
4350 return self->hashcode;
4351}
Tim Peters2a799bf2002-12-16 20:18:38 +00004352
4353static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004354datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004355{
4356 PyObject *clone;
4357 PyObject *tuple;
4358 int y = GET_YEAR(self);
4359 int m = GET_MONTH(self);
4360 int d = GET_DAY(self);
4361 int hh = DATE_GET_HOUR(self);
4362 int mm = DATE_GET_MINUTE(self);
4363 int ss = DATE_GET_SECOND(self);
4364 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004365 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004366
4367 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004368 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004369 &y, &m, &d, &hh, &mm, &ss, &us,
4370 &tzinfo))
4371 return NULL;
4372 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4373 if (tuple == NULL)
4374 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00004375 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004376 Py_DECREF(tuple);
4377 return clone;
4378}
4379
4380static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004381datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004382{
Tim Peters52dcce22003-01-23 16:36:11 +00004383 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004384 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004385 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004386
Tim Peters80475bb2002-12-25 07:40:55 +00004387 PyObject *tzinfo;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004388 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004389
Tim Peters52dcce22003-01-23 16:36:11 +00004390 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4391 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004392 return NULL;
4393
Tim Peters52dcce22003-01-23 16:36:11 +00004394 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4395 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004396
Tim Peters52dcce22003-01-23 16:36:11 +00004397 /* Conversion to self's own time zone is a NOP. */
4398 if (self->tzinfo == tzinfo) {
4399 Py_INCREF(self);
4400 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004401 }
Tim Peters521fc152002-12-31 17:36:56 +00004402
Tim Peters52dcce22003-01-23 16:36:11 +00004403 /* Convert self to UTC. */
4404 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4405 if (offset == -1 && PyErr_Occurred())
4406 return NULL;
4407 if (none)
4408 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004409
Tim Peters52dcce22003-01-23 16:36:11 +00004410 y = GET_YEAR(self);
4411 m = GET_MONTH(self);
4412 d = GET_DAY(self);
4413 hh = DATE_GET_HOUR(self);
4414 mm = DATE_GET_MINUTE(self);
4415 ss = DATE_GET_SECOND(self);
4416 us = DATE_GET_MICROSECOND(self);
4417
4418 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004419 if ((mm < 0 || mm >= 60) &&
4420 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004421 return NULL;
4422
4423 /* Attach new tzinfo and let fromutc() do the rest. */
4424 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4425 if (result != NULL) {
4426 PyObject *temp = result;
4427
4428 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4429 Py_DECREF(temp);
4430 }
Tim Petersadf64202003-01-04 06:03:15 +00004431 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004432
Tim Peters52dcce22003-01-23 16:36:11 +00004433NeedAware:
4434 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4435 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004436 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004437}
4438
4439static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004440datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004441{
4442 int dstflag = -1;
4443
Tim Petersa9bc1682003-01-11 03:39:11 +00004444 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004445 int none;
4446
4447 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4448 if (dstflag == -1 && PyErr_Occurred())
4449 return NULL;
4450
4451 if (none)
4452 dstflag = -1;
4453 else if (dstflag != 0)
4454 dstflag = 1;
4455
4456 }
4457 return build_struct_time(GET_YEAR(self),
4458 GET_MONTH(self),
4459 GET_DAY(self),
4460 DATE_GET_HOUR(self),
4461 DATE_GET_MINUTE(self),
4462 DATE_GET_SECOND(self),
4463 dstflag);
4464}
4465
4466static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004467datetime_getdate(PyDateTime_DateTime *self)
4468{
4469 return new_date(GET_YEAR(self),
4470 GET_MONTH(self),
4471 GET_DAY(self));
4472}
4473
4474static PyObject *
4475datetime_gettime(PyDateTime_DateTime *self)
4476{
4477 return new_time(DATE_GET_HOUR(self),
4478 DATE_GET_MINUTE(self),
4479 DATE_GET_SECOND(self),
4480 DATE_GET_MICROSECOND(self),
4481 Py_None);
4482}
4483
4484static PyObject *
4485datetime_gettimetz(PyDateTime_DateTime *self)
4486{
4487 return new_time(DATE_GET_HOUR(self),
4488 DATE_GET_MINUTE(self),
4489 DATE_GET_SECOND(self),
4490 DATE_GET_MICROSECOND(self),
4491 HASTZINFO(self) ? self->tzinfo : Py_None);
4492}
4493
4494static PyObject *
4495datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004496{
4497 int y = GET_YEAR(self);
4498 int m = GET_MONTH(self);
4499 int d = GET_DAY(self);
4500 int hh = DATE_GET_HOUR(self);
4501 int mm = DATE_GET_MINUTE(self);
4502 int ss = DATE_GET_SECOND(self);
4503 int us = 0; /* microseconds are ignored in a timetuple */
4504 int offset = 0;
4505
Tim Petersa9bc1682003-01-11 03:39:11 +00004506 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004507 int none;
4508
4509 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4510 if (offset == -1 && PyErr_Occurred())
4511 return NULL;
4512 }
4513 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4514 * 0 in a UTC timetuple regardless of what dst() says.
4515 */
4516 if (offset) {
4517 /* Subtract offset minutes & normalize. */
4518 int stat;
4519
4520 mm -= offset;
4521 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4522 if (stat < 0) {
4523 /* At the edges, it's possible we overflowed
4524 * beyond MINYEAR or MAXYEAR.
4525 */
4526 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4527 PyErr_Clear();
4528 else
4529 return NULL;
4530 }
4531 }
4532 return build_struct_time(y, m, d, hh, mm, ss, 0);
4533}
4534
Tim Peters371935f2003-02-01 01:52:50 +00004535/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004536
Tim Petersa9bc1682003-01-11 03:39:11 +00004537/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004538 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4539 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004540 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004541 */
4542static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004543datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004544{
4545 PyObject *basestate;
4546 PyObject *result = NULL;
4547
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004548 basestate = PyString_FromStringAndSize((char *)self->data,
Tim Peters33e0f382003-01-10 02:05:14 +00004549 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004550 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004551 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004552 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00004553 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004554 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004555 Py_DECREF(basestate);
4556 }
4557 return result;
4558}
4559
4560static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004561datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004562{
Christian Heimese93237d2007-12-19 02:37:44 +00004563 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004564}
4565
Tim Petersa9bc1682003-01-11 03:39:11 +00004566static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004567
Tim Peters2a799bf2002-12-16 20:18:38 +00004568 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004569
Tim Petersa9bc1682003-01-11 03:39:11 +00004570 {"now", (PyCFunction)datetime_now,
Neal Norwitza84dcd72007-05-22 07:16:44 +00004571 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004572 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004573
Tim Petersa9bc1682003-01-11 03:39:11 +00004574 {"utcnow", (PyCFunction)datetime_utcnow,
4575 METH_NOARGS | METH_CLASS,
4576 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4577
4578 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Neal Norwitza84dcd72007-05-22 07:16:44 +00004579 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004580 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004581
Tim Petersa9bc1682003-01-11 03:39:11 +00004582 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4583 METH_VARARGS | METH_CLASS,
4584 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4585 "(like time.time()).")},
4586
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004587 {"strptime", (PyCFunction)datetime_strptime,
4588 METH_VARARGS | METH_CLASS,
4589 PyDoc_STR("string, format -> new datetime parsed from a string "
4590 "(like time.strptime()).")},
4591
Tim Petersa9bc1682003-01-11 03:39:11 +00004592 {"combine", (PyCFunction)datetime_combine,
4593 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4594 PyDoc_STR("date, time -> datetime with same date and time fields")},
4595
Tim Peters2a799bf2002-12-16 20:18:38 +00004596 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004597
Tim Petersa9bc1682003-01-11 03:39:11 +00004598 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4599 PyDoc_STR("Return date object with same year, month and day.")},
4600
4601 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4602 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4603
4604 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4605 PyDoc_STR("Return time object with same time and tzinfo.")},
4606
4607 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4608 PyDoc_STR("Return ctime() style string.")},
4609
4610 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004611 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4612
Tim Petersa9bc1682003-01-11 03:39:11 +00004613 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004614 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4615
Neal Norwitza84dcd72007-05-22 07:16:44 +00004616 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004617 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4618 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4619 "sep is used to separate the year from the time, and "
4620 "defaults to 'T'.")},
4621
Tim Petersa9bc1682003-01-11 03:39:11 +00004622 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004623 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4624
Tim Petersa9bc1682003-01-11 03:39:11 +00004625 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004626 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4627
Tim Petersa9bc1682003-01-11 03:39:11 +00004628 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004629 PyDoc_STR("Return self.tzinfo.dst(self).")},
4630
Neal Norwitza84dcd72007-05-22 07:16:44 +00004631 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
Tim Petersa9bc1682003-01-11 03:39:11 +00004632 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004633
Neal Norwitza84dcd72007-05-22 07:16:44 +00004634 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004635 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4636
Guido van Rossum177e41a2003-01-30 22:06:23 +00004637 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4638 PyDoc_STR("__reduce__() -> (cls, state)")},
4639
Tim Peters2a799bf2002-12-16 20:18:38 +00004640 {NULL, NULL}
4641};
4642
Tim Petersa9bc1682003-01-11 03:39:11 +00004643static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004644PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4645\n\
4646The year, month and day arguments are required. tzinfo may be None, or an\n\
4647instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004648
Tim Petersa9bc1682003-01-11 03:39:11 +00004649static PyNumberMethods datetime_as_number = {
4650 datetime_add, /* nb_add */
4651 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004652 0, /* nb_multiply */
4653 0, /* nb_divide */
4654 0, /* nb_remainder */
4655 0, /* nb_divmod */
4656 0, /* nb_power */
4657 0, /* nb_negative */
4658 0, /* nb_positive */
4659 0, /* nb_absolute */
4660 0, /* nb_nonzero */
4661};
4662
Tim Petersa9bc1682003-01-11 03:39:11 +00004663statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004664 PyObject_HEAD_INIT(NULL)
4665 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004666 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004667 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004668 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004669 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004670 0, /* tp_print */
4671 0, /* tp_getattr */
4672 0, /* tp_setattr */
4673 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004674 (reprfunc)datetime_repr, /* tp_repr */
4675 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004676 0, /* tp_as_sequence */
4677 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004678 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004679 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004680 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004681 PyObject_GenericGetAttr, /* tp_getattro */
4682 0, /* tp_setattro */
4683 0, /* tp_as_buffer */
4684 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4685 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004686 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004687 0, /* tp_traverse */
4688 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004689 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004690 0, /* tp_weaklistoffset */
4691 0, /* tp_iter */
4692 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004693 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004694 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004695 datetime_getset, /* tp_getset */
4696 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004697 0, /* tp_dict */
4698 0, /* tp_descr_get */
4699 0, /* tp_descr_set */
4700 0, /* tp_dictoffset */
4701 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00004702 datetime_alloc, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004703 datetime_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00004704 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004705};
4706
4707/* ---------------------------------------------------------------------------
4708 * Module methods and initialization.
4709 */
4710
4711static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004712 {NULL, NULL}
4713};
4714
Tim Peters9ddf40b2004-06-20 22:41:32 +00004715/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4716 * datetime.h.
4717 */
4718static PyDateTime_CAPI CAPI = {
4719 &PyDateTime_DateType,
4720 &PyDateTime_DateTimeType,
4721 &PyDateTime_TimeType,
4722 &PyDateTime_DeltaType,
4723 &PyDateTime_TZInfoType,
4724 new_date_ex,
4725 new_datetime_ex,
4726 new_time_ex,
4727 new_delta_ex,
4728 datetime_fromtimestamp,
4729 date_fromtimestamp
4730};
4731
4732
Tim Peters2a799bf2002-12-16 20:18:38 +00004733PyMODINIT_FUNC
4734initdatetime(void)
4735{
4736 PyObject *m; /* a module object */
4737 PyObject *d; /* its dict */
4738 PyObject *x;
4739
Tim Peters2a799bf2002-12-16 20:18:38 +00004740 m = Py_InitModule3("datetime", module_methods,
4741 "Fast implementation of the datetime type.");
Neal Norwitz1ac754f2006-01-19 06:09:39 +00004742 if (m == NULL)
4743 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004744
4745 if (PyType_Ready(&PyDateTime_DateType) < 0)
4746 return;
4747 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4748 return;
4749 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4750 return;
4751 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4752 return;
4753 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4754 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004755
Tim Peters2a799bf2002-12-16 20:18:38 +00004756 /* timedelta values */
4757 d = PyDateTime_DeltaType.tp_dict;
4758
Tim Peters2a799bf2002-12-16 20:18:38 +00004759 x = new_delta(0, 0, 1, 0);
4760 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4761 return;
4762 Py_DECREF(x);
4763
4764 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4765 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4766 return;
4767 Py_DECREF(x);
4768
4769 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4770 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4771 return;
4772 Py_DECREF(x);
4773
4774 /* date values */
4775 d = PyDateTime_DateType.tp_dict;
4776
4777 x = new_date(1, 1, 1);
4778 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4779 return;
4780 Py_DECREF(x);
4781
4782 x = new_date(MAXYEAR, 12, 31);
4783 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4784 return;
4785 Py_DECREF(x);
4786
4787 x = new_delta(1, 0, 0, 0);
4788 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4789 return;
4790 Py_DECREF(x);
4791
Tim Peters37f39822003-01-10 03:49:02 +00004792 /* time values */
4793 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004794
Tim Peters37f39822003-01-10 03:49:02 +00004795 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004796 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4797 return;
4798 Py_DECREF(x);
4799
Tim Peters37f39822003-01-10 03:49:02 +00004800 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004801 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4802 return;
4803 Py_DECREF(x);
4804
4805 x = new_delta(0, 0, 1, 0);
4806 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4807 return;
4808 Py_DECREF(x);
4809
Tim Petersa9bc1682003-01-11 03:39:11 +00004810 /* datetime values */
4811 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004812
Tim Petersa9bc1682003-01-11 03:39:11 +00004813 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004814 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4815 return;
4816 Py_DECREF(x);
4817
Tim Petersa9bc1682003-01-11 03:39:11 +00004818 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004819 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4820 return;
4821 Py_DECREF(x);
4822
4823 x = new_delta(0, 0, 1, 0);
4824 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4825 return;
4826 Py_DECREF(x);
4827
Tim Peters2a799bf2002-12-16 20:18:38 +00004828 /* module initialization */
4829 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4830 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4831
4832 Py_INCREF(&PyDateTime_DateType);
4833 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4834
Tim Petersa9bc1682003-01-11 03:39:11 +00004835 Py_INCREF(&PyDateTime_DateTimeType);
4836 PyModule_AddObject(m, "datetime",
4837 (PyObject *)&PyDateTime_DateTimeType);
4838
4839 Py_INCREF(&PyDateTime_TimeType);
4840 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4841
Tim Peters2a799bf2002-12-16 20:18:38 +00004842 Py_INCREF(&PyDateTime_DeltaType);
4843 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4844
Tim Peters2a799bf2002-12-16 20:18:38 +00004845 Py_INCREF(&PyDateTime_TZInfoType);
4846 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4847
Tim Peters9ddf40b2004-06-20 22:41:32 +00004848 x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
4849 NULL);
4850 if (x == NULL)
4851 return;
4852 PyModule_AddObject(m, "datetime_CAPI", x);
4853
Tim Peters2a799bf2002-12-16 20:18:38 +00004854 /* A 4-year cycle has an extra leap day over what we'd get from
4855 * pasting together 4 single years.
4856 */
4857 assert(DI4Y == 4 * 365 + 1);
4858 assert(DI4Y == days_before_year(4+1));
4859
4860 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4861 * get from pasting together 4 100-year cycles.
4862 */
4863 assert(DI400Y == 4 * DI100Y + 1);
4864 assert(DI400Y == days_before_year(400+1));
4865
4866 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4867 * pasting together 25 4-year cycles.
4868 */
4869 assert(DI100Y == 25 * DI4Y - 1);
4870 assert(DI100Y == days_before_year(100+1));
4871
4872 us_per_us = PyInt_FromLong(1);
4873 us_per_ms = PyInt_FromLong(1000);
4874 us_per_second = PyInt_FromLong(1000000);
4875 us_per_minute = PyInt_FromLong(60000000);
4876 seconds_per_day = PyInt_FromLong(24 * 3600);
4877 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4878 us_per_minute == NULL || seconds_per_day == NULL)
4879 return;
4880
4881 /* The rest are too big for 32-bit ints, but even
4882 * us_per_week fits in 40 bits, so doubles should be exact.
4883 */
4884 us_per_hour = PyLong_FromDouble(3600000000.0);
4885 us_per_day = PyLong_FromDouble(86400000000.0);
4886 us_per_week = PyLong_FromDouble(604800000000.0);
4887 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4888 return;
4889}
Tim Petersf3615152003-01-01 21:51:37 +00004890
4891/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004892Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004893 x.n = x stripped of its timezone -- its naive time.
4894 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4895 return None
4896 x.d = x.dst(), and assuming that doesn't raise an exception or
4897 return None
4898 x.s = x's standard offset, x.o - x.d
4899
4900Now some derived rules, where k is a duration (timedelta).
4901
49021. x.o = x.s + x.d
4903 This follows from the definition of x.s.
4904
Tim Petersc5dc4da2003-01-02 17:55:03 +000049052. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004906 This is actually a requirement, an assumption we need to make about
4907 sane tzinfo classes.
4908
49093. The naive UTC time corresponding to x is x.n - x.o.
4910 This is again a requirement for a sane tzinfo class.
4911
49124. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004913 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004914
Tim Petersc5dc4da2003-01-02 17:55:03 +000049155. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004916 Again follows from how arithmetic is defined.
4917
Tim Peters8bb5ad22003-01-24 02:44:45 +00004918Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004919(meaning that the various tzinfo methods exist, and don't blow up or return
4920None when called).
4921
Tim Petersa9bc1682003-01-11 03:39:11 +00004922The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004923x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004924
4925By #3, we want
4926
Tim Peters8bb5ad22003-01-24 02:44:45 +00004927 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004928
4929The algorithm starts by attaching tz to x.n, and calling that y. So
4930x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4931becomes true; in effect, we want to solve [2] for k:
4932
Tim Peters8bb5ad22003-01-24 02:44:45 +00004933 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004934
4935By #1, this is the same as
4936
Tim Peters8bb5ad22003-01-24 02:44:45 +00004937 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004938
4939By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4940Substituting that into [3],
4941
Tim Peters8bb5ad22003-01-24 02:44:45 +00004942 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4943 k - (y+k).s - (y+k).d = 0; rearranging,
4944 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4945 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004946
Tim Peters8bb5ad22003-01-24 02:44:45 +00004947On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4948approximate k by ignoring the (y+k).d term at first. Note that k can't be
4949very large, since all offset-returning methods return a duration of magnitude
4950less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4951be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004952
4953In any case, the new value is
4954
Tim Peters8bb5ad22003-01-24 02:44:45 +00004955 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004956
Tim Peters8bb5ad22003-01-24 02:44:45 +00004957It's helpful to step back at look at [4] from a higher level: it's simply
4958mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004959
4960At this point, if
4961
Tim Peters8bb5ad22003-01-24 02:44:45 +00004962 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004963
4964we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004965at the start of daylight time. Picture US Eastern for concreteness. The wall
4966time 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 +00004967sense then. The docs ask that an Eastern tzinfo class consider such a time to
4968be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4969on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004970the only spelling that makes sense on the local wall clock.
4971
Tim Petersc5dc4da2003-01-02 17:55:03 +00004972In fact, if [5] holds at this point, we do have the standard-time spelling,
4973but that takes a bit of proof. We first prove a stronger result. What's the
4974difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004975
Tim Peters8bb5ad22003-01-24 02:44:45 +00004976 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004977
Tim Petersc5dc4da2003-01-02 17:55:03 +00004978Now
4979 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004980 (y + y.s).n = by #5
4981 y.n + y.s = since y.n = x.n
4982 x.n + y.s = since z and y are have the same tzinfo member,
4983 y.s = z.s by #2
4984 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004985
Tim Petersc5dc4da2003-01-02 17:55:03 +00004986Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004987
Tim Petersc5dc4da2003-01-02 17:55:03 +00004988 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004989 x.n - ((x.n + z.s) - z.o) = expanding
4990 x.n - x.n - z.s + z.o = cancelling
4991 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004992 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004993
Tim Petersc5dc4da2003-01-02 17:55:03 +00004994So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004995
Tim Petersc5dc4da2003-01-02 17:55:03 +00004996If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004997spelling we wanted in the endcase described above. We're done. Contrarily,
4998if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004999
Tim Petersc5dc4da2003-01-02 17:55:03 +00005000If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5001add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005002local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005003
Tim Petersc5dc4da2003-01-02 17:55:03 +00005004Let
Tim Petersf3615152003-01-01 21:51:37 +00005005
Tim Peters4fede1a2003-01-04 00:26:59 +00005006 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005007
Tim Peters4fede1a2003-01-04 00:26:59 +00005008and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005009
Tim Peters8bb5ad22003-01-24 02:44:45 +00005010 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005011
Tim Peters8bb5ad22003-01-24 02:44:45 +00005012If so, we're done. If not, the tzinfo class is insane, according to the
5013assumptions we've made. This also requires a bit of proof. As before, let's
5014compute the difference between the LHS and RHS of [8] (and skipping some of
5015the justifications for the kinds of substitutions we've done several times
5016already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005017
Tim Peters8bb5ad22003-01-24 02:44:45 +00005018 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5019 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5020 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5021 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5022 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00005023 - z.o + z'.o = #1 twice
5024 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5025 z'.d - z.d
5026
5027So 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 +00005028we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5029return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005030
Tim Peters8bb5ad22003-01-24 02:44:45 +00005031How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5032a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5033would have to change the result dst() returns: we start in DST, and moving
5034a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005035
Tim Peters8bb5ad22003-01-24 02:44:45 +00005036There isn't a sane case where this can happen. The closest it gets is at
5037the end of DST, where there's an hour in UTC with no spelling in a hybrid
5038tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5039that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5040UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5041time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5042clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5043standard time. Since that's what the local clock *does*, we want to map both
5044UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005045in local time, but so it goes -- it's the way the local clock works.
5046
Tim Peters8bb5ad22003-01-24 02:44:45 +00005047When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5048so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5049z' = 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 +00005050(correctly) concludes that z' is not UTC-equivalent to x.
5051
5052Because we know z.d said z was in daylight time (else [5] would have held and
5053we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005054and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005055return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5056but the reasoning doesn't depend on the example -- it depends on there being
5057two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005058z' must be in standard time, and is the spelling we want in this case.
5059
5060Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5061concerned (because it takes z' as being in standard time rather than the
5062daylight time we intend here), but returning it gives the real-life "local
5063clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5064tz.
5065
5066When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5067the 1:MM standard time spelling we want.
5068
5069So how can this break? One of the assumptions must be violated. Two
5070possibilities:
5071
50721) [2] effectively says that y.s is invariant across all y belong to a given
5073 time zone. This isn't true if, for political reasons or continental drift,
5074 a region decides to change its base offset from UTC.
5075
50762) There may be versions of "double daylight" time where the tail end of
5077 the analysis gives up a step too early. I haven't thought about that
5078 enough to say.
5079
5080In any case, it's clear that the default fromutc() is strong enough to handle
5081"almost all" time zones: so long as the standard offset is invariant, it
5082doesn't matter if daylight time transition points change from year to year, or
5083if daylight time is skipped in some years; it doesn't matter how large or
5084small dst() may get within its bounds; and it doesn't even matter if some
5085perverse time zone returns a negative dst()). So a breaking case must be
5086pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005087--------------------------------------------------------------------------- */