The silencing of DeprecationWarning was not taking -3 into consideration. Since
[python.git] / Modules / datetimemodule.c
blob7b9e2713f9bb04873fb69cb8647f72cd1c485f48
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 assert(bufflen >= x);
1366 return buffer + x;
1369 static char *
1370 isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1372 int x;
1373 int us = DATE_GET_MICROSECOND(dt);
1375 x = PyOS_snprintf(buffer, bufflen,
1376 "%02d:%02d:%02d",
1377 DATE_GET_HOUR(dt),
1378 DATE_GET_MINUTE(dt),
1379 DATE_GET_SECOND(dt));
1380 assert(bufflen >= x);
1381 if (us)
1382 x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us);
1383 assert(bufflen >= x);
1384 return buffer + x;
1387 /* ---------------------------------------------------------------------------
1388 * Wrap functions from the time module. These aren't directly available
1389 * from C. Perhaps they should be.
1392 /* Call time.time() and return its result (a Python float). */
1393 static PyObject *
1394 time_time(void)
1396 PyObject *result = NULL;
1397 PyObject *time = PyImport_ImportModuleNoBlock("time");
1399 if (time != NULL) {
1400 result = PyObject_CallMethod(time, "time", "()");
1401 Py_DECREF(time);
1403 return result;
1406 /* Build a time.struct_time. The weekday and day number are automatically
1407 * computed from the y,m,d args.
1409 static PyObject *
1410 build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1412 PyObject *time;
1413 PyObject *result = NULL;
1415 time = PyImport_ImportModuleNoBlock("time");
1416 if (time != NULL) {
1417 result = PyObject_CallMethod(time, "struct_time",
1418 "((iiiiiiiii))",
1419 y, m, d,
1420 hh, mm, ss,
1421 weekday(y, m, d),
1422 days_before_month(y, m) + d,
1423 dstflag);
1424 Py_DECREF(time);
1426 return result;
1429 /* ---------------------------------------------------------------------------
1430 * Miscellaneous helpers.
1433 /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1434 * The comparisons here all most naturally compute a cmp()-like result.
1435 * This little helper turns that into a bool result for rich comparisons.
1437 static PyObject *
1438 diff_to_bool(int diff, int op)
1440 PyObject *result;
1441 int istrue;
1443 switch (op) {
1444 case Py_EQ: istrue = diff == 0; break;
1445 case Py_NE: istrue = diff != 0; break;
1446 case Py_LE: istrue = diff <= 0; break;
1447 case Py_GE: istrue = diff >= 0; break;
1448 case Py_LT: istrue = diff < 0; break;
1449 case Py_GT: istrue = diff > 0; break;
1450 default:
1451 assert(! "op unknown");
1452 istrue = 0; /* To shut up compiler */
1454 result = istrue ? Py_True : Py_False;
1455 Py_INCREF(result);
1456 return result;
1459 /* Raises a "can't compare" TypeError and returns NULL. */
1460 static PyObject *
1461 cmperror(PyObject *a, PyObject *b)
1463 PyErr_Format(PyExc_TypeError,
1464 "can't compare %s to %s",
1465 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1466 return NULL;
1469 /* ---------------------------------------------------------------------------
1470 * Cached Python objects; these are set by the module init function.
1473 /* Conversion factors. */
1474 static PyObject *us_per_us = NULL; /* 1 */
1475 static PyObject *us_per_ms = NULL; /* 1000 */
1476 static PyObject *us_per_second = NULL; /* 1000000 */
1477 static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1478 static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1479 static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1480 static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1481 static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1483 /* ---------------------------------------------------------------------------
1484 * Class implementations.
1488 * PyDateTime_Delta implementation.
1491 /* Convert a timedelta to a number of us,
1492 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1493 * as a Python int or long.
1494 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1495 * due to ubiquitous overflow possibilities.
1497 static PyObject *
1498 delta_to_microseconds(PyDateTime_Delta *self)
1500 PyObject *x1 = NULL;
1501 PyObject *x2 = NULL;
1502 PyObject *x3 = NULL;
1503 PyObject *result = NULL;
1505 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1506 if (x1 == NULL)
1507 goto Done;
1508 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1509 if (x2 == NULL)
1510 goto Done;
1511 Py_DECREF(x1);
1512 x1 = NULL;
1514 /* x2 has days in seconds */
1515 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1516 if (x1 == NULL)
1517 goto Done;
1518 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1519 if (x3 == NULL)
1520 goto Done;
1521 Py_DECREF(x1);
1522 Py_DECREF(x2);
1523 x1 = x2 = NULL;
1525 /* x3 has days+seconds in seconds */
1526 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1527 if (x1 == NULL)
1528 goto Done;
1529 Py_DECREF(x3);
1530 x3 = NULL;
1532 /* x1 has days+seconds in us */
1533 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1534 if (x2 == NULL)
1535 goto Done;
1536 result = PyNumber_Add(x1, x2);
1538 Done:
1539 Py_XDECREF(x1);
1540 Py_XDECREF(x2);
1541 Py_XDECREF(x3);
1542 return result;
1545 /* Convert a number of us (as a Python int or long) to a timedelta.
1547 static PyObject *
1548 microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1550 int us;
1551 int s;
1552 int d;
1553 long temp;
1555 PyObject *tuple = NULL;
1556 PyObject *num = NULL;
1557 PyObject *result = NULL;
1559 tuple = PyNumber_Divmod(pyus, us_per_second);
1560 if (tuple == NULL)
1561 goto Done;
1563 num = PyTuple_GetItem(tuple, 1); /* us */
1564 if (num == NULL)
1565 goto Done;
1566 temp = PyLong_AsLong(num);
1567 num = NULL;
1568 if (temp == -1 && PyErr_Occurred())
1569 goto Done;
1570 assert(0 <= temp && temp < 1000000);
1571 us = (int)temp;
1572 if (us < 0) {
1573 /* The divisor was positive, so this must be an error. */
1574 assert(PyErr_Occurred());
1575 goto Done;
1578 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1579 if (num == NULL)
1580 goto Done;
1581 Py_INCREF(num);
1582 Py_DECREF(tuple);
1584 tuple = PyNumber_Divmod(num, seconds_per_day);
1585 if (tuple == NULL)
1586 goto Done;
1587 Py_DECREF(num);
1589 num = PyTuple_GetItem(tuple, 1); /* seconds */
1590 if (num == NULL)
1591 goto Done;
1592 temp = PyLong_AsLong(num);
1593 num = NULL;
1594 if (temp == -1 && PyErr_Occurred())
1595 goto Done;
1596 assert(0 <= temp && temp < 24*3600);
1597 s = (int)temp;
1599 if (s < 0) {
1600 /* The divisor was positive, so this must be an error. */
1601 assert(PyErr_Occurred());
1602 goto Done;
1605 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1606 if (num == NULL)
1607 goto Done;
1608 Py_INCREF(num);
1609 temp = PyLong_AsLong(num);
1610 if (temp == -1 && PyErr_Occurred())
1611 goto Done;
1612 d = (int)temp;
1613 if ((long)d != temp) {
1614 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1615 "large to fit in a C int");
1616 goto Done;
1618 result = new_delta_ex(d, s, us, 0, type);
1620 Done:
1621 Py_XDECREF(tuple);
1622 Py_XDECREF(num);
1623 return result;
1626 #define microseconds_to_delta(pymicros) \
1627 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1629 static PyObject *
1630 multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1632 PyObject *pyus_in;
1633 PyObject *pyus_out;
1634 PyObject *result;
1636 pyus_in = delta_to_microseconds(delta);
1637 if (pyus_in == NULL)
1638 return NULL;
1640 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1641 Py_DECREF(pyus_in);
1642 if (pyus_out == NULL)
1643 return NULL;
1645 result = microseconds_to_delta(pyus_out);
1646 Py_DECREF(pyus_out);
1647 return result;
1650 static PyObject *
1651 divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1653 PyObject *pyus_in;
1654 PyObject *pyus_out;
1655 PyObject *result;
1657 pyus_in = delta_to_microseconds(delta);
1658 if (pyus_in == NULL)
1659 return NULL;
1661 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1662 Py_DECREF(pyus_in);
1663 if (pyus_out == NULL)
1664 return NULL;
1666 result = microseconds_to_delta(pyus_out);
1667 Py_DECREF(pyus_out);
1668 return result;
1671 static PyObject *
1672 delta_add(PyObject *left, PyObject *right)
1674 PyObject *result = Py_NotImplemented;
1676 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1677 /* delta + delta */
1678 /* The C-level additions can't overflow because of the
1679 * invariant bounds.
1681 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1682 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1683 int microseconds = GET_TD_MICROSECONDS(left) +
1684 GET_TD_MICROSECONDS(right);
1685 result = new_delta(days, seconds, microseconds, 1);
1688 if (result == Py_NotImplemented)
1689 Py_INCREF(result);
1690 return result;
1693 static PyObject *
1694 delta_negative(PyDateTime_Delta *self)
1696 return new_delta(-GET_TD_DAYS(self),
1697 -GET_TD_SECONDS(self),
1698 -GET_TD_MICROSECONDS(self),
1702 static PyObject *
1703 delta_positive(PyDateTime_Delta *self)
1705 /* Could optimize this (by returning self) if this isn't a
1706 * subclass -- but who uses unary + ? Approximately nobody.
1708 return new_delta(GET_TD_DAYS(self),
1709 GET_TD_SECONDS(self),
1710 GET_TD_MICROSECONDS(self),
1714 static PyObject *
1715 delta_abs(PyDateTime_Delta *self)
1717 PyObject *result;
1719 assert(GET_TD_MICROSECONDS(self) >= 0);
1720 assert(GET_TD_SECONDS(self) >= 0);
1722 if (GET_TD_DAYS(self) < 0)
1723 result = delta_negative(self);
1724 else
1725 result = delta_positive(self);
1727 return result;
1730 static PyObject *
1731 delta_subtract(PyObject *left, PyObject *right)
1733 PyObject *result = Py_NotImplemented;
1735 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1736 /* delta - delta */
1737 PyObject *minus_right = PyNumber_Negative(right);
1738 if (minus_right) {
1739 result = delta_add(left, minus_right);
1740 Py_DECREF(minus_right);
1742 else
1743 result = NULL;
1746 if (result == Py_NotImplemented)
1747 Py_INCREF(result);
1748 return result;
1751 /* This is more natural as a tp_compare, but doesn't work then: for whatever
1752 * reason, Python's try_3way_compare ignores tp_compare unless
1753 * PyInstance_Check returns true, but these aren't old-style classes.
1755 static PyObject *
1756 delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1758 int diff = 42; /* nonsense */
1760 if (PyDelta_Check(other)) {
1761 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1762 if (diff == 0) {
1763 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1764 if (diff == 0)
1765 diff = GET_TD_MICROSECONDS(self) -
1766 GET_TD_MICROSECONDS(other);
1769 else if (op == Py_EQ || op == Py_NE)
1770 diff = 1; /* any non-zero value will do */
1772 else /* stop this from falling back to address comparison */
1773 return cmperror((PyObject *)self, other);
1775 return diff_to_bool(diff, op);
1778 static PyObject *delta_getstate(PyDateTime_Delta *self);
1780 static long
1781 delta_hash(PyDateTime_Delta *self)
1783 if (self->hashcode == -1) {
1784 PyObject *temp = delta_getstate(self);
1785 if (temp != NULL) {
1786 self->hashcode = PyObject_Hash(temp);
1787 Py_DECREF(temp);
1790 return self->hashcode;
1793 static PyObject *
1794 delta_multiply(PyObject *left, PyObject *right)
1796 PyObject *result = Py_NotImplemented;
1798 if (PyDelta_Check(left)) {
1799 /* delta * ??? */
1800 if (PyInt_Check(right) || PyLong_Check(right))
1801 result = multiply_int_timedelta(right,
1802 (PyDateTime_Delta *) left);
1804 else if (PyInt_Check(left) || PyLong_Check(left))
1805 result = multiply_int_timedelta(left,
1806 (PyDateTime_Delta *) right);
1808 if (result == Py_NotImplemented)
1809 Py_INCREF(result);
1810 return result;
1813 static PyObject *
1814 delta_divide(PyObject *left, PyObject *right)
1816 PyObject *result = Py_NotImplemented;
1818 if (PyDelta_Check(left)) {
1819 /* delta * ??? */
1820 if (PyInt_Check(right) || PyLong_Check(right))
1821 result = divide_timedelta_int(
1822 (PyDateTime_Delta *)left,
1823 right);
1826 if (result == Py_NotImplemented)
1827 Py_INCREF(result);
1828 return result;
1831 /* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1832 * timedelta constructor. sofar is the # of microseconds accounted for
1833 * so far, and there are factor microseconds per current unit, the number
1834 * of which is given by num. num * factor is added to sofar in a
1835 * numerically careful way, and that's the result. Any fractional
1836 * microseconds left over (this can happen if num is a float type) are
1837 * added into *leftover.
1838 * Note that there are many ways this can give an error (NULL) return.
1840 static PyObject *
1841 accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1842 double *leftover)
1844 PyObject *prod;
1845 PyObject *sum;
1847 assert(num != NULL);
1849 if (PyInt_Check(num) || PyLong_Check(num)) {
1850 prod = PyNumber_Multiply(num, factor);
1851 if (prod == NULL)
1852 return NULL;
1853 sum = PyNumber_Add(sofar, prod);
1854 Py_DECREF(prod);
1855 return sum;
1858 if (PyFloat_Check(num)) {
1859 double dnum;
1860 double fracpart;
1861 double intpart;
1862 PyObject *x;
1863 PyObject *y;
1865 /* The Plan: decompose num into an integer part and a
1866 * fractional part, num = intpart + fracpart.
1867 * Then num * factor ==
1868 * intpart * factor + fracpart * factor
1869 * and the LHS can be computed exactly in long arithmetic.
1870 * The RHS is again broken into an int part and frac part.
1871 * and the frac part is added into *leftover.
1873 dnum = PyFloat_AsDouble(num);
1874 if (dnum == -1.0 && PyErr_Occurred())
1875 return NULL;
1876 fracpart = modf(dnum, &intpart);
1877 x = PyLong_FromDouble(intpart);
1878 if (x == NULL)
1879 return NULL;
1881 prod = PyNumber_Multiply(x, factor);
1882 Py_DECREF(x);
1883 if (prod == NULL)
1884 return NULL;
1886 sum = PyNumber_Add(sofar, prod);
1887 Py_DECREF(prod);
1888 if (sum == NULL)
1889 return NULL;
1891 if (fracpart == 0.0)
1892 return sum;
1893 /* So far we've lost no information. Dealing with the
1894 * fractional part requires float arithmetic, and may
1895 * lose a little info.
1897 assert(PyInt_Check(factor) || PyLong_Check(factor));
1898 if (PyInt_Check(factor))
1899 dnum = (double)PyInt_AsLong(factor);
1900 else
1901 dnum = PyLong_AsDouble(factor);
1903 dnum *= fracpart;
1904 fracpart = modf(dnum, &intpart);
1905 x = PyLong_FromDouble(intpart);
1906 if (x == NULL) {
1907 Py_DECREF(sum);
1908 return NULL;
1911 y = PyNumber_Add(sum, x);
1912 Py_DECREF(sum);
1913 Py_DECREF(x);
1914 *leftover += fracpart;
1915 return y;
1918 PyErr_Format(PyExc_TypeError,
1919 "unsupported type for timedelta %s component: %s",
1920 tag, Py_TYPE(num)->tp_name);
1921 return NULL;
1924 static PyObject *
1925 delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1927 PyObject *self = NULL;
1929 /* Argument objects. */
1930 PyObject *day = NULL;
1931 PyObject *second = NULL;
1932 PyObject *us = NULL;
1933 PyObject *ms = NULL;
1934 PyObject *minute = NULL;
1935 PyObject *hour = NULL;
1936 PyObject *week = NULL;
1938 PyObject *x = NULL; /* running sum of microseconds */
1939 PyObject *y = NULL; /* temp sum of microseconds */
1940 double leftover_us = 0.0;
1942 static char *keywords[] = {
1943 "days", "seconds", "microseconds", "milliseconds",
1944 "minutes", "hours", "weeks", NULL
1947 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1948 keywords,
1949 &day, &second, &us,
1950 &ms, &minute, &hour, &week) == 0)
1951 goto Done;
1953 x = PyInt_FromLong(0);
1954 if (x == NULL)
1955 goto Done;
1957 #define CLEANUP \
1958 Py_DECREF(x); \
1959 x = y; \
1960 if (x == NULL) \
1961 goto Done
1963 if (us) {
1964 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1965 CLEANUP;
1967 if (ms) {
1968 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1969 CLEANUP;
1971 if (second) {
1972 y = accum("seconds", x, second, us_per_second, &leftover_us);
1973 CLEANUP;
1975 if (minute) {
1976 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1977 CLEANUP;
1979 if (hour) {
1980 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1981 CLEANUP;
1983 if (day) {
1984 y = accum("days", x, day, us_per_day, &leftover_us);
1985 CLEANUP;
1987 if (week) {
1988 y = accum("weeks", x, week, us_per_week, &leftover_us);
1989 CLEANUP;
1991 if (leftover_us) {
1992 /* Round to nearest whole # of us, and add into x. */
1993 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1994 if (temp == NULL) {
1995 Py_DECREF(x);
1996 goto Done;
1998 y = PyNumber_Add(x, temp);
1999 Py_DECREF(temp);
2000 CLEANUP;
2003 self = microseconds_to_delta_ex(x, type);
2004 Py_DECREF(x);
2005 Done:
2006 return self;
2008 #undef CLEANUP
2011 static int
2012 delta_nonzero(PyDateTime_Delta *self)
2014 return (GET_TD_DAYS(self) != 0
2015 || GET_TD_SECONDS(self) != 0
2016 || GET_TD_MICROSECONDS(self) != 0);
2019 static PyObject *
2020 delta_repr(PyDateTime_Delta *self)
2022 if (GET_TD_MICROSECONDS(self) != 0)
2023 return PyString_FromFormat("%s(%d, %d, %d)",
2024 Py_TYPE(self)->tp_name,
2025 GET_TD_DAYS(self),
2026 GET_TD_SECONDS(self),
2027 GET_TD_MICROSECONDS(self));
2028 if (GET_TD_SECONDS(self) != 0)
2029 return PyString_FromFormat("%s(%d, %d)",
2030 Py_TYPE(self)->tp_name,
2031 GET_TD_DAYS(self),
2032 GET_TD_SECONDS(self));
2034 return PyString_FromFormat("%s(%d)",
2035 Py_TYPE(self)->tp_name,
2036 GET_TD_DAYS(self));
2039 static PyObject *
2040 delta_str(PyDateTime_Delta *self)
2042 int days = GET_TD_DAYS(self);
2043 int seconds = GET_TD_SECONDS(self);
2044 int us = GET_TD_MICROSECONDS(self);
2045 int hours;
2046 int minutes;
2047 char buf[100];
2048 char *pbuf = buf;
2049 size_t buflen = sizeof(buf);
2050 int n;
2052 minutes = divmod(seconds, 60, &seconds);
2053 hours = divmod(minutes, 60, &minutes);
2055 if (days) {
2056 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2057 (days == 1 || days == -1) ? "" : "s");
2058 if (n < 0 || (size_t)n >= buflen)
2059 goto Fail;
2060 pbuf += n;
2061 buflen -= (size_t)n;
2064 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2065 hours, minutes, seconds);
2066 if (n < 0 || (size_t)n >= buflen)
2067 goto Fail;
2068 pbuf += n;
2069 buflen -= (size_t)n;
2071 if (us) {
2072 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2073 if (n < 0 || (size_t)n >= buflen)
2074 goto Fail;
2075 pbuf += n;
2078 return PyString_FromStringAndSize(buf, pbuf - buf);
2080 Fail:
2081 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2082 return NULL;
2085 /* Pickle support, a simple use of __reduce__. */
2087 /* __getstate__ isn't exposed */
2088 static PyObject *
2089 delta_getstate(PyDateTime_Delta *self)
2091 return Py_BuildValue("iii", GET_TD_DAYS(self),
2092 GET_TD_SECONDS(self),
2093 GET_TD_MICROSECONDS(self));
2096 static PyObject *
2097 delta_total_seconds(PyObject *self)
2099 return PyFloat_FromDouble(GET_TD_MICROSECONDS(self) / 1000000.0 +
2100 GET_TD_SECONDS(self) +
2101 GET_TD_DAYS(self) * 24.0 * 3600.0);
2104 static PyObject *
2105 delta_reduce(PyDateTime_Delta* self)
2107 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
2110 #define OFFSET(field) offsetof(PyDateTime_Delta, field)
2112 static PyMemberDef delta_members[] = {
2114 {"days", T_INT, OFFSET(days), READONLY,
2115 PyDoc_STR("Number of days.")},
2117 {"seconds", T_INT, OFFSET(seconds), READONLY,
2118 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2120 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2121 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2122 {NULL}
2125 static PyMethodDef delta_methods[] = {
2126 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2127 PyDoc_STR("Total seconds in the duration.")},
2129 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2130 PyDoc_STR("__reduce__() -> (cls, state)")},
2132 {NULL, NULL},
2135 static char delta_doc[] =
2136 PyDoc_STR("Difference between two datetime values.");
2138 static PyNumberMethods delta_as_number = {
2139 delta_add, /* nb_add */
2140 delta_subtract, /* nb_subtract */
2141 delta_multiply, /* nb_multiply */
2142 delta_divide, /* nb_divide */
2143 0, /* nb_remainder */
2144 0, /* nb_divmod */
2145 0, /* nb_power */
2146 (unaryfunc)delta_negative, /* nb_negative */
2147 (unaryfunc)delta_positive, /* nb_positive */
2148 (unaryfunc)delta_abs, /* nb_absolute */
2149 (inquiry)delta_nonzero, /* nb_nonzero */
2150 0, /*nb_invert*/
2151 0, /*nb_lshift*/
2152 0, /*nb_rshift*/
2153 0, /*nb_and*/
2154 0, /*nb_xor*/
2155 0, /*nb_or*/
2156 0, /*nb_coerce*/
2157 0, /*nb_int*/
2158 0, /*nb_long*/
2159 0, /*nb_float*/
2160 0, /*nb_oct*/
2161 0, /*nb_hex*/
2162 0, /*nb_inplace_add*/
2163 0, /*nb_inplace_subtract*/
2164 0, /*nb_inplace_multiply*/
2165 0, /*nb_inplace_divide*/
2166 0, /*nb_inplace_remainder*/
2167 0, /*nb_inplace_power*/
2168 0, /*nb_inplace_lshift*/
2169 0, /*nb_inplace_rshift*/
2170 0, /*nb_inplace_and*/
2171 0, /*nb_inplace_xor*/
2172 0, /*nb_inplace_or*/
2173 delta_divide, /* nb_floor_divide */
2174 0, /* nb_true_divide */
2175 0, /* nb_inplace_floor_divide */
2176 0, /* nb_inplace_true_divide */
2179 static PyTypeObject PyDateTime_DeltaType = {
2180 PyVarObject_HEAD_INIT(NULL, 0)
2181 "datetime.timedelta", /* tp_name */
2182 sizeof(PyDateTime_Delta), /* tp_basicsize */
2183 0, /* tp_itemsize */
2184 0, /* tp_dealloc */
2185 0, /* tp_print */
2186 0, /* tp_getattr */
2187 0, /* tp_setattr */
2188 0, /* tp_compare */
2189 (reprfunc)delta_repr, /* tp_repr */
2190 &delta_as_number, /* tp_as_number */
2191 0, /* tp_as_sequence */
2192 0, /* tp_as_mapping */
2193 (hashfunc)delta_hash, /* tp_hash */
2194 0, /* tp_call */
2195 (reprfunc)delta_str, /* tp_str */
2196 PyObject_GenericGetAttr, /* tp_getattro */
2197 0, /* tp_setattro */
2198 0, /* tp_as_buffer */
2199 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2200 Py_TPFLAGS_BASETYPE, /* tp_flags */
2201 delta_doc, /* tp_doc */
2202 0, /* tp_traverse */
2203 0, /* tp_clear */
2204 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2205 0, /* tp_weaklistoffset */
2206 0, /* tp_iter */
2207 0, /* tp_iternext */
2208 delta_methods, /* tp_methods */
2209 delta_members, /* tp_members */
2210 0, /* tp_getset */
2211 0, /* tp_base */
2212 0, /* tp_dict */
2213 0, /* tp_descr_get */
2214 0, /* tp_descr_set */
2215 0, /* tp_dictoffset */
2216 0, /* tp_init */
2217 0, /* tp_alloc */
2218 delta_new, /* tp_new */
2219 0, /* tp_free */
2223 * PyDateTime_Date implementation.
2226 /* Accessor properties. */
2228 static PyObject *
2229 date_year(PyDateTime_Date *self, void *unused)
2231 return PyInt_FromLong(GET_YEAR(self));
2234 static PyObject *
2235 date_month(PyDateTime_Date *self, void *unused)
2237 return PyInt_FromLong(GET_MONTH(self));
2240 static PyObject *
2241 date_day(PyDateTime_Date *self, void *unused)
2243 return PyInt_FromLong(GET_DAY(self));
2246 static PyGetSetDef date_getset[] = {
2247 {"year", (getter)date_year},
2248 {"month", (getter)date_month},
2249 {"day", (getter)date_day},
2250 {NULL}
2253 /* Constructors. */
2255 static char *date_kws[] = {"year", "month", "day", NULL};
2257 static PyObject *
2258 date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2260 PyObject *self = NULL;
2261 PyObject *state;
2262 int year;
2263 int month;
2264 int day;
2266 /* Check for invocation from pickle with __getstate__ state */
2267 if (PyTuple_GET_SIZE(args) == 1 &&
2268 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2269 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2270 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
2272 PyDateTime_Date *me;
2274 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2275 if (me != NULL) {
2276 char *pdata = PyString_AS_STRING(state);
2277 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2278 me->hashcode = -1;
2280 return (PyObject *)me;
2283 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2284 &year, &month, &day)) {
2285 if (check_date_args(year, month, day) < 0)
2286 return NULL;
2287 self = new_date_ex(year, month, day, type);
2289 return self;
2292 /* Return new date from localtime(t). */
2293 static PyObject *
2294 date_local_from_time_t(PyObject *cls, double ts)
2296 struct tm *tm;
2297 time_t t;
2298 PyObject *result = NULL;
2300 t = _PyTime_DoubleToTimet(ts);
2301 if (t == (time_t)-1 && PyErr_Occurred())
2302 return NULL;
2303 tm = localtime(&t);
2304 if (tm)
2305 result = PyObject_CallFunction(cls, "iii",
2306 tm->tm_year + 1900,
2307 tm->tm_mon + 1,
2308 tm->tm_mday);
2309 else
2310 PyErr_SetString(PyExc_ValueError,
2311 "timestamp out of range for "
2312 "platform localtime() function");
2313 return result;
2316 /* Return new date from current time.
2317 * We say this is equivalent to fromtimestamp(time.time()), and the
2318 * only way to be sure of that is to *call* time.time(). That's not
2319 * generally the same as calling C's time.
2321 static PyObject *
2322 date_today(PyObject *cls, PyObject *dummy)
2324 PyObject *time;
2325 PyObject *result;
2327 time = time_time();
2328 if (time == NULL)
2329 return NULL;
2331 /* Note well: today() is a class method, so this may not call
2332 * date.fromtimestamp. For example, it may call
2333 * datetime.fromtimestamp. That's why we need all the accuracy
2334 * time.time() delivers; if someone were gonzo about optimization,
2335 * date.today() could get away with plain C time().
2337 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2338 Py_DECREF(time);
2339 return result;
2342 /* Return new date from given timestamp (Python timestamp -- a double). */
2343 static PyObject *
2344 date_fromtimestamp(PyObject *cls, PyObject *args)
2346 double timestamp;
2347 PyObject *result = NULL;
2349 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2350 result = date_local_from_time_t(cls, timestamp);
2351 return result;
2354 /* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2355 * the ordinal is out of range.
2357 static PyObject *
2358 date_fromordinal(PyObject *cls, PyObject *args)
2360 PyObject *result = NULL;
2361 int ordinal;
2363 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2364 int year;
2365 int month;
2366 int day;
2368 if (ordinal < 1)
2369 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2370 ">= 1");
2371 else {
2372 ord_to_ymd(ordinal, &year, &month, &day);
2373 result = PyObject_CallFunction(cls, "iii",
2374 year, month, day);
2377 return result;
2381 * Date arithmetic.
2384 /* date + timedelta -> date. If arg negate is true, subtract the timedelta
2385 * instead.
2387 static PyObject *
2388 add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2390 PyObject *result = NULL;
2391 int year = GET_YEAR(date);
2392 int month = GET_MONTH(date);
2393 int deltadays = GET_TD_DAYS(delta);
2394 /* C-level overflow is impossible because |deltadays| < 1e9. */
2395 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2397 if (normalize_date(&year, &month, &day) >= 0)
2398 result = new_date(year, month, day);
2399 return result;
2402 static PyObject *
2403 date_add(PyObject *left, PyObject *right)
2405 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2406 Py_INCREF(Py_NotImplemented);
2407 return Py_NotImplemented;
2409 if (PyDate_Check(left)) {
2410 /* date + ??? */
2411 if (PyDelta_Check(right))
2412 /* date + delta */
2413 return add_date_timedelta((PyDateTime_Date *) left,
2414 (PyDateTime_Delta *) right,
2417 else {
2418 /* ??? + date
2419 * 'right' must be one of us, or we wouldn't have been called
2421 if (PyDelta_Check(left))
2422 /* delta + date */
2423 return add_date_timedelta((PyDateTime_Date *) right,
2424 (PyDateTime_Delta *) left,
2427 Py_INCREF(Py_NotImplemented);
2428 return Py_NotImplemented;
2431 static PyObject *
2432 date_subtract(PyObject *left, PyObject *right)
2434 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2435 Py_INCREF(Py_NotImplemented);
2436 return Py_NotImplemented;
2438 if (PyDate_Check(left)) {
2439 if (PyDate_Check(right)) {
2440 /* date - date */
2441 int left_ord = ymd_to_ord(GET_YEAR(left),
2442 GET_MONTH(left),
2443 GET_DAY(left));
2444 int right_ord = ymd_to_ord(GET_YEAR(right),
2445 GET_MONTH(right),
2446 GET_DAY(right));
2447 return new_delta(left_ord - right_ord, 0, 0, 0);
2449 if (PyDelta_Check(right)) {
2450 /* date - delta */
2451 return add_date_timedelta((PyDateTime_Date *) left,
2452 (PyDateTime_Delta *) right,
2456 Py_INCREF(Py_NotImplemented);
2457 return Py_NotImplemented;
2461 /* Various ways to turn a date into a string. */
2463 static PyObject *
2464 date_repr(PyDateTime_Date *self)
2466 char buffer[1028];
2467 const char *type_name;
2469 type_name = Py_TYPE(self)->tp_name;
2470 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2471 type_name,
2472 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2474 return PyString_FromString(buffer);
2477 static PyObject *
2478 date_isoformat(PyDateTime_Date *self)
2480 char buffer[128];
2482 isoformat_date(self, buffer, sizeof(buffer));
2483 return PyString_FromString(buffer);
2486 /* str() calls the appropriate isoformat() method. */
2487 static PyObject *
2488 date_str(PyDateTime_Date *self)
2490 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2494 static PyObject *
2495 date_ctime(PyDateTime_Date *self)
2497 return format_ctime(self, 0, 0, 0);
2500 static PyObject *
2501 date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2503 /* This method can be inherited, and needs to call the
2504 * timetuple() method appropriate to self's class.
2506 PyObject *result;
2507 PyObject *tuple;
2508 const char *format;
2509 Py_ssize_t format_len;
2510 static char *keywords[] = {"format", NULL};
2512 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2513 &format, &format_len))
2514 return NULL;
2516 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2517 if (tuple == NULL)
2518 return NULL;
2519 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
2520 (PyObject *)self);
2521 Py_DECREF(tuple);
2522 return result;
2525 static PyObject *
2526 date_format(PyDateTime_Date *self, PyObject *args)
2528 PyObject *format;
2530 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2531 return NULL;
2533 /* Check for str or unicode */
2534 if (PyString_Check(format)) {
2535 /* If format is zero length, return str(self) */
2536 if (PyString_GET_SIZE(format) == 0)
2537 return PyObject_Str((PyObject *)self);
2538 } else if (PyUnicode_Check(format)) {
2539 /* If format is zero length, return str(self) */
2540 if (PyUnicode_GET_SIZE(format) == 0)
2541 return PyObject_Unicode((PyObject *)self);
2542 } else {
2543 PyErr_Format(PyExc_ValueError,
2544 "__format__ expects str or unicode, not %.200s",
2545 Py_TYPE(format)->tp_name);
2546 return NULL;
2548 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2551 /* ISO methods. */
2553 static PyObject *
2554 date_isoweekday(PyDateTime_Date *self)
2556 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2558 return PyInt_FromLong(dow + 1);
2561 static PyObject *
2562 date_isocalendar(PyDateTime_Date *self)
2564 int year = GET_YEAR(self);
2565 int week1_monday = iso_week1_monday(year);
2566 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2567 int week;
2568 int day;
2570 week = divmod(today - week1_monday, 7, &day);
2571 if (week < 0) {
2572 --year;
2573 week1_monday = iso_week1_monday(year);
2574 week = divmod(today - week1_monday, 7, &day);
2576 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2577 ++year;
2578 week = 0;
2580 return Py_BuildValue("iii", year, week + 1, day + 1);
2583 /* Miscellaneous methods. */
2585 /* This is more natural as a tp_compare, but doesn't work then: for whatever
2586 * reason, Python's try_3way_compare ignores tp_compare unless
2587 * PyInstance_Check returns true, but these aren't old-style classes.
2589 static PyObject *
2590 date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2592 int diff = 42; /* nonsense */
2594 if (PyDate_Check(other))
2595 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2596 _PyDateTime_DATE_DATASIZE);
2598 else if (PyObject_HasAttrString(other, "timetuple")) {
2599 /* A hook for other kinds of date objects. */
2600 Py_INCREF(Py_NotImplemented);
2601 return Py_NotImplemented;
2603 else if (op == Py_EQ || op == Py_NE)
2604 diff = 1; /* any non-zero value will do */
2606 else /* stop this from falling back to address comparison */
2607 return cmperror((PyObject *)self, other);
2609 return diff_to_bool(diff, op);
2612 static PyObject *
2613 date_timetuple(PyDateTime_Date *self)
2615 return build_struct_time(GET_YEAR(self),
2616 GET_MONTH(self),
2617 GET_DAY(self),
2618 0, 0, 0, -1);
2621 static PyObject *
2622 date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2624 PyObject *clone;
2625 PyObject *tuple;
2626 int year = GET_YEAR(self);
2627 int month = GET_MONTH(self);
2628 int day = GET_DAY(self);
2630 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2631 &year, &month, &day))
2632 return NULL;
2633 tuple = Py_BuildValue("iii", year, month, day);
2634 if (tuple == NULL)
2635 return NULL;
2636 clone = date_new(Py_TYPE(self), tuple, NULL);
2637 Py_DECREF(tuple);
2638 return clone;
2641 static PyObject *date_getstate(PyDateTime_Date *self);
2643 static long
2644 date_hash(PyDateTime_Date *self)
2646 if (self->hashcode == -1) {
2647 PyObject *temp = date_getstate(self);
2648 if (temp != NULL) {
2649 self->hashcode = PyObject_Hash(temp);
2650 Py_DECREF(temp);
2653 return self->hashcode;
2656 static PyObject *
2657 date_toordinal(PyDateTime_Date *self)
2659 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2660 GET_DAY(self)));
2663 static PyObject *
2664 date_weekday(PyDateTime_Date *self)
2666 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2668 return PyInt_FromLong(dow);
2671 /* Pickle support, a simple use of __reduce__. */
2673 /* __getstate__ isn't exposed */
2674 static PyObject *
2675 date_getstate(PyDateTime_Date *self)
2677 return Py_BuildValue(
2678 "(N)",
2679 PyString_FromStringAndSize((char *)self->data,
2680 _PyDateTime_DATE_DATASIZE));
2683 static PyObject *
2684 date_reduce(PyDateTime_Date *self, PyObject *arg)
2686 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
2689 static PyMethodDef date_methods[] = {
2691 /* Class methods: */
2693 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2694 METH_CLASS,
2695 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2696 "time.time()).")},
2698 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2699 METH_CLASS,
2700 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2701 "ordinal.")},
2703 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2704 PyDoc_STR("Current date or datetime: same as "
2705 "self.__class__.fromtimestamp(time.time()).")},
2707 /* Instance methods: */
2709 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2710 PyDoc_STR("Return ctime() style string.")},
2712 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2713 PyDoc_STR("format -> strftime() style string.")},
2715 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2716 PyDoc_STR("Formats self with strftime.")},
2718 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2719 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2721 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2722 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2723 "weekday.")},
2725 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2726 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2728 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2729 PyDoc_STR("Return the day of the week represented by the date.\n"
2730 "Monday == 1 ... Sunday == 7")},
2732 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2733 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2734 "1 is day 1.")},
2736 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2737 PyDoc_STR("Return the day of the week represented by the date.\n"
2738 "Monday == 0 ... Sunday == 6")},
2740 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2741 PyDoc_STR("Return date with new specified fields.")},
2743 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2744 PyDoc_STR("__reduce__() -> (cls, state)")},
2746 {NULL, NULL}
2749 static char date_doc[] =
2750 PyDoc_STR("date(year, month, day) --> date object");
2752 static PyNumberMethods date_as_number = {
2753 date_add, /* nb_add */
2754 date_subtract, /* nb_subtract */
2755 0, /* nb_multiply */
2756 0, /* nb_divide */
2757 0, /* nb_remainder */
2758 0, /* nb_divmod */
2759 0, /* nb_power */
2760 0, /* nb_negative */
2761 0, /* nb_positive */
2762 0, /* nb_absolute */
2763 0, /* nb_nonzero */
2766 static PyTypeObject PyDateTime_DateType = {
2767 PyVarObject_HEAD_INIT(NULL, 0)
2768 "datetime.date", /* tp_name */
2769 sizeof(PyDateTime_Date), /* tp_basicsize */
2770 0, /* tp_itemsize */
2771 0, /* tp_dealloc */
2772 0, /* tp_print */
2773 0, /* tp_getattr */
2774 0, /* tp_setattr */
2775 0, /* tp_compare */
2776 (reprfunc)date_repr, /* tp_repr */
2777 &date_as_number, /* tp_as_number */
2778 0, /* tp_as_sequence */
2779 0, /* tp_as_mapping */
2780 (hashfunc)date_hash, /* tp_hash */
2781 0, /* tp_call */
2782 (reprfunc)date_str, /* tp_str */
2783 PyObject_GenericGetAttr, /* tp_getattro */
2784 0, /* tp_setattro */
2785 0, /* tp_as_buffer */
2786 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2787 Py_TPFLAGS_BASETYPE, /* tp_flags */
2788 date_doc, /* tp_doc */
2789 0, /* tp_traverse */
2790 0, /* tp_clear */
2791 (richcmpfunc)date_richcompare, /* tp_richcompare */
2792 0, /* tp_weaklistoffset */
2793 0, /* tp_iter */
2794 0, /* tp_iternext */
2795 date_methods, /* tp_methods */
2796 0, /* tp_members */
2797 date_getset, /* tp_getset */
2798 0, /* tp_base */
2799 0, /* tp_dict */
2800 0, /* tp_descr_get */
2801 0, /* tp_descr_set */
2802 0, /* tp_dictoffset */
2803 0, /* tp_init */
2804 0, /* tp_alloc */
2805 date_new, /* tp_new */
2806 0, /* tp_free */
2810 * PyDateTime_TZInfo implementation.
2813 /* This is a pure abstract base class, so doesn't do anything beyond
2814 * raising NotImplemented exceptions. Real tzinfo classes need
2815 * to derive from this. This is mostly for clarity, and for efficiency in
2816 * datetime and time constructors (their tzinfo arguments need to
2817 * be subclasses of this tzinfo class, which is easy and quick to check).
2819 * Note: For reasons having to do with pickling of subclasses, we have
2820 * to allow tzinfo objects to be instantiated. This wasn't an issue
2821 * in the Python implementation (__init__() could raise NotImplementedError
2822 * there without ill effect), but doing so in the C implementation hit a
2823 * brick wall.
2826 static PyObject *
2827 tzinfo_nogo(const char* methodname)
2829 PyErr_Format(PyExc_NotImplementedError,
2830 "a tzinfo subclass must implement %s()",
2831 methodname);
2832 return NULL;
2835 /* Methods. A subclass must implement these. */
2837 static PyObject *
2838 tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2840 return tzinfo_nogo("tzname");
2843 static PyObject *
2844 tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2846 return tzinfo_nogo("utcoffset");
2849 static PyObject *
2850 tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2852 return tzinfo_nogo("dst");
2855 static PyObject *
2856 tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2858 int y, m, d, hh, mm, ss, us;
2860 PyObject *result;
2861 int off, dst;
2862 int none;
2863 int delta;
2865 if (! PyDateTime_Check(dt)) {
2866 PyErr_SetString(PyExc_TypeError,
2867 "fromutc: argument must be a datetime");
2868 return NULL;
2870 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2871 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2872 "is not self");
2873 return NULL;
2876 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2877 if (off == -1 && PyErr_Occurred())
2878 return NULL;
2879 if (none) {
2880 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2881 "utcoffset() result required");
2882 return NULL;
2885 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2886 if (dst == -1 && PyErr_Occurred())
2887 return NULL;
2888 if (none) {
2889 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2890 "dst() result required");
2891 return NULL;
2894 y = GET_YEAR(dt);
2895 m = GET_MONTH(dt);
2896 d = GET_DAY(dt);
2897 hh = DATE_GET_HOUR(dt);
2898 mm = DATE_GET_MINUTE(dt);
2899 ss = DATE_GET_SECOND(dt);
2900 us = DATE_GET_MICROSECOND(dt);
2902 delta = off - dst;
2903 mm += delta;
2904 if ((mm < 0 || mm >= 60) &&
2905 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2906 return NULL;
2907 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2908 if (result == NULL)
2909 return result;
2911 dst = call_dst(dt->tzinfo, result, &none);
2912 if (dst == -1 && PyErr_Occurred())
2913 goto Fail;
2914 if (none)
2915 goto Inconsistent;
2916 if (dst == 0)
2917 return result;
2919 mm += dst;
2920 if ((mm < 0 || mm >= 60) &&
2921 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2922 goto Fail;
2923 Py_DECREF(result);
2924 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2925 return result;
2927 Inconsistent:
2928 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2929 "inconsistent results; cannot convert");
2931 /* fall thru to failure */
2932 Fail:
2933 Py_DECREF(result);
2934 return NULL;
2938 * Pickle support. This is solely so that tzinfo subclasses can use
2939 * pickling -- tzinfo itself is supposed to be uninstantiable.
2942 static PyObject *
2943 tzinfo_reduce(PyObject *self)
2945 PyObject *args, *state, *tmp;
2946 PyObject *getinitargs, *getstate;
2948 tmp = PyTuple_New(0);
2949 if (tmp == NULL)
2950 return NULL;
2952 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2953 if (getinitargs != NULL) {
2954 args = PyObject_CallObject(getinitargs, tmp);
2955 Py_DECREF(getinitargs);
2956 if (args == NULL) {
2957 Py_DECREF(tmp);
2958 return NULL;
2961 else {
2962 PyErr_Clear();
2963 args = tmp;
2964 Py_INCREF(args);
2967 getstate = PyObject_GetAttrString(self, "__getstate__");
2968 if (getstate != NULL) {
2969 state = PyObject_CallObject(getstate, tmp);
2970 Py_DECREF(getstate);
2971 if (state == NULL) {
2972 Py_DECREF(args);
2973 Py_DECREF(tmp);
2974 return NULL;
2977 else {
2978 PyObject **dictptr;
2979 PyErr_Clear();
2980 state = Py_None;
2981 dictptr = _PyObject_GetDictPtr(self);
2982 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2983 state = *dictptr;
2984 Py_INCREF(state);
2987 Py_DECREF(tmp);
2989 if (state == Py_None) {
2990 Py_DECREF(state);
2991 return Py_BuildValue("(ON)", Py_TYPE(self), args);
2993 else
2994 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
2997 static PyMethodDef tzinfo_methods[] = {
2999 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3000 PyDoc_STR("datetime -> string name of time zone.")},
3002 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
3003 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3004 "west of UTC).")},
3006 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3007 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3009 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
3010 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3012 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3013 PyDoc_STR("-> (cls, state)")},
3015 {NULL, NULL}
3018 static char tzinfo_doc[] =
3019 PyDoc_STR("Abstract base class for time zone info objects.");
3021 statichere PyTypeObject PyDateTime_TZInfoType = {
3022 PyObject_HEAD_INIT(NULL)
3023 0, /* ob_size */
3024 "datetime.tzinfo", /* tp_name */
3025 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3026 0, /* tp_itemsize */
3027 0, /* tp_dealloc */
3028 0, /* tp_print */
3029 0, /* tp_getattr */
3030 0, /* tp_setattr */
3031 0, /* tp_compare */
3032 0, /* tp_repr */
3033 0, /* tp_as_number */
3034 0, /* tp_as_sequence */
3035 0, /* tp_as_mapping */
3036 0, /* tp_hash */
3037 0, /* tp_call */
3038 0, /* tp_str */
3039 PyObject_GenericGetAttr, /* tp_getattro */
3040 0, /* tp_setattro */
3041 0, /* tp_as_buffer */
3042 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3043 Py_TPFLAGS_BASETYPE, /* tp_flags */
3044 tzinfo_doc, /* tp_doc */
3045 0, /* tp_traverse */
3046 0, /* tp_clear */
3047 0, /* tp_richcompare */
3048 0, /* tp_weaklistoffset */
3049 0, /* tp_iter */
3050 0, /* tp_iternext */
3051 tzinfo_methods, /* tp_methods */
3052 0, /* tp_members */
3053 0, /* tp_getset */
3054 0, /* tp_base */
3055 0, /* tp_dict */
3056 0, /* tp_descr_get */
3057 0, /* tp_descr_set */
3058 0, /* tp_dictoffset */
3059 0, /* tp_init */
3060 0, /* tp_alloc */
3061 PyType_GenericNew, /* tp_new */
3062 0, /* tp_free */
3066 * PyDateTime_Time implementation.
3069 /* Accessor properties.
3072 static PyObject *
3073 time_hour(PyDateTime_Time *self, void *unused)
3075 return PyInt_FromLong(TIME_GET_HOUR(self));
3078 static PyObject *
3079 time_minute(PyDateTime_Time *self, void *unused)
3081 return PyInt_FromLong(TIME_GET_MINUTE(self));
3084 /* The name time_second conflicted with some platform header file. */
3085 static PyObject *
3086 py_time_second(PyDateTime_Time *self, void *unused)
3088 return PyInt_FromLong(TIME_GET_SECOND(self));
3091 static PyObject *
3092 time_microsecond(PyDateTime_Time *self, void *unused)
3094 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3097 static PyObject *
3098 time_tzinfo(PyDateTime_Time *self, void *unused)
3100 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3101 Py_INCREF(result);
3102 return result;
3105 static PyGetSetDef time_getset[] = {
3106 {"hour", (getter)time_hour},
3107 {"minute", (getter)time_minute},
3108 {"second", (getter)py_time_second},
3109 {"microsecond", (getter)time_microsecond},
3110 {"tzinfo", (getter)time_tzinfo},
3111 {NULL}
3115 * Constructors.
3118 static char *time_kws[] = {"hour", "minute", "second", "microsecond",
3119 "tzinfo", NULL};
3121 static PyObject *
3122 time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3124 PyObject *self = NULL;
3125 PyObject *state;
3126 int hour = 0;
3127 int minute = 0;
3128 int second = 0;
3129 int usecond = 0;
3130 PyObject *tzinfo = Py_None;
3132 /* Check for invocation from pickle with __getstate__ state */
3133 if (PyTuple_GET_SIZE(args) >= 1 &&
3134 PyTuple_GET_SIZE(args) <= 2 &&
3135 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3136 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3137 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
3139 PyDateTime_Time *me;
3140 char aware;
3142 if (PyTuple_GET_SIZE(args) == 2) {
3143 tzinfo = PyTuple_GET_ITEM(args, 1);
3144 if (check_tzinfo_subclass(tzinfo) < 0) {
3145 PyErr_SetString(PyExc_TypeError, "bad "
3146 "tzinfo state arg");
3147 return NULL;
3150 aware = (char)(tzinfo != Py_None);
3151 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3152 if (me != NULL) {
3153 char *pdata = PyString_AS_STRING(state);
3155 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3156 me->hashcode = -1;
3157 me->hastzinfo = aware;
3158 if (aware) {
3159 Py_INCREF(tzinfo);
3160 me->tzinfo = tzinfo;
3163 return (PyObject *)me;
3166 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3167 &hour, &minute, &second, &usecond,
3168 &tzinfo)) {
3169 if (check_time_args(hour, minute, second, usecond) < 0)
3170 return NULL;
3171 if (check_tzinfo_subclass(tzinfo) < 0)
3172 return NULL;
3173 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3174 type);
3176 return self;
3180 * Destructor.
3183 static void
3184 time_dealloc(PyDateTime_Time *self)
3186 if (HASTZINFO(self)) {
3187 Py_XDECREF(self->tzinfo);
3189 Py_TYPE(self)->tp_free((PyObject *)self);
3193 * Indirect access to tzinfo methods.
3196 /* These are all METH_NOARGS, so don't need to check the arglist. */
3197 static PyObject *
3198 time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
3199 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3200 "utcoffset", Py_None);
3203 static PyObject *
3204 time_dst(PyDateTime_Time *self, PyObject *unused) {
3205 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3206 "dst", Py_None);
3209 static PyObject *
3210 time_tzname(PyDateTime_Time *self, PyObject *unused) {
3211 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3212 Py_None);
3216 * Various ways to turn a time into a string.
3219 static PyObject *
3220 time_repr(PyDateTime_Time *self)
3222 char buffer[100];
3223 const char *type_name = Py_TYPE(self)->tp_name;
3224 int h = TIME_GET_HOUR(self);
3225 int m = TIME_GET_MINUTE(self);
3226 int s = TIME_GET_SECOND(self);
3227 int us = TIME_GET_MICROSECOND(self);
3228 PyObject *result = NULL;
3230 if (us)
3231 PyOS_snprintf(buffer, sizeof(buffer),
3232 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
3233 else if (s)
3234 PyOS_snprintf(buffer, sizeof(buffer),
3235 "%s(%d, %d, %d)", type_name, h, m, s);
3236 else
3237 PyOS_snprintf(buffer, sizeof(buffer),
3238 "%s(%d, %d)", type_name, h, m);
3239 result = PyString_FromString(buffer);
3240 if (result != NULL && HASTZINFO(self))
3241 result = append_keyword_tzinfo(result, self->tzinfo);
3242 return result;
3245 static PyObject *
3246 time_str(PyDateTime_Time *self)
3248 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3251 static PyObject *
3252 time_isoformat(PyDateTime_Time *self, PyObject *unused)
3254 char buf[100];
3255 PyObject *result;
3256 /* Reuse the time format code from the datetime type. */
3257 PyDateTime_DateTime datetime;
3258 PyDateTime_DateTime *pdatetime = &datetime;
3260 /* Copy over just the time bytes. */
3261 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3262 self->data,
3263 _PyDateTime_TIME_DATASIZE);
3265 isoformat_time(pdatetime, buf, sizeof(buf));
3266 result = PyString_FromString(buf);
3267 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3268 return result;
3270 /* We need to append the UTC offset. */
3271 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3272 Py_None) < 0) {
3273 Py_DECREF(result);
3274 return NULL;
3276 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3277 return result;
3280 static PyObject *
3281 time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3283 PyObject *result;
3284 PyObject *tuple;
3285 const char *format;
3286 Py_ssize_t format_len;
3287 static char *keywords[] = {"format", NULL};
3289 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3290 &format, &format_len))
3291 return NULL;
3293 /* Python's strftime does insane things with the year part of the
3294 * timetuple. The year is forced to (the otherwise nonsensical)
3295 * 1900 to worm around that.
3297 tuple = Py_BuildValue("iiiiiiiii",
3298 1900, 1, 1, /* year, month, day */
3299 TIME_GET_HOUR(self),
3300 TIME_GET_MINUTE(self),
3301 TIME_GET_SECOND(self),
3302 0, 1, -1); /* weekday, daynum, dst */
3303 if (tuple == NULL)
3304 return NULL;
3305 assert(PyTuple_Size(tuple) == 9);
3306 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3307 Py_None);
3308 Py_DECREF(tuple);
3309 return result;
3313 * Miscellaneous methods.
3316 /* This is more natural as a tp_compare, but doesn't work then: for whatever
3317 * reason, Python's try_3way_compare ignores tp_compare unless
3318 * PyInstance_Check returns true, but these aren't old-style classes.
3320 static PyObject *
3321 time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3323 int diff;
3324 naivety n1, n2;
3325 int offset1, offset2;
3327 if (! PyTime_Check(other)) {
3328 if (op == Py_EQ || op == Py_NE) {
3329 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3330 Py_INCREF(result);
3331 return result;
3333 /* Stop this from falling back to address comparison. */
3334 return cmperror((PyObject *)self, other);
3336 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3337 other, &offset2, &n2, Py_None) < 0)
3338 return NULL;
3339 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3340 /* If they're both naive, or both aware and have the same offsets,
3341 * we get off cheap. Note that if they're both naive, offset1 ==
3342 * offset2 == 0 at this point.
3344 if (n1 == n2 && offset1 == offset2) {
3345 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3346 _PyDateTime_TIME_DATASIZE);
3347 return diff_to_bool(diff, op);
3350 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3351 assert(offset1 != offset2); /* else last "if" handled it */
3352 /* Convert everything except microseconds to seconds. These
3353 * can't overflow (no more than the # of seconds in 2 days).
3355 offset1 = TIME_GET_HOUR(self) * 3600 +
3356 (TIME_GET_MINUTE(self) - offset1) * 60 +
3357 TIME_GET_SECOND(self);
3358 offset2 = TIME_GET_HOUR(other) * 3600 +
3359 (TIME_GET_MINUTE(other) - offset2) * 60 +
3360 TIME_GET_SECOND(other);
3361 diff = offset1 - offset2;
3362 if (diff == 0)
3363 diff = TIME_GET_MICROSECOND(self) -
3364 TIME_GET_MICROSECOND(other);
3365 return diff_to_bool(diff, op);
3368 assert(n1 != n2);
3369 PyErr_SetString(PyExc_TypeError,
3370 "can't compare offset-naive and "
3371 "offset-aware times");
3372 return NULL;
3375 static long
3376 time_hash(PyDateTime_Time *self)
3378 if (self->hashcode == -1) {
3379 naivety n;
3380 int offset;
3381 PyObject *temp;
3383 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3384 assert(n != OFFSET_UNKNOWN);
3385 if (n == OFFSET_ERROR)
3386 return -1;
3388 /* Reduce this to a hash of another object. */
3389 if (offset == 0)
3390 temp = PyString_FromStringAndSize((char *)self->data,
3391 _PyDateTime_TIME_DATASIZE);
3392 else {
3393 int hour;
3394 int minute;
3396 assert(n == OFFSET_AWARE);
3397 assert(HASTZINFO(self));
3398 hour = divmod(TIME_GET_HOUR(self) * 60 +
3399 TIME_GET_MINUTE(self) - offset,
3401 &minute);
3402 if (0 <= hour && hour < 24)
3403 temp = new_time(hour, minute,
3404 TIME_GET_SECOND(self),
3405 TIME_GET_MICROSECOND(self),
3406 Py_None);
3407 else
3408 temp = Py_BuildValue("iiii",
3409 hour, minute,
3410 TIME_GET_SECOND(self),
3411 TIME_GET_MICROSECOND(self));
3413 if (temp != NULL) {
3414 self->hashcode = PyObject_Hash(temp);
3415 Py_DECREF(temp);
3418 return self->hashcode;
3421 static PyObject *
3422 time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3424 PyObject *clone;
3425 PyObject *tuple;
3426 int hh = TIME_GET_HOUR(self);
3427 int mm = TIME_GET_MINUTE(self);
3428 int ss = TIME_GET_SECOND(self);
3429 int us = TIME_GET_MICROSECOND(self);
3430 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
3432 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3433 time_kws,
3434 &hh, &mm, &ss, &us, &tzinfo))
3435 return NULL;
3436 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3437 if (tuple == NULL)
3438 return NULL;
3439 clone = time_new(Py_TYPE(self), tuple, NULL);
3440 Py_DECREF(tuple);
3441 return clone;
3444 static int
3445 time_nonzero(PyDateTime_Time *self)
3447 int offset;
3448 int none;
3450 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3451 /* Since utcoffset is in whole minutes, nothing can
3452 * alter the conclusion that this is nonzero.
3454 return 1;
3456 offset = 0;
3457 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3458 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3459 if (offset == -1 && PyErr_Occurred())
3460 return -1;
3462 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3465 /* Pickle support, a simple use of __reduce__. */
3467 /* Let basestate be the non-tzinfo data string.
3468 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3469 * So it's a tuple in any (non-error) case.
3470 * __getstate__ isn't exposed.
3472 static PyObject *
3473 time_getstate(PyDateTime_Time *self)
3475 PyObject *basestate;
3476 PyObject *result = NULL;
3478 basestate = PyString_FromStringAndSize((char *)self->data,
3479 _PyDateTime_TIME_DATASIZE);
3480 if (basestate != NULL) {
3481 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3482 result = PyTuple_Pack(1, basestate);
3483 else
3484 result = PyTuple_Pack(2, basestate, self->tzinfo);
3485 Py_DECREF(basestate);
3487 return result;
3490 static PyObject *
3491 time_reduce(PyDateTime_Time *self, PyObject *arg)
3493 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
3496 static PyMethodDef time_methods[] = {
3498 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3499 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3500 "[+HH:MM].")},
3502 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3503 PyDoc_STR("format -> strftime() style string.")},
3505 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3506 PyDoc_STR("Formats self with strftime.")},
3508 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3509 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3511 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3512 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3514 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3515 PyDoc_STR("Return self.tzinfo.dst(self).")},
3517 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3518 PyDoc_STR("Return time with new specified fields.")},
3520 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3521 PyDoc_STR("__reduce__() -> (cls, state)")},
3523 {NULL, NULL}
3526 static char time_doc[] =
3527 PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3529 All arguments are optional. tzinfo may be None, or an instance of\n\
3530 a tzinfo subclass. The remaining arguments may be ints or longs.\n");
3532 static PyNumberMethods time_as_number = {
3533 0, /* nb_add */
3534 0, /* nb_subtract */
3535 0, /* nb_multiply */
3536 0, /* nb_divide */
3537 0, /* nb_remainder */
3538 0, /* nb_divmod */
3539 0, /* nb_power */
3540 0, /* nb_negative */
3541 0, /* nb_positive */
3542 0, /* nb_absolute */
3543 (inquiry)time_nonzero, /* nb_nonzero */
3546 statichere PyTypeObject PyDateTime_TimeType = {
3547 PyObject_HEAD_INIT(NULL)
3548 0, /* ob_size */
3549 "datetime.time", /* tp_name */
3550 sizeof(PyDateTime_Time), /* tp_basicsize */
3551 0, /* tp_itemsize */
3552 (destructor)time_dealloc, /* tp_dealloc */
3553 0, /* tp_print */
3554 0, /* tp_getattr */
3555 0, /* tp_setattr */
3556 0, /* tp_compare */
3557 (reprfunc)time_repr, /* tp_repr */
3558 &time_as_number, /* tp_as_number */
3559 0, /* tp_as_sequence */
3560 0, /* tp_as_mapping */
3561 (hashfunc)time_hash, /* tp_hash */
3562 0, /* tp_call */
3563 (reprfunc)time_str, /* tp_str */
3564 PyObject_GenericGetAttr, /* tp_getattro */
3565 0, /* tp_setattro */
3566 0, /* tp_as_buffer */
3567 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3568 Py_TPFLAGS_BASETYPE, /* tp_flags */
3569 time_doc, /* tp_doc */
3570 0, /* tp_traverse */
3571 0, /* tp_clear */
3572 (richcmpfunc)time_richcompare, /* tp_richcompare */
3573 0, /* tp_weaklistoffset */
3574 0, /* tp_iter */
3575 0, /* tp_iternext */
3576 time_methods, /* tp_methods */
3577 0, /* tp_members */
3578 time_getset, /* tp_getset */
3579 0, /* tp_base */
3580 0, /* tp_dict */
3581 0, /* tp_descr_get */
3582 0, /* tp_descr_set */
3583 0, /* tp_dictoffset */
3584 0, /* tp_init */
3585 time_alloc, /* tp_alloc */
3586 time_new, /* tp_new */
3587 0, /* tp_free */
3591 * PyDateTime_DateTime implementation.
3594 /* Accessor properties. Properties for day, month, and year are inherited
3595 * from date.
3598 static PyObject *
3599 datetime_hour(PyDateTime_DateTime *self, void *unused)
3601 return PyInt_FromLong(DATE_GET_HOUR(self));
3604 static PyObject *
3605 datetime_minute(PyDateTime_DateTime *self, void *unused)
3607 return PyInt_FromLong(DATE_GET_MINUTE(self));
3610 static PyObject *
3611 datetime_second(PyDateTime_DateTime *self, void *unused)
3613 return PyInt_FromLong(DATE_GET_SECOND(self));
3616 static PyObject *
3617 datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3619 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3622 static PyObject *
3623 datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3625 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3626 Py_INCREF(result);
3627 return result;
3630 static PyGetSetDef datetime_getset[] = {
3631 {"hour", (getter)datetime_hour},
3632 {"minute", (getter)datetime_minute},
3633 {"second", (getter)datetime_second},
3634 {"microsecond", (getter)datetime_microsecond},
3635 {"tzinfo", (getter)datetime_tzinfo},
3636 {NULL}
3640 * Constructors.
3643 static char *datetime_kws[] = {
3644 "year", "month", "day", "hour", "minute", "second",
3645 "microsecond", "tzinfo", NULL
3648 static PyObject *
3649 datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3651 PyObject *self = NULL;
3652 PyObject *state;
3653 int year;
3654 int month;
3655 int day;
3656 int hour = 0;
3657 int minute = 0;
3658 int second = 0;
3659 int usecond = 0;
3660 PyObject *tzinfo = Py_None;
3662 /* Check for invocation from pickle with __getstate__ state */
3663 if (PyTuple_GET_SIZE(args) >= 1 &&
3664 PyTuple_GET_SIZE(args) <= 2 &&
3665 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3666 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3667 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
3669 PyDateTime_DateTime *me;
3670 char aware;
3672 if (PyTuple_GET_SIZE(args) == 2) {
3673 tzinfo = PyTuple_GET_ITEM(args, 1);
3674 if (check_tzinfo_subclass(tzinfo) < 0) {
3675 PyErr_SetString(PyExc_TypeError, "bad "
3676 "tzinfo state arg");
3677 return NULL;
3680 aware = (char)(tzinfo != Py_None);
3681 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3682 if (me != NULL) {
3683 char *pdata = PyString_AS_STRING(state);
3685 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3686 me->hashcode = -1;
3687 me->hastzinfo = aware;
3688 if (aware) {
3689 Py_INCREF(tzinfo);
3690 me->tzinfo = tzinfo;
3693 return (PyObject *)me;
3696 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3697 &year, &month, &day, &hour, &minute,
3698 &second, &usecond, &tzinfo)) {
3699 if (check_date_args(year, month, day) < 0)
3700 return NULL;
3701 if (check_time_args(hour, minute, second, usecond) < 0)
3702 return NULL;
3703 if (check_tzinfo_subclass(tzinfo) < 0)
3704 return NULL;
3705 self = new_datetime_ex(year, month, day,
3706 hour, minute, second, usecond,
3707 tzinfo, type);
3709 return self;
3712 /* TM_FUNC is the shared type of localtime() and gmtime(). */
3713 typedef struct tm *(*TM_FUNC)(const time_t *timer);
3715 /* Internal helper.
3716 * Build datetime from a time_t and a distinct count of microseconds.
3717 * Pass localtime or gmtime for f, to control the interpretation of timet.
3719 static PyObject *
3720 datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3721 PyObject *tzinfo)
3723 struct tm *tm;
3724 PyObject *result = NULL;
3726 tm = f(&timet);
3727 if (tm) {
3728 /* The platform localtime/gmtime may insert leap seconds,
3729 * indicated by tm->tm_sec > 59. We don't care about them,
3730 * except to the extent that passing them on to the datetime
3731 * constructor would raise ValueError for a reason that
3732 * made no sense to the user.
3734 if (tm->tm_sec > 59)
3735 tm->tm_sec = 59;
3736 result = PyObject_CallFunction(cls, "iiiiiiiO",
3737 tm->tm_year + 1900,
3738 tm->tm_mon + 1,
3739 tm->tm_mday,
3740 tm->tm_hour,
3741 tm->tm_min,
3742 tm->tm_sec,
3744 tzinfo);
3746 else
3747 PyErr_SetString(PyExc_ValueError,
3748 "timestamp out of range for "
3749 "platform localtime()/gmtime() function");
3750 return result;
3753 /* Internal helper.
3754 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3755 * to control the interpretation of the timestamp. Since a double doesn't
3756 * have enough bits to cover a datetime's full range of precision, it's
3757 * better to call datetime_from_timet_and_us provided you have a way
3758 * to get that much precision (e.g., C time() isn't good enough).
3760 static PyObject *
3761 datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3762 PyObject *tzinfo)
3764 time_t timet;
3765 double fraction;
3766 int us;
3768 timet = _PyTime_DoubleToTimet(timestamp);
3769 if (timet == (time_t)-1 && PyErr_Occurred())
3770 return NULL;
3771 fraction = timestamp - (double)timet;
3772 us = (int)round_to_long(fraction * 1e6);
3773 if (us < 0) {
3774 /* Truncation towards zero is not what we wanted
3775 for negative numbers (Python's mod semantics) */
3776 timet -= 1;
3777 us += 1000000;
3779 /* If timestamp is less than one microsecond smaller than a
3780 * full second, round up. Otherwise, ValueErrors are raised
3781 * for some floats. */
3782 if (us == 1000000) {
3783 timet += 1;
3784 us = 0;
3786 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3789 /* Internal helper.
3790 * Build most accurate possible datetime for current time. Pass localtime or
3791 * gmtime for f as appropriate.
3793 static PyObject *
3794 datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3796 #ifdef HAVE_GETTIMEOFDAY
3797 struct timeval t;
3799 #ifdef GETTIMEOFDAY_NO_TZ
3800 gettimeofday(&t);
3801 #else
3802 gettimeofday(&t, (struct timezone *)NULL);
3803 #endif
3804 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3805 tzinfo);
3807 #else /* ! HAVE_GETTIMEOFDAY */
3808 /* No flavor of gettimeofday exists on this platform. Python's
3809 * time.time() does a lot of other platform tricks to get the
3810 * best time it can on the platform, and we're not going to do
3811 * better than that (if we could, the better code would belong
3812 * in time.time()!) We're limited by the precision of a double,
3813 * though.
3815 PyObject *time;
3816 double dtime;
3818 time = time_time();
3819 if (time == NULL)
3820 return NULL;
3821 dtime = PyFloat_AsDouble(time);
3822 Py_DECREF(time);
3823 if (dtime == -1.0 && PyErr_Occurred())
3824 return NULL;
3825 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3826 #endif /* ! HAVE_GETTIMEOFDAY */
3829 /* Return best possible local time -- this isn't constrained by the
3830 * precision of a timestamp.
3832 static PyObject *
3833 datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
3835 PyObject *self;
3836 PyObject *tzinfo = Py_None;
3837 static char *keywords[] = {"tz", NULL};
3839 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3840 &tzinfo))
3841 return NULL;
3842 if (check_tzinfo_subclass(tzinfo) < 0)
3843 return NULL;
3845 self = datetime_best_possible(cls,
3846 tzinfo == Py_None ? localtime : gmtime,
3847 tzinfo);
3848 if (self != NULL && tzinfo != Py_None) {
3849 /* Convert UTC to tzinfo's zone. */
3850 PyObject *temp = self;
3851 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3852 Py_DECREF(temp);
3854 return self;
3857 /* Return best possible UTC time -- this isn't constrained by the
3858 * precision of a timestamp.
3860 static PyObject *
3861 datetime_utcnow(PyObject *cls, PyObject *dummy)
3863 return datetime_best_possible(cls, gmtime, Py_None);
3866 /* Return new local datetime from timestamp (Python timestamp -- a double). */
3867 static PyObject *
3868 datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
3870 PyObject *self;
3871 double timestamp;
3872 PyObject *tzinfo = Py_None;
3873 static char *keywords[] = {"timestamp", "tz", NULL};
3875 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3876 keywords, &timestamp, &tzinfo))
3877 return NULL;
3878 if (check_tzinfo_subclass(tzinfo) < 0)
3879 return NULL;
3881 self = datetime_from_timestamp(cls,
3882 tzinfo == Py_None ? localtime : gmtime,
3883 timestamp,
3884 tzinfo);
3885 if (self != NULL && tzinfo != Py_None) {
3886 /* Convert UTC to tzinfo's zone. */
3887 PyObject *temp = self;
3888 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3889 Py_DECREF(temp);
3891 return self;
3894 /* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3895 static PyObject *
3896 datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3898 double timestamp;
3899 PyObject *result = NULL;
3901 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3902 result = datetime_from_timestamp(cls, gmtime, timestamp,
3903 Py_None);
3904 return result;
3907 /* Return new datetime from time.strptime(). */
3908 static PyObject *
3909 datetime_strptime(PyObject *cls, PyObject *args)
3911 static PyObject *module = NULL;
3912 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3913 const char *string, *format;
3915 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3916 return NULL;
3918 if (module == NULL &&
3919 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3920 return NULL;
3922 /* _strptime._strptime returns a two-element tuple. The first
3923 element is a time.struct_time object. The second is the
3924 microseconds (which are not defined for time.struct_time). */
3925 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
3926 if (obj != NULL) {
3927 int i, good_timetuple = 1;
3928 long int ia[7];
3929 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3930 st = PySequence_GetItem(obj, 0);
3931 frac = PySequence_GetItem(obj, 1);
3932 if (st == NULL || frac == NULL)
3933 good_timetuple = 0;
3934 /* copy y/m/d/h/m/s values out of the
3935 time.struct_time */
3936 if (good_timetuple &&
3937 PySequence_Check(st) &&
3938 PySequence_Size(st) >= 6) {
3939 for (i=0; i < 6; i++) {
3940 PyObject *p = PySequence_GetItem(st, i);
3941 if (p == NULL) {
3942 good_timetuple = 0;
3943 break;
3945 if (PyInt_Check(p))
3946 ia[i] = PyInt_AsLong(p);
3947 else
3948 good_timetuple = 0;
3949 Py_DECREF(p);
3952 else
3953 good_timetuple = 0;
3954 /* follow that up with a little dose of microseconds */
3955 if (PyInt_Check(frac))
3956 ia[6] = PyInt_AsLong(frac);
3957 else
3958 good_timetuple = 0;
3960 else
3961 good_timetuple = 0;
3962 if (good_timetuple)
3963 result = PyObject_CallFunction(cls, "iiiiiii",
3964 ia[0], ia[1], ia[2],
3965 ia[3], ia[4], ia[5],
3966 ia[6]);
3967 else
3968 PyErr_SetString(PyExc_ValueError,
3969 "unexpected value from _strptime._strptime");
3971 Py_XDECREF(obj);
3972 Py_XDECREF(st);
3973 Py_XDECREF(frac);
3974 return result;
3977 /* Return new datetime from date/datetime and time arguments. */
3978 static PyObject *
3979 datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3981 static char *keywords[] = {"date", "time", NULL};
3982 PyObject *date;
3983 PyObject *time;
3984 PyObject *result = NULL;
3986 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3987 &PyDateTime_DateType, &date,
3988 &PyDateTime_TimeType, &time)) {
3989 PyObject *tzinfo = Py_None;
3991 if (HASTZINFO(time))
3992 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3993 result = PyObject_CallFunction(cls, "iiiiiiiO",
3994 GET_YEAR(date),
3995 GET_MONTH(date),
3996 GET_DAY(date),
3997 TIME_GET_HOUR(time),
3998 TIME_GET_MINUTE(time),
3999 TIME_GET_SECOND(time),
4000 TIME_GET_MICROSECOND(time),
4001 tzinfo);
4003 return result;
4007 * Destructor.
4010 static void
4011 datetime_dealloc(PyDateTime_DateTime *self)
4013 if (HASTZINFO(self)) {
4014 Py_XDECREF(self->tzinfo);
4016 Py_TYPE(self)->tp_free((PyObject *)self);
4020 * Indirect access to tzinfo methods.
4023 /* These are all METH_NOARGS, so don't need to check the arglist. */
4024 static PyObject *
4025 datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
4026 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4027 "utcoffset", (PyObject *)self);
4030 static PyObject *
4031 datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
4032 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4033 "dst", (PyObject *)self);
4036 static PyObject *
4037 datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
4038 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4039 (PyObject *)self);
4043 * datetime arithmetic.
4046 /* factor must be 1 (to add) or -1 (to subtract). The result inherits
4047 * the tzinfo state of date.
4049 static PyObject *
4050 add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4051 int factor)
4053 /* Note that the C-level additions can't overflow, because of
4054 * invariant bounds on the member values.
4056 int year = GET_YEAR(date);
4057 int month = GET_MONTH(date);
4058 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4059 int hour = DATE_GET_HOUR(date);
4060 int minute = DATE_GET_MINUTE(date);
4061 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4062 int microsecond = DATE_GET_MICROSECOND(date) +
4063 GET_TD_MICROSECONDS(delta) * factor;
4065 assert(factor == 1 || factor == -1);
4066 if (normalize_datetime(&year, &month, &day,
4067 &hour, &minute, &second, &microsecond) < 0)
4068 return NULL;
4069 else
4070 return new_datetime(year, month, day,
4071 hour, minute, second, microsecond,
4072 HASTZINFO(date) ? date->tzinfo : Py_None);
4075 static PyObject *
4076 datetime_add(PyObject *left, PyObject *right)
4078 if (PyDateTime_Check(left)) {
4079 /* datetime + ??? */
4080 if (PyDelta_Check(right))
4081 /* datetime + delta */
4082 return add_datetime_timedelta(
4083 (PyDateTime_DateTime *)left,
4084 (PyDateTime_Delta *)right,
4087 else if (PyDelta_Check(left)) {
4088 /* delta + datetime */
4089 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4090 (PyDateTime_Delta *) left,
4093 Py_INCREF(Py_NotImplemented);
4094 return Py_NotImplemented;
4097 static PyObject *
4098 datetime_subtract(PyObject *left, PyObject *right)
4100 PyObject *result = Py_NotImplemented;
4102 if (PyDateTime_Check(left)) {
4103 /* datetime - ??? */
4104 if (PyDateTime_Check(right)) {
4105 /* datetime - datetime */
4106 naivety n1, n2;
4107 int offset1, offset2;
4108 int delta_d, delta_s, delta_us;
4110 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4111 right, &offset2, &n2,
4112 right) < 0)
4113 return NULL;
4114 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4115 if (n1 != n2) {
4116 PyErr_SetString(PyExc_TypeError,
4117 "can't subtract offset-naive and "
4118 "offset-aware datetimes");
4119 return NULL;
4121 delta_d = ymd_to_ord(GET_YEAR(left),
4122 GET_MONTH(left),
4123 GET_DAY(left)) -
4124 ymd_to_ord(GET_YEAR(right),
4125 GET_MONTH(right),
4126 GET_DAY(right));
4127 /* These can't overflow, since the values are
4128 * normalized. At most this gives the number of
4129 * seconds in one day.
4131 delta_s = (DATE_GET_HOUR(left) -
4132 DATE_GET_HOUR(right)) * 3600 +
4133 (DATE_GET_MINUTE(left) -
4134 DATE_GET_MINUTE(right)) * 60 +
4135 (DATE_GET_SECOND(left) -
4136 DATE_GET_SECOND(right));
4137 delta_us = DATE_GET_MICROSECOND(left) -
4138 DATE_GET_MICROSECOND(right);
4139 /* (left - offset1) - (right - offset2) =
4140 * (left - right) + (offset2 - offset1)
4142 delta_s += (offset2 - offset1) * 60;
4143 result = new_delta(delta_d, delta_s, delta_us, 1);
4145 else if (PyDelta_Check(right)) {
4146 /* datetime - delta */
4147 result = add_datetime_timedelta(
4148 (PyDateTime_DateTime *)left,
4149 (PyDateTime_Delta *)right,
4150 -1);
4154 if (result == Py_NotImplemented)
4155 Py_INCREF(result);
4156 return result;
4159 /* Various ways to turn a datetime into a string. */
4161 static PyObject *
4162 datetime_repr(PyDateTime_DateTime *self)
4164 char buffer[1000];
4165 const char *type_name = Py_TYPE(self)->tp_name;
4166 PyObject *baserepr;
4168 if (DATE_GET_MICROSECOND(self)) {
4169 PyOS_snprintf(buffer, sizeof(buffer),
4170 "%s(%d, %d, %d, %d, %d, %d, %d)",
4171 type_name,
4172 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4173 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4174 DATE_GET_SECOND(self),
4175 DATE_GET_MICROSECOND(self));
4177 else if (DATE_GET_SECOND(self)) {
4178 PyOS_snprintf(buffer, sizeof(buffer),
4179 "%s(%d, %d, %d, %d, %d, %d)",
4180 type_name,
4181 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4182 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4183 DATE_GET_SECOND(self));
4185 else {
4186 PyOS_snprintf(buffer, sizeof(buffer),
4187 "%s(%d, %d, %d, %d, %d)",
4188 type_name,
4189 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4190 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4192 baserepr = PyString_FromString(buffer);
4193 if (baserepr == NULL || ! HASTZINFO(self))
4194 return baserepr;
4195 return append_keyword_tzinfo(baserepr, self->tzinfo);
4198 static PyObject *
4199 datetime_str(PyDateTime_DateTime *self)
4201 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4204 static PyObject *
4205 datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4207 char sep = 'T';
4208 static char *keywords[] = {"sep", NULL};
4209 char buffer[100];
4210 char *cp;
4211 PyObject *result;
4213 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4214 &sep))
4215 return NULL;
4216 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4217 assert(cp != NULL);
4218 *cp++ = sep;
4219 cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4220 result = PyString_FromStringAndSize(buffer, cp - buffer);
4221 if (result == NULL || ! HASTZINFO(self))
4222 return result;
4224 /* We need to append the UTC offset. */
4225 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4226 (PyObject *)self) < 0) {
4227 Py_DECREF(result);
4228 return NULL;
4230 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
4231 return result;
4234 static PyObject *
4235 datetime_ctime(PyDateTime_DateTime *self)
4237 return format_ctime((PyDateTime_Date *)self,
4238 DATE_GET_HOUR(self),
4239 DATE_GET_MINUTE(self),
4240 DATE_GET_SECOND(self));
4243 /* Miscellaneous methods. */
4245 /* This is more natural as a tp_compare, but doesn't work then: for whatever
4246 * reason, Python's try_3way_compare ignores tp_compare unless
4247 * PyInstance_Check returns true, but these aren't old-style classes.
4249 static PyObject *
4250 datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4252 int diff;
4253 naivety n1, n2;
4254 int offset1, offset2;
4256 if (! PyDateTime_Check(other)) {
4257 /* If other has a "timetuple" attr, that's an advertised
4258 * hook for other classes to ask to get comparison control.
4259 * However, date instances have a timetuple attr, and we
4260 * don't want to allow that comparison. Because datetime
4261 * is a subclass of date, when mixing date and datetime
4262 * in a comparison, Python gives datetime the first shot
4263 * (it's the more specific subtype). So we can stop that
4264 * combination here reliably.
4266 if (PyObject_HasAttrString(other, "timetuple") &&
4267 ! PyDate_Check(other)) {
4268 /* A hook for other kinds of datetime objects. */
4269 Py_INCREF(Py_NotImplemented);
4270 return Py_NotImplemented;
4272 if (op == Py_EQ || op == Py_NE) {
4273 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4274 Py_INCREF(result);
4275 return result;
4277 /* Stop this from falling back to address comparison. */
4278 return cmperror((PyObject *)self, other);
4281 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4282 (PyObject *)self,
4283 other, &offset2, &n2,
4284 other) < 0)
4285 return NULL;
4286 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4287 /* If they're both naive, or both aware and have the same offsets,
4288 * we get off cheap. Note that if they're both naive, offset1 ==
4289 * offset2 == 0 at this point.
4291 if (n1 == n2 && offset1 == offset2) {
4292 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4293 _PyDateTime_DATETIME_DATASIZE);
4294 return diff_to_bool(diff, op);
4297 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4298 PyDateTime_Delta *delta;
4300 assert(offset1 != offset2); /* else last "if" handled it */
4301 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4302 other);
4303 if (delta == NULL)
4304 return NULL;
4305 diff = GET_TD_DAYS(delta);
4306 if (diff == 0)
4307 diff = GET_TD_SECONDS(delta) |
4308 GET_TD_MICROSECONDS(delta);
4309 Py_DECREF(delta);
4310 return diff_to_bool(diff, op);
4313 assert(n1 != n2);
4314 PyErr_SetString(PyExc_TypeError,
4315 "can't compare offset-naive and "
4316 "offset-aware datetimes");
4317 return NULL;
4320 static long
4321 datetime_hash(PyDateTime_DateTime *self)
4323 if (self->hashcode == -1) {
4324 naivety n;
4325 int offset;
4326 PyObject *temp;
4328 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4329 &offset);
4330 assert(n != OFFSET_UNKNOWN);
4331 if (n == OFFSET_ERROR)
4332 return -1;
4334 /* Reduce this to a hash of another object. */
4335 if (n == OFFSET_NAIVE)
4336 temp = PyString_FromStringAndSize(
4337 (char *)self->data,
4338 _PyDateTime_DATETIME_DATASIZE);
4339 else {
4340 int days;
4341 int seconds;
4343 assert(n == OFFSET_AWARE);
4344 assert(HASTZINFO(self));
4345 days = ymd_to_ord(GET_YEAR(self),
4346 GET_MONTH(self),
4347 GET_DAY(self));
4348 seconds = DATE_GET_HOUR(self) * 3600 +
4349 (DATE_GET_MINUTE(self) - offset) * 60 +
4350 DATE_GET_SECOND(self);
4351 temp = new_delta(days,
4352 seconds,
4353 DATE_GET_MICROSECOND(self),
4356 if (temp != NULL) {
4357 self->hashcode = PyObject_Hash(temp);
4358 Py_DECREF(temp);
4361 return self->hashcode;
4364 static PyObject *
4365 datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4367 PyObject *clone;
4368 PyObject *tuple;
4369 int y = GET_YEAR(self);
4370 int m = GET_MONTH(self);
4371 int d = GET_DAY(self);
4372 int hh = DATE_GET_HOUR(self);
4373 int mm = DATE_GET_MINUTE(self);
4374 int ss = DATE_GET_SECOND(self);
4375 int us = DATE_GET_MICROSECOND(self);
4376 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
4378 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4379 datetime_kws,
4380 &y, &m, &d, &hh, &mm, &ss, &us,
4381 &tzinfo))
4382 return NULL;
4383 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4384 if (tuple == NULL)
4385 return NULL;
4386 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4387 Py_DECREF(tuple);
4388 return clone;
4391 static PyObject *
4392 datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4394 int y, m, d, hh, mm, ss, us;
4395 PyObject *result;
4396 int offset, none;
4398 PyObject *tzinfo;
4399 static char *keywords[] = {"tz", NULL};
4401 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4402 &PyDateTime_TZInfoType, &tzinfo))
4403 return NULL;
4405 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4406 goto NeedAware;
4408 /* Conversion to self's own time zone is a NOP. */
4409 if (self->tzinfo == tzinfo) {
4410 Py_INCREF(self);
4411 return (PyObject *)self;
4414 /* Convert self to UTC. */
4415 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4416 if (offset == -1 && PyErr_Occurred())
4417 return NULL;
4418 if (none)
4419 goto NeedAware;
4421 y = GET_YEAR(self);
4422 m = GET_MONTH(self);
4423 d = GET_DAY(self);
4424 hh = DATE_GET_HOUR(self);
4425 mm = DATE_GET_MINUTE(self);
4426 ss = DATE_GET_SECOND(self);
4427 us = DATE_GET_MICROSECOND(self);
4429 mm -= offset;
4430 if ((mm < 0 || mm >= 60) &&
4431 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4432 return NULL;
4434 /* Attach new tzinfo and let fromutc() do the rest. */
4435 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4436 if (result != NULL) {
4437 PyObject *temp = result;
4439 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4440 Py_DECREF(temp);
4442 return result;
4444 NeedAware:
4445 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4446 "a naive datetime");
4447 return NULL;
4450 static PyObject *
4451 datetime_timetuple(PyDateTime_DateTime *self)
4453 int dstflag = -1;
4455 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4456 int none;
4458 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4459 if (dstflag == -1 && PyErr_Occurred())
4460 return NULL;
4462 if (none)
4463 dstflag = -1;
4464 else if (dstflag != 0)
4465 dstflag = 1;
4468 return build_struct_time(GET_YEAR(self),
4469 GET_MONTH(self),
4470 GET_DAY(self),
4471 DATE_GET_HOUR(self),
4472 DATE_GET_MINUTE(self),
4473 DATE_GET_SECOND(self),
4474 dstflag);
4477 static PyObject *
4478 datetime_getdate(PyDateTime_DateTime *self)
4480 return new_date(GET_YEAR(self),
4481 GET_MONTH(self),
4482 GET_DAY(self));
4485 static PyObject *
4486 datetime_gettime(PyDateTime_DateTime *self)
4488 return new_time(DATE_GET_HOUR(self),
4489 DATE_GET_MINUTE(self),
4490 DATE_GET_SECOND(self),
4491 DATE_GET_MICROSECOND(self),
4492 Py_None);
4495 static PyObject *
4496 datetime_gettimetz(PyDateTime_DateTime *self)
4498 return new_time(DATE_GET_HOUR(self),
4499 DATE_GET_MINUTE(self),
4500 DATE_GET_SECOND(self),
4501 DATE_GET_MICROSECOND(self),
4502 HASTZINFO(self) ? self->tzinfo : Py_None);
4505 static PyObject *
4506 datetime_utctimetuple(PyDateTime_DateTime *self)
4508 int y = GET_YEAR(self);
4509 int m = GET_MONTH(self);
4510 int d = GET_DAY(self);
4511 int hh = DATE_GET_HOUR(self);
4512 int mm = DATE_GET_MINUTE(self);
4513 int ss = DATE_GET_SECOND(self);
4514 int us = 0; /* microseconds are ignored in a timetuple */
4515 int offset = 0;
4517 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4518 int none;
4520 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4521 if (offset == -1 && PyErr_Occurred())
4522 return NULL;
4524 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4525 * 0 in a UTC timetuple regardless of what dst() says.
4527 if (offset) {
4528 /* Subtract offset minutes & normalize. */
4529 int stat;
4531 mm -= offset;
4532 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4533 if (stat < 0) {
4534 /* At the edges, it's possible we overflowed
4535 * beyond MINYEAR or MAXYEAR.
4537 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4538 PyErr_Clear();
4539 else
4540 return NULL;
4543 return build_struct_time(y, m, d, hh, mm, ss, 0);
4546 /* Pickle support, a simple use of __reduce__. */
4548 /* Let basestate be the non-tzinfo data string.
4549 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4550 * So it's a tuple in any (non-error) case.
4551 * __getstate__ isn't exposed.
4553 static PyObject *
4554 datetime_getstate(PyDateTime_DateTime *self)
4556 PyObject *basestate;
4557 PyObject *result = NULL;
4559 basestate = PyString_FromStringAndSize((char *)self->data,
4560 _PyDateTime_DATETIME_DATASIZE);
4561 if (basestate != NULL) {
4562 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4563 result = PyTuple_Pack(1, basestate);
4564 else
4565 result = PyTuple_Pack(2, basestate, self->tzinfo);
4566 Py_DECREF(basestate);
4568 return result;
4571 static PyObject *
4572 datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
4574 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
4577 static PyMethodDef datetime_methods[] = {
4579 /* Class methods: */
4581 {"now", (PyCFunction)datetime_now,
4582 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4583 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4585 {"utcnow", (PyCFunction)datetime_utcnow,
4586 METH_NOARGS | METH_CLASS,
4587 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4589 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4590 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4591 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4593 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4594 METH_VARARGS | METH_CLASS,
4595 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4596 "(like time.time()).")},
4598 {"strptime", (PyCFunction)datetime_strptime,
4599 METH_VARARGS | METH_CLASS,
4600 PyDoc_STR("string, format -> new datetime parsed from a string "
4601 "(like time.strptime()).")},
4603 {"combine", (PyCFunction)datetime_combine,
4604 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4605 PyDoc_STR("date, time -> datetime with same date and time fields")},
4607 /* Instance methods: */
4609 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4610 PyDoc_STR("Return date object with same year, month and day.")},
4612 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4613 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4615 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4616 PyDoc_STR("Return time object with same time and tzinfo.")},
4618 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4619 PyDoc_STR("Return ctime() style string.")},
4621 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4622 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4624 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4625 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4627 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4628 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4629 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4630 "sep is used to separate the year from the time, and "
4631 "defaults to 'T'.")},
4633 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4634 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4636 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4637 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4639 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4640 PyDoc_STR("Return self.tzinfo.dst(self).")},
4642 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4643 PyDoc_STR("Return datetime with new specified fields.")},
4645 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4646 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4648 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4649 PyDoc_STR("__reduce__() -> (cls, state)")},
4651 {NULL, NULL}
4654 static char datetime_doc[] =
4655 PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4657 The year, month and day arguments are required. tzinfo may be None, or an\n\
4658 instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
4660 static PyNumberMethods datetime_as_number = {
4661 datetime_add, /* nb_add */
4662 datetime_subtract, /* nb_subtract */
4663 0, /* nb_multiply */
4664 0, /* nb_divide */
4665 0, /* nb_remainder */
4666 0, /* nb_divmod */
4667 0, /* nb_power */
4668 0, /* nb_negative */
4669 0, /* nb_positive */
4670 0, /* nb_absolute */
4671 0, /* nb_nonzero */
4674 statichere PyTypeObject PyDateTime_DateTimeType = {
4675 PyObject_HEAD_INIT(NULL)
4676 0, /* ob_size */
4677 "datetime.datetime", /* tp_name */
4678 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4679 0, /* tp_itemsize */
4680 (destructor)datetime_dealloc, /* tp_dealloc */
4681 0, /* tp_print */
4682 0, /* tp_getattr */
4683 0, /* tp_setattr */
4684 0, /* tp_compare */
4685 (reprfunc)datetime_repr, /* tp_repr */
4686 &datetime_as_number, /* tp_as_number */
4687 0, /* tp_as_sequence */
4688 0, /* tp_as_mapping */
4689 (hashfunc)datetime_hash, /* tp_hash */
4690 0, /* tp_call */
4691 (reprfunc)datetime_str, /* tp_str */
4692 PyObject_GenericGetAttr, /* tp_getattro */
4693 0, /* tp_setattro */
4694 0, /* tp_as_buffer */
4695 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4696 Py_TPFLAGS_BASETYPE, /* tp_flags */
4697 datetime_doc, /* tp_doc */
4698 0, /* tp_traverse */
4699 0, /* tp_clear */
4700 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
4701 0, /* tp_weaklistoffset */
4702 0, /* tp_iter */
4703 0, /* tp_iternext */
4704 datetime_methods, /* tp_methods */
4705 0, /* tp_members */
4706 datetime_getset, /* tp_getset */
4707 &PyDateTime_DateType, /* tp_base */
4708 0, /* tp_dict */
4709 0, /* tp_descr_get */
4710 0, /* tp_descr_set */
4711 0, /* tp_dictoffset */
4712 0, /* tp_init */
4713 datetime_alloc, /* tp_alloc */
4714 datetime_new, /* tp_new */
4715 0, /* tp_free */
4718 /* ---------------------------------------------------------------------------
4719 * Module methods and initialization.
4722 static PyMethodDef module_methods[] = {
4723 {NULL, NULL}
4726 /* C API. Clients get at this via PyDateTime_IMPORT, defined in
4727 * datetime.h.
4729 static PyDateTime_CAPI CAPI = {
4730 &PyDateTime_DateType,
4731 &PyDateTime_DateTimeType,
4732 &PyDateTime_TimeType,
4733 &PyDateTime_DeltaType,
4734 &PyDateTime_TZInfoType,
4735 new_date_ex,
4736 new_datetime_ex,
4737 new_time_ex,
4738 new_delta_ex,
4739 datetime_fromtimestamp,
4740 date_fromtimestamp
4744 PyMODINIT_FUNC
4745 initdatetime(void)
4747 PyObject *m; /* a module object */
4748 PyObject *d; /* its dict */
4749 PyObject *x;
4751 m = Py_InitModule3("datetime", module_methods,
4752 "Fast implementation of the datetime type.");
4753 if (m == NULL)
4754 return;
4756 if (PyType_Ready(&PyDateTime_DateType) < 0)
4757 return;
4758 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4759 return;
4760 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4761 return;
4762 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4763 return;
4764 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4765 return;
4767 /* timedelta values */
4768 d = PyDateTime_DeltaType.tp_dict;
4770 x = new_delta(0, 0, 1, 0);
4771 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4772 return;
4773 Py_DECREF(x);
4775 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4776 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4777 return;
4778 Py_DECREF(x);
4780 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4781 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4782 return;
4783 Py_DECREF(x);
4785 /* date values */
4786 d = PyDateTime_DateType.tp_dict;
4788 x = new_date(1, 1, 1);
4789 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4790 return;
4791 Py_DECREF(x);
4793 x = new_date(MAXYEAR, 12, 31);
4794 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4795 return;
4796 Py_DECREF(x);
4798 x = new_delta(1, 0, 0, 0);
4799 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4800 return;
4801 Py_DECREF(x);
4803 /* time values */
4804 d = PyDateTime_TimeType.tp_dict;
4806 x = new_time(0, 0, 0, 0, Py_None);
4807 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4808 return;
4809 Py_DECREF(x);
4811 x = new_time(23, 59, 59, 999999, Py_None);
4812 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4813 return;
4814 Py_DECREF(x);
4816 x = new_delta(0, 0, 1, 0);
4817 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4818 return;
4819 Py_DECREF(x);
4821 /* datetime values */
4822 d = PyDateTime_DateTimeType.tp_dict;
4824 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4825 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4826 return;
4827 Py_DECREF(x);
4829 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4830 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4831 return;
4832 Py_DECREF(x);
4834 x = new_delta(0, 0, 1, 0);
4835 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4836 return;
4837 Py_DECREF(x);
4839 /* module initialization */
4840 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4841 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4843 Py_INCREF(&PyDateTime_DateType);
4844 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4846 Py_INCREF(&PyDateTime_DateTimeType);
4847 PyModule_AddObject(m, "datetime",
4848 (PyObject *)&PyDateTime_DateTimeType);
4850 Py_INCREF(&PyDateTime_TimeType);
4851 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4853 Py_INCREF(&PyDateTime_DeltaType);
4854 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4856 Py_INCREF(&PyDateTime_TZInfoType);
4857 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4859 x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
4860 NULL);
4861 if (x == NULL)
4862 return;
4863 PyModule_AddObject(m, "datetime_CAPI", x);
4865 /* A 4-year cycle has an extra leap day over what we'd get from
4866 * pasting together 4 single years.
4868 assert(DI4Y == 4 * 365 + 1);
4869 assert(DI4Y == days_before_year(4+1));
4871 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4872 * get from pasting together 4 100-year cycles.
4874 assert(DI400Y == 4 * DI100Y + 1);
4875 assert(DI400Y == days_before_year(400+1));
4877 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4878 * pasting together 25 4-year cycles.
4880 assert(DI100Y == 25 * DI4Y - 1);
4881 assert(DI100Y == days_before_year(100+1));
4883 us_per_us = PyInt_FromLong(1);
4884 us_per_ms = PyInt_FromLong(1000);
4885 us_per_second = PyInt_FromLong(1000000);
4886 us_per_minute = PyInt_FromLong(60000000);
4887 seconds_per_day = PyInt_FromLong(24 * 3600);
4888 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4889 us_per_minute == NULL || seconds_per_day == NULL)
4890 return;
4892 /* The rest are too big for 32-bit ints, but even
4893 * us_per_week fits in 40 bits, so doubles should be exact.
4895 us_per_hour = PyLong_FromDouble(3600000000.0);
4896 us_per_day = PyLong_FromDouble(86400000000.0);
4897 us_per_week = PyLong_FromDouble(604800000000.0);
4898 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4899 return;
4902 /* ---------------------------------------------------------------------------
4903 Some time zone algebra. For a datetime x, let
4904 x.n = x stripped of its timezone -- its naive time.
4905 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4906 return None
4907 x.d = x.dst(), and assuming that doesn't raise an exception or
4908 return None
4909 x.s = x's standard offset, x.o - x.d
4911 Now some derived rules, where k is a duration (timedelta).
4913 1. x.o = x.s + x.d
4914 This follows from the definition of x.s.
4916 2. If x and y have the same tzinfo member, x.s = y.s.
4917 This is actually a requirement, an assumption we need to make about
4918 sane tzinfo classes.
4920 3. The naive UTC time corresponding to x is x.n - x.o.
4921 This is again a requirement for a sane tzinfo class.
4923 4. (x+k).s = x.s
4924 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
4926 5. (x+k).n = x.n + k
4927 Again follows from how arithmetic is defined.
4929 Now we can explain tz.fromutc(x). Let's assume it's an interesting case
4930 (meaning that the various tzinfo methods exist, and don't blow up or return
4931 None when called).
4933 The function wants to return a datetime y with timezone tz, equivalent to x.
4934 x is already in UTC.
4936 By #3, we want
4938 y.n - y.o = x.n [1]
4940 The algorithm starts by attaching tz to x.n, and calling that y. So
4941 x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4942 becomes true; in effect, we want to solve [2] for k:
4944 (y+k).n - (y+k).o = x.n [2]
4946 By #1, this is the same as
4948 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
4950 By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4951 Substituting that into [3],
4953 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4954 k - (y+k).s - (y+k).d = 0; rearranging,
4955 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4956 k = y.s - (y+k).d
4958 On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4959 approximate k by ignoring the (y+k).d term at first. Note that k can't be
4960 very large, since all offset-returning methods return a duration of magnitude
4961 less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4962 be 0, so ignoring it has no consequence then.
4964 In any case, the new value is
4966 z = y + y.s [4]
4968 It's helpful to step back at look at [4] from a higher level: it's simply
4969 mapping from UTC to tz's standard time.
4971 At this point, if
4973 z.n - z.o = x.n [5]
4975 we have an equivalent time, and are almost done. The insecurity here is
4976 at the start of daylight time. Picture US Eastern for concreteness. The wall
4977 time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
4978 sense then. The docs ask that an Eastern tzinfo class consider such a time to
4979 be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4980 on the day DST starts. We want to return the 1:MM EST spelling because that's
4981 the only spelling that makes sense on the local wall clock.
4983 In fact, if [5] holds at this point, we do have the standard-time spelling,
4984 but that takes a bit of proof. We first prove a stronger result. What's the
4985 difference between the LHS and RHS of [5]? Let
4987 diff = x.n - (z.n - z.o) [6]
4990 z.n = by [4]
4991 (y + y.s).n = by #5
4992 y.n + y.s = since y.n = x.n
4993 x.n + y.s = since z and y are have the same tzinfo member,
4994 y.s = z.s by #2
4995 x.n + z.s
4997 Plugging that back into [6] gives
4999 diff =
5000 x.n - ((x.n + z.s) - z.o) = expanding
5001 x.n - x.n - z.s + z.o = cancelling
5002 - z.s + z.o = by #2
5005 So diff = z.d.
5007 If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
5008 spelling we wanted in the endcase described above. We're done. Contrarily,
5009 if z.d = 0, then we have a UTC equivalent, and are also done.
5011 If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5012 add to z (in effect, z is in tz's standard time, and we need to shift the
5013 local clock into tz's daylight time).
5017 z' = z + z.d = z + diff [7]
5019 and we can again ask whether
5021 z'.n - z'.o = x.n [8]
5023 If so, we're done. If not, the tzinfo class is insane, according to the
5024 assumptions we've made. This also requires a bit of proof. As before, let's
5025 compute the difference between the LHS and RHS of [8] (and skipping some of
5026 the justifications for the kinds of substitutions we've done several times
5027 already):
5029 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5030 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5031 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5032 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5033 - z.n + z.n - z.o + z'.o = cancel z.n
5034 - z.o + z'.o = #1 twice
5035 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5036 z'.d - z.d
5038 So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
5039 we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5040 return z', not bothering to compute z'.d.
5042 How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5043 a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5044 would have to change the result dst() returns: we start in DST, and moving
5045 a little further into it takes us out of DST.
5047 There isn't a sane case where this can happen. The closest it gets is at
5048 the end of DST, where there's an hour in UTC with no spelling in a hybrid
5049 tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5050 that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5051 UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5052 time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5053 clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5054 standard time. Since that's what the local clock *does*, we want to map both
5055 UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
5056 in local time, but so it goes -- it's the way the local clock works.
5058 When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5059 so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5060 z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
5061 (correctly) concludes that z' is not UTC-equivalent to x.
5063 Because we know z.d said z was in daylight time (else [5] would have held and
5064 we would have stopped then), and we know z.d != z'.d (else [8] would have held
5065 and we would have stopped then), and there are only 2 possible values dst() can
5066 return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5067 but the reasoning doesn't depend on the example -- it depends on there being
5068 two possible dst() outcomes, one zero and the other non-zero). Therefore
5069 z' must be in standard time, and is the spelling we want in this case.
5071 Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5072 concerned (because it takes z' as being in standard time rather than the
5073 daylight time we intend here), but returning it gives the real-life "local
5074 clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5077 When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5078 the 1:MM standard time spelling we want.
5080 So how can this break? One of the assumptions must be violated. Two
5081 possibilities:
5083 1) [2] effectively says that y.s is invariant across all y belong to a given
5084 time zone. This isn't true if, for political reasons or continental drift,
5085 a region decides to change its base offset from UTC.
5087 2) There may be versions of "double daylight" time where the tail end of
5088 the analysis gives up a step too early. I haven't thought about that
5089 enough to say.
5091 In any case, it's clear that the default fromutc() is strong enough to handle
5092 "almost all" time zones: so long as the standard offset is invariant, it
5093 doesn't matter if daylight time transition points change from year to year, or
5094 if daylight time is skipped in some years; it doesn't matter how large or
5095 small dst() may get within its bounds; and it doesn't even matter if some
5096 perverse time zone returns a negative dst()). So a breaking case must be
5097 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
5098 --------------------------------------------------------------------------- */