Issue 6340: update by Gregor Lingl of his tdemo_chaos demo program.
[python.git] / Modules / datetimemodule.c
blobfcbd2e9ad2af613bc5946aa805816b8b933ce014
1 /* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
5 #define PY_SSIZE_T_CLEAN
7 #include "Python.h"
8 #include "modsupport.h"
9 #include "structmember.h"
11 #include <time.h>
13 #include "timefuncs.h"
15 /* Differentiate between building the core module and building extension
16 * modules.
18 #ifndef Py_BUILD_CORE
19 #define Py_BUILD_CORE
20 #endif
21 #include "datetime.h"
22 #undef Py_BUILD_CORE
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).
29 #if SIZEOF_INT < 4
30 # error "datetime.c requires that C int have at least 32 bits"
31 #endif
33 #define MINYEAR 1
34 #define MAXYEAR 9999
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.
41 #define MAX_DELTA_DAYS 999999999
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
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))
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)))
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)))
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)
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))
89 /* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
90 * p->hastzinfo.
92 #define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
94 /* 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
98 #define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
100 /* Forward declarations. */
101 static PyTypeObject PyDateTime_DateType;
102 static PyTypeObject PyDateTime_DateTimeType;
103 static PyTypeObject PyDateTime_DeltaType;
104 static PyTypeObject PyDateTime_TimeType;
105 static PyTypeObject PyDateTime_TZInfoType;
107 /* ---------------------------------------------------------------------------
108 * Math utilities.
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.
115 #define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
116 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
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).
127 static int
128 divmod(int x, int y, int *r)
130 int quo;
132 assert(y > 0);
133 quo = x / y;
134 *r = x - quo * y;
135 if (*r < 0) {
136 --quo;
137 *r += y;
139 assert(0 <= *r && *r < y);
140 return quo;
143 /* Round a double to the nearest long. |x| must be small enough to fit
144 * in a C long; this is not checked.
146 static long
147 round_to_long(double x)
149 if (x >= 0.0)
150 x = floor(x + 0.5);
151 else
152 x = ceil(x - 0.5);
153 return (long)x;
156 /* ---------------------------------------------------------------------------
157 * General calendrical helper functions
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.
164 static 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
169 static 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
174 /* year -> 1 if leap year, else 0. */
175 static int
176 is_leap(int year)
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).
183 const unsigned int ayear = (unsigned int)year;
184 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
187 /* year, month -> number of days in that month in that year */
188 static int
189 days_in_month(int year, int month)
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];
199 /* year, month -> number of days in year preceeding first day of month */
200 static int
201 days_before_month(int year, int month)
203 int days;
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;
213 /* year -> number of days before January 1st of year. Remember that we
214 * start with year 1, so days_before_year(1) == 0.
216 static int
217 days_before_year(int year)
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.
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;
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.
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 */
241 /* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
242 static void
243 ord_to_ymd(int ordinal, int *year, int *month, int *day)
245 int n, n1, n4, n100, n400, leapyear, preceding;
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:
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
269 assert(ordinal >= 1);
270 --ordinal;
271 n400 = ordinal / DI400Y;
272 n = ordinal % DI400Y;
273 *year = n400 * 400 + 1;
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.
282 n100 = n / DI100Y;
283 n = n % DI100Y;
285 /* Now compute how many 4-year cycles precede it. */
286 n4 = n / DI4Y;
287 n = n % DI4Y;
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.
293 n1 = n / 365;
294 n = n % 365;
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;
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.
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);
318 n -= preceding;
319 assert(0 <= n);
320 assert(n < days_in_month(*year, *month));
322 *day = n + 1;
325 /* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
326 static int
327 ymd_to_ord(int year, int month, int day)
329 return days_before_year(year) + days_before_month(year, month) + day;
332 /* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
333 static int
334 weekday(int year, int month, int day)
336 return (ymd_to_ord(year, month, day) + 6) % 7;
339 /* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
340 * first calendar week containing a Thursday.
342 static int
343 iso_week1_monday(int year)
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;
351 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
352 week1_monday += 7;
353 return week1_monday;
356 /* ---------------------------------------------------------------------------
357 * Range checkers.
360 /* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
361 * If not, raise OverflowError and return -1.
363 static int
364 check_delta_day_range(int days)
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",
370 days, MAX_DELTA_DAYS);
371 return -1;
374 /* Check that date arguments are in range. Return 0 if they are. If they
375 * aren't, raise ValueError and return -1.
377 static int
378 check_date_args(int year, int month, int day)
381 if (year < MINYEAR || year > MAXYEAR) {
382 PyErr_SetString(PyExc_ValueError,
383 "year is out of range");
384 return -1;
386 if (month < 1 || month > 12) {
387 PyErr_SetString(PyExc_ValueError,
388 "month must be in 1..12");
389 return -1;
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;
396 return 0;
399 /* Check that time arguments are in range. Return 0 if they are. If they
400 * aren't, raise ValueError and return -1.
402 static int
403 check_time_args(int h, int m, int s, int us)
405 if (h < 0 || h > 23) {
406 PyErr_SetString(PyExc_ValueError,
407 "hour must be in 0..23");
408 return -1;
410 if (m < 0 || m > 59) {
411 PyErr_SetString(PyExc_ValueError,
412 "minute must be in 0..59");
413 return -1;
415 if (s < 0 || s > 59) {
416 PyErr_SetString(PyExc_ValueError,
417 "second must be in 0..59");
418 return -1;
420 if (us < 0 || us > 999999) {
421 PyErr_SetString(PyExc_ValueError,
422 "microsecond must be in 0..999999");
423 return -1;
425 return 0;
428 /* ---------------------------------------------------------------------------
429 * Normalization utilities.
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.
438 static void
439 normalize_pair(int *hi, int *lo, int factor)
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;
449 assert(0 <= *lo && *lo < factor);
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.
458 static void
459 normalize_d_s_us(int *d, int *s, int *us)
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.
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.
475 assert(0 <= *s && *s < 24*3600);
476 assert(0 <= *us && *us < 1000000);
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.
485 static void
486 normalize_y_m_d(int *y, int *m, int *d)
488 int dim; /* # of days in month */
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.
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.
504 assert(1 <= *m && *m <= 12);
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.
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).
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;
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;
536 else {
537 int ordinal = ymd_to_ord(*y, *m, 1) +
538 *d - 1;
539 ord_to_ymd(ordinal, y, m, d);
542 assert(*m > 0);
543 assert(*d > 0);
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.
550 static int
551 normalize_date(int *year, int *month, int *day)
553 int result;
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;
563 return result;
566 /* Force all the datetime fields into range. The parameters are both
567 * inputs and outputs. Returns < 0 on error.
569 static int
570 normalize_datetime(int *year, int *month, int *day,
571 int *hour, int *minute, int *second,
572 int *microsecond)
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);
581 /* ---------------------------------------------------------------------------
582 * 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.
587 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
588 * 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).
602 static PyObject *
603 time_alloc(PyTypeObject *type, Py_ssize_t aware)
605 PyObject *self;
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;
617 static PyObject *
618 datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
620 PyObject *self;
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;
632 /* ---------------------------------------------------------------------------
633 * Helpers for setting object fields. These work on pointers to the
634 * appropriate base class.
637 /* For date and datetime. */
638 static void
639 set_date_fields(PyDateTime_Date *self, int y, int m, int d)
641 self->hashcode = -1;
642 SET_YEAR(self, y);
643 SET_MONTH(self, m);
644 SET_DAY(self, d);
647 /* ---------------------------------------------------------------------------
648 * Create various objects, mostly without range checking.
651 /* Create a date instance with no range checking. */
652 static PyObject *
653 new_date_ex(int year, int month, int day, PyTypeObject *type)
655 PyDateTime_Date *self;
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;
663 #define new_date(year, month, day) \
664 new_date_ex(year, month, day, &PyDateTime_DateType)
666 /* Create a datetime instance with no range checking. */
667 static PyObject *
668 new_datetime_ex(int year, int month, int day, int hour, int minute,
669 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
671 PyDateTime_DateTime *self;
672 char aware = tzinfo != Py_None;
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;
687 return (PyObject *)self;
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)
694 /* Create a time instance with no range checking. */
695 static PyObject *
696 new_time_ex(int hour, int minute, int second, int usecond,
697 PyObject *tzinfo, PyTypeObject *type)
699 PyDateTime_Time *self;
700 char aware = tzinfo != Py_None;
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;
715 return (PyObject *)self;
718 #define new_time(hh, mm, ss, us, tzinfo) \
719 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
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).
727 static PyObject *
728 new_delta_ex(int days, int seconds, int microseconds, int normalize,
729 PyTypeObject *type)
731 PyDateTime_Delta *self;
733 if (normalize)
734 normalize_d_s_us(&days, &seconds, &microseconds);
735 assert(0 <= seconds && seconds < 24*3600);
736 assert(0 <= microseconds && microseconds < 1000000);
738 if (check_delta_day_range(days) < 0)
739 return NULL;
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);
748 return (PyObject *) self;
751 #define new_delta(d, s, us, normalize) \
752 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
754 /* ---------------------------------------------------------------------------
755 * tzinfo helpers.
758 /* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
759 * raise TypeError and return -1.
761 static int
762 check_tzinfo_subclass(PyObject *p)
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'",
769 Py_TYPE(p)->tp_name);
770 return -1;
773 /* Return tzinfo.methname(tzinfoarg), without any checking of results.
774 * If tzinfo is None, returns None.
776 static PyObject *
777 call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
779 PyObject *result;
781 assert(tzinfo && methname && tzinfoarg);
782 assert(check_tzinfo_subclass(tzinfo) >= 0);
783 if (tzinfo == Py_None) {
784 result = Py_None;
785 Py_INCREF(result);
787 else
788 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
789 return result;
792 /* 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.
796 static PyObject *
797 get_tzinfo_member(PyObject *self)
799 PyObject *tzinfo = NULL;
801 if (PyDateTime_Check(self) && HASTZINFO(self))
802 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
803 else if (PyTime_Check(self) && HASTZINFO(self))
804 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
806 return tzinfo;
809 /* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
810 * 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
812 * 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.
815 * Else *none is set to 0 and the integer method result is returned.
817 static int
818 call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
819 int *none)
821 PyObject *u;
822 int result = -1;
824 assert(tzinfo != NULL);
825 assert(PyTZInfo_Check(tzinfo));
826 assert(tzinfoarg != NULL);
828 *none = 0;
829 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
830 if (u == NULL)
831 return -1;
833 else if (u == Py_None) {
834 result = 0;
835 *none = 1;
837 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
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;
856 else {
857 PyErr_Format(PyExc_TypeError,
858 "tzinfo.%s() must return None or "
859 "timedelta, not '%s'",
860 name, Py_TYPE(u)->tp_name);
863 Py_DECREF(u);
864 if (result < -1439 || result > 1439) {
865 PyErr_Format(PyExc_ValueError,
866 "tzinfo.%s() returned %d; must be in "
867 "-1439 .. 1439",
868 name, result);
869 result = -1;
871 return result;
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()
877 * 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).
882 static int
883 call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
885 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
888 /* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
890 static PyObject *
891 offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
892 PyObject *result;
894 assert(tzinfo && name && tzinfoarg);
895 if (tzinfo == Py_None) {
896 result = Py_None;
897 Py_INCREF(result);
899 else {
900 int none;
901 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
902 &none);
903 if (offset < 0 && PyErr_Occurred())
904 return NULL;
905 if (none) {
906 result = Py_None;
907 Py_INCREF(result);
909 else
910 result = new_delta(0, offset * 60, 0, 1);
912 return result;
915 /* 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()
918 & doesn't return None or timedelta, TypeError is raised and this
919 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
920 * 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).
923 static int
924 call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
926 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
929 /* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
930 * an instance of the tzinfo class or None. If tzinfo isn't None, and
931 * tzname() doesn't return None or a string, TypeError is raised and this
932 * returns NULL.
934 static PyObject *
935 call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
937 PyObject *result;
939 assert(tzinfo != NULL);
940 assert(check_tzinfo_subclass(tzinfo) >= 0);
941 assert(tzinfoarg != NULL);
943 if (tzinfo == Py_None) {
944 result = Py_None;
945 Py_INCREF(result);
947 else
948 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
950 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
951 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
952 "return None or a string, not '%s'",
953 Py_TYPE(result)->tp_name);
954 Py_DECREF(result);
955 result = NULL;
957 return result;
960 typedef enum {
961 /* an exception has been set; the caller should pass it on */
962 OFFSET_ERROR,
964 /* type isn't date, datetime, or time subclass */
965 OFFSET_UNKNOWN,
967 /* date,
968 * datetime with !hastzinfo
969 * datetime with None tzinfo,
970 * datetime where utcoffset() returns None
971 * time with !hastzinfo
972 * time with None tzinfo,
973 * time where utcoffset() returns None
975 OFFSET_NAIVE,
977 /* time or datetime where utcoffset() doesn't return None */
978 OFFSET_AWARE
979 } naivety;
981 /* Classify an object as to whether it's naive or offset-aware. See
982 * 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).
984 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
985 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
987 static naivety
988 classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
990 int none;
991 PyObject *tzinfo;
993 assert(tzinfoarg != NULL);
994 *offset = 0;
995 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
996 if (tzinfo == Py_None)
997 return OFFSET_NAIVE;
998 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;
1003 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1004 if (*offset == -1 && PyErr_Occurred())
1005 return OFFSET_ERROR;
1006 return none ? OFFSET_NAIVE : OFFSET_AWARE;
1009 /* 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.
1018 static int
1019 classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
1020 PyObject *tzinfoarg1,
1021 PyObject *o2, int *offset2, naivety *n2,
1022 PyObject *tzinfoarg2)
1024 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1025 *offset1 = *offset2 = 0;
1026 *n1 = *n2 = OFFSET_NAIVE;
1028 else {
1029 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1030 if (*n1 == OFFSET_ERROR)
1031 return -1;
1032 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1033 if (*n2 == OFFSET_ERROR)
1034 return -1;
1036 return 0;
1039 /* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1040 * stuff
1041 * ", tzinfo=" + repr(tzinfo)
1042 * before the closing ")".
1044 static PyObject *
1045 append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1047 PyObject *temp;
1049 assert(PyString_Check(repr));
1050 assert(tzinfo);
1051 if (tzinfo == Py_None)
1052 return repr;
1053 /* Get rid of the trailing ')'. */
1054 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1055 temp = PyString_FromStringAndSize(PyString_AsString(repr),
1056 PyString_Size(repr) - 1);
1057 Py_DECREF(repr);
1058 if (temp == NULL)
1059 return NULL;
1060 repr = temp;
1062 /* Append ", tzinfo=". */
1063 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
1065 /* Append repr(tzinfo). */
1066 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
1068 /* Add a closing paren. */
1069 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
1070 return repr;
1073 /* ---------------------------------------------------------------------------
1074 * String format helpers.
1077 static PyObject *
1078 format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
1080 static const char *DayNames[] = {
1081 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1083 static const char *MonthNames[] = {
1084 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1085 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1088 char buffer[128];
1089 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
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));
1095 return PyString_FromString(buffer);
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.
1108 static int
1109 format_utcoffset(char *buf, size_t buflen, const char *sep,
1110 PyObject *tzinfo, PyObject *tzinfoarg)
1112 int offset;
1113 int hours;
1114 int minutes;
1115 char sign;
1116 int none;
1118 assert(buflen >= 1);
1120 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1121 if (offset == -1 && PyErr_Occurred())
1122 return -1;
1123 if (none) {
1124 *buf = '\0';
1125 return 0;
1127 sign = '+';
1128 if (offset < 0) {
1129 sign = '-';
1130 offset = - offset;
1132 hours = divmod(offset, 60, &minutes);
1133 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1134 return 0;
1137 static PyObject *
1138 make_freplacement(PyObject *object)
1140 char freplacement[64];
1141 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);
1148 return PyString_FromStringAndSize(freplacement, strlen(freplacement));
1151 /* 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
1153 * giving special meanings to the %z, %Z and %f format codes via a
1154 * preprocessing step on the format string.
1155 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1156 * needed.
1158 static PyObject *
1159 wrap_strftime(PyObject *object, const char *format, size_t format_len,
1160 PyObject *timetuple, PyObject *tzinfoarg)
1162 PyObject *result = NULL; /* guilty until proved innocent */
1164 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1165 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1166 PyObject *freplacement = NULL; /* py string, replacement for %f */
1168 const char *pin; /* pointer to next char in input format */
1169 char ch; /* next char in input format */
1171 PyObject *newfmt = NULL; /* py string, the output format */
1172 char *pnew; /* pointer to available byte in output format */
1173 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 */
1177 const char *ptoappend; /* ptr to string to append to output buffer */
1178 size_t ntoappend; /* # of bytes to append to output buffer */
1180 assert(object && format && timetuple);
1182 /* 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.
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;
1207 /* Scan the input format, looking for %z/%Z/%f escapes, building
1208 * a new format. Since computing the replacements for those codes
1209 * is expensive, don't unless they're actually used.
1211 if (format_len > INT_MAX - 1) {
1212 PyErr_NoMemory();
1213 goto Done;
1216 totalnew = format_len + 1; /* realistic if no %z/%Z/%f */
1217 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1218 if (newfmt == NULL) goto Done;
1219 pnew = PyString_AsString(newfmt);
1220 usednew = 0;
1222 pin = format;
1223 while ((ch = *pin++) != '\0') {
1224 if (ch != '%') {
1225 ptoappend = pin - 1;
1226 ntoappend = 1;
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;
1234 /* A % has been seen and ch is the character after it. */
1235 else if (ch == 'z') {
1236 if (zreplacement == NULL) {
1237 /* format utcoffset */
1238 char buf[100];
1239 PyObject *tzinfo = get_tzinfo_member(object);
1240 zreplacement = PyString_FromString("");
1241 if (zreplacement == NULL) goto Done;
1242 if (tzinfo != Py_None && tzinfo != NULL) {
1243 assert(tzinfoarg != NULL);
1244 if (format_utcoffset(buf,
1245 sizeof(buf),
1247 tzinfo,
1248 tzinfoarg) < 0)
1249 goto Done;
1250 Py_DECREF(zreplacement);
1251 zreplacement = PyString_FromString(buf);
1252 if (zreplacement == NULL) goto Done;
1255 assert(zreplacement != NULL);
1256 ptoappend = PyString_AS_STRING(zreplacement);
1257 ntoappend = PyString_GET_SIZE(zreplacement);
1259 else if (ch == 'Z') {
1260 /* format tzname */
1261 if (Zreplacement == NULL) {
1262 PyObject *tzinfo = get_tzinfo_member(object);
1263 Zreplacement = PyString_FromString("");
1264 if (Zreplacement == NULL) goto Done;
1265 if (tzinfo != Py_None && tzinfo != NULL) {
1266 PyObject *temp;
1267 assert(tzinfoarg != NULL);
1268 temp = call_tzname(tzinfo, tzinfoarg);
1269 if (temp == NULL) goto Done;
1270 if (temp != Py_None) {
1271 assert(PyString_Check(temp));
1272 /* 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.
1278 Py_DECREF(Zreplacement);
1279 Zreplacement = PyObject_CallMethod(
1280 temp, "replace",
1281 "ss", "%", "%%");
1282 Py_DECREF(temp);
1283 if (Zreplacement == NULL)
1284 goto Done;
1285 if (!PyString_Check(Zreplacement)) {
1286 PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
1287 goto Done;
1290 else
1291 Py_DECREF(temp);
1294 assert(Zreplacement != NULL);
1295 ptoappend = PyString_AS_STRING(Zreplacement);
1296 ntoappend = PyString_GET_SIZE(Zreplacement);
1298 else if (ch == 'f') {
1299 /* format microseconds */
1300 if (freplacement == NULL) {
1301 freplacement = make_freplacement(object);
1302 if (freplacement == NULL)
1303 goto Done;
1305 assert(freplacement != NULL);
1306 assert(PyString_Check(freplacement));
1307 ptoappend = PyString_AS_STRING(freplacement);
1308 ntoappend = PyString_GET_SIZE(freplacement);
1310 else {
1311 /* percent followed by neither z nor Z */
1312 ptoappend = pin - 2;
1313 ntoappend = 2;
1316 /* Append the ntoappend chars starting at ptoappend to
1317 * the new format.
1319 assert(ptoappend != NULL);
1320 assert(ntoappend >= 0);
1321 if (ntoappend == 0)
1322 continue;
1323 while (usednew + ntoappend > totalnew) {
1324 size_t bigger = totalnew << 1;
1325 if ((bigger >> 1) != totalnew) { /* overflow */
1326 PyErr_NoMemory();
1327 goto Done;
1329 if (_PyString_Resize(&newfmt, bigger) < 0)
1330 goto Done;
1331 totalnew = bigger;
1332 pnew = PyString_AsString(newfmt) + usednew;
1334 memcpy(pnew, ptoappend, ntoappend);
1335 pnew += ntoappend;
1336 usednew += ntoappend;
1337 assert(usednew <= totalnew);
1338 } /* end while() */
1340 if (_PyString_Resize(&newfmt, usednew) < 0)
1341 goto Done;
1343 PyObject *time = PyImport_ImportModuleNoBlock("time");
1344 if (time == NULL)
1345 goto Done;
1346 result = PyObject_CallMethod(time, "strftime", "OO",
1347 newfmt, timetuple);
1348 Py_DECREF(time);
1350 Done:
1351 Py_XDECREF(freplacement);
1352 Py_XDECREF(zreplacement);
1353 Py_XDECREF(Zreplacement);
1354 Py_XDECREF(newfmt);
1355 return result;
1358 static char *
1359 isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1361 int x;
1362 x = PyOS_snprintf(buffer, bufflen,
1363 "%04d-%02d-%02d",
1364 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1365 return buffer + x;
1368 static void
1369 isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1371 int us = DATE_GET_MICROSECOND(dt);
1373 PyOS_snprintf(buffer, bufflen,
1374 "%02d:%02d:%02d", /* 8 characters */
1375 DATE_GET_HOUR(dt),
1376 DATE_GET_MINUTE(dt),
1377 DATE_GET_SECOND(dt));
1378 if (us)
1379 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1382 /* ---------------------------------------------------------------------------
1383 * Wrap functions from the time module. These aren't directly available
1384 * from C. Perhaps they should be.
1387 /* Call time.time() and return its result (a Python float). */
1388 static PyObject *
1389 time_time(void)
1391 PyObject *result = NULL;
1392 PyObject *time = PyImport_ImportModuleNoBlock("time");
1394 if (time != NULL) {
1395 result = PyObject_CallMethod(time, "time", "()");
1396 Py_DECREF(time);
1398 return result;
1401 /* Build a time.struct_time. The weekday and day number are automatically
1402 * computed from the y,m,d args.
1404 static PyObject *
1405 build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1407 PyObject *time;
1408 PyObject *result = NULL;
1410 time = PyImport_ImportModuleNoBlock("time");
1411 if (time != NULL) {
1412 result = PyObject_CallMethod(time, "struct_time",
1413 "((iiiiiiiii))",
1414 y, m, d,
1415 hh, mm, ss,
1416 weekday(y, m, d),
1417 days_before_month(y, m) + d,
1418 dstflag);
1419 Py_DECREF(time);
1421 return result;
1424 /* ---------------------------------------------------------------------------
1425 * Miscellaneous helpers.
1428 /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1429 * The comparisons here all most naturally compute a cmp()-like result.
1430 * This little helper turns that into a bool result for rich comparisons.
1432 static PyObject *
1433 diff_to_bool(int diff, int op)
1435 PyObject *result;
1436 int istrue;
1438 switch (op) {
1439 case Py_EQ: istrue = diff == 0; break;
1440 case Py_NE: istrue = diff != 0; break;
1441 case Py_LE: istrue = diff <= 0; break;
1442 case Py_GE: istrue = diff >= 0; break;
1443 case Py_LT: istrue = diff < 0; break;
1444 case Py_GT: istrue = diff > 0; break;
1445 default:
1446 assert(! "op unknown");
1447 istrue = 0; /* To shut up compiler */
1449 result = istrue ? Py_True : Py_False;
1450 Py_INCREF(result);
1451 return result;
1454 /* Raises a "can't compare" TypeError and returns NULL. */
1455 static PyObject *
1456 cmperror(PyObject *a, PyObject *b)
1458 PyErr_Format(PyExc_TypeError,
1459 "can't compare %s to %s",
1460 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1461 return NULL;
1464 /* ---------------------------------------------------------------------------
1465 * Cached Python objects; these are set by the module init function.
1468 /* Conversion factors. */
1469 static PyObject *us_per_us = NULL; /* 1 */
1470 static PyObject *us_per_ms = NULL; /* 1000 */
1471 static PyObject *us_per_second = NULL; /* 1000000 */
1472 static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1473 static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1474 static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1475 static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1476 static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1478 /* ---------------------------------------------------------------------------
1479 * Class implementations.
1483 * PyDateTime_Delta implementation.
1486 /* Convert a timedelta to a number of us,
1487 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1488 * as a Python int or long.
1489 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1490 * due to ubiquitous overflow possibilities.
1492 static PyObject *
1493 delta_to_microseconds(PyDateTime_Delta *self)
1495 PyObject *x1 = NULL;
1496 PyObject *x2 = NULL;
1497 PyObject *x3 = NULL;
1498 PyObject *result = NULL;
1500 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1501 if (x1 == NULL)
1502 goto Done;
1503 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1504 if (x2 == NULL)
1505 goto Done;
1506 Py_DECREF(x1);
1507 x1 = NULL;
1509 /* x2 has days in seconds */
1510 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1511 if (x1 == NULL)
1512 goto Done;
1513 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1514 if (x3 == NULL)
1515 goto Done;
1516 Py_DECREF(x1);
1517 Py_DECREF(x2);
1518 x1 = x2 = NULL;
1520 /* x3 has days+seconds in seconds */
1521 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1522 if (x1 == NULL)
1523 goto Done;
1524 Py_DECREF(x3);
1525 x3 = NULL;
1527 /* x1 has days+seconds in us */
1528 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1529 if (x2 == NULL)
1530 goto Done;
1531 result = PyNumber_Add(x1, x2);
1533 Done:
1534 Py_XDECREF(x1);
1535 Py_XDECREF(x2);
1536 Py_XDECREF(x3);
1537 return result;
1540 /* Convert a number of us (as a Python int or long) to a timedelta.
1542 static PyObject *
1543 microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1545 int us;
1546 int s;
1547 int d;
1548 long temp;
1550 PyObject *tuple = NULL;
1551 PyObject *num = NULL;
1552 PyObject *result = NULL;
1554 tuple = PyNumber_Divmod(pyus, us_per_second);
1555 if (tuple == NULL)
1556 goto Done;
1558 num = PyTuple_GetItem(tuple, 1); /* us */
1559 if (num == NULL)
1560 goto Done;
1561 temp = PyLong_AsLong(num);
1562 num = NULL;
1563 if (temp == -1 && PyErr_Occurred())
1564 goto Done;
1565 assert(0 <= temp && temp < 1000000);
1566 us = (int)temp;
1567 if (us < 0) {
1568 /* The divisor was positive, so this must be an error. */
1569 assert(PyErr_Occurred());
1570 goto Done;
1573 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1574 if (num == NULL)
1575 goto Done;
1576 Py_INCREF(num);
1577 Py_DECREF(tuple);
1579 tuple = PyNumber_Divmod(num, seconds_per_day);
1580 if (tuple == NULL)
1581 goto Done;
1582 Py_DECREF(num);
1584 num = PyTuple_GetItem(tuple, 1); /* seconds */
1585 if (num == NULL)
1586 goto Done;
1587 temp = PyLong_AsLong(num);
1588 num = NULL;
1589 if (temp == -1 && PyErr_Occurred())
1590 goto Done;
1591 assert(0 <= temp && temp < 24*3600);
1592 s = (int)temp;
1594 if (s < 0) {
1595 /* The divisor was positive, so this must be an error. */
1596 assert(PyErr_Occurred());
1597 goto Done;
1600 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1601 if (num == NULL)
1602 goto Done;
1603 Py_INCREF(num);
1604 temp = PyLong_AsLong(num);
1605 if (temp == -1 && PyErr_Occurred())
1606 goto Done;
1607 d = (int)temp;
1608 if ((long)d != temp) {
1609 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1610 "large to fit in a C int");
1611 goto Done;
1613 result = new_delta_ex(d, s, us, 0, type);
1615 Done:
1616 Py_XDECREF(tuple);
1617 Py_XDECREF(num);
1618 return result;
1621 #define microseconds_to_delta(pymicros) \
1622 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1624 static PyObject *
1625 multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1627 PyObject *pyus_in;
1628 PyObject *pyus_out;
1629 PyObject *result;
1631 pyus_in = delta_to_microseconds(delta);
1632 if (pyus_in == NULL)
1633 return NULL;
1635 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1636 Py_DECREF(pyus_in);
1637 if (pyus_out == NULL)
1638 return NULL;
1640 result = microseconds_to_delta(pyus_out);
1641 Py_DECREF(pyus_out);
1642 return result;
1645 static PyObject *
1646 divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1648 PyObject *pyus_in;
1649 PyObject *pyus_out;
1650 PyObject *result;
1652 pyus_in = delta_to_microseconds(delta);
1653 if (pyus_in == NULL)
1654 return NULL;
1656 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1657 Py_DECREF(pyus_in);
1658 if (pyus_out == NULL)
1659 return NULL;
1661 result = microseconds_to_delta(pyus_out);
1662 Py_DECREF(pyus_out);
1663 return result;
1666 static PyObject *
1667 delta_add(PyObject *left, PyObject *right)
1669 PyObject *result = Py_NotImplemented;
1671 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1672 /* delta + delta */
1673 /* The C-level additions can't overflow because of the
1674 * invariant bounds.
1676 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1677 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1678 int microseconds = GET_TD_MICROSECONDS(left) +
1679 GET_TD_MICROSECONDS(right);
1680 result = new_delta(days, seconds, microseconds, 1);
1683 if (result == Py_NotImplemented)
1684 Py_INCREF(result);
1685 return result;
1688 static PyObject *
1689 delta_negative(PyDateTime_Delta *self)
1691 return new_delta(-GET_TD_DAYS(self),
1692 -GET_TD_SECONDS(self),
1693 -GET_TD_MICROSECONDS(self),
1697 static PyObject *
1698 delta_positive(PyDateTime_Delta *self)
1700 /* Could optimize this (by returning self) if this isn't a
1701 * subclass -- but who uses unary + ? Approximately nobody.
1703 return new_delta(GET_TD_DAYS(self),
1704 GET_TD_SECONDS(self),
1705 GET_TD_MICROSECONDS(self),
1709 static PyObject *
1710 delta_abs(PyDateTime_Delta *self)
1712 PyObject *result;
1714 assert(GET_TD_MICROSECONDS(self) >= 0);
1715 assert(GET_TD_SECONDS(self) >= 0);
1717 if (GET_TD_DAYS(self) < 0)
1718 result = delta_negative(self);
1719 else
1720 result = delta_positive(self);
1722 return result;
1725 static PyObject *
1726 delta_subtract(PyObject *left, PyObject *right)
1728 PyObject *result = Py_NotImplemented;
1730 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1731 /* delta - delta */
1732 PyObject *minus_right = PyNumber_Negative(right);
1733 if (minus_right) {
1734 result = delta_add(left, minus_right);
1735 Py_DECREF(minus_right);
1737 else
1738 result = NULL;
1741 if (result == Py_NotImplemented)
1742 Py_INCREF(result);
1743 return result;
1746 /* This is more natural as a tp_compare, but doesn't work then: for whatever
1747 * reason, Python's try_3way_compare ignores tp_compare unless
1748 * PyInstance_Check returns true, but these aren't old-style classes.
1750 static PyObject *
1751 delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1753 int diff = 42; /* nonsense */
1755 if (PyDelta_Check(other)) {
1756 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1757 if (diff == 0) {
1758 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1759 if (diff == 0)
1760 diff = GET_TD_MICROSECONDS(self) -
1761 GET_TD_MICROSECONDS(other);
1764 else if (op == Py_EQ || op == Py_NE)
1765 diff = 1; /* any non-zero value will do */
1767 else /* stop this from falling back to address comparison */
1768 return cmperror((PyObject *)self, other);
1770 return diff_to_bool(diff, op);
1773 static PyObject *delta_getstate(PyDateTime_Delta *self);
1775 static long
1776 delta_hash(PyDateTime_Delta *self)
1778 if (self->hashcode == -1) {
1779 PyObject *temp = delta_getstate(self);
1780 if (temp != NULL) {
1781 self->hashcode = PyObject_Hash(temp);
1782 Py_DECREF(temp);
1785 return self->hashcode;
1788 static PyObject *
1789 delta_multiply(PyObject *left, PyObject *right)
1791 PyObject *result = Py_NotImplemented;
1793 if (PyDelta_Check(left)) {
1794 /* delta * ??? */
1795 if (PyInt_Check(right) || PyLong_Check(right))
1796 result = multiply_int_timedelta(right,
1797 (PyDateTime_Delta *) left);
1799 else if (PyInt_Check(left) || PyLong_Check(left))
1800 result = multiply_int_timedelta(left,
1801 (PyDateTime_Delta *) right);
1803 if (result == Py_NotImplemented)
1804 Py_INCREF(result);
1805 return result;
1808 static PyObject *
1809 delta_divide(PyObject *left, PyObject *right)
1811 PyObject *result = Py_NotImplemented;
1813 if (PyDelta_Check(left)) {
1814 /* delta * ??? */
1815 if (PyInt_Check(right) || PyLong_Check(right))
1816 result = divide_timedelta_int(
1817 (PyDateTime_Delta *)left,
1818 right);
1821 if (result == Py_NotImplemented)
1822 Py_INCREF(result);
1823 return result;
1826 /* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1827 * timedelta constructor. sofar is the # of microseconds accounted for
1828 * so far, and there are factor microseconds per current unit, the number
1829 * of which is given by num. num * factor is added to sofar in a
1830 * numerically careful way, and that's the result. Any fractional
1831 * microseconds left over (this can happen if num is a float type) are
1832 * added into *leftover.
1833 * Note that there are many ways this can give an error (NULL) return.
1835 static PyObject *
1836 accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1837 double *leftover)
1839 PyObject *prod;
1840 PyObject *sum;
1842 assert(num != NULL);
1844 if (PyInt_Check(num) || PyLong_Check(num)) {
1845 prod = PyNumber_Multiply(num, factor);
1846 if (prod == NULL)
1847 return NULL;
1848 sum = PyNumber_Add(sofar, prod);
1849 Py_DECREF(prod);
1850 return sum;
1853 if (PyFloat_Check(num)) {
1854 double dnum;
1855 double fracpart;
1856 double intpart;
1857 PyObject *x;
1858 PyObject *y;
1860 /* The Plan: decompose num into an integer part and a
1861 * fractional part, num = intpart + fracpart.
1862 * Then num * factor ==
1863 * intpart * factor + fracpart * factor
1864 * and the LHS can be computed exactly in long arithmetic.
1865 * The RHS is again broken into an int part and frac part.
1866 * and the frac part is added into *leftover.
1868 dnum = PyFloat_AsDouble(num);
1869 if (dnum == -1.0 && PyErr_Occurred())
1870 return NULL;
1871 fracpart = modf(dnum, &intpart);
1872 x = PyLong_FromDouble(intpart);
1873 if (x == NULL)
1874 return NULL;
1876 prod = PyNumber_Multiply(x, factor);
1877 Py_DECREF(x);
1878 if (prod == NULL)
1879 return NULL;
1881 sum = PyNumber_Add(sofar, prod);
1882 Py_DECREF(prod);
1883 if (sum == NULL)
1884 return NULL;
1886 if (fracpart == 0.0)
1887 return sum;
1888 /* So far we've lost no information. Dealing with the
1889 * fractional part requires float arithmetic, and may
1890 * lose a little info.
1892 assert(PyInt_Check(factor) || PyLong_Check(factor));
1893 if (PyInt_Check(factor))
1894 dnum = (double)PyInt_AsLong(factor);
1895 else
1896 dnum = PyLong_AsDouble(factor);
1898 dnum *= fracpart;
1899 fracpart = modf(dnum, &intpart);
1900 x = PyLong_FromDouble(intpart);
1901 if (x == NULL) {
1902 Py_DECREF(sum);
1903 return NULL;
1906 y = PyNumber_Add(sum, x);
1907 Py_DECREF(sum);
1908 Py_DECREF(x);
1909 *leftover += fracpart;
1910 return y;
1913 PyErr_Format(PyExc_TypeError,
1914 "unsupported type for timedelta %s component: %s",
1915 tag, Py_TYPE(num)->tp_name);
1916 return NULL;
1919 static PyObject *
1920 delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1922 PyObject *self = NULL;
1924 /* Argument objects. */
1925 PyObject *day = NULL;
1926 PyObject *second = NULL;
1927 PyObject *us = NULL;
1928 PyObject *ms = NULL;
1929 PyObject *minute = NULL;
1930 PyObject *hour = NULL;
1931 PyObject *week = NULL;
1933 PyObject *x = NULL; /* running sum of microseconds */
1934 PyObject *y = NULL; /* temp sum of microseconds */
1935 double leftover_us = 0.0;
1937 static char *keywords[] = {
1938 "days", "seconds", "microseconds", "milliseconds",
1939 "minutes", "hours", "weeks", NULL
1942 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1943 keywords,
1944 &day, &second, &us,
1945 &ms, &minute, &hour, &week) == 0)
1946 goto Done;
1948 x = PyInt_FromLong(0);
1949 if (x == NULL)
1950 goto Done;
1952 #define CLEANUP \
1953 Py_DECREF(x); \
1954 x = y; \
1955 if (x == NULL) \
1956 goto Done
1958 if (us) {
1959 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1960 CLEANUP;
1962 if (ms) {
1963 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1964 CLEANUP;
1966 if (second) {
1967 y = accum("seconds", x, second, us_per_second, &leftover_us);
1968 CLEANUP;
1970 if (minute) {
1971 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1972 CLEANUP;
1974 if (hour) {
1975 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1976 CLEANUP;
1978 if (day) {
1979 y = accum("days", x, day, us_per_day, &leftover_us);
1980 CLEANUP;
1982 if (week) {
1983 y = accum("weeks", x, week, us_per_week, &leftover_us);
1984 CLEANUP;
1986 if (leftover_us) {
1987 /* Round to nearest whole # of us, and add into x. */
1988 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1989 if (temp == NULL) {
1990 Py_DECREF(x);
1991 goto Done;
1993 y = PyNumber_Add(x, temp);
1994 Py_DECREF(temp);
1995 CLEANUP;
1998 self = microseconds_to_delta_ex(x, type);
1999 Py_DECREF(x);
2000 Done:
2001 return self;
2003 #undef CLEANUP
2006 static int
2007 delta_nonzero(PyDateTime_Delta *self)
2009 return (GET_TD_DAYS(self) != 0
2010 || GET_TD_SECONDS(self) != 0
2011 || GET_TD_MICROSECONDS(self) != 0);
2014 static PyObject *
2015 delta_repr(PyDateTime_Delta *self)
2017 if (GET_TD_MICROSECONDS(self) != 0)
2018 return PyString_FromFormat("%s(%d, %d, %d)",
2019 Py_TYPE(self)->tp_name,
2020 GET_TD_DAYS(self),
2021 GET_TD_SECONDS(self),
2022 GET_TD_MICROSECONDS(self));
2023 if (GET_TD_SECONDS(self) != 0)
2024 return PyString_FromFormat("%s(%d, %d)",
2025 Py_TYPE(self)->tp_name,
2026 GET_TD_DAYS(self),
2027 GET_TD_SECONDS(self));
2029 return PyString_FromFormat("%s(%d)",
2030 Py_TYPE(self)->tp_name,
2031 GET_TD_DAYS(self));
2034 static PyObject *
2035 delta_str(PyDateTime_Delta *self)
2037 int days = GET_TD_DAYS(self);
2038 int seconds = GET_TD_SECONDS(self);
2039 int us = GET_TD_MICROSECONDS(self);
2040 int hours;
2041 int minutes;
2042 char buf[100];
2043 char *pbuf = buf;
2044 size_t buflen = sizeof(buf);
2045 int n;
2047 minutes = divmod(seconds, 60, &seconds);
2048 hours = divmod(minutes, 60, &minutes);
2050 if (days) {
2051 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2052 (days == 1 || days == -1) ? "" : "s");
2053 if (n < 0 || (size_t)n >= buflen)
2054 goto Fail;
2055 pbuf += n;
2056 buflen -= (size_t)n;
2059 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2060 hours, minutes, seconds);
2061 if (n < 0 || (size_t)n >= buflen)
2062 goto Fail;
2063 pbuf += n;
2064 buflen -= (size_t)n;
2066 if (us) {
2067 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2068 if (n < 0 || (size_t)n >= buflen)
2069 goto Fail;
2070 pbuf += n;
2073 return PyString_FromStringAndSize(buf, pbuf - buf);
2075 Fail:
2076 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2077 return NULL;
2080 /* Pickle support, a simple use of __reduce__. */
2082 /* __getstate__ isn't exposed */
2083 static PyObject *
2084 delta_getstate(PyDateTime_Delta *self)
2086 return Py_BuildValue("iii", GET_TD_DAYS(self),
2087 GET_TD_SECONDS(self),
2088 GET_TD_MICROSECONDS(self));
2091 static PyObject *
2092 delta_reduce(PyDateTime_Delta* self)
2094 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
2097 #define OFFSET(field) offsetof(PyDateTime_Delta, field)
2099 static PyMemberDef delta_members[] = {
2101 {"days", T_INT, OFFSET(days), READONLY,
2102 PyDoc_STR("Number of days.")},
2104 {"seconds", T_INT, OFFSET(seconds), READONLY,
2105 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2107 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2108 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2109 {NULL}
2112 static PyMethodDef delta_methods[] = {
2113 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2114 PyDoc_STR("__reduce__() -> (cls, state)")},
2116 {NULL, NULL},
2119 static char delta_doc[] =
2120 PyDoc_STR("Difference between two datetime values.");
2122 static PyNumberMethods delta_as_number = {
2123 delta_add, /* nb_add */
2124 delta_subtract, /* nb_subtract */
2125 delta_multiply, /* nb_multiply */
2126 delta_divide, /* nb_divide */
2127 0, /* nb_remainder */
2128 0, /* nb_divmod */
2129 0, /* nb_power */
2130 (unaryfunc)delta_negative, /* nb_negative */
2131 (unaryfunc)delta_positive, /* nb_positive */
2132 (unaryfunc)delta_abs, /* nb_absolute */
2133 (inquiry)delta_nonzero, /* nb_nonzero */
2134 0, /*nb_invert*/
2135 0, /*nb_lshift*/
2136 0, /*nb_rshift*/
2137 0, /*nb_and*/
2138 0, /*nb_xor*/
2139 0, /*nb_or*/
2140 0, /*nb_coerce*/
2141 0, /*nb_int*/
2142 0, /*nb_long*/
2143 0, /*nb_float*/
2144 0, /*nb_oct*/
2145 0, /*nb_hex*/
2146 0, /*nb_inplace_add*/
2147 0, /*nb_inplace_subtract*/
2148 0, /*nb_inplace_multiply*/
2149 0, /*nb_inplace_divide*/
2150 0, /*nb_inplace_remainder*/
2151 0, /*nb_inplace_power*/
2152 0, /*nb_inplace_lshift*/
2153 0, /*nb_inplace_rshift*/
2154 0, /*nb_inplace_and*/
2155 0, /*nb_inplace_xor*/
2156 0, /*nb_inplace_or*/
2157 delta_divide, /* nb_floor_divide */
2158 0, /* nb_true_divide */
2159 0, /* nb_inplace_floor_divide */
2160 0, /* nb_inplace_true_divide */
2163 static PyTypeObject PyDateTime_DeltaType = {
2164 PyVarObject_HEAD_INIT(NULL, 0)
2165 "datetime.timedelta", /* tp_name */
2166 sizeof(PyDateTime_Delta), /* tp_basicsize */
2167 0, /* tp_itemsize */
2168 0, /* tp_dealloc */
2169 0, /* tp_print */
2170 0, /* tp_getattr */
2171 0, /* tp_setattr */
2172 0, /* tp_compare */
2173 (reprfunc)delta_repr, /* tp_repr */
2174 &delta_as_number, /* tp_as_number */
2175 0, /* tp_as_sequence */
2176 0, /* tp_as_mapping */
2177 (hashfunc)delta_hash, /* tp_hash */
2178 0, /* tp_call */
2179 (reprfunc)delta_str, /* tp_str */
2180 PyObject_GenericGetAttr, /* tp_getattro */
2181 0, /* tp_setattro */
2182 0, /* tp_as_buffer */
2183 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2184 Py_TPFLAGS_BASETYPE, /* tp_flags */
2185 delta_doc, /* tp_doc */
2186 0, /* tp_traverse */
2187 0, /* tp_clear */
2188 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2189 0, /* tp_weaklistoffset */
2190 0, /* tp_iter */
2191 0, /* tp_iternext */
2192 delta_methods, /* tp_methods */
2193 delta_members, /* tp_members */
2194 0, /* tp_getset */
2195 0, /* tp_base */
2196 0, /* tp_dict */
2197 0, /* tp_descr_get */
2198 0, /* tp_descr_set */
2199 0, /* tp_dictoffset */
2200 0, /* tp_init */
2201 0, /* tp_alloc */
2202 delta_new, /* tp_new */
2203 0, /* tp_free */
2207 * PyDateTime_Date implementation.
2210 /* Accessor properties. */
2212 static PyObject *
2213 date_year(PyDateTime_Date *self, void *unused)
2215 return PyInt_FromLong(GET_YEAR(self));
2218 static PyObject *
2219 date_month(PyDateTime_Date *self, void *unused)
2221 return PyInt_FromLong(GET_MONTH(self));
2224 static PyObject *
2225 date_day(PyDateTime_Date *self, void *unused)
2227 return PyInt_FromLong(GET_DAY(self));
2230 static PyGetSetDef date_getset[] = {
2231 {"year", (getter)date_year},
2232 {"month", (getter)date_month},
2233 {"day", (getter)date_day},
2234 {NULL}
2237 /* Constructors. */
2239 static char *date_kws[] = {"year", "month", "day", NULL};
2241 static PyObject *
2242 date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2244 PyObject *self = NULL;
2245 PyObject *state;
2246 int year;
2247 int month;
2248 int day;
2250 /* Check for invocation from pickle with __getstate__ state */
2251 if (PyTuple_GET_SIZE(args) == 1 &&
2252 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2253 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2254 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
2256 PyDateTime_Date *me;
2258 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2259 if (me != NULL) {
2260 char *pdata = PyString_AS_STRING(state);
2261 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2262 me->hashcode = -1;
2264 return (PyObject *)me;
2267 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2268 &year, &month, &day)) {
2269 if (check_date_args(year, month, day) < 0)
2270 return NULL;
2271 self = new_date_ex(year, month, day, type);
2273 return self;
2276 /* Return new date from localtime(t). */
2277 static PyObject *
2278 date_local_from_time_t(PyObject *cls, double ts)
2280 struct tm *tm;
2281 time_t t;
2282 PyObject *result = NULL;
2284 t = _PyTime_DoubleToTimet(ts);
2285 if (t == (time_t)-1 && PyErr_Occurred())
2286 return NULL;
2287 tm = localtime(&t);
2288 if (tm)
2289 result = PyObject_CallFunction(cls, "iii",
2290 tm->tm_year + 1900,
2291 tm->tm_mon + 1,
2292 tm->tm_mday);
2293 else
2294 PyErr_SetString(PyExc_ValueError,
2295 "timestamp out of range for "
2296 "platform localtime() function");
2297 return result;
2300 /* Return new date from current time.
2301 * We say this is equivalent to fromtimestamp(time.time()), and the
2302 * only way to be sure of that is to *call* time.time(). That's not
2303 * generally the same as calling C's time.
2305 static PyObject *
2306 date_today(PyObject *cls, PyObject *dummy)
2308 PyObject *time;
2309 PyObject *result;
2311 time = time_time();
2312 if (time == NULL)
2313 return NULL;
2315 /* Note well: today() is a class method, so this may not call
2316 * date.fromtimestamp. For example, it may call
2317 * datetime.fromtimestamp. That's why we need all the accuracy
2318 * time.time() delivers; if someone were gonzo about optimization,
2319 * date.today() could get away with plain C time().
2321 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2322 Py_DECREF(time);
2323 return result;
2326 /* Return new date from given timestamp (Python timestamp -- a double). */
2327 static PyObject *
2328 date_fromtimestamp(PyObject *cls, PyObject *args)
2330 double timestamp;
2331 PyObject *result = NULL;
2333 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2334 result = date_local_from_time_t(cls, timestamp);
2335 return result;
2338 /* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2339 * the ordinal is out of range.
2341 static PyObject *
2342 date_fromordinal(PyObject *cls, PyObject *args)
2344 PyObject *result = NULL;
2345 int ordinal;
2347 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2348 int year;
2349 int month;
2350 int day;
2352 if (ordinal < 1)
2353 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2354 ">= 1");
2355 else {
2356 ord_to_ymd(ordinal, &year, &month, &day);
2357 result = PyObject_CallFunction(cls, "iii",
2358 year, month, day);
2361 return result;
2365 * Date arithmetic.
2368 /* date + timedelta -> date. If arg negate is true, subtract the timedelta
2369 * instead.
2371 static PyObject *
2372 add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2374 PyObject *result = NULL;
2375 int year = GET_YEAR(date);
2376 int month = GET_MONTH(date);
2377 int deltadays = GET_TD_DAYS(delta);
2378 /* C-level overflow is impossible because |deltadays| < 1e9. */
2379 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2381 if (normalize_date(&year, &month, &day) >= 0)
2382 result = new_date(year, month, day);
2383 return result;
2386 static PyObject *
2387 date_add(PyObject *left, PyObject *right)
2389 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2390 Py_INCREF(Py_NotImplemented);
2391 return Py_NotImplemented;
2393 if (PyDate_Check(left)) {
2394 /* date + ??? */
2395 if (PyDelta_Check(right))
2396 /* date + delta */
2397 return add_date_timedelta((PyDateTime_Date *) left,
2398 (PyDateTime_Delta *) right,
2401 else {
2402 /* ??? + date
2403 * 'right' must be one of us, or we wouldn't have been called
2405 if (PyDelta_Check(left))
2406 /* delta + date */
2407 return add_date_timedelta((PyDateTime_Date *) right,
2408 (PyDateTime_Delta *) left,
2411 Py_INCREF(Py_NotImplemented);
2412 return Py_NotImplemented;
2415 static PyObject *
2416 date_subtract(PyObject *left, PyObject *right)
2418 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2419 Py_INCREF(Py_NotImplemented);
2420 return Py_NotImplemented;
2422 if (PyDate_Check(left)) {
2423 if (PyDate_Check(right)) {
2424 /* date - date */
2425 int left_ord = ymd_to_ord(GET_YEAR(left),
2426 GET_MONTH(left),
2427 GET_DAY(left));
2428 int right_ord = ymd_to_ord(GET_YEAR(right),
2429 GET_MONTH(right),
2430 GET_DAY(right));
2431 return new_delta(left_ord - right_ord, 0, 0, 0);
2433 if (PyDelta_Check(right)) {
2434 /* date - delta */
2435 return add_date_timedelta((PyDateTime_Date *) left,
2436 (PyDateTime_Delta *) right,
2440 Py_INCREF(Py_NotImplemented);
2441 return Py_NotImplemented;
2445 /* Various ways to turn a date into a string. */
2447 static PyObject *
2448 date_repr(PyDateTime_Date *self)
2450 char buffer[1028];
2451 const char *type_name;
2453 type_name = Py_TYPE(self)->tp_name;
2454 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2455 type_name,
2456 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2458 return PyString_FromString(buffer);
2461 static PyObject *
2462 date_isoformat(PyDateTime_Date *self)
2464 char buffer[128];
2466 isoformat_date(self, buffer, sizeof(buffer));
2467 return PyString_FromString(buffer);
2470 /* str() calls the appropriate isoformat() method. */
2471 static PyObject *
2472 date_str(PyDateTime_Date *self)
2474 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2478 static PyObject *
2479 date_ctime(PyDateTime_Date *self)
2481 return format_ctime(self, 0, 0, 0);
2484 static PyObject *
2485 date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2487 /* This method can be inherited, and needs to call the
2488 * timetuple() method appropriate to self's class.
2490 PyObject *result;
2491 PyObject *tuple;
2492 const char *format;
2493 Py_ssize_t format_len;
2494 static char *keywords[] = {"format", NULL};
2496 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2497 &format, &format_len))
2498 return NULL;
2500 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2501 if (tuple == NULL)
2502 return NULL;
2503 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
2504 (PyObject *)self);
2505 Py_DECREF(tuple);
2506 return result;
2509 static PyObject *
2510 date_format(PyDateTime_Date *self, PyObject *args)
2512 PyObject *format;
2514 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2515 return NULL;
2517 /* Check for str or unicode */
2518 if (PyString_Check(format)) {
2519 /* If format is zero length, return str(self) */
2520 if (PyString_GET_SIZE(format) == 0)
2521 return PyObject_Str((PyObject *)self);
2522 } else if (PyUnicode_Check(format)) {
2523 /* If format is zero length, return str(self) */
2524 if (PyUnicode_GET_SIZE(format) == 0)
2525 return PyObject_Unicode((PyObject *)self);
2526 } else {
2527 PyErr_Format(PyExc_ValueError,
2528 "__format__ expects str or unicode, not %.200s",
2529 Py_TYPE(format)->tp_name);
2530 return NULL;
2532 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2535 /* ISO methods. */
2537 static PyObject *
2538 date_isoweekday(PyDateTime_Date *self)
2540 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2542 return PyInt_FromLong(dow + 1);
2545 static PyObject *
2546 date_isocalendar(PyDateTime_Date *self)
2548 int year = GET_YEAR(self);
2549 int week1_monday = iso_week1_monday(year);
2550 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2551 int week;
2552 int day;
2554 week = divmod(today - week1_monday, 7, &day);
2555 if (week < 0) {
2556 --year;
2557 week1_monday = iso_week1_monday(year);
2558 week = divmod(today - week1_monday, 7, &day);
2560 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2561 ++year;
2562 week = 0;
2564 return Py_BuildValue("iii", year, week + 1, day + 1);
2567 /* Miscellaneous methods. */
2569 /* This is more natural as a tp_compare, but doesn't work then: for whatever
2570 * reason, Python's try_3way_compare ignores tp_compare unless
2571 * PyInstance_Check returns true, but these aren't old-style classes.
2573 static PyObject *
2574 date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2576 int diff = 42; /* nonsense */
2578 if (PyDate_Check(other))
2579 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2580 _PyDateTime_DATE_DATASIZE);
2582 else if (PyObject_HasAttrString(other, "timetuple")) {
2583 /* A hook for other kinds of date objects. */
2584 Py_INCREF(Py_NotImplemented);
2585 return Py_NotImplemented;
2587 else if (op == Py_EQ || op == Py_NE)
2588 diff = 1; /* any non-zero value will do */
2590 else /* stop this from falling back to address comparison */
2591 return cmperror((PyObject *)self, other);
2593 return diff_to_bool(diff, op);
2596 static PyObject *
2597 date_timetuple(PyDateTime_Date *self)
2599 return build_struct_time(GET_YEAR(self),
2600 GET_MONTH(self),
2601 GET_DAY(self),
2602 0, 0, 0, -1);
2605 static PyObject *
2606 date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2608 PyObject *clone;
2609 PyObject *tuple;
2610 int year = GET_YEAR(self);
2611 int month = GET_MONTH(self);
2612 int day = GET_DAY(self);
2614 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2615 &year, &month, &day))
2616 return NULL;
2617 tuple = Py_BuildValue("iii", year, month, day);
2618 if (tuple == NULL)
2619 return NULL;
2620 clone = date_new(Py_TYPE(self), tuple, NULL);
2621 Py_DECREF(tuple);
2622 return clone;
2625 static PyObject *date_getstate(PyDateTime_Date *self);
2627 static long
2628 date_hash(PyDateTime_Date *self)
2630 if (self->hashcode == -1) {
2631 PyObject *temp = date_getstate(self);
2632 if (temp != NULL) {
2633 self->hashcode = PyObject_Hash(temp);
2634 Py_DECREF(temp);
2637 return self->hashcode;
2640 static PyObject *
2641 date_toordinal(PyDateTime_Date *self)
2643 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2644 GET_DAY(self)));
2647 static PyObject *
2648 date_weekday(PyDateTime_Date *self)
2650 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2652 return PyInt_FromLong(dow);
2655 /* Pickle support, a simple use of __reduce__. */
2657 /* __getstate__ isn't exposed */
2658 static PyObject *
2659 date_getstate(PyDateTime_Date *self)
2661 return Py_BuildValue(
2662 "(N)",
2663 PyString_FromStringAndSize((char *)self->data,
2664 _PyDateTime_DATE_DATASIZE));
2667 static PyObject *
2668 date_reduce(PyDateTime_Date *self, PyObject *arg)
2670 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
2673 static PyMethodDef date_methods[] = {
2675 /* Class methods: */
2677 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2678 METH_CLASS,
2679 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2680 "time.time()).")},
2682 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2683 METH_CLASS,
2684 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2685 "ordinal.")},
2687 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2688 PyDoc_STR("Current date or datetime: same as "
2689 "self.__class__.fromtimestamp(time.time()).")},
2691 /* Instance methods: */
2693 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2694 PyDoc_STR("Return ctime() style string.")},
2696 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2697 PyDoc_STR("format -> strftime() style string.")},
2699 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2700 PyDoc_STR("Formats self with strftime.")},
2702 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2703 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2705 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2706 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2707 "weekday.")},
2709 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2710 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2712 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2713 PyDoc_STR("Return the day of the week represented by the date.\n"
2714 "Monday == 1 ... Sunday == 7")},
2716 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2717 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2718 "1 is day 1.")},
2720 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2721 PyDoc_STR("Return the day of the week represented by the date.\n"
2722 "Monday == 0 ... Sunday == 6")},
2724 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2725 PyDoc_STR("Return date with new specified fields.")},
2727 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2728 PyDoc_STR("__reduce__() -> (cls, state)")},
2730 {NULL, NULL}
2733 static char date_doc[] =
2734 PyDoc_STR("date(year, month, day) --> date object");
2736 static PyNumberMethods date_as_number = {
2737 date_add, /* nb_add */
2738 date_subtract, /* nb_subtract */
2739 0, /* nb_multiply */
2740 0, /* nb_divide */
2741 0, /* nb_remainder */
2742 0, /* nb_divmod */
2743 0, /* nb_power */
2744 0, /* nb_negative */
2745 0, /* nb_positive */
2746 0, /* nb_absolute */
2747 0, /* nb_nonzero */
2750 static PyTypeObject PyDateTime_DateType = {
2751 PyVarObject_HEAD_INIT(NULL, 0)
2752 "datetime.date", /* tp_name */
2753 sizeof(PyDateTime_Date), /* tp_basicsize */
2754 0, /* tp_itemsize */
2755 0, /* tp_dealloc */
2756 0, /* tp_print */
2757 0, /* tp_getattr */
2758 0, /* tp_setattr */
2759 0, /* tp_compare */
2760 (reprfunc)date_repr, /* tp_repr */
2761 &date_as_number, /* tp_as_number */
2762 0, /* tp_as_sequence */
2763 0, /* tp_as_mapping */
2764 (hashfunc)date_hash, /* tp_hash */
2765 0, /* tp_call */
2766 (reprfunc)date_str, /* tp_str */
2767 PyObject_GenericGetAttr, /* tp_getattro */
2768 0, /* tp_setattro */
2769 0, /* tp_as_buffer */
2770 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2771 Py_TPFLAGS_BASETYPE, /* tp_flags */
2772 date_doc, /* tp_doc */
2773 0, /* tp_traverse */
2774 0, /* tp_clear */
2775 (richcmpfunc)date_richcompare, /* tp_richcompare */
2776 0, /* tp_weaklistoffset */
2777 0, /* tp_iter */
2778 0, /* tp_iternext */
2779 date_methods, /* tp_methods */
2780 0, /* tp_members */
2781 date_getset, /* tp_getset */
2782 0, /* tp_base */
2783 0, /* tp_dict */
2784 0, /* tp_descr_get */
2785 0, /* tp_descr_set */
2786 0, /* tp_dictoffset */
2787 0, /* tp_init */
2788 0, /* tp_alloc */
2789 date_new, /* tp_new */
2790 0, /* tp_free */
2794 * PyDateTime_TZInfo implementation.
2797 /* This is a pure abstract base class, so doesn't do anything beyond
2798 * raising NotImplemented exceptions. Real tzinfo classes need
2799 * to derive from this. This is mostly for clarity, and for efficiency in
2800 * datetime and time constructors (their tzinfo arguments need to
2801 * be subclasses of this tzinfo class, which is easy and quick to check).
2803 * Note: For reasons having to do with pickling of subclasses, we have
2804 * to allow tzinfo objects to be instantiated. This wasn't an issue
2805 * in the Python implementation (__init__() could raise NotImplementedError
2806 * there without ill effect), but doing so in the C implementation hit a
2807 * brick wall.
2810 static PyObject *
2811 tzinfo_nogo(const char* methodname)
2813 PyErr_Format(PyExc_NotImplementedError,
2814 "a tzinfo subclass must implement %s()",
2815 methodname);
2816 return NULL;
2819 /* Methods. A subclass must implement these. */
2821 static PyObject *
2822 tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2824 return tzinfo_nogo("tzname");
2827 static PyObject *
2828 tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2830 return tzinfo_nogo("utcoffset");
2833 static PyObject *
2834 tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2836 return tzinfo_nogo("dst");
2839 static PyObject *
2840 tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2842 int y, m, d, hh, mm, ss, us;
2844 PyObject *result;
2845 int off, dst;
2846 int none;
2847 int delta;
2849 if (! PyDateTime_Check(dt)) {
2850 PyErr_SetString(PyExc_TypeError,
2851 "fromutc: argument must be a datetime");
2852 return NULL;
2854 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2855 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2856 "is not self");
2857 return NULL;
2860 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2861 if (off == -1 && PyErr_Occurred())
2862 return NULL;
2863 if (none) {
2864 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2865 "utcoffset() result required");
2866 return NULL;
2869 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2870 if (dst == -1 && PyErr_Occurred())
2871 return NULL;
2872 if (none) {
2873 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2874 "dst() result required");
2875 return NULL;
2878 y = GET_YEAR(dt);
2879 m = GET_MONTH(dt);
2880 d = GET_DAY(dt);
2881 hh = DATE_GET_HOUR(dt);
2882 mm = DATE_GET_MINUTE(dt);
2883 ss = DATE_GET_SECOND(dt);
2884 us = DATE_GET_MICROSECOND(dt);
2886 delta = off - dst;
2887 mm += delta;
2888 if ((mm < 0 || mm >= 60) &&
2889 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2890 return NULL;
2891 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2892 if (result == NULL)
2893 return result;
2895 dst = call_dst(dt->tzinfo, result, &none);
2896 if (dst == -1 && PyErr_Occurred())
2897 goto Fail;
2898 if (none)
2899 goto Inconsistent;
2900 if (dst == 0)
2901 return result;
2903 mm += dst;
2904 if ((mm < 0 || mm >= 60) &&
2905 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2906 goto Fail;
2907 Py_DECREF(result);
2908 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2909 return result;
2911 Inconsistent:
2912 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2913 "inconsistent results; cannot convert");
2915 /* fall thru to failure */
2916 Fail:
2917 Py_DECREF(result);
2918 return NULL;
2922 * Pickle support. This is solely so that tzinfo subclasses can use
2923 * pickling -- tzinfo itself is supposed to be uninstantiable.
2926 static PyObject *
2927 tzinfo_reduce(PyObject *self)
2929 PyObject *args, *state, *tmp;
2930 PyObject *getinitargs, *getstate;
2932 tmp = PyTuple_New(0);
2933 if (tmp == NULL)
2934 return NULL;
2936 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2937 if (getinitargs != NULL) {
2938 args = PyObject_CallObject(getinitargs, tmp);
2939 Py_DECREF(getinitargs);
2940 if (args == NULL) {
2941 Py_DECREF(tmp);
2942 return NULL;
2945 else {
2946 PyErr_Clear();
2947 args = tmp;
2948 Py_INCREF(args);
2951 getstate = PyObject_GetAttrString(self, "__getstate__");
2952 if (getstate != NULL) {
2953 state = PyObject_CallObject(getstate, tmp);
2954 Py_DECREF(getstate);
2955 if (state == NULL) {
2956 Py_DECREF(args);
2957 Py_DECREF(tmp);
2958 return NULL;
2961 else {
2962 PyObject **dictptr;
2963 PyErr_Clear();
2964 state = Py_None;
2965 dictptr = _PyObject_GetDictPtr(self);
2966 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2967 state = *dictptr;
2968 Py_INCREF(state);
2971 Py_DECREF(tmp);
2973 if (state == Py_None) {
2974 Py_DECREF(state);
2975 return Py_BuildValue("(ON)", Py_TYPE(self), args);
2977 else
2978 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
2981 static PyMethodDef tzinfo_methods[] = {
2983 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2984 PyDoc_STR("datetime -> string name of time zone.")},
2986 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2987 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2988 "west of UTC).")},
2990 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2991 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2993 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2994 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2996 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2997 PyDoc_STR("-> (cls, state)")},
2999 {NULL, NULL}
3002 static char tzinfo_doc[] =
3003 PyDoc_STR("Abstract base class for time zone info objects.");
3005 statichere PyTypeObject PyDateTime_TZInfoType = {
3006 PyObject_HEAD_INIT(NULL)
3007 0, /* ob_size */
3008 "datetime.tzinfo", /* tp_name */
3009 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3010 0, /* tp_itemsize */
3011 0, /* tp_dealloc */
3012 0, /* tp_print */
3013 0, /* tp_getattr */
3014 0, /* tp_setattr */
3015 0, /* tp_compare */
3016 0, /* tp_repr */
3017 0, /* tp_as_number */
3018 0, /* tp_as_sequence */
3019 0, /* tp_as_mapping */
3020 0, /* tp_hash */
3021 0, /* tp_call */
3022 0, /* tp_str */
3023 PyObject_GenericGetAttr, /* tp_getattro */
3024 0, /* tp_setattro */
3025 0, /* tp_as_buffer */
3026 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3027 Py_TPFLAGS_BASETYPE, /* tp_flags */
3028 tzinfo_doc, /* tp_doc */
3029 0, /* tp_traverse */
3030 0, /* tp_clear */
3031 0, /* tp_richcompare */
3032 0, /* tp_weaklistoffset */
3033 0, /* tp_iter */
3034 0, /* tp_iternext */
3035 tzinfo_methods, /* tp_methods */
3036 0, /* tp_members */
3037 0, /* tp_getset */
3038 0, /* tp_base */
3039 0, /* tp_dict */
3040 0, /* tp_descr_get */
3041 0, /* tp_descr_set */
3042 0, /* tp_dictoffset */
3043 0, /* tp_init */
3044 0, /* tp_alloc */
3045 PyType_GenericNew, /* tp_new */
3046 0, /* tp_free */
3050 * PyDateTime_Time implementation.
3053 /* Accessor properties.
3056 static PyObject *
3057 time_hour(PyDateTime_Time *self, void *unused)
3059 return PyInt_FromLong(TIME_GET_HOUR(self));
3062 static PyObject *
3063 time_minute(PyDateTime_Time *self, void *unused)
3065 return PyInt_FromLong(TIME_GET_MINUTE(self));
3068 /* The name time_second conflicted with some platform header file. */
3069 static PyObject *
3070 py_time_second(PyDateTime_Time *self, void *unused)
3072 return PyInt_FromLong(TIME_GET_SECOND(self));
3075 static PyObject *
3076 time_microsecond(PyDateTime_Time *self, void *unused)
3078 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3081 static PyObject *
3082 time_tzinfo(PyDateTime_Time *self, void *unused)
3084 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3085 Py_INCREF(result);
3086 return result;
3089 static PyGetSetDef time_getset[] = {
3090 {"hour", (getter)time_hour},
3091 {"minute", (getter)time_minute},
3092 {"second", (getter)py_time_second},
3093 {"microsecond", (getter)time_microsecond},
3094 {"tzinfo", (getter)time_tzinfo},
3095 {NULL}
3099 * Constructors.
3102 static char *time_kws[] = {"hour", "minute", "second", "microsecond",
3103 "tzinfo", NULL};
3105 static PyObject *
3106 time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3108 PyObject *self = NULL;
3109 PyObject *state;
3110 int hour = 0;
3111 int minute = 0;
3112 int second = 0;
3113 int usecond = 0;
3114 PyObject *tzinfo = Py_None;
3116 /* Check for invocation from pickle with __getstate__ state */
3117 if (PyTuple_GET_SIZE(args) >= 1 &&
3118 PyTuple_GET_SIZE(args) <= 2 &&
3119 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3120 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3121 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
3123 PyDateTime_Time *me;
3124 char aware;
3126 if (PyTuple_GET_SIZE(args) == 2) {
3127 tzinfo = PyTuple_GET_ITEM(args, 1);
3128 if (check_tzinfo_subclass(tzinfo) < 0) {
3129 PyErr_SetString(PyExc_TypeError, "bad "
3130 "tzinfo state arg");
3131 return NULL;
3134 aware = (char)(tzinfo != Py_None);
3135 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3136 if (me != NULL) {
3137 char *pdata = PyString_AS_STRING(state);
3139 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3140 me->hashcode = -1;
3141 me->hastzinfo = aware;
3142 if (aware) {
3143 Py_INCREF(tzinfo);
3144 me->tzinfo = tzinfo;
3147 return (PyObject *)me;
3150 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3151 &hour, &minute, &second, &usecond,
3152 &tzinfo)) {
3153 if (check_time_args(hour, minute, second, usecond) < 0)
3154 return NULL;
3155 if (check_tzinfo_subclass(tzinfo) < 0)
3156 return NULL;
3157 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3158 type);
3160 return self;
3164 * Destructor.
3167 static void
3168 time_dealloc(PyDateTime_Time *self)
3170 if (HASTZINFO(self)) {
3171 Py_XDECREF(self->tzinfo);
3173 Py_TYPE(self)->tp_free((PyObject *)self);
3177 * Indirect access to tzinfo methods.
3180 /* These are all METH_NOARGS, so don't need to check the arglist. */
3181 static PyObject *
3182 time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
3183 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3184 "utcoffset", Py_None);
3187 static PyObject *
3188 time_dst(PyDateTime_Time *self, PyObject *unused) {
3189 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3190 "dst", Py_None);
3193 static PyObject *
3194 time_tzname(PyDateTime_Time *self, PyObject *unused) {
3195 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3196 Py_None);
3200 * Various ways to turn a time into a string.
3203 static PyObject *
3204 time_repr(PyDateTime_Time *self)
3206 char buffer[100];
3207 const char *type_name = Py_TYPE(self)->tp_name;
3208 int h = TIME_GET_HOUR(self);
3209 int m = TIME_GET_MINUTE(self);
3210 int s = TIME_GET_SECOND(self);
3211 int us = TIME_GET_MICROSECOND(self);
3212 PyObject *result = NULL;
3214 if (us)
3215 PyOS_snprintf(buffer, sizeof(buffer),
3216 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
3217 else if (s)
3218 PyOS_snprintf(buffer, sizeof(buffer),
3219 "%s(%d, %d, %d)", type_name, h, m, s);
3220 else
3221 PyOS_snprintf(buffer, sizeof(buffer),
3222 "%s(%d, %d)", type_name, h, m);
3223 result = PyString_FromString(buffer);
3224 if (result != NULL && HASTZINFO(self))
3225 result = append_keyword_tzinfo(result, self->tzinfo);
3226 return result;
3229 static PyObject *
3230 time_str(PyDateTime_Time *self)
3232 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3235 static PyObject *
3236 time_isoformat(PyDateTime_Time *self, PyObject *unused)
3238 char buf[100];
3239 PyObject *result;
3240 /* Reuse the time format code from the datetime type. */
3241 PyDateTime_DateTime datetime;
3242 PyDateTime_DateTime *pdatetime = &datetime;
3244 /* Copy over just the time bytes. */
3245 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3246 self->data,
3247 _PyDateTime_TIME_DATASIZE);
3249 isoformat_time(pdatetime, buf, sizeof(buf));
3250 result = PyString_FromString(buf);
3251 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3252 return result;
3254 /* We need to append the UTC offset. */
3255 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3256 Py_None) < 0) {
3257 Py_DECREF(result);
3258 return NULL;
3260 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3261 return result;
3264 static PyObject *
3265 time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3267 PyObject *result;
3268 PyObject *tuple;
3269 const char *format;
3270 Py_ssize_t format_len;
3271 static char *keywords[] = {"format", NULL};
3273 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3274 &format, &format_len))
3275 return NULL;
3277 /* Python's strftime does insane things with the year part of the
3278 * timetuple. The year is forced to (the otherwise nonsensical)
3279 * 1900 to worm around that.
3281 tuple = Py_BuildValue("iiiiiiiii",
3282 1900, 1, 1, /* year, month, day */
3283 TIME_GET_HOUR(self),
3284 TIME_GET_MINUTE(self),
3285 TIME_GET_SECOND(self),
3286 0, 1, -1); /* weekday, daynum, dst */
3287 if (tuple == NULL)
3288 return NULL;
3289 assert(PyTuple_Size(tuple) == 9);
3290 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3291 Py_None);
3292 Py_DECREF(tuple);
3293 return result;
3297 * Miscellaneous methods.
3300 /* This is more natural as a tp_compare, but doesn't work then: for whatever
3301 * reason, Python's try_3way_compare ignores tp_compare unless
3302 * PyInstance_Check returns true, but these aren't old-style classes.
3304 static PyObject *
3305 time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3307 int diff;
3308 naivety n1, n2;
3309 int offset1, offset2;
3311 if (! PyTime_Check(other)) {
3312 if (op == Py_EQ || op == Py_NE) {
3313 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3314 Py_INCREF(result);
3315 return result;
3317 /* Stop this from falling back to address comparison. */
3318 return cmperror((PyObject *)self, other);
3320 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3321 other, &offset2, &n2, Py_None) < 0)
3322 return NULL;
3323 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3324 /* If they're both naive, or both aware and have the same offsets,
3325 * we get off cheap. Note that if they're both naive, offset1 ==
3326 * offset2 == 0 at this point.
3328 if (n1 == n2 && offset1 == offset2) {
3329 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3330 _PyDateTime_TIME_DATASIZE);
3331 return diff_to_bool(diff, op);
3334 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3335 assert(offset1 != offset2); /* else last "if" handled it */
3336 /* Convert everything except microseconds to seconds. These
3337 * can't overflow (no more than the # of seconds in 2 days).
3339 offset1 = TIME_GET_HOUR(self) * 3600 +
3340 (TIME_GET_MINUTE(self) - offset1) * 60 +
3341 TIME_GET_SECOND(self);
3342 offset2 = TIME_GET_HOUR(other) * 3600 +
3343 (TIME_GET_MINUTE(other) - offset2) * 60 +
3344 TIME_GET_SECOND(other);
3345 diff = offset1 - offset2;
3346 if (diff == 0)
3347 diff = TIME_GET_MICROSECOND(self) -
3348 TIME_GET_MICROSECOND(other);
3349 return diff_to_bool(diff, op);
3352 assert(n1 != n2);
3353 PyErr_SetString(PyExc_TypeError,
3354 "can't compare offset-naive and "
3355 "offset-aware times");
3356 return NULL;
3359 static long
3360 time_hash(PyDateTime_Time *self)
3362 if (self->hashcode == -1) {
3363 naivety n;
3364 int offset;
3365 PyObject *temp;
3367 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3368 assert(n != OFFSET_UNKNOWN);
3369 if (n == OFFSET_ERROR)
3370 return -1;
3372 /* Reduce this to a hash of another object. */
3373 if (offset == 0)
3374 temp = PyString_FromStringAndSize((char *)self->data,
3375 _PyDateTime_TIME_DATASIZE);
3376 else {
3377 int hour;
3378 int minute;
3380 assert(n == OFFSET_AWARE);
3381 assert(HASTZINFO(self));
3382 hour = divmod(TIME_GET_HOUR(self) * 60 +
3383 TIME_GET_MINUTE(self) - offset,
3385 &minute);
3386 if (0 <= hour && hour < 24)
3387 temp = new_time(hour, minute,
3388 TIME_GET_SECOND(self),
3389 TIME_GET_MICROSECOND(self),
3390 Py_None);
3391 else
3392 temp = Py_BuildValue("iiii",
3393 hour, minute,
3394 TIME_GET_SECOND(self),
3395 TIME_GET_MICROSECOND(self));
3397 if (temp != NULL) {
3398 self->hashcode = PyObject_Hash(temp);
3399 Py_DECREF(temp);
3402 return self->hashcode;
3405 static PyObject *
3406 time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3408 PyObject *clone;
3409 PyObject *tuple;
3410 int hh = TIME_GET_HOUR(self);
3411 int mm = TIME_GET_MINUTE(self);
3412 int ss = TIME_GET_SECOND(self);
3413 int us = TIME_GET_MICROSECOND(self);
3414 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
3416 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3417 time_kws,
3418 &hh, &mm, &ss, &us, &tzinfo))
3419 return NULL;
3420 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3421 if (tuple == NULL)
3422 return NULL;
3423 clone = time_new(Py_TYPE(self), tuple, NULL);
3424 Py_DECREF(tuple);
3425 return clone;
3428 static int
3429 time_nonzero(PyDateTime_Time *self)
3431 int offset;
3432 int none;
3434 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3435 /* Since utcoffset is in whole minutes, nothing can
3436 * alter the conclusion that this is nonzero.
3438 return 1;
3440 offset = 0;
3441 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3442 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3443 if (offset == -1 && PyErr_Occurred())
3444 return -1;
3446 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3449 /* Pickle support, a simple use of __reduce__. */
3451 /* Let basestate be the non-tzinfo data string.
3452 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3453 * So it's a tuple in any (non-error) case.
3454 * __getstate__ isn't exposed.
3456 static PyObject *
3457 time_getstate(PyDateTime_Time *self)
3459 PyObject *basestate;
3460 PyObject *result = NULL;
3462 basestate = PyString_FromStringAndSize((char *)self->data,
3463 _PyDateTime_TIME_DATASIZE);
3464 if (basestate != NULL) {
3465 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3466 result = PyTuple_Pack(1, basestate);
3467 else
3468 result = PyTuple_Pack(2, basestate, self->tzinfo);
3469 Py_DECREF(basestate);
3471 return result;
3474 static PyObject *
3475 time_reduce(PyDateTime_Time *self, PyObject *arg)
3477 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
3480 static PyMethodDef time_methods[] = {
3482 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3483 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3484 "[+HH:MM].")},
3486 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3487 PyDoc_STR("format -> strftime() style string.")},
3489 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3490 PyDoc_STR("Formats self with strftime.")},
3492 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3493 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3495 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3496 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3498 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3499 PyDoc_STR("Return self.tzinfo.dst(self).")},
3501 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3502 PyDoc_STR("Return time with new specified fields.")},
3504 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3505 PyDoc_STR("__reduce__() -> (cls, state)")},
3507 {NULL, NULL}
3510 static char time_doc[] =
3511 PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3513 All arguments are optional. tzinfo may be None, or an instance of\n\
3514 a tzinfo subclass. The remaining arguments may be ints or longs.\n");
3516 static PyNumberMethods time_as_number = {
3517 0, /* nb_add */
3518 0, /* nb_subtract */
3519 0, /* nb_multiply */
3520 0, /* nb_divide */
3521 0, /* nb_remainder */
3522 0, /* nb_divmod */
3523 0, /* nb_power */
3524 0, /* nb_negative */
3525 0, /* nb_positive */
3526 0, /* nb_absolute */
3527 (inquiry)time_nonzero, /* nb_nonzero */
3530 statichere PyTypeObject PyDateTime_TimeType = {
3531 PyObject_HEAD_INIT(NULL)
3532 0, /* ob_size */
3533 "datetime.time", /* tp_name */
3534 sizeof(PyDateTime_Time), /* tp_basicsize */
3535 0, /* tp_itemsize */
3536 (destructor)time_dealloc, /* tp_dealloc */
3537 0, /* tp_print */
3538 0, /* tp_getattr */
3539 0, /* tp_setattr */
3540 0, /* tp_compare */
3541 (reprfunc)time_repr, /* tp_repr */
3542 &time_as_number, /* tp_as_number */
3543 0, /* tp_as_sequence */
3544 0, /* tp_as_mapping */
3545 (hashfunc)time_hash, /* tp_hash */
3546 0, /* tp_call */
3547 (reprfunc)time_str, /* tp_str */
3548 PyObject_GenericGetAttr, /* tp_getattro */
3549 0, /* tp_setattro */
3550 0, /* tp_as_buffer */
3551 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3552 Py_TPFLAGS_BASETYPE, /* tp_flags */
3553 time_doc, /* tp_doc */
3554 0, /* tp_traverse */
3555 0, /* tp_clear */
3556 (richcmpfunc)time_richcompare, /* tp_richcompare */
3557 0, /* tp_weaklistoffset */
3558 0, /* tp_iter */
3559 0, /* tp_iternext */
3560 time_methods, /* tp_methods */
3561 0, /* tp_members */
3562 time_getset, /* tp_getset */
3563 0, /* tp_base */
3564 0, /* tp_dict */
3565 0, /* tp_descr_get */
3566 0, /* tp_descr_set */
3567 0, /* tp_dictoffset */
3568 0, /* tp_init */
3569 time_alloc, /* tp_alloc */
3570 time_new, /* tp_new */
3571 0, /* tp_free */
3575 * PyDateTime_DateTime implementation.
3578 /* Accessor properties. Properties for day, month, and year are inherited
3579 * from date.
3582 static PyObject *
3583 datetime_hour(PyDateTime_DateTime *self, void *unused)
3585 return PyInt_FromLong(DATE_GET_HOUR(self));
3588 static PyObject *
3589 datetime_minute(PyDateTime_DateTime *self, void *unused)
3591 return PyInt_FromLong(DATE_GET_MINUTE(self));
3594 static PyObject *
3595 datetime_second(PyDateTime_DateTime *self, void *unused)
3597 return PyInt_FromLong(DATE_GET_SECOND(self));
3600 static PyObject *
3601 datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3603 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3606 static PyObject *
3607 datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3609 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3610 Py_INCREF(result);
3611 return result;
3614 static PyGetSetDef datetime_getset[] = {
3615 {"hour", (getter)datetime_hour},
3616 {"minute", (getter)datetime_minute},
3617 {"second", (getter)datetime_second},
3618 {"microsecond", (getter)datetime_microsecond},
3619 {"tzinfo", (getter)datetime_tzinfo},
3620 {NULL}
3624 * Constructors.
3627 static char *datetime_kws[] = {
3628 "year", "month", "day", "hour", "minute", "second",
3629 "microsecond", "tzinfo", NULL
3632 static PyObject *
3633 datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3635 PyObject *self = NULL;
3636 PyObject *state;
3637 int year;
3638 int month;
3639 int day;
3640 int hour = 0;
3641 int minute = 0;
3642 int second = 0;
3643 int usecond = 0;
3644 PyObject *tzinfo = Py_None;
3646 /* Check for invocation from pickle with __getstate__ state */
3647 if (PyTuple_GET_SIZE(args) >= 1 &&
3648 PyTuple_GET_SIZE(args) <= 2 &&
3649 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3650 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3651 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
3653 PyDateTime_DateTime *me;
3654 char aware;
3656 if (PyTuple_GET_SIZE(args) == 2) {
3657 tzinfo = PyTuple_GET_ITEM(args, 1);
3658 if (check_tzinfo_subclass(tzinfo) < 0) {
3659 PyErr_SetString(PyExc_TypeError, "bad "
3660 "tzinfo state arg");
3661 return NULL;
3664 aware = (char)(tzinfo != Py_None);
3665 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3666 if (me != NULL) {
3667 char *pdata = PyString_AS_STRING(state);
3669 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3670 me->hashcode = -1;
3671 me->hastzinfo = aware;
3672 if (aware) {
3673 Py_INCREF(tzinfo);
3674 me->tzinfo = tzinfo;
3677 return (PyObject *)me;
3680 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3681 &year, &month, &day, &hour, &minute,
3682 &second, &usecond, &tzinfo)) {
3683 if (check_date_args(year, month, day) < 0)
3684 return NULL;
3685 if (check_time_args(hour, minute, second, usecond) < 0)
3686 return NULL;
3687 if (check_tzinfo_subclass(tzinfo) < 0)
3688 return NULL;
3689 self = new_datetime_ex(year, month, day,
3690 hour, minute, second, usecond,
3691 tzinfo, type);
3693 return self;
3696 /* TM_FUNC is the shared type of localtime() and gmtime(). */
3697 typedef struct tm *(*TM_FUNC)(const time_t *timer);
3699 /* Internal helper.
3700 * Build datetime from a time_t and a distinct count of microseconds.
3701 * Pass localtime or gmtime for f, to control the interpretation of timet.
3703 static PyObject *
3704 datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3705 PyObject *tzinfo)
3707 struct tm *tm;
3708 PyObject *result = NULL;
3710 tm = f(&timet);
3711 if (tm) {
3712 /* The platform localtime/gmtime may insert leap seconds,
3713 * indicated by tm->tm_sec > 59. We don't care about them,
3714 * except to the extent that passing them on to the datetime
3715 * constructor would raise ValueError for a reason that
3716 * made no sense to the user.
3718 if (tm->tm_sec > 59)
3719 tm->tm_sec = 59;
3720 result = PyObject_CallFunction(cls, "iiiiiiiO",
3721 tm->tm_year + 1900,
3722 tm->tm_mon + 1,
3723 tm->tm_mday,
3724 tm->tm_hour,
3725 tm->tm_min,
3726 tm->tm_sec,
3728 tzinfo);
3730 else
3731 PyErr_SetString(PyExc_ValueError,
3732 "timestamp out of range for "
3733 "platform localtime()/gmtime() function");
3734 return result;
3737 /* Internal helper.
3738 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3739 * to control the interpretation of the timestamp. Since a double doesn't
3740 * have enough bits to cover a datetime's full range of precision, it's
3741 * better to call datetime_from_timet_and_us provided you have a way
3742 * to get that much precision (e.g., C time() isn't good enough).
3744 static PyObject *
3745 datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3746 PyObject *tzinfo)
3748 time_t timet;
3749 double fraction;
3750 int us;
3752 timet = _PyTime_DoubleToTimet(timestamp);
3753 if (timet == (time_t)-1 && PyErr_Occurred())
3754 return NULL;
3755 fraction = timestamp - (double)timet;
3756 us = (int)round_to_long(fraction * 1e6);
3757 if (us < 0) {
3758 /* Truncation towards zero is not what we wanted
3759 for negative numbers (Python's mod semantics) */
3760 timet -= 1;
3761 us += 1000000;
3763 /* If timestamp is less than one microsecond smaller than a
3764 * full second, round up. Otherwise, ValueErrors are raised
3765 * for some floats. */
3766 if (us == 1000000) {
3767 timet += 1;
3768 us = 0;
3770 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3773 /* Internal helper.
3774 * Build most accurate possible datetime for current time. Pass localtime or
3775 * gmtime for f as appropriate.
3777 static PyObject *
3778 datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3780 #ifdef HAVE_GETTIMEOFDAY
3781 struct timeval t;
3783 #ifdef GETTIMEOFDAY_NO_TZ
3784 gettimeofday(&t);
3785 #else
3786 gettimeofday(&t, (struct timezone *)NULL);
3787 #endif
3788 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3789 tzinfo);
3791 #else /* ! HAVE_GETTIMEOFDAY */
3792 /* No flavor of gettimeofday exists on this platform. Python's
3793 * time.time() does a lot of other platform tricks to get the
3794 * best time it can on the platform, and we're not going to do
3795 * better than that (if we could, the better code would belong
3796 * in time.time()!) We're limited by the precision of a double,
3797 * though.
3799 PyObject *time;
3800 double dtime;
3802 time = time_time();
3803 if (time == NULL)
3804 return NULL;
3805 dtime = PyFloat_AsDouble(time);
3806 Py_DECREF(time);
3807 if (dtime == -1.0 && PyErr_Occurred())
3808 return NULL;
3809 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3810 #endif /* ! HAVE_GETTIMEOFDAY */
3813 /* Return best possible local time -- this isn't constrained by the
3814 * precision of a timestamp.
3816 static PyObject *
3817 datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
3819 PyObject *self;
3820 PyObject *tzinfo = Py_None;
3821 static char *keywords[] = {"tz", NULL};
3823 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3824 &tzinfo))
3825 return NULL;
3826 if (check_tzinfo_subclass(tzinfo) < 0)
3827 return NULL;
3829 self = datetime_best_possible(cls,
3830 tzinfo == Py_None ? localtime : gmtime,
3831 tzinfo);
3832 if (self != NULL && tzinfo != Py_None) {
3833 /* Convert UTC to tzinfo's zone. */
3834 PyObject *temp = self;
3835 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3836 Py_DECREF(temp);
3838 return self;
3841 /* Return best possible UTC time -- this isn't constrained by the
3842 * precision of a timestamp.
3844 static PyObject *
3845 datetime_utcnow(PyObject *cls, PyObject *dummy)
3847 return datetime_best_possible(cls, gmtime, Py_None);
3850 /* Return new local datetime from timestamp (Python timestamp -- a double). */
3851 static PyObject *
3852 datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
3854 PyObject *self;
3855 double timestamp;
3856 PyObject *tzinfo = Py_None;
3857 static char *keywords[] = {"timestamp", "tz", NULL};
3859 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3860 keywords, &timestamp, &tzinfo))
3861 return NULL;
3862 if (check_tzinfo_subclass(tzinfo) < 0)
3863 return NULL;
3865 self = datetime_from_timestamp(cls,
3866 tzinfo == Py_None ? localtime : gmtime,
3867 timestamp,
3868 tzinfo);
3869 if (self != NULL && tzinfo != Py_None) {
3870 /* Convert UTC to tzinfo's zone. */
3871 PyObject *temp = self;
3872 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3873 Py_DECREF(temp);
3875 return self;
3878 /* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3879 static PyObject *
3880 datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3882 double timestamp;
3883 PyObject *result = NULL;
3885 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3886 result = datetime_from_timestamp(cls, gmtime, timestamp,
3887 Py_None);
3888 return result;
3891 /* Return new datetime from time.strptime(). */
3892 static PyObject *
3893 datetime_strptime(PyObject *cls, PyObject *args)
3895 static PyObject *module = NULL;
3896 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3897 const char *string, *format;
3899 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3900 return NULL;
3902 if (module == NULL &&
3903 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3904 return NULL;
3906 /* _strptime._strptime returns a two-element tuple. The first
3907 element is a time.struct_time object. The second is the
3908 microseconds (which are not defined for time.struct_time). */
3909 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
3910 if (obj != NULL) {
3911 int i, good_timetuple = 1;
3912 long int ia[7];
3913 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3914 st = PySequence_GetItem(obj, 0);
3915 frac = PySequence_GetItem(obj, 1);
3916 if (st == NULL || frac == NULL)
3917 good_timetuple = 0;
3918 /* copy y/m/d/h/m/s values out of the
3919 time.struct_time */
3920 if (good_timetuple &&
3921 PySequence_Check(st) &&
3922 PySequence_Size(st) >= 6) {
3923 for (i=0; i < 6; i++) {
3924 PyObject *p = PySequence_GetItem(st, i);
3925 if (p == NULL) {
3926 good_timetuple = 0;
3927 break;
3929 if (PyInt_Check(p))
3930 ia[i] = PyInt_AsLong(p);
3931 else
3932 good_timetuple = 0;
3933 Py_DECREF(p);
3936 else
3937 good_timetuple = 0;
3938 /* follow that up with a little dose of microseconds */
3939 if (PyInt_Check(frac))
3940 ia[6] = PyInt_AsLong(frac);
3941 else
3942 good_timetuple = 0;
3944 else
3945 good_timetuple = 0;
3946 if (good_timetuple)
3947 result = PyObject_CallFunction(cls, "iiiiiii",
3948 ia[0], ia[1], ia[2],
3949 ia[3], ia[4], ia[5],
3950 ia[6]);
3951 else
3952 PyErr_SetString(PyExc_ValueError,
3953 "unexpected value from _strptime._strptime");
3955 Py_XDECREF(obj);
3956 Py_XDECREF(st);
3957 Py_XDECREF(frac);
3958 return result;
3961 /* Return new datetime from date/datetime and time arguments. */
3962 static PyObject *
3963 datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3965 static char *keywords[] = {"date", "time", NULL};
3966 PyObject *date;
3967 PyObject *time;
3968 PyObject *result = NULL;
3970 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3971 &PyDateTime_DateType, &date,
3972 &PyDateTime_TimeType, &time)) {
3973 PyObject *tzinfo = Py_None;
3975 if (HASTZINFO(time))
3976 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3977 result = PyObject_CallFunction(cls, "iiiiiiiO",
3978 GET_YEAR(date),
3979 GET_MONTH(date),
3980 GET_DAY(date),
3981 TIME_GET_HOUR(time),
3982 TIME_GET_MINUTE(time),
3983 TIME_GET_SECOND(time),
3984 TIME_GET_MICROSECOND(time),
3985 tzinfo);
3987 return result;
3991 * Destructor.
3994 static void
3995 datetime_dealloc(PyDateTime_DateTime *self)
3997 if (HASTZINFO(self)) {
3998 Py_XDECREF(self->tzinfo);
4000 Py_TYPE(self)->tp_free((PyObject *)self);
4004 * Indirect access to tzinfo methods.
4007 /* These are all METH_NOARGS, so don't need to check the arglist. */
4008 static PyObject *
4009 datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
4010 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4011 "utcoffset", (PyObject *)self);
4014 static PyObject *
4015 datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
4016 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4017 "dst", (PyObject *)self);
4020 static PyObject *
4021 datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
4022 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4023 (PyObject *)self);
4027 * datetime arithmetic.
4030 /* factor must be 1 (to add) or -1 (to subtract). The result inherits
4031 * the tzinfo state of date.
4033 static PyObject *
4034 add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4035 int factor)
4037 /* Note that the C-level additions can't overflow, because of
4038 * invariant bounds on the member values.
4040 int year = GET_YEAR(date);
4041 int month = GET_MONTH(date);
4042 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4043 int hour = DATE_GET_HOUR(date);
4044 int minute = DATE_GET_MINUTE(date);
4045 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4046 int microsecond = DATE_GET_MICROSECOND(date) +
4047 GET_TD_MICROSECONDS(delta) * factor;
4049 assert(factor == 1 || factor == -1);
4050 if (normalize_datetime(&year, &month, &day,
4051 &hour, &minute, &second, &microsecond) < 0)
4052 return NULL;
4053 else
4054 return new_datetime(year, month, day,
4055 hour, minute, second, microsecond,
4056 HASTZINFO(date) ? date->tzinfo : Py_None);
4059 static PyObject *
4060 datetime_add(PyObject *left, PyObject *right)
4062 if (PyDateTime_Check(left)) {
4063 /* datetime + ??? */
4064 if (PyDelta_Check(right))
4065 /* datetime + delta */
4066 return add_datetime_timedelta(
4067 (PyDateTime_DateTime *)left,
4068 (PyDateTime_Delta *)right,
4071 else if (PyDelta_Check(left)) {
4072 /* delta + datetime */
4073 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4074 (PyDateTime_Delta *) left,
4077 Py_INCREF(Py_NotImplemented);
4078 return Py_NotImplemented;
4081 static PyObject *
4082 datetime_subtract(PyObject *left, PyObject *right)
4084 PyObject *result = Py_NotImplemented;
4086 if (PyDateTime_Check(left)) {
4087 /* datetime - ??? */
4088 if (PyDateTime_Check(right)) {
4089 /* datetime - datetime */
4090 naivety n1, n2;
4091 int offset1, offset2;
4092 int delta_d, delta_s, delta_us;
4094 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4095 right, &offset2, &n2,
4096 right) < 0)
4097 return NULL;
4098 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4099 if (n1 != n2) {
4100 PyErr_SetString(PyExc_TypeError,
4101 "can't subtract offset-naive and "
4102 "offset-aware datetimes");
4103 return NULL;
4105 delta_d = ymd_to_ord(GET_YEAR(left),
4106 GET_MONTH(left),
4107 GET_DAY(left)) -
4108 ymd_to_ord(GET_YEAR(right),
4109 GET_MONTH(right),
4110 GET_DAY(right));
4111 /* These can't overflow, since the values are
4112 * normalized. At most this gives the number of
4113 * seconds in one day.
4115 delta_s = (DATE_GET_HOUR(left) -
4116 DATE_GET_HOUR(right)) * 3600 +
4117 (DATE_GET_MINUTE(left) -
4118 DATE_GET_MINUTE(right)) * 60 +
4119 (DATE_GET_SECOND(left) -
4120 DATE_GET_SECOND(right));
4121 delta_us = DATE_GET_MICROSECOND(left) -
4122 DATE_GET_MICROSECOND(right);
4123 /* (left - offset1) - (right - offset2) =
4124 * (left - right) + (offset2 - offset1)
4126 delta_s += (offset2 - offset1) * 60;
4127 result = new_delta(delta_d, delta_s, delta_us, 1);
4129 else if (PyDelta_Check(right)) {
4130 /* datetime - delta */
4131 result = add_datetime_timedelta(
4132 (PyDateTime_DateTime *)left,
4133 (PyDateTime_Delta *)right,
4134 -1);
4138 if (result == Py_NotImplemented)
4139 Py_INCREF(result);
4140 return result;
4143 /* Various ways to turn a datetime into a string. */
4145 static PyObject *
4146 datetime_repr(PyDateTime_DateTime *self)
4148 char buffer[1000];
4149 const char *type_name = Py_TYPE(self)->tp_name;
4150 PyObject *baserepr;
4152 if (DATE_GET_MICROSECOND(self)) {
4153 PyOS_snprintf(buffer, sizeof(buffer),
4154 "%s(%d, %d, %d, %d, %d, %d, %d)",
4155 type_name,
4156 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4157 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4158 DATE_GET_SECOND(self),
4159 DATE_GET_MICROSECOND(self));
4161 else if (DATE_GET_SECOND(self)) {
4162 PyOS_snprintf(buffer, sizeof(buffer),
4163 "%s(%d, %d, %d, %d, %d, %d)",
4164 type_name,
4165 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4166 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4167 DATE_GET_SECOND(self));
4169 else {
4170 PyOS_snprintf(buffer, sizeof(buffer),
4171 "%s(%d, %d, %d, %d, %d)",
4172 type_name,
4173 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4174 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4176 baserepr = PyString_FromString(buffer);
4177 if (baserepr == NULL || ! HASTZINFO(self))
4178 return baserepr;
4179 return append_keyword_tzinfo(baserepr, self->tzinfo);
4182 static PyObject *
4183 datetime_str(PyDateTime_DateTime *self)
4185 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4188 static PyObject *
4189 datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4191 char sep = 'T';
4192 static char *keywords[] = {"sep", NULL};
4193 char buffer[100];
4194 char *cp;
4195 PyObject *result;
4197 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4198 &sep))
4199 return NULL;
4200 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4201 assert(cp != NULL);
4202 *cp++ = sep;
4203 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4204 result = PyString_FromString(buffer);
4205 if (result == NULL || ! HASTZINFO(self))
4206 return result;
4208 /* We need to append the UTC offset. */
4209 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4210 (PyObject *)self) < 0) {
4211 Py_DECREF(result);
4212 return NULL;
4214 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
4215 return result;
4218 static PyObject *
4219 datetime_ctime(PyDateTime_DateTime *self)
4221 return format_ctime((PyDateTime_Date *)self,
4222 DATE_GET_HOUR(self),
4223 DATE_GET_MINUTE(self),
4224 DATE_GET_SECOND(self));
4227 /* Miscellaneous methods. */
4229 /* This is more natural as a tp_compare, but doesn't work then: for whatever
4230 * reason, Python's try_3way_compare ignores tp_compare unless
4231 * PyInstance_Check returns true, but these aren't old-style classes.
4233 static PyObject *
4234 datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4236 int diff;
4237 naivety n1, n2;
4238 int offset1, offset2;
4240 if (! PyDateTime_Check(other)) {
4241 /* If other has a "timetuple" attr, that's an advertised
4242 * hook for other classes to ask to get comparison control.
4243 * However, date instances have a timetuple attr, and we
4244 * don't want to allow that comparison. Because datetime
4245 * is a subclass of date, when mixing date and datetime
4246 * in a comparison, Python gives datetime the first shot
4247 * (it's the more specific subtype). So we can stop that
4248 * combination here reliably.
4250 if (PyObject_HasAttrString(other, "timetuple") &&
4251 ! PyDate_Check(other)) {
4252 /* A hook for other kinds of datetime objects. */
4253 Py_INCREF(Py_NotImplemented);
4254 return Py_NotImplemented;
4256 if (op == Py_EQ || op == Py_NE) {
4257 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4258 Py_INCREF(result);
4259 return result;
4261 /* Stop this from falling back to address comparison. */
4262 return cmperror((PyObject *)self, other);
4265 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4266 (PyObject *)self,
4267 other, &offset2, &n2,
4268 other) < 0)
4269 return NULL;
4270 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4271 /* If they're both naive, or both aware and have the same offsets,
4272 * we get off cheap. Note that if they're both naive, offset1 ==
4273 * offset2 == 0 at this point.
4275 if (n1 == n2 && offset1 == offset2) {
4276 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4277 _PyDateTime_DATETIME_DATASIZE);
4278 return diff_to_bool(diff, op);
4281 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4282 PyDateTime_Delta *delta;
4284 assert(offset1 != offset2); /* else last "if" handled it */
4285 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4286 other);
4287 if (delta == NULL)
4288 return NULL;
4289 diff = GET_TD_DAYS(delta);
4290 if (diff == 0)
4291 diff = GET_TD_SECONDS(delta) |
4292 GET_TD_MICROSECONDS(delta);
4293 Py_DECREF(delta);
4294 return diff_to_bool(diff, op);
4297 assert(n1 != n2);
4298 PyErr_SetString(PyExc_TypeError,
4299 "can't compare offset-naive and "
4300 "offset-aware datetimes");
4301 return NULL;
4304 static long
4305 datetime_hash(PyDateTime_DateTime *self)
4307 if (self->hashcode == -1) {
4308 naivety n;
4309 int offset;
4310 PyObject *temp;
4312 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4313 &offset);
4314 assert(n != OFFSET_UNKNOWN);
4315 if (n == OFFSET_ERROR)
4316 return -1;
4318 /* Reduce this to a hash of another object. */
4319 if (n == OFFSET_NAIVE)
4320 temp = PyString_FromStringAndSize(
4321 (char *)self->data,
4322 _PyDateTime_DATETIME_DATASIZE);
4323 else {
4324 int days;
4325 int seconds;
4327 assert(n == OFFSET_AWARE);
4328 assert(HASTZINFO(self));
4329 days = ymd_to_ord(GET_YEAR(self),
4330 GET_MONTH(self),
4331 GET_DAY(self));
4332 seconds = DATE_GET_HOUR(self) * 3600 +
4333 (DATE_GET_MINUTE(self) - offset) * 60 +
4334 DATE_GET_SECOND(self);
4335 temp = new_delta(days,
4336 seconds,
4337 DATE_GET_MICROSECOND(self),
4340 if (temp != NULL) {
4341 self->hashcode = PyObject_Hash(temp);
4342 Py_DECREF(temp);
4345 return self->hashcode;
4348 static PyObject *
4349 datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4351 PyObject *clone;
4352 PyObject *tuple;
4353 int y = GET_YEAR(self);
4354 int m = GET_MONTH(self);
4355 int d = GET_DAY(self);
4356 int hh = DATE_GET_HOUR(self);
4357 int mm = DATE_GET_MINUTE(self);
4358 int ss = DATE_GET_SECOND(self);
4359 int us = DATE_GET_MICROSECOND(self);
4360 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
4362 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4363 datetime_kws,
4364 &y, &m, &d, &hh, &mm, &ss, &us,
4365 &tzinfo))
4366 return NULL;
4367 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4368 if (tuple == NULL)
4369 return NULL;
4370 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4371 Py_DECREF(tuple);
4372 return clone;
4375 static PyObject *
4376 datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4378 int y, m, d, hh, mm, ss, us;
4379 PyObject *result;
4380 int offset, none;
4382 PyObject *tzinfo;
4383 static char *keywords[] = {"tz", NULL};
4385 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4386 &PyDateTime_TZInfoType, &tzinfo))
4387 return NULL;
4389 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4390 goto NeedAware;
4392 /* Conversion to self's own time zone is a NOP. */
4393 if (self->tzinfo == tzinfo) {
4394 Py_INCREF(self);
4395 return (PyObject *)self;
4398 /* Convert self to UTC. */
4399 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4400 if (offset == -1 && PyErr_Occurred())
4401 return NULL;
4402 if (none)
4403 goto NeedAware;
4405 y = GET_YEAR(self);
4406 m = GET_MONTH(self);
4407 d = GET_DAY(self);
4408 hh = DATE_GET_HOUR(self);
4409 mm = DATE_GET_MINUTE(self);
4410 ss = DATE_GET_SECOND(self);
4411 us = DATE_GET_MICROSECOND(self);
4413 mm -= offset;
4414 if ((mm < 0 || mm >= 60) &&
4415 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4416 return NULL;
4418 /* Attach new tzinfo and let fromutc() do the rest. */
4419 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4420 if (result != NULL) {
4421 PyObject *temp = result;
4423 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4424 Py_DECREF(temp);
4426 return result;
4428 NeedAware:
4429 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4430 "a naive datetime");
4431 return NULL;
4434 static PyObject *
4435 datetime_timetuple(PyDateTime_DateTime *self)
4437 int dstflag = -1;
4439 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4440 int none;
4442 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4443 if (dstflag == -1 && PyErr_Occurred())
4444 return NULL;
4446 if (none)
4447 dstflag = -1;
4448 else if (dstflag != 0)
4449 dstflag = 1;
4452 return build_struct_time(GET_YEAR(self),
4453 GET_MONTH(self),
4454 GET_DAY(self),
4455 DATE_GET_HOUR(self),
4456 DATE_GET_MINUTE(self),
4457 DATE_GET_SECOND(self),
4458 dstflag);
4461 static PyObject *
4462 datetime_getdate(PyDateTime_DateTime *self)
4464 return new_date(GET_YEAR(self),
4465 GET_MONTH(self),
4466 GET_DAY(self));
4469 static PyObject *
4470 datetime_gettime(PyDateTime_DateTime *self)
4472 return new_time(DATE_GET_HOUR(self),
4473 DATE_GET_MINUTE(self),
4474 DATE_GET_SECOND(self),
4475 DATE_GET_MICROSECOND(self),
4476 Py_None);
4479 static PyObject *
4480 datetime_gettimetz(PyDateTime_DateTime *self)
4482 return new_time(DATE_GET_HOUR(self),
4483 DATE_GET_MINUTE(self),
4484 DATE_GET_SECOND(self),
4485 DATE_GET_MICROSECOND(self),
4486 HASTZINFO(self) ? self->tzinfo : Py_None);
4489 static PyObject *
4490 datetime_utctimetuple(PyDateTime_DateTime *self)
4492 int y = GET_YEAR(self);
4493 int m = GET_MONTH(self);
4494 int d = GET_DAY(self);
4495 int hh = DATE_GET_HOUR(self);
4496 int mm = DATE_GET_MINUTE(self);
4497 int ss = DATE_GET_SECOND(self);
4498 int us = 0; /* microseconds are ignored in a timetuple */
4499 int offset = 0;
4501 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4502 int none;
4504 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4505 if (offset == -1 && PyErr_Occurred())
4506 return NULL;
4508 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4509 * 0 in a UTC timetuple regardless of what dst() says.
4511 if (offset) {
4512 /* Subtract offset minutes & normalize. */
4513 int stat;
4515 mm -= offset;
4516 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4517 if (stat < 0) {
4518 /* At the edges, it's possible we overflowed
4519 * beyond MINYEAR or MAXYEAR.
4521 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4522 PyErr_Clear();
4523 else
4524 return NULL;
4527 return build_struct_time(y, m, d, hh, mm, ss, 0);
4530 /* Pickle support, a simple use of __reduce__. */
4532 /* Let basestate be the non-tzinfo data string.
4533 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4534 * So it's a tuple in any (non-error) case.
4535 * __getstate__ isn't exposed.
4537 static PyObject *
4538 datetime_getstate(PyDateTime_DateTime *self)
4540 PyObject *basestate;
4541 PyObject *result = NULL;
4543 basestate = PyString_FromStringAndSize((char *)self->data,
4544 _PyDateTime_DATETIME_DATASIZE);
4545 if (basestate != NULL) {
4546 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4547 result = PyTuple_Pack(1, basestate);
4548 else
4549 result = PyTuple_Pack(2, basestate, self->tzinfo);
4550 Py_DECREF(basestate);
4552 return result;
4555 static PyObject *
4556 datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
4558 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
4561 static PyMethodDef datetime_methods[] = {
4563 /* Class methods: */
4565 {"now", (PyCFunction)datetime_now,
4566 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4567 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4569 {"utcnow", (PyCFunction)datetime_utcnow,
4570 METH_NOARGS | METH_CLASS,
4571 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4573 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4574 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4575 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4577 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4578 METH_VARARGS | METH_CLASS,
4579 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4580 "(like time.time()).")},
4582 {"strptime", (PyCFunction)datetime_strptime,
4583 METH_VARARGS | METH_CLASS,
4584 PyDoc_STR("string, format -> new datetime parsed from a string "
4585 "(like time.strptime()).")},
4587 {"combine", (PyCFunction)datetime_combine,
4588 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4589 PyDoc_STR("date, time -> datetime with same date and time fields")},
4591 /* Instance methods: */
4593 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4594 PyDoc_STR("Return date object with same year, month and day.")},
4596 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4597 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4599 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4600 PyDoc_STR("Return time object with same time and tzinfo.")},
4602 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4603 PyDoc_STR("Return ctime() style string.")},
4605 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4606 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4608 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4609 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4611 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4612 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4613 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4614 "sep is used to separate the year from the time, and "
4615 "defaults to 'T'.")},
4617 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4618 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4620 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4621 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4623 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4624 PyDoc_STR("Return self.tzinfo.dst(self).")},
4626 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4627 PyDoc_STR("Return datetime with new specified fields.")},
4629 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4630 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4632 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4633 PyDoc_STR("__reduce__() -> (cls, state)")},
4635 {NULL, NULL}
4638 static char datetime_doc[] =
4639 PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4641 The year, month and day arguments are required. tzinfo may be None, or an\n\
4642 instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
4644 static PyNumberMethods datetime_as_number = {
4645 datetime_add, /* nb_add */
4646 datetime_subtract, /* nb_subtract */
4647 0, /* nb_multiply */
4648 0, /* nb_divide */
4649 0, /* nb_remainder */
4650 0, /* nb_divmod */
4651 0, /* nb_power */
4652 0, /* nb_negative */
4653 0, /* nb_positive */
4654 0, /* nb_absolute */
4655 0, /* nb_nonzero */
4658 statichere PyTypeObject PyDateTime_DateTimeType = {
4659 PyObject_HEAD_INIT(NULL)
4660 0, /* ob_size */
4661 "datetime.datetime", /* tp_name */
4662 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4663 0, /* tp_itemsize */
4664 (destructor)datetime_dealloc, /* tp_dealloc */
4665 0, /* tp_print */
4666 0, /* tp_getattr */
4667 0, /* tp_setattr */
4668 0, /* tp_compare */
4669 (reprfunc)datetime_repr, /* tp_repr */
4670 &datetime_as_number, /* tp_as_number */
4671 0, /* tp_as_sequence */
4672 0, /* tp_as_mapping */
4673 (hashfunc)datetime_hash, /* tp_hash */
4674 0, /* tp_call */
4675 (reprfunc)datetime_str, /* tp_str */
4676 PyObject_GenericGetAttr, /* tp_getattro */
4677 0, /* tp_setattro */
4678 0, /* tp_as_buffer */
4679 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4680 Py_TPFLAGS_BASETYPE, /* tp_flags */
4681 datetime_doc, /* tp_doc */
4682 0, /* tp_traverse */
4683 0, /* tp_clear */
4684 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
4685 0, /* tp_weaklistoffset */
4686 0, /* tp_iter */
4687 0, /* tp_iternext */
4688 datetime_methods, /* tp_methods */
4689 0, /* tp_members */
4690 datetime_getset, /* tp_getset */
4691 &PyDateTime_DateType, /* tp_base */
4692 0, /* tp_dict */
4693 0, /* tp_descr_get */
4694 0, /* tp_descr_set */
4695 0, /* tp_dictoffset */
4696 0, /* tp_init */
4697 datetime_alloc, /* tp_alloc */
4698 datetime_new, /* tp_new */
4699 0, /* tp_free */
4702 /* ---------------------------------------------------------------------------
4703 * Module methods and initialization.
4706 static PyMethodDef module_methods[] = {
4707 {NULL, NULL}
4710 /* C API. Clients get at this via PyDateTime_IMPORT, defined in
4711 * datetime.h.
4713 static PyDateTime_CAPI CAPI = {
4714 &PyDateTime_DateType,
4715 &PyDateTime_DateTimeType,
4716 &PyDateTime_TimeType,
4717 &PyDateTime_DeltaType,
4718 &PyDateTime_TZInfoType,
4719 new_date_ex,
4720 new_datetime_ex,
4721 new_time_ex,
4722 new_delta_ex,
4723 datetime_fromtimestamp,
4724 date_fromtimestamp
4728 PyMODINIT_FUNC
4729 initdatetime(void)
4731 PyObject *m; /* a module object */
4732 PyObject *d; /* its dict */
4733 PyObject *x;
4735 m = Py_InitModule3("datetime", module_methods,
4736 "Fast implementation of the datetime type.");
4737 if (m == NULL)
4738 return;
4740 if (PyType_Ready(&PyDateTime_DateType) < 0)
4741 return;
4742 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4743 return;
4744 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4745 return;
4746 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4747 return;
4748 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4749 return;
4751 /* timedelta values */
4752 d = PyDateTime_DeltaType.tp_dict;
4754 x = new_delta(0, 0, 1, 0);
4755 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4756 return;
4757 Py_DECREF(x);
4759 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4760 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4761 return;
4762 Py_DECREF(x);
4764 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4765 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4766 return;
4767 Py_DECREF(x);
4769 /* date values */
4770 d = PyDateTime_DateType.tp_dict;
4772 x = new_date(1, 1, 1);
4773 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4774 return;
4775 Py_DECREF(x);
4777 x = new_date(MAXYEAR, 12, 31);
4778 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4779 return;
4780 Py_DECREF(x);
4782 x = new_delta(1, 0, 0, 0);
4783 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4784 return;
4785 Py_DECREF(x);
4787 /* time values */
4788 d = PyDateTime_TimeType.tp_dict;
4790 x = new_time(0, 0, 0, 0, Py_None);
4791 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4792 return;
4793 Py_DECREF(x);
4795 x = new_time(23, 59, 59, 999999, Py_None);
4796 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4797 return;
4798 Py_DECREF(x);
4800 x = new_delta(0, 0, 1, 0);
4801 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4802 return;
4803 Py_DECREF(x);
4805 /* datetime values */
4806 d = PyDateTime_DateTimeType.tp_dict;
4808 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4809 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4810 return;
4811 Py_DECREF(x);
4813 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4814 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4815 return;
4816 Py_DECREF(x);
4818 x = new_delta(0, 0, 1, 0);
4819 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4820 return;
4821 Py_DECREF(x);
4823 /* module initialization */
4824 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4825 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4827 Py_INCREF(&PyDateTime_DateType);
4828 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4830 Py_INCREF(&PyDateTime_DateTimeType);
4831 PyModule_AddObject(m, "datetime",
4832 (PyObject *)&PyDateTime_DateTimeType);
4834 Py_INCREF(&PyDateTime_TimeType);
4835 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4837 Py_INCREF(&PyDateTime_DeltaType);
4838 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4840 Py_INCREF(&PyDateTime_TZInfoType);
4841 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4843 x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
4844 NULL);
4845 if (x == NULL)
4846 return;
4847 PyModule_AddObject(m, "datetime_CAPI", x);
4849 /* A 4-year cycle has an extra leap day over what we'd get from
4850 * pasting together 4 single years.
4852 assert(DI4Y == 4 * 365 + 1);
4853 assert(DI4Y == days_before_year(4+1));
4855 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4856 * get from pasting together 4 100-year cycles.
4858 assert(DI400Y == 4 * DI100Y + 1);
4859 assert(DI400Y == days_before_year(400+1));
4861 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4862 * pasting together 25 4-year cycles.
4864 assert(DI100Y == 25 * DI4Y - 1);
4865 assert(DI100Y == days_before_year(100+1));
4867 us_per_us = PyInt_FromLong(1);
4868 us_per_ms = PyInt_FromLong(1000);
4869 us_per_second = PyInt_FromLong(1000000);
4870 us_per_minute = PyInt_FromLong(60000000);
4871 seconds_per_day = PyInt_FromLong(24 * 3600);
4872 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4873 us_per_minute == NULL || seconds_per_day == NULL)
4874 return;
4876 /* The rest are too big for 32-bit ints, but even
4877 * us_per_week fits in 40 bits, so doubles should be exact.
4879 us_per_hour = PyLong_FromDouble(3600000000.0);
4880 us_per_day = PyLong_FromDouble(86400000000.0);
4881 us_per_week = PyLong_FromDouble(604800000000.0);
4882 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4883 return;
4886 /* ---------------------------------------------------------------------------
4887 Some time zone algebra. For a datetime x, let
4888 x.n = x stripped of its timezone -- its naive time.
4889 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4890 return None
4891 x.d = x.dst(), and assuming that doesn't raise an exception or
4892 return None
4893 x.s = x's standard offset, x.o - x.d
4895 Now some derived rules, where k is a duration (timedelta).
4897 1. x.o = x.s + x.d
4898 This follows from the definition of x.s.
4900 2. If x and y have the same tzinfo member, x.s = y.s.
4901 This is actually a requirement, an assumption we need to make about
4902 sane tzinfo classes.
4904 3. The naive UTC time corresponding to x is x.n - x.o.
4905 This is again a requirement for a sane tzinfo class.
4907 4. (x+k).s = x.s
4908 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
4910 5. (x+k).n = x.n + k
4911 Again follows from how arithmetic is defined.
4913 Now we can explain tz.fromutc(x). Let's assume it's an interesting case
4914 (meaning that the various tzinfo methods exist, and don't blow up or return
4915 None when called).
4917 The function wants to return a datetime y with timezone tz, equivalent to x.
4918 x is already in UTC.
4920 By #3, we want
4922 y.n - y.o = x.n [1]
4924 The algorithm starts by attaching tz to x.n, and calling that y. So
4925 x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4926 becomes true; in effect, we want to solve [2] for k:
4928 (y+k).n - (y+k).o = x.n [2]
4930 By #1, this is the same as
4932 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
4934 By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4935 Substituting that into [3],
4937 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4938 k - (y+k).s - (y+k).d = 0; rearranging,
4939 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4940 k = y.s - (y+k).d
4942 On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4943 approximate k by ignoring the (y+k).d term at first. Note that k can't be
4944 very large, since all offset-returning methods return a duration of magnitude
4945 less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4946 be 0, so ignoring it has no consequence then.
4948 In any case, the new value is
4950 z = y + y.s [4]
4952 It's helpful to step back at look at [4] from a higher level: it's simply
4953 mapping from UTC to tz's standard time.
4955 At this point, if
4957 z.n - z.o = x.n [5]
4959 we have an equivalent time, and are almost done. The insecurity here is
4960 at the start of daylight time. Picture US Eastern for concreteness. The wall
4961 time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
4962 sense then. The docs ask that an Eastern tzinfo class consider such a time to
4963 be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4964 on the day DST starts. We want to return the 1:MM EST spelling because that's
4965 the only spelling that makes sense on the local wall clock.
4967 In fact, if [5] holds at this point, we do have the standard-time spelling,
4968 but that takes a bit of proof. We first prove a stronger result. What's the
4969 difference between the LHS and RHS of [5]? Let
4971 diff = x.n - (z.n - z.o) [6]
4974 z.n = by [4]
4975 (y + y.s).n = by #5
4976 y.n + y.s = since y.n = x.n
4977 x.n + y.s = since z and y are have the same tzinfo member,
4978 y.s = z.s by #2
4979 x.n + z.s
4981 Plugging that back into [6] gives
4983 diff =
4984 x.n - ((x.n + z.s) - z.o) = expanding
4985 x.n - x.n - z.s + z.o = cancelling
4986 - z.s + z.o = by #2
4989 So diff = z.d.
4991 If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
4992 spelling we wanted in the endcase described above. We're done. Contrarily,
4993 if z.d = 0, then we have a UTC equivalent, and are also done.
4995 If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4996 add to z (in effect, z is in tz's standard time, and we need to shift the
4997 local clock into tz's daylight time).
5001 z' = z + z.d = z + diff [7]
5003 and we can again ask whether
5005 z'.n - z'.o = x.n [8]
5007 If so, we're done. If not, the tzinfo class is insane, according to the
5008 assumptions we've made. This also requires a bit of proof. As before, let's
5009 compute the difference between the LHS and RHS of [8] (and skipping some of
5010 the justifications for the kinds of substitutions we've done several times
5011 already):
5013 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5014 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5015 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5016 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5017 - z.n + z.n - z.o + z'.o = cancel z.n
5018 - z.o + z'.o = #1 twice
5019 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5020 z'.d - z.d
5022 So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
5023 we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5024 return z', not bothering to compute z'.d.
5026 How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5027 a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5028 would have to change the result dst() returns: we start in DST, and moving
5029 a little further into it takes us out of DST.
5031 There isn't a sane case where this can happen. The closest it gets is at
5032 the end of DST, where there's an hour in UTC with no spelling in a hybrid
5033 tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5034 that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5035 UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5036 time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5037 clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5038 standard time. Since that's what the local clock *does*, we want to map both
5039 UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
5040 in local time, but so it goes -- it's the way the local clock works.
5042 When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5043 so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5044 z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
5045 (correctly) concludes that z' is not UTC-equivalent to x.
5047 Because we know z.d said z was in daylight time (else [5] would have held and
5048 we would have stopped then), and we know z.d != z'.d (else [8] would have held
5049 and we would have stopped then), and there are only 2 possible values dst() can
5050 return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5051 but the reasoning doesn't depend on the example -- it depends on there being
5052 two possible dst() outcomes, one zero and the other non-zero). Therefore
5053 z' must be in standard time, and is the spelling we want in this case.
5055 Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5056 concerned (because it takes z' as being in standard time rather than the
5057 daylight time we intend here), but returning it gives the real-life "local
5058 clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5061 When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5062 the 1:MM standard time spelling we want.
5064 So how can this break? One of the assumptions must be violated. Two
5065 possibilities:
5067 1) [2] effectively says that y.s is invariant across all y belong to a given
5068 time zone. This isn't true if, for political reasons or continental drift,
5069 a region decides to change its base offset from UTC.
5071 2) There may be versions of "double daylight" time where the tail end of
5072 the analysis gives up a step too early. I haven't thought about that
5073 enough to say.
5075 In any case, it's clear that the default fromutc() is strong enough to handle
5076 "almost all" time zones: so long as the standard offset is invariant, it
5077 doesn't matter if daylight time transition points change from year to year, or
5078 if daylight time is skipped in some years; it doesn't matter how large or
5079 small dst() may get within its bounds; and it doesn't even matter if some
5080 perverse time zone returns a negative dst()). So a breaking case must be
5081 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
5082 --------------------------------------------------------------------------- */