move sections
[python/dscho.git] / Modules / datetimemodule.c
blobf907093015619f6dec2be77fe71f0b6d4769c1d0
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
35 #define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
37 /* Nine decimal digits is easy to communicate, and leaves enough room
38 * so that two delta days can be added w/o fear of overflowing a signed
39 * 32-bit int, and with plenty of room left over to absorb any possible
40 * carries from adding seconds.
42 #define MAX_DELTA_DAYS 999999999
44 /* Rename the long macros in datetime.h to more reasonable short names. */
45 #define GET_YEAR PyDateTime_GET_YEAR
46 #define GET_MONTH PyDateTime_GET_MONTH
47 #define GET_DAY PyDateTime_GET_DAY
48 #define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
49 #define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
50 #define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
51 #define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
53 /* Date accessors for date and datetime. */
54 #define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
55 ((o)->data[1] = ((v) & 0x00ff)))
56 #define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
57 #define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
59 /* Date/Time accessors for datetime. */
60 #define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
61 #define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
62 #define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
63 #define DATE_SET_MICROSECOND(o, v) \
64 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
65 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
66 ((o)->data[9] = ((v) & 0x0000ff)))
68 /* Time accessors for time. */
69 #define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
70 #define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
71 #define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
72 #define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
73 #define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
74 #define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
75 #define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
76 #define TIME_SET_MICROSECOND(o, v) \
77 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
78 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
79 ((o)->data[5] = ((v) & 0x0000ff)))
81 /* Delta accessors for timedelta. */
82 #define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
83 #define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
84 #define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
86 #define SET_TD_DAYS(o, v) ((o)->days = (v))
87 #define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
88 #define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
90 /* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
91 * p->hastzinfo.
93 #define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
95 /* M is a char or int claiming to be a valid month. The macro is equivalent
96 * to the two-sided Python test
97 * 1 <= M <= 12
99 #define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
101 /* Forward declarations. */
102 static PyTypeObject PyDateTime_DateType;
103 static PyTypeObject PyDateTime_DateTimeType;
104 static PyTypeObject PyDateTime_DeltaType;
105 static PyTypeObject PyDateTime_TimeType;
106 static PyTypeObject PyDateTime_TZInfoType;
108 /* ---------------------------------------------------------------------------
109 * Math utilities.
112 /* k = i+j overflows iff k differs in sign from both inputs,
113 * iff k^i has sign bit set and k^j has sign bit set,
114 * iff (k^i)&(k^j) has sign bit set.
116 #define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
117 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
119 /* Compute Python divmod(x, y), returning the quotient and storing the
120 * remainder into *r. The quotient is the floor of x/y, and that's
121 * the real point of this. C will probably truncate instead (C99
122 * requires truncation; C89 left it implementation-defined).
123 * Simplification: we *require* that y > 0 here. That's appropriate
124 * for all the uses made of it. This simplifies the code and makes
125 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
126 * overflow case).
128 static int
129 divmod(int x, int y, int *r)
131 int quo;
133 assert(y > 0);
134 quo = x / y;
135 *r = x - quo * y;
136 if (*r < 0) {
137 --quo;
138 *r += y;
140 assert(0 <= *r && *r < y);
141 return quo;
144 /* Round a double to the nearest long. |x| must be small enough to fit
145 * in a C long; this is not checked.
147 static long
148 round_to_long(double x)
150 if (x >= 0.0)
151 x = floor(x + 0.5);
152 else
153 x = ceil(x - 0.5);
154 return (long)x;
157 /* ---------------------------------------------------------------------------
158 * General calendrical helper functions
161 /* For each month ordinal in 1..12, the number of days in that month,
162 * and the number of days before that month in the same year. These
163 * are correct for non-leap years only.
165 static int _days_in_month[] = {
166 0, /* unused; this vector uses 1-based indexing */
167 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
170 static int _days_before_month[] = {
171 0, /* unused; this vector uses 1-based indexing */
172 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
175 /* year -> 1 if leap year, else 0. */
176 static int
177 is_leap(int year)
179 /* Cast year to unsigned. The result is the same either way, but
180 * C can generate faster code for unsigned mod than for signed
181 * mod (especially for % 4 -- a good compiler should just grab
182 * the last 2 bits when the LHS is unsigned).
184 const unsigned int ayear = (unsigned int)year;
185 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
188 /* year, month -> number of days in that month in that year */
189 static int
190 days_in_month(int year, int month)
192 assert(month >= 1);
193 assert(month <= 12);
194 if (month == 2 && is_leap(year))
195 return 29;
196 else
197 return _days_in_month[month];
200 /* year, month -> number of days in year preceeding first day of month */
201 static int
202 days_before_month(int year, int month)
204 int days;
206 assert(month >= 1);
207 assert(month <= 12);
208 days = _days_before_month[month];
209 if (month > 2 && is_leap(year))
210 ++days;
211 return days;
214 /* year -> number of days before January 1st of year. Remember that we
215 * start with year 1, so days_before_year(1) == 0.
217 static int
218 days_before_year(int year)
220 int y = year - 1;
221 /* This is incorrect if year <= 0; we really want the floor
222 * here. But so long as MINYEAR is 1, the smallest year this
223 * can see is 0 (this can happen in some normalization endcases),
224 * so we'll just special-case that.
226 assert (year >= 0);
227 if (y >= 0)
228 return y*365 + y/4 - y/100 + y/400;
229 else {
230 assert(y == -1);
231 return -366;
235 /* Number of days in 4, 100, and 400 year cycles. That these have
236 * the correct values is asserted in the module init function.
238 #define DI4Y 1461 /* days_before_year(5); days in 4 years */
239 #define DI100Y 36524 /* days_before_year(101); days in 100 years */
240 #define DI400Y 146097 /* days_before_year(401); days in 400 years */
242 /* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
243 static void
244 ord_to_ymd(int ordinal, int *year, int *month, int *day)
246 int n, n1, n4, n100, n400, leapyear, preceding;
248 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
249 * leap years repeats exactly every 400 years. The basic strategy is
250 * to find the closest 400-year boundary at or before ordinal, then
251 * work with the offset from that boundary to ordinal. Life is much
252 * clearer if we subtract 1 from ordinal first -- then the values
253 * of ordinal at 400-year boundaries are exactly those divisible
254 * by DI400Y:
256 * D M Y n n-1
257 * -- --- ---- ---------- ----------------
258 * 31 Dec -400 -DI400Y -DI400Y -1
259 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
260 * ...
261 * 30 Dec 000 -1 -2
262 * 31 Dec 000 0 -1
263 * 1 Jan 001 1 0 400-year boundary
264 * 2 Jan 001 2 1
265 * 3 Jan 001 3 2
266 * ...
267 * 31 Dec 400 DI400Y DI400Y -1
268 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
270 assert(ordinal >= 1);
271 --ordinal;
272 n400 = ordinal / DI400Y;
273 n = ordinal % DI400Y;
274 *year = n400 * 400 + 1;
276 /* Now n is the (non-negative) offset, in days, from January 1 of
277 * year, to the desired date. Now compute how many 100-year cycles
278 * precede n.
279 * Note that it's possible for n100 to equal 4! In that case 4 full
280 * 100-year cycles precede the desired day, which implies the
281 * desired day is December 31 at the end of a 400-year cycle.
283 n100 = n / DI100Y;
284 n = n % DI100Y;
286 /* Now compute how many 4-year cycles precede it. */
287 n4 = n / DI4Y;
288 n = n % DI4Y;
290 /* And now how many single years. Again n1 can be 4, and again
291 * meaning that the desired day is December 31 at the end of the
292 * 4-year cycle.
294 n1 = n / 365;
295 n = n % 365;
297 *year += n100 * 100 + n4 * 4 + n1;
298 if (n1 == 4 || n100 == 4) {
299 assert(n == 0);
300 *year -= 1;
301 *month = 12;
302 *day = 31;
303 return;
306 /* Now the year is correct, and n is the offset from January 1. We
307 * find the month via an estimate that's either exact or one too
308 * large.
310 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
311 assert(leapyear == is_leap(*year));
312 *month = (n + 50) >> 5;
313 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
314 if (preceding > n) {
315 /* estimate is too large */
316 *month -= 1;
317 preceding -= days_in_month(*year, *month);
319 n -= preceding;
320 assert(0 <= n);
321 assert(n < days_in_month(*year, *month));
323 *day = n + 1;
326 /* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
327 static int
328 ymd_to_ord(int year, int month, int day)
330 return days_before_year(year) + days_before_month(year, month) + day;
333 /* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
334 static int
335 weekday(int year, int month, int day)
337 return (ymd_to_ord(year, month, day) + 6) % 7;
340 /* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
341 * first calendar week containing a Thursday.
343 static int
344 iso_week1_monday(int year)
346 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
347 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
348 int first_weekday = (first_day + 6) % 7;
349 /* ordinal of closest Monday at or before 1/1 */
350 int week1_monday = first_day - first_weekday;
352 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
353 week1_monday += 7;
354 return week1_monday;
357 /* ---------------------------------------------------------------------------
358 * Range checkers.
361 /* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
362 * If not, raise OverflowError and return -1.
364 static int
365 check_delta_day_range(int days)
367 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
368 return 0;
369 PyErr_Format(PyExc_OverflowError,
370 "days=%d; must have magnitude <= %d",
371 days, MAX_DELTA_DAYS);
372 return -1;
375 /* Check that date arguments are in range. Return 0 if they are. If they
376 * aren't, raise ValueError and return -1.
378 static int
379 check_date_args(int year, int month, int day)
382 if (year < MINYEAR || year > MAXYEAR) {
383 PyErr_SetString(PyExc_ValueError,
384 "year is out of range");
385 return -1;
387 if (month < 1 || month > 12) {
388 PyErr_SetString(PyExc_ValueError,
389 "month must be in 1..12");
390 return -1;
392 if (day < 1 || day > days_in_month(year, month)) {
393 PyErr_SetString(PyExc_ValueError,
394 "day is out of range for month");
395 return -1;
397 return 0;
400 /* Check that time arguments are in range. Return 0 if they are. If they
401 * aren't, raise ValueError and return -1.
403 static int
404 check_time_args(int h, int m, int s, int us)
406 if (h < 0 || h > 23) {
407 PyErr_SetString(PyExc_ValueError,
408 "hour must be in 0..23");
409 return -1;
411 if (m < 0 || m > 59) {
412 PyErr_SetString(PyExc_ValueError,
413 "minute must be in 0..59");
414 return -1;
416 if (s < 0 || s > 59) {
417 PyErr_SetString(PyExc_ValueError,
418 "second must be in 0..59");
419 return -1;
421 if (us < 0 || us > 999999) {
422 PyErr_SetString(PyExc_ValueError,
423 "microsecond must be in 0..999999");
424 return -1;
426 return 0;
429 /* ---------------------------------------------------------------------------
430 * Normalization utilities.
433 /* One step of a mixed-radix conversion. A "hi" unit is equivalent to
434 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
435 * at least factor, enough of *lo is converted into "hi" units so that
436 * 0 <= *lo < factor. The input values must be such that int overflow
437 * is impossible.
439 static void
440 normalize_pair(int *hi, int *lo, int factor)
442 assert(factor > 0);
443 assert(lo != hi);
444 if (*lo < 0 || *lo >= factor) {
445 const int num_hi = divmod(*lo, factor, lo);
446 const int new_hi = *hi + num_hi;
447 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
448 *hi = new_hi;
450 assert(0 <= *lo && *lo < factor);
453 /* Fiddle days (d), seconds (s), and microseconds (us) so that
454 * 0 <= *s < 24*3600
455 * 0 <= *us < 1000000
456 * The input values must be such that the internals don't overflow.
457 * The way this routine is used, we don't get close.
459 static void
460 normalize_d_s_us(int *d, int *s, int *us)
462 if (*us < 0 || *us >= 1000000) {
463 normalize_pair(s, us, 1000000);
464 /* |s| can't be bigger than about
465 * |original s| + |original us|/1000000 now.
469 if (*s < 0 || *s >= 24*3600) {
470 normalize_pair(d, s, 24*3600);
471 /* |d| can't be bigger than about
472 * |original d| +
473 * (|original s| + |original us|/1000000) / (24*3600) now.
476 assert(0 <= *s && *s < 24*3600);
477 assert(0 <= *us && *us < 1000000);
480 /* Fiddle years (y), months (m), and days (d) so that
481 * 1 <= *m <= 12
482 * 1 <= *d <= days_in_month(*y, *m)
483 * The input values must be such that the internals don't overflow.
484 * The way this routine is used, we don't get close.
486 static int
487 normalize_y_m_d(int *y, int *m, int *d)
489 int dim; /* # of days in month */
491 /* This gets muddy: the proper range for day can't be determined
492 * without knowing the correct month and year, but if day is, e.g.,
493 * plus or minus a million, the current month and year values make
494 * no sense (and may also be out of bounds themselves).
495 * Saying 12 months == 1 year should be non-controversial.
497 if (*m < 1 || *m > 12) {
498 --*m;
499 normalize_pair(y, m, 12);
500 ++*m;
501 /* |y| can't be bigger than about
502 * |original y| + |original m|/12 now.
505 assert(1 <= *m && *m <= 12);
507 /* Now only day can be out of bounds (year may also be out of bounds
508 * for a datetime object, but we don't care about that here).
509 * If day is out of bounds, what to do is arguable, but at least the
510 * method here is principled and explainable.
512 dim = days_in_month(*y, *m);
513 if (*d < 1 || *d > dim) {
514 /* Move day-1 days from the first of the month. First try to
515 * get off cheap if we're only one day out of range
516 * (adjustments for timezone alone can't be worse than that).
518 if (*d == 0) {
519 --*m;
520 if (*m > 0)
521 *d = days_in_month(*y, *m);
522 else {
523 --*y;
524 *m = 12;
525 *d = 31;
528 else if (*d == dim + 1) {
529 /* move forward a day */
530 ++*m;
531 *d = 1;
532 if (*m > 12) {
533 *m = 1;
534 ++*y;
537 else {
538 int ordinal = ymd_to_ord(*y, *m, 1) +
539 *d - 1;
540 if (ordinal < 1 || ordinal > MAXORDINAL) {
541 goto error;
542 } else {
543 ord_to_ymd(ordinal, y, m, d);
544 return 0;
548 assert(*m > 0);
549 assert(*d > 0);
550 if (MINYEAR <= *y && *y <= MAXYEAR)
551 return 0;
552 error:
553 PyErr_SetString(PyExc_OverflowError,
554 "date value out of range");
555 return -1;
559 /* Fiddle out-of-bounds months and days so that the result makes some kind
560 * of sense. The parameters are both inputs and outputs. Returns < 0 on
561 * failure, where failure means the adjusted year is out of bounds.
563 static int
564 normalize_date(int *year, int *month, int *day)
566 return normalize_y_m_d(year, month, day);
569 /* Force all the datetime fields into range. The parameters are both
570 * inputs and outputs. Returns < 0 on error.
572 static int
573 normalize_datetime(int *year, int *month, int *day,
574 int *hour, int *minute, int *second,
575 int *microsecond)
577 normalize_pair(second, microsecond, 1000000);
578 normalize_pair(minute, second, 60);
579 normalize_pair(hour, minute, 60);
580 normalize_pair(day, hour, 24);
581 return normalize_date(year, month, day);
584 /* ---------------------------------------------------------------------------
585 * Basic object allocation: tp_alloc implementations. These allocate
586 * Python objects of the right size and type, and do the Python object-
587 * initialization bit. If there's not enough memory, they return NULL after
588 * setting MemoryError. All data members remain uninitialized trash.
590 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
591 * member is needed. This is ugly, imprecise, and possibly insecure.
592 * tp_basicsize for the time and datetime types is set to the size of the
593 * struct that has room for the tzinfo member, so subclasses in Python will
594 * allocate enough space for a tzinfo member whether or not one is actually
595 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
596 * part is that PyType_GenericAlloc() (which subclasses in Python end up
597 * using) just happens today to effectively ignore the nitems argument
598 * when tp_itemsize is 0, which it is for these type objects. If that
599 * changes, perhaps the callers of tp_alloc slots in this file should
600 * be changed to force a 0 nitems argument unless the type being allocated
601 * is a base type implemented in this file (so that tp_alloc is time_alloc
602 * or datetime_alloc below, which know about the nitems abuse).
605 static PyObject *
606 time_alloc(PyTypeObject *type, Py_ssize_t aware)
608 PyObject *self;
610 self = (PyObject *)
611 PyObject_MALLOC(aware ?
612 sizeof(PyDateTime_Time) :
613 sizeof(_PyDateTime_BaseTime));
614 if (self == NULL)
615 return (PyObject *)PyErr_NoMemory();
616 PyObject_INIT(self, type);
617 return self;
620 static PyObject *
621 datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
623 PyObject *self;
625 self = (PyObject *)
626 PyObject_MALLOC(aware ?
627 sizeof(PyDateTime_DateTime) :
628 sizeof(_PyDateTime_BaseDateTime));
629 if (self == NULL)
630 return (PyObject *)PyErr_NoMemory();
631 PyObject_INIT(self, type);
632 return self;
635 /* ---------------------------------------------------------------------------
636 * Helpers for setting object fields. These work on pointers to the
637 * appropriate base class.
640 /* For date and datetime. */
641 static void
642 set_date_fields(PyDateTime_Date *self, int y, int m, int d)
644 self->hashcode = -1;
645 SET_YEAR(self, y);
646 SET_MONTH(self, m);
647 SET_DAY(self, d);
650 /* ---------------------------------------------------------------------------
651 * Create various objects, mostly without range checking.
654 /* Create a date instance with no range checking. */
655 static PyObject *
656 new_date_ex(int year, int month, int day, PyTypeObject *type)
658 PyDateTime_Date *self;
660 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
661 if (self != NULL)
662 set_date_fields(self, year, month, day);
663 return (PyObject *) self;
666 #define new_date(year, month, day) \
667 new_date_ex(year, month, day, &PyDateTime_DateType)
669 /* Create a datetime instance with no range checking. */
670 static PyObject *
671 new_datetime_ex(int year, int month, int day, int hour, int minute,
672 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
674 PyDateTime_DateTime *self;
675 char aware = tzinfo != Py_None;
677 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
678 if (self != NULL) {
679 self->hastzinfo = aware;
680 set_date_fields((PyDateTime_Date *)self, year, month, day);
681 DATE_SET_HOUR(self, hour);
682 DATE_SET_MINUTE(self, minute);
683 DATE_SET_SECOND(self, second);
684 DATE_SET_MICROSECOND(self, usecond);
685 if (aware) {
686 Py_INCREF(tzinfo);
687 self->tzinfo = tzinfo;
690 return (PyObject *)self;
693 #define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
694 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
695 &PyDateTime_DateTimeType)
697 /* Create a time instance with no range checking. */
698 static PyObject *
699 new_time_ex(int hour, int minute, int second, int usecond,
700 PyObject *tzinfo, PyTypeObject *type)
702 PyDateTime_Time *self;
703 char aware = tzinfo != Py_None;
705 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
706 if (self != NULL) {
707 self->hastzinfo = aware;
708 self->hashcode = -1;
709 TIME_SET_HOUR(self, hour);
710 TIME_SET_MINUTE(self, minute);
711 TIME_SET_SECOND(self, second);
712 TIME_SET_MICROSECOND(self, usecond);
713 if (aware) {
714 Py_INCREF(tzinfo);
715 self->tzinfo = tzinfo;
718 return (PyObject *)self;
721 #define new_time(hh, mm, ss, us, tzinfo) \
722 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
724 /* Create a timedelta instance. Normalize the members iff normalize is
725 * true. Passing false is a speed optimization, if you know for sure
726 * that seconds and microseconds are already in their proper ranges. In any
727 * case, raises OverflowError and returns NULL if the normalized days is out
728 * of range).
730 static PyObject *
731 new_delta_ex(int days, int seconds, int microseconds, int normalize,
732 PyTypeObject *type)
734 PyDateTime_Delta *self;
736 if (normalize)
737 normalize_d_s_us(&days, &seconds, &microseconds);
738 assert(0 <= seconds && seconds < 24*3600);
739 assert(0 <= microseconds && microseconds < 1000000);
741 if (check_delta_day_range(days) < 0)
742 return NULL;
744 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
745 if (self != NULL) {
746 self->hashcode = -1;
747 SET_TD_DAYS(self, days);
748 SET_TD_SECONDS(self, seconds);
749 SET_TD_MICROSECONDS(self, microseconds);
751 return (PyObject *) self;
754 #define new_delta(d, s, us, normalize) \
755 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
757 /* ---------------------------------------------------------------------------
758 * tzinfo helpers.
761 /* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
762 * raise TypeError and return -1.
764 static int
765 check_tzinfo_subclass(PyObject *p)
767 if (p == Py_None || PyTZInfo_Check(p))
768 return 0;
769 PyErr_Format(PyExc_TypeError,
770 "tzinfo argument must be None or of a tzinfo subclass, "
771 "not type '%s'",
772 Py_TYPE(p)->tp_name);
773 return -1;
776 /* Return tzinfo.methname(tzinfoarg), without any checking of results.
777 * If tzinfo is None, returns None.
779 static PyObject *
780 call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
782 PyObject *result;
784 assert(tzinfo && methname && tzinfoarg);
785 assert(check_tzinfo_subclass(tzinfo) >= 0);
786 if (tzinfo == Py_None) {
787 result = Py_None;
788 Py_INCREF(result);
790 else
791 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
792 return result;
795 /* If self has a tzinfo member, return a BORROWED reference to it. Else
796 * return NULL, which is NOT AN ERROR. There are no error returns here,
797 * and the caller must not decref the result.
799 static PyObject *
800 get_tzinfo_member(PyObject *self)
802 PyObject *tzinfo = NULL;
804 if (PyDateTime_Check(self) && HASTZINFO(self))
805 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
806 else if (PyTime_Check(self) && HASTZINFO(self))
807 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
809 return tzinfo;
812 /* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
813 * result. tzinfo must be an instance of the tzinfo class. If the method
814 * returns None, this returns 0 and sets *none to 1. If the method doesn't
815 * return None or timedelta, TypeError is raised and this returns -1. If it
816 * returnsa timedelta and the value is out of range or isn't a whole number
817 * of minutes, ValueError is raised and this returns -1.
818 * Else *none is set to 0 and the integer method result is returned.
820 static int
821 call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
822 int *none)
824 PyObject *u;
825 int result = -1;
827 assert(tzinfo != NULL);
828 assert(PyTZInfo_Check(tzinfo));
829 assert(tzinfoarg != NULL);
831 *none = 0;
832 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
833 if (u == NULL)
834 return -1;
836 else if (u == Py_None) {
837 result = 0;
838 *none = 1;
840 else if (PyDelta_Check(u)) {
841 const int days = GET_TD_DAYS(u);
842 if (days < -1 || days > 0)
843 result = 24*60; /* trigger ValueError below */
844 else {
845 /* next line can't overflow because we know days
846 * is -1 or 0 now
848 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
849 result = divmod(ss, 60, &ss);
850 if (ss || GET_TD_MICROSECONDS(u)) {
851 PyErr_Format(PyExc_ValueError,
852 "tzinfo.%s() must return a "
853 "whole number of minutes",
854 name);
855 result = -1;
859 else {
860 PyErr_Format(PyExc_TypeError,
861 "tzinfo.%s() must return None or "
862 "timedelta, not '%s'",
863 name, Py_TYPE(u)->tp_name);
866 Py_DECREF(u);
867 if (result < -1439 || result > 1439) {
868 PyErr_Format(PyExc_ValueError,
869 "tzinfo.%s() returned %d; must be in "
870 "-1439 .. 1439",
871 name, result);
872 result = -1;
874 return result;
877 /* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
878 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
879 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
880 * doesn't return None or timedelta, TypeError is raised and this returns -1.
881 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
882 * # of minutes), ValueError is raised and this returns -1. Else *none is
883 * set to 0 and the offset is returned (as int # of minutes east of UTC).
885 static int
886 call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
888 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
891 /* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
893 static PyObject *
894 offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
895 PyObject *result;
897 assert(tzinfo && name && tzinfoarg);
898 if (tzinfo == Py_None) {
899 result = Py_None;
900 Py_INCREF(result);
902 else {
903 int none;
904 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
905 &none);
906 if (offset < 0 && PyErr_Occurred())
907 return NULL;
908 if (none) {
909 result = Py_None;
910 Py_INCREF(result);
912 else
913 result = new_delta(0, offset * 60, 0, 1);
915 return result;
918 /* Call tzinfo.dst(tzinfoarg), and extract an integer from the
919 * result. tzinfo must be an instance of the tzinfo class. If dst()
920 * returns None, call_dst returns 0 and sets *none to 1. If dst()
921 & doesn't return None or timedelta, TypeError is raised and this
922 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
923 * ValueError is raised and this returns -1. Else *none is set to 0 and
924 * the offset is returned (as an int # of minutes east of UTC).
926 static int
927 call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
929 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
932 /* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
933 * an instance of the tzinfo class or None. If tzinfo isn't None, and
934 * tzname() doesn't return None or a string, TypeError is raised and this
935 * returns NULL.
937 static PyObject *
938 call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
940 PyObject *result;
942 assert(tzinfo != NULL);
943 assert(check_tzinfo_subclass(tzinfo) >= 0);
944 assert(tzinfoarg != NULL);
946 if (tzinfo == Py_None) {
947 result = Py_None;
948 Py_INCREF(result);
950 else
951 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
953 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
954 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
955 "return None or a string, not '%s'",
956 Py_TYPE(result)->tp_name);
957 Py_DECREF(result);
958 result = NULL;
960 return result;
963 typedef enum {
964 /* an exception has been set; the caller should pass it on */
965 OFFSET_ERROR,
967 /* type isn't date, datetime, or time subclass */
968 OFFSET_UNKNOWN,
970 /* date,
971 * datetime with !hastzinfo
972 * datetime with None tzinfo,
973 * datetime where utcoffset() returns None
974 * time with !hastzinfo
975 * time with None tzinfo,
976 * time where utcoffset() returns None
978 OFFSET_NAIVE,
980 /* time or datetime where utcoffset() doesn't return None */
981 OFFSET_AWARE
982 } naivety;
984 /* Classify an object as to whether it's naive or offset-aware. See
985 * the "naivety" typedef for details. If the type is aware, *offset is set
986 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
987 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
988 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
990 static naivety
991 classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
993 int none;
994 PyObject *tzinfo;
996 assert(tzinfoarg != NULL);
997 *offset = 0;
998 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
999 if (tzinfo == Py_None)
1000 return OFFSET_NAIVE;
1001 if (tzinfo == NULL) {
1002 /* note that a datetime passes the PyDate_Check test */
1003 return (PyTime_Check(op) || PyDate_Check(op)) ?
1004 OFFSET_NAIVE : OFFSET_UNKNOWN;
1006 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1007 if (*offset == -1 && PyErr_Occurred())
1008 return OFFSET_ERROR;
1009 return none ? OFFSET_NAIVE : OFFSET_AWARE;
1012 /* Classify two objects as to whether they're naive or offset-aware.
1013 * This isn't quite the same as calling classify_utcoffset() twice: for
1014 * binary operations (comparison and subtraction), we generally want to
1015 * ignore the tzinfo members if they're identical. This is by design,
1016 * so that results match "naive" expectations when mixing objects from a
1017 * single timezone. So in that case, this sets both offsets to 0 and
1018 * both naiveties to OFFSET_NAIVE.
1019 * The function returns 0 if everything's OK, and -1 on error.
1021 static int
1022 classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
1023 PyObject *tzinfoarg1,
1024 PyObject *o2, int *offset2, naivety *n2,
1025 PyObject *tzinfoarg2)
1027 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1028 *offset1 = *offset2 = 0;
1029 *n1 = *n2 = OFFSET_NAIVE;
1031 else {
1032 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1033 if (*n1 == OFFSET_ERROR)
1034 return -1;
1035 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1036 if (*n2 == OFFSET_ERROR)
1037 return -1;
1039 return 0;
1042 /* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1043 * stuff
1044 * ", tzinfo=" + repr(tzinfo)
1045 * before the closing ")".
1047 static PyObject *
1048 append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1050 PyObject *temp;
1052 assert(PyString_Check(repr));
1053 assert(tzinfo);
1054 if (tzinfo == Py_None)
1055 return repr;
1056 /* Get rid of the trailing ')'. */
1057 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1058 temp = PyString_FromStringAndSize(PyString_AsString(repr),
1059 PyString_Size(repr) - 1);
1060 Py_DECREF(repr);
1061 if (temp == NULL)
1062 return NULL;
1063 repr = temp;
1065 /* Append ", tzinfo=". */
1066 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
1068 /* Append repr(tzinfo). */
1069 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
1071 /* Add a closing paren. */
1072 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
1073 return repr;
1076 /* ---------------------------------------------------------------------------
1077 * String format helpers.
1080 static PyObject *
1081 format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
1083 static const char *DayNames[] = {
1084 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1086 static const char *MonthNames[] = {
1087 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1088 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1091 char buffer[128];
1092 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1094 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
1095 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
1096 GET_DAY(date), hours, minutes, seconds,
1097 GET_YEAR(date));
1098 return PyString_FromString(buffer);
1101 /* Add an hours & minutes UTC offset string to buf. buf has no more than
1102 * buflen bytes remaining. The UTC offset is gotten by calling
1103 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1104 * *buf, and that's all. Else the returned value is checked for sanity (an
1105 * integer in range), and if that's OK it's converted to an hours & minutes
1106 * string of the form
1107 * sign HH sep MM
1108 * Returns 0 if everything is OK. If the return value from utcoffset() is
1109 * bogus, an appropriate exception is set and -1 is returned.
1111 static int
1112 format_utcoffset(char *buf, size_t buflen, const char *sep,
1113 PyObject *tzinfo, PyObject *tzinfoarg)
1115 int offset;
1116 int hours;
1117 int minutes;
1118 char sign;
1119 int none;
1121 assert(buflen >= 1);
1123 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1124 if (offset == -1 && PyErr_Occurred())
1125 return -1;
1126 if (none) {
1127 *buf = '\0';
1128 return 0;
1130 sign = '+';
1131 if (offset < 0) {
1132 sign = '-';
1133 offset = - offset;
1135 hours = divmod(offset, 60, &minutes);
1136 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1137 return 0;
1140 static PyObject *
1141 make_freplacement(PyObject *object)
1143 char freplacement[64];
1144 if (PyTime_Check(object))
1145 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1146 else if (PyDateTime_Check(object))
1147 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1148 else
1149 sprintf(freplacement, "%06d", 0);
1151 return PyString_FromStringAndSize(freplacement, strlen(freplacement));
1154 /* I sure don't want to reproduce the strftime code from the time module,
1155 * so this imports the module and calls it. All the hair is due to
1156 * giving special meanings to the %z, %Z and %f format codes via a
1157 * preprocessing step on the format string.
1158 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1159 * needed.
1161 static PyObject *
1162 wrap_strftime(PyObject *object, const char *format, size_t format_len,
1163 PyObject *timetuple, PyObject *tzinfoarg)
1165 PyObject *result = NULL; /* guilty until proved innocent */
1167 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1168 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1169 PyObject *freplacement = NULL; /* py string, replacement for %f */
1171 const char *pin; /* pointer to next char in input format */
1172 char ch; /* next char in input format */
1174 PyObject *newfmt = NULL; /* py string, the output format */
1175 char *pnew; /* pointer to available byte in output format */
1176 size_t totalnew; /* number bytes total in output format buffer,
1177 exclusive of trailing \0 */
1178 size_t usednew; /* number bytes used so far in output format buffer */
1180 const char *ptoappend; /* ptr to string to append to output buffer */
1181 size_t ntoappend; /* # of bytes to append to output buffer */
1183 assert(object && format && timetuple);
1185 /* Give up if the year is before 1900.
1186 * Python strftime() plays games with the year, and different
1187 * games depending on whether envar PYTHON2K is set. This makes
1188 * years before 1900 a nightmare, even if the platform strftime
1189 * supports them (and not all do).
1190 * We could get a lot farther here by avoiding Python's strftime
1191 * wrapper and calling the C strftime() directly, but that isn't
1192 * an option in the Python implementation of this module.
1195 long year;
1196 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1197 if (pyyear == NULL) return NULL;
1198 assert(PyInt_Check(pyyear));
1199 year = PyInt_AsLong(pyyear);
1200 Py_DECREF(pyyear);
1201 if (year < 1900) {
1202 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1203 "1900; the datetime strftime() "
1204 "methods require year >= 1900",
1205 year);
1206 return NULL;
1210 /* Scan the input format, looking for %z/%Z/%f escapes, building
1211 * a new format. Since computing the replacements for those codes
1212 * is expensive, don't unless they're actually used.
1214 if (format_len > INT_MAX - 1) {
1215 PyErr_NoMemory();
1216 goto Done;
1219 totalnew = format_len + 1; /* realistic if no %z/%Z/%f */
1220 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1221 if (newfmt == NULL) goto Done;
1222 pnew = PyString_AsString(newfmt);
1223 usednew = 0;
1225 pin = format;
1226 while ((ch = *pin++) != '\0') {
1227 if (ch != '%') {
1228 ptoappend = pin - 1;
1229 ntoappend = 1;
1231 else if ((ch = *pin++) == '\0') {
1232 /* There's a lone trailing %; doesn't make sense. */
1233 PyErr_SetString(PyExc_ValueError, "strftime format "
1234 "ends with raw %");
1235 goto Done;
1237 /* A % has been seen and ch is the character after it. */
1238 else if (ch == 'z') {
1239 if (zreplacement == NULL) {
1240 /* format utcoffset */
1241 char buf[100];
1242 PyObject *tzinfo = get_tzinfo_member(object);
1243 zreplacement = PyString_FromString("");
1244 if (zreplacement == NULL) goto Done;
1245 if (tzinfo != Py_None && tzinfo != NULL) {
1246 assert(tzinfoarg != NULL);
1247 if (format_utcoffset(buf,
1248 sizeof(buf),
1250 tzinfo,
1251 tzinfoarg) < 0)
1252 goto Done;
1253 Py_DECREF(zreplacement);
1254 zreplacement = PyString_FromString(buf);
1255 if (zreplacement == NULL) goto Done;
1258 assert(zreplacement != NULL);
1259 ptoappend = PyString_AS_STRING(zreplacement);
1260 ntoappend = PyString_GET_SIZE(zreplacement);
1262 else if (ch == 'Z') {
1263 /* format tzname */
1264 if (Zreplacement == NULL) {
1265 PyObject *tzinfo = get_tzinfo_member(object);
1266 Zreplacement = PyString_FromString("");
1267 if (Zreplacement == NULL) goto Done;
1268 if (tzinfo != Py_None && tzinfo != NULL) {
1269 PyObject *temp;
1270 assert(tzinfoarg != NULL);
1271 temp = call_tzname(tzinfo, tzinfoarg);
1272 if (temp == NULL) goto Done;
1273 if (temp != Py_None) {
1274 assert(PyString_Check(temp));
1275 /* Since the tzname is getting
1276 * stuffed into the format, we
1277 * have to double any % signs
1278 * so that strftime doesn't
1279 * treat them as format codes.
1281 Py_DECREF(Zreplacement);
1282 Zreplacement = PyObject_CallMethod(
1283 temp, "replace",
1284 "ss", "%", "%%");
1285 Py_DECREF(temp);
1286 if (Zreplacement == NULL)
1287 goto Done;
1288 if (!PyString_Check(Zreplacement)) {
1289 PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
1290 goto Done;
1293 else
1294 Py_DECREF(temp);
1297 assert(Zreplacement != NULL);
1298 ptoappend = PyString_AS_STRING(Zreplacement);
1299 ntoappend = PyString_GET_SIZE(Zreplacement);
1301 else if (ch == 'f') {
1302 /* format microseconds */
1303 if (freplacement == NULL) {
1304 freplacement = make_freplacement(object);
1305 if (freplacement == NULL)
1306 goto Done;
1308 assert(freplacement != NULL);
1309 assert(PyString_Check(freplacement));
1310 ptoappend = PyString_AS_STRING(freplacement);
1311 ntoappend = PyString_GET_SIZE(freplacement);
1313 else {
1314 /* percent followed by neither z nor Z */
1315 ptoappend = pin - 2;
1316 ntoappend = 2;
1319 /* Append the ntoappend chars starting at ptoappend to
1320 * the new format.
1322 assert(ptoappend != NULL);
1323 assert(ntoappend >= 0);
1324 if (ntoappend == 0)
1325 continue;
1326 while (usednew + ntoappend > totalnew) {
1327 size_t bigger = totalnew << 1;
1328 if ((bigger >> 1) != totalnew) { /* overflow */
1329 PyErr_NoMemory();
1330 goto Done;
1332 if (_PyString_Resize(&newfmt, bigger) < 0)
1333 goto Done;
1334 totalnew = bigger;
1335 pnew = PyString_AsString(newfmt) + usednew;
1337 memcpy(pnew, ptoappend, ntoappend);
1338 pnew += ntoappend;
1339 usednew += ntoappend;
1340 assert(usednew <= totalnew);
1341 } /* end while() */
1343 if (_PyString_Resize(&newfmt, usednew) < 0)
1344 goto Done;
1346 PyObject *time = PyImport_ImportModuleNoBlock("time");
1347 if (time == NULL)
1348 goto Done;
1349 result = PyObject_CallMethod(time, "strftime", "OO",
1350 newfmt, timetuple);
1351 Py_DECREF(time);
1353 Done:
1354 Py_XDECREF(freplacement);
1355 Py_XDECREF(zreplacement);
1356 Py_XDECREF(Zreplacement);
1357 Py_XDECREF(newfmt);
1358 return result;
1361 static char *
1362 isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1364 int x;
1365 x = PyOS_snprintf(buffer, bufflen,
1366 "%04d-%02d-%02d",
1367 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1368 assert(bufflen >= x);
1369 return buffer + x;
1372 static char *
1373 isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1375 int x;
1376 int us = DATE_GET_MICROSECOND(dt);
1378 x = PyOS_snprintf(buffer, bufflen,
1379 "%02d:%02d:%02d",
1380 DATE_GET_HOUR(dt),
1381 DATE_GET_MINUTE(dt),
1382 DATE_GET_SECOND(dt));
1383 assert(bufflen >= x);
1384 if (us)
1385 x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us);
1386 assert(bufflen >= x);
1387 return buffer + x;
1390 /* ---------------------------------------------------------------------------
1391 * Wrap functions from the time module. These aren't directly available
1392 * from C. Perhaps they should be.
1395 /* Call time.time() and return its result (a Python float). */
1396 static PyObject *
1397 time_time(void)
1399 PyObject *result = NULL;
1400 PyObject *time = PyImport_ImportModuleNoBlock("time");
1402 if (time != NULL) {
1403 result = PyObject_CallMethod(time, "time", "()");
1404 Py_DECREF(time);
1406 return result;
1409 /* Build a time.struct_time. The weekday and day number are automatically
1410 * computed from the y,m,d args.
1412 static PyObject *
1413 build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1415 PyObject *time;
1416 PyObject *result = NULL;
1418 time = PyImport_ImportModuleNoBlock("time");
1419 if (time != NULL) {
1420 result = PyObject_CallMethod(time, "struct_time",
1421 "((iiiiiiiii))",
1422 y, m, d,
1423 hh, mm, ss,
1424 weekday(y, m, d),
1425 days_before_month(y, m) + d,
1426 dstflag);
1427 Py_DECREF(time);
1429 return result;
1432 /* ---------------------------------------------------------------------------
1433 * Miscellaneous helpers.
1436 /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1437 * The comparisons here all most naturally compute a cmp()-like result.
1438 * This little helper turns that into a bool result for rich comparisons.
1440 static PyObject *
1441 diff_to_bool(int diff, int op)
1443 PyObject *result;
1444 int istrue;
1446 switch (op) {
1447 case Py_EQ: istrue = diff == 0; break;
1448 case Py_NE: istrue = diff != 0; break;
1449 case Py_LE: istrue = diff <= 0; break;
1450 case Py_GE: istrue = diff >= 0; break;
1451 case Py_LT: istrue = diff < 0; break;
1452 case Py_GT: istrue = diff > 0; break;
1453 default:
1454 assert(! "op unknown");
1455 istrue = 0; /* To shut up compiler */
1457 result = istrue ? Py_True : Py_False;
1458 Py_INCREF(result);
1459 return result;
1462 /* Raises a "can't compare" TypeError and returns NULL. */
1463 static PyObject *
1464 cmperror(PyObject *a, PyObject *b)
1466 PyErr_Format(PyExc_TypeError,
1467 "can't compare %s to %s",
1468 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1469 return NULL;
1472 /* ---------------------------------------------------------------------------
1473 * Cached Python objects; these are set by the module init function.
1476 /* Conversion factors. */
1477 static PyObject *us_per_us = NULL; /* 1 */
1478 static PyObject *us_per_ms = NULL; /* 1000 */
1479 static PyObject *us_per_second = NULL; /* 1000000 */
1480 static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1481 static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1482 static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1483 static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1484 static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1486 /* ---------------------------------------------------------------------------
1487 * Class implementations.
1491 * PyDateTime_Delta implementation.
1494 /* Convert a timedelta to a number of us,
1495 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1496 * as a Python int or long.
1497 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1498 * due to ubiquitous overflow possibilities.
1500 static PyObject *
1501 delta_to_microseconds(PyDateTime_Delta *self)
1503 PyObject *x1 = NULL;
1504 PyObject *x2 = NULL;
1505 PyObject *x3 = NULL;
1506 PyObject *result = NULL;
1508 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1509 if (x1 == NULL)
1510 goto Done;
1511 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1512 if (x2 == NULL)
1513 goto Done;
1514 Py_DECREF(x1);
1515 x1 = NULL;
1517 /* x2 has days in seconds */
1518 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1519 if (x1 == NULL)
1520 goto Done;
1521 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1522 if (x3 == NULL)
1523 goto Done;
1524 Py_DECREF(x1);
1525 Py_DECREF(x2);
1526 x2 = NULL;
1528 /* x3 has days+seconds in seconds */
1529 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1530 if (x1 == NULL)
1531 goto Done;
1532 Py_DECREF(x3);
1533 x3 = NULL;
1535 /* x1 has days+seconds in us */
1536 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1537 if (x2 == NULL)
1538 goto Done;
1539 result = PyNumber_Add(x1, x2);
1541 Done:
1542 Py_XDECREF(x1);
1543 Py_XDECREF(x2);
1544 Py_XDECREF(x3);
1545 return result;
1548 /* Convert a number of us (as a Python int or long) to a timedelta.
1550 static PyObject *
1551 microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1553 int us;
1554 int s;
1555 int d;
1556 long temp;
1558 PyObject *tuple = NULL;
1559 PyObject *num = NULL;
1560 PyObject *result = NULL;
1562 tuple = PyNumber_Divmod(pyus, us_per_second);
1563 if (tuple == NULL)
1564 goto Done;
1566 num = PyTuple_GetItem(tuple, 1); /* us */
1567 if (num == NULL)
1568 goto Done;
1569 temp = PyLong_AsLong(num);
1570 num = NULL;
1571 if (temp == -1 && PyErr_Occurred())
1572 goto Done;
1573 assert(0 <= temp && temp < 1000000);
1574 us = (int)temp;
1575 if (us < 0) {
1576 /* The divisor was positive, so this must be an error. */
1577 assert(PyErr_Occurred());
1578 goto Done;
1581 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1582 if (num == NULL)
1583 goto Done;
1584 Py_INCREF(num);
1585 Py_DECREF(tuple);
1587 tuple = PyNumber_Divmod(num, seconds_per_day);
1588 if (tuple == NULL)
1589 goto Done;
1590 Py_DECREF(num);
1592 num = PyTuple_GetItem(tuple, 1); /* seconds */
1593 if (num == NULL)
1594 goto Done;
1595 temp = PyLong_AsLong(num);
1596 num = NULL;
1597 if (temp == -1 && PyErr_Occurred())
1598 goto Done;
1599 assert(0 <= temp && temp < 24*3600);
1600 s = (int)temp;
1602 if (s < 0) {
1603 /* The divisor was positive, so this must be an error. */
1604 assert(PyErr_Occurred());
1605 goto Done;
1608 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1609 if (num == NULL)
1610 goto Done;
1611 Py_INCREF(num);
1612 temp = PyLong_AsLong(num);
1613 if (temp == -1 && PyErr_Occurred())
1614 goto Done;
1615 d = (int)temp;
1616 if ((long)d != temp) {
1617 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1618 "large to fit in a C int");
1619 goto Done;
1621 result = new_delta_ex(d, s, us, 0, type);
1623 Done:
1624 Py_XDECREF(tuple);
1625 Py_XDECREF(num);
1626 return result;
1629 #define microseconds_to_delta(pymicros) \
1630 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1632 static PyObject *
1633 multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1635 PyObject *pyus_in;
1636 PyObject *pyus_out;
1637 PyObject *result;
1639 pyus_in = delta_to_microseconds(delta);
1640 if (pyus_in == NULL)
1641 return NULL;
1643 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1644 Py_DECREF(pyus_in);
1645 if (pyus_out == NULL)
1646 return NULL;
1648 result = microseconds_to_delta(pyus_out);
1649 Py_DECREF(pyus_out);
1650 return result;
1653 static PyObject *
1654 divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1656 PyObject *pyus_in;
1657 PyObject *pyus_out;
1658 PyObject *result;
1660 pyus_in = delta_to_microseconds(delta);
1661 if (pyus_in == NULL)
1662 return NULL;
1664 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1665 Py_DECREF(pyus_in);
1666 if (pyus_out == NULL)
1667 return NULL;
1669 result = microseconds_to_delta(pyus_out);
1670 Py_DECREF(pyus_out);
1671 return result;
1674 static PyObject *
1675 delta_add(PyObject *left, PyObject *right)
1677 PyObject *result = Py_NotImplemented;
1679 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1680 /* delta + delta */
1681 /* The C-level additions can't overflow because of the
1682 * invariant bounds.
1684 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1685 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1686 int microseconds = GET_TD_MICROSECONDS(left) +
1687 GET_TD_MICROSECONDS(right);
1688 result = new_delta(days, seconds, microseconds, 1);
1691 if (result == Py_NotImplemented)
1692 Py_INCREF(result);
1693 return result;
1696 static PyObject *
1697 delta_negative(PyDateTime_Delta *self)
1699 return new_delta(-GET_TD_DAYS(self),
1700 -GET_TD_SECONDS(self),
1701 -GET_TD_MICROSECONDS(self),
1705 static PyObject *
1706 delta_positive(PyDateTime_Delta *self)
1708 /* Could optimize this (by returning self) if this isn't a
1709 * subclass -- but who uses unary + ? Approximately nobody.
1711 return new_delta(GET_TD_DAYS(self),
1712 GET_TD_SECONDS(self),
1713 GET_TD_MICROSECONDS(self),
1717 static PyObject *
1718 delta_abs(PyDateTime_Delta *self)
1720 PyObject *result;
1722 assert(GET_TD_MICROSECONDS(self) >= 0);
1723 assert(GET_TD_SECONDS(self) >= 0);
1725 if (GET_TD_DAYS(self) < 0)
1726 result = delta_negative(self);
1727 else
1728 result = delta_positive(self);
1730 return result;
1733 static PyObject *
1734 delta_subtract(PyObject *left, PyObject *right)
1736 PyObject *result = Py_NotImplemented;
1738 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1739 /* delta - delta */
1740 PyObject *minus_right = PyNumber_Negative(right);
1741 if (minus_right) {
1742 result = delta_add(left, minus_right);
1743 Py_DECREF(minus_right);
1745 else
1746 result = NULL;
1749 if (result == Py_NotImplemented)
1750 Py_INCREF(result);
1751 return result;
1754 /* This is more natural as a tp_compare, but doesn't work then: for whatever
1755 * reason, Python's try_3way_compare ignores tp_compare unless
1756 * PyInstance_Check returns true, but these aren't old-style classes.
1758 static PyObject *
1759 delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1761 int diff = 42; /* nonsense */
1763 if (PyDelta_Check(other)) {
1764 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1765 if (diff == 0) {
1766 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1767 if (diff == 0)
1768 diff = GET_TD_MICROSECONDS(self) -
1769 GET_TD_MICROSECONDS(other);
1772 else if (op == Py_EQ || op == Py_NE)
1773 diff = 1; /* any non-zero value will do */
1775 else /* stop this from falling back to address comparison */
1776 return cmperror((PyObject *)self, other);
1778 return diff_to_bool(diff, op);
1781 static PyObject *delta_getstate(PyDateTime_Delta *self);
1783 static long
1784 delta_hash(PyDateTime_Delta *self)
1786 if (self->hashcode == -1) {
1787 PyObject *temp = delta_getstate(self);
1788 if (temp != NULL) {
1789 self->hashcode = PyObject_Hash(temp);
1790 Py_DECREF(temp);
1793 return self->hashcode;
1796 static PyObject *
1797 delta_multiply(PyObject *left, PyObject *right)
1799 PyObject *result = Py_NotImplemented;
1801 if (PyDelta_Check(left)) {
1802 /* delta * ??? */
1803 if (PyInt_Check(right) || PyLong_Check(right))
1804 result = multiply_int_timedelta(right,
1805 (PyDateTime_Delta *) left);
1807 else if (PyInt_Check(left) || PyLong_Check(left))
1808 result = multiply_int_timedelta(left,
1809 (PyDateTime_Delta *) right);
1811 if (result == Py_NotImplemented)
1812 Py_INCREF(result);
1813 return result;
1816 static PyObject *
1817 delta_divide(PyObject *left, PyObject *right)
1819 PyObject *result = Py_NotImplemented;
1821 if (PyDelta_Check(left)) {
1822 /* delta * ??? */
1823 if (PyInt_Check(right) || PyLong_Check(right))
1824 result = divide_timedelta_int(
1825 (PyDateTime_Delta *)left,
1826 right);
1829 if (result == Py_NotImplemented)
1830 Py_INCREF(result);
1831 return result;
1834 /* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1835 * timedelta constructor. sofar is the # of microseconds accounted for
1836 * so far, and there are factor microseconds per current unit, the number
1837 * of which is given by num. num * factor is added to sofar in a
1838 * numerically careful way, and that's the result. Any fractional
1839 * microseconds left over (this can happen if num is a float type) are
1840 * added into *leftover.
1841 * Note that there are many ways this can give an error (NULL) return.
1843 static PyObject *
1844 accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1845 double *leftover)
1847 PyObject *prod;
1848 PyObject *sum;
1850 assert(num != NULL);
1852 if (PyInt_Check(num) || PyLong_Check(num)) {
1853 prod = PyNumber_Multiply(num, factor);
1854 if (prod == NULL)
1855 return NULL;
1856 sum = PyNumber_Add(sofar, prod);
1857 Py_DECREF(prod);
1858 return sum;
1861 if (PyFloat_Check(num)) {
1862 double dnum;
1863 double fracpart;
1864 double intpart;
1865 PyObject *x;
1866 PyObject *y;
1868 /* The Plan: decompose num into an integer part and a
1869 * fractional part, num = intpart + fracpart.
1870 * Then num * factor ==
1871 * intpart * factor + fracpart * factor
1872 * and the LHS can be computed exactly in long arithmetic.
1873 * The RHS is again broken into an int part and frac part.
1874 * and the frac part is added into *leftover.
1876 dnum = PyFloat_AsDouble(num);
1877 if (dnum == -1.0 && PyErr_Occurred())
1878 return NULL;
1879 fracpart = modf(dnum, &intpart);
1880 x = PyLong_FromDouble(intpart);
1881 if (x == NULL)
1882 return NULL;
1884 prod = PyNumber_Multiply(x, factor);
1885 Py_DECREF(x);
1886 if (prod == NULL)
1887 return NULL;
1889 sum = PyNumber_Add(sofar, prod);
1890 Py_DECREF(prod);
1891 if (sum == NULL)
1892 return NULL;
1894 if (fracpart == 0.0)
1895 return sum;
1896 /* So far we've lost no information. Dealing with the
1897 * fractional part requires float arithmetic, and may
1898 * lose a little info.
1900 assert(PyInt_Check(factor) || PyLong_Check(factor));
1901 if (PyInt_Check(factor))
1902 dnum = (double)PyInt_AsLong(factor);
1903 else
1904 dnum = PyLong_AsDouble(factor);
1906 dnum *= fracpart;
1907 fracpart = modf(dnum, &intpart);
1908 x = PyLong_FromDouble(intpart);
1909 if (x == NULL) {
1910 Py_DECREF(sum);
1911 return NULL;
1914 y = PyNumber_Add(sum, x);
1915 Py_DECREF(sum);
1916 Py_DECREF(x);
1917 *leftover += fracpart;
1918 return y;
1921 PyErr_Format(PyExc_TypeError,
1922 "unsupported type for timedelta %s component: %s",
1923 tag, Py_TYPE(num)->tp_name);
1924 return NULL;
1927 static PyObject *
1928 delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1930 PyObject *self = NULL;
1932 /* Argument objects. */
1933 PyObject *day = NULL;
1934 PyObject *second = NULL;
1935 PyObject *us = NULL;
1936 PyObject *ms = NULL;
1937 PyObject *minute = NULL;
1938 PyObject *hour = NULL;
1939 PyObject *week = NULL;
1941 PyObject *x = NULL; /* running sum of microseconds */
1942 PyObject *y = NULL; /* temp sum of microseconds */
1943 double leftover_us = 0.0;
1945 static char *keywords[] = {
1946 "days", "seconds", "microseconds", "milliseconds",
1947 "minutes", "hours", "weeks", NULL
1950 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1951 keywords,
1952 &day, &second, &us,
1953 &ms, &minute, &hour, &week) == 0)
1954 goto Done;
1956 x = PyInt_FromLong(0);
1957 if (x == NULL)
1958 goto Done;
1960 #define CLEANUP \
1961 Py_DECREF(x); \
1962 x = y; \
1963 if (x == NULL) \
1964 goto Done
1966 if (us) {
1967 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1968 CLEANUP;
1970 if (ms) {
1971 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1972 CLEANUP;
1974 if (second) {
1975 y = accum("seconds", x, second, us_per_second, &leftover_us);
1976 CLEANUP;
1978 if (minute) {
1979 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1980 CLEANUP;
1982 if (hour) {
1983 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1984 CLEANUP;
1986 if (day) {
1987 y = accum("days", x, day, us_per_day, &leftover_us);
1988 CLEANUP;
1990 if (week) {
1991 y = accum("weeks", x, week, us_per_week, &leftover_us);
1992 CLEANUP;
1994 if (leftover_us) {
1995 /* Round to nearest whole # of us, and add into x. */
1996 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1997 if (temp == NULL) {
1998 Py_DECREF(x);
1999 goto Done;
2001 y = PyNumber_Add(x, temp);
2002 Py_DECREF(temp);
2003 CLEANUP;
2006 self = microseconds_to_delta_ex(x, type);
2007 Py_DECREF(x);
2008 Done:
2009 return self;
2011 #undef CLEANUP
2014 static int
2015 delta_nonzero(PyDateTime_Delta *self)
2017 return (GET_TD_DAYS(self) != 0
2018 || GET_TD_SECONDS(self) != 0
2019 || GET_TD_MICROSECONDS(self) != 0);
2022 static PyObject *
2023 delta_repr(PyDateTime_Delta *self)
2025 if (GET_TD_MICROSECONDS(self) != 0)
2026 return PyString_FromFormat("%s(%d, %d, %d)",
2027 Py_TYPE(self)->tp_name,
2028 GET_TD_DAYS(self),
2029 GET_TD_SECONDS(self),
2030 GET_TD_MICROSECONDS(self));
2031 if (GET_TD_SECONDS(self) != 0)
2032 return PyString_FromFormat("%s(%d, %d)",
2033 Py_TYPE(self)->tp_name,
2034 GET_TD_DAYS(self),
2035 GET_TD_SECONDS(self));
2037 return PyString_FromFormat("%s(%d)",
2038 Py_TYPE(self)->tp_name,
2039 GET_TD_DAYS(self));
2042 static PyObject *
2043 delta_str(PyDateTime_Delta *self)
2045 int days = GET_TD_DAYS(self);
2046 int seconds = GET_TD_SECONDS(self);
2047 int us = GET_TD_MICROSECONDS(self);
2048 int hours;
2049 int minutes;
2050 char buf[100];
2051 char *pbuf = buf;
2052 size_t buflen = sizeof(buf);
2053 int n;
2055 minutes = divmod(seconds, 60, &seconds);
2056 hours = divmod(minutes, 60, &minutes);
2058 if (days) {
2059 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2060 (days == 1 || days == -1) ? "" : "s");
2061 if (n < 0 || (size_t)n >= buflen)
2062 goto Fail;
2063 pbuf += n;
2064 buflen -= (size_t)n;
2067 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2068 hours, minutes, seconds);
2069 if (n < 0 || (size_t)n >= buflen)
2070 goto Fail;
2071 pbuf += n;
2072 buflen -= (size_t)n;
2074 if (us) {
2075 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2076 if (n < 0 || (size_t)n >= buflen)
2077 goto Fail;
2078 pbuf += n;
2081 return PyString_FromStringAndSize(buf, pbuf - buf);
2083 Fail:
2084 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2085 return NULL;
2088 /* Pickle support, a simple use of __reduce__. */
2090 /* __getstate__ isn't exposed */
2091 static PyObject *
2092 delta_getstate(PyDateTime_Delta *self)
2094 return Py_BuildValue("iii", GET_TD_DAYS(self),
2095 GET_TD_SECONDS(self),
2096 GET_TD_MICROSECONDS(self));
2099 static PyObject *
2100 delta_total_seconds(PyObject *self)
2102 PyObject *total_seconds;
2103 PyObject *total_microseconds;
2104 PyObject *one_million;
2106 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2107 if (total_microseconds == NULL)
2108 return NULL;
2110 one_million = PyLong_FromLong(1000000L);
2111 if (one_million == NULL) {
2112 Py_DECREF(total_microseconds);
2113 return NULL;
2116 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
2118 Py_DECREF(total_microseconds);
2119 Py_DECREF(one_million);
2120 return total_seconds;
2123 static PyObject *
2124 delta_reduce(PyDateTime_Delta* self)
2126 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
2129 #define OFFSET(field) offsetof(PyDateTime_Delta, field)
2131 static PyMemberDef delta_members[] = {
2133 {"days", T_INT, OFFSET(days), READONLY,
2134 PyDoc_STR("Number of days.")},
2136 {"seconds", T_INT, OFFSET(seconds), READONLY,
2137 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2139 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2140 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2141 {NULL}
2144 static PyMethodDef delta_methods[] = {
2145 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2146 PyDoc_STR("Total seconds in the duration.")},
2148 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2149 PyDoc_STR("__reduce__() -> (cls, state)")},
2151 {NULL, NULL},
2154 static char delta_doc[] =
2155 PyDoc_STR("Difference between two datetime values.");
2157 static PyNumberMethods delta_as_number = {
2158 delta_add, /* nb_add */
2159 delta_subtract, /* nb_subtract */
2160 delta_multiply, /* nb_multiply */
2161 delta_divide, /* nb_divide */
2162 0, /* nb_remainder */
2163 0, /* nb_divmod */
2164 0, /* nb_power */
2165 (unaryfunc)delta_negative, /* nb_negative */
2166 (unaryfunc)delta_positive, /* nb_positive */
2167 (unaryfunc)delta_abs, /* nb_absolute */
2168 (inquiry)delta_nonzero, /* nb_nonzero */
2169 0, /*nb_invert*/
2170 0, /*nb_lshift*/
2171 0, /*nb_rshift*/
2172 0, /*nb_and*/
2173 0, /*nb_xor*/
2174 0, /*nb_or*/
2175 0, /*nb_coerce*/
2176 0, /*nb_int*/
2177 0, /*nb_long*/
2178 0, /*nb_float*/
2179 0, /*nb_oct*/
2180 0, /*nb_hex*/
2181 0, /*nb_inplace_add*/
2182 0, /*nb_inplace_subtract*/
2183 0, /*nb_inplace_multiply*/
2184 0, /*nb_inplace_divide*/
2185 0, /*nb_inplace_remainder*/
2186 0, /*nb_inplace_power*/
2187 0, /*nb_inplace_lshift*/
2188 0, /*nb_inplace_rshift*/
2189 0, /*nb_inplace_and*/
2190 0, /*nb_inplace_xor*/
2191 0, /*nb_inplace_or*/
2192 delta_divide, /* nb_floor_divide */
2193 0, /* nb_true_divide */
2194 0, /* nb_inplace_floor_divide */
2195 0, /* nb_inplace_true_divide */
2198 static PyTypeObject PyDateTime_DeltaType = {
2199 PyVarObject_HEAD_INIT(NULL, 0)
2200 "datetime.timedelta", /* tp_name */
2201 sizeof(PyDateTime_Delta), /* tp_basicsize */
2202 0, /* tp_itemsize */
2203 0, /* tp_dealloc */
2204 0, /* tp_print */
2205 0, /* tp_getattr */
2206 0, /* tp_setattr */
2207 0, /* tp_compare */
2208 (reprfunc)delta_repr, /* tp_repr */
2209 &delta_as_number, /* tp_as_number */
2210 0, /* tp_as_sequence */
2211 0, /* tp_as_mapping */
2212 (hashfunc)delta_hash, /* tp_hash */
2213 0, /* tp_call */
2214 (reprfunc)delta_str, /* tp_str */
2215 PyObject_GenericGetAttr, /* tp_getattro */
2216 0, /* tp_setattro */
2217 0, /* tp_as_buffer */
2218 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2219 Py_TPFLAGS_BASETYPE, /* tp_flags */
2220 delta_doc, /* tp_doc */
2221 0, /* tp_traverse */
2222 0, /* tp_clear */
2223 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2224 0, /* tp_weaklistoffset */
2225 0, /* tp_iter */
2226 0, /* tp_iternext */
2227 delta_methods, /* tp_methods */
2228 delta_members, /* tp_members */
2229 0, /* tp_getset */
2230 0, /* tp_base */
2231 0, /* tp_dict */
2232 0, /* tp_descr_get */
2233 0, /* tp_descr_set */
2234 0, /* tp_dictoffset */
2235 0, /* tp_init */
2236 0, /* tp_alloc */
2237 delta_new, /* tp_new */
2238 0, /* tp_free */
2242 * PyDateTime_Date implementation.
2245 /* Accessor properties. */
2247 static PyObject *
2248 date_year(PyDateTime_Date *self, void *unused)
2250 return PyInt_FromLong(GET_YEAR(self));
2253 static PyObject *
2254 date_month(PyDateTime_Date *self, void *unused)
2256 return PyInt_FromLong(GET_MONTH(self));
2259 static PyObject *
2260 date_day(PyDateTime_Date *self, void *unused)
2262 return PyInt_FromLong(GET_DAY(self));
2265 static PyGetSetDef date_getset[] = {
2266 {"year", (getter)date_year},
2267 {"month", (getter)date_month},
2268 {"day", (getter)date_day},
2269 {NULL}
2272 /* Constructors. */
2274 static char *date_kws[] = {"year", "month", "day", NULL};
2276 static PyObject *
2277 date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2279 PyObject *self = NULL;
2280 PyObject *state;
2281 int year;
2282 int month;
2283 int day;
2285 /* Check for invocation from pickle with __getstate__ state */
2286 if (PyTuple_GET_SIZE(args) == 1 &&
2287 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2288 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2289 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
2291 PyDateTime_Date *me;
2293 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2294 if (me != NULL) {
2295 char *pdata = PyString_AS_STRING(state);
2296 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2297 me->hashcode = -1;
2299 return (PyObject *)me;
2302 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2303 &year, &month, &day)) {
2304 if (check_date_args(year, month, day) < 0)
2305 return NULL;
2306 self = new_date_ex(year, month, day, type);
2308 return self;
2311 /* Return new date from localtime(t). */
2312 static PyObject *
2313 date_local_from_time_t(PyObject *cls, double ts)
2315 struct tm *tm;
2316 time_t t;
2317 PyObject *result = NULL;
2319 t = _PyTime_DoubleToTimet(ts);
2320 if (t == (time_t)-1 && PyErr_Occurred())
2321 return NULL;
2322 tm = localtime(&t);
2323 if (tm)
2324 result = PyObject_CallFunction(cls, "iii",
2325 tm->tm_year + 1900,
2326 tm->tm_mon + 1,
2327 tm->tm_mday);
2328 else
2329 PyErr_SetString(PyExc_ValueError,
2330 "timestamp out of range for "
2331 "platform localtime() function");
2332 return result;
2335 /* Return new date from current time.
2336 * We say this is equivalent to fromtimestamp(time.time()), and the
2337 * only way to be sure of that is to *call* time.time(). That's not
2338 * generally the same as calling C's time.
2340 static PyObject *
2341 date_today(PyObject *cls, PyObject *dummy)
2343 PyObject *time;
2344 PyObject *result;
2346 time = time_time();
2347 if (time == NULL)
2348 return NULL;
2350 /* Note well: today() is a class method, so this may not call
2351 * date.fromtimestamp. For example, it may call
2352 * datetime.fromtimestamp. That's why we need all the accuracy
2353 * time.time() delivers; if someone were gonzo about optimization,
2354 * date.today() could get away with plain C time().
2356 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2357 Py_DECREF(time);
2358 return result;
2361 /* Return new date from given timestamp (Python timestamp -- a double). */
2362 static PyObject *
2363 date_fromtimestamp(PyObject *cls, PyObject *args)
2365 double timestamp;
2366 PyObject *result = NULL;
2368 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2369 result = date_local_from_time_t(cls, timestamp);
2370 return result;
2373 /* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2374 * the ordinal is out of range.
2376 static PyObject *
2377 date_fromordinal(PyObject *cls, PyObject *args)
2379 PyObject *result = NULL;
2380 int ordinal;
2382 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2383 int year;
2384 int month;
2385 int day;
2387 if (ordinal < 1)
2388 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2389 ">= 1");
2390 else {
2391 ord_to_ymd(ordinal, &year, &month, &day);
2392 result = PyObject_CallFunction(cls, "iii",
2393 year, month, day);
2396 return result;
2400 * Date arithmetic.
2403 /* date + timedelta -> date. If arg negate is true, subtract the timedelta
2404 * instead.
2406 static PyObject *
2407 add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2409 PyObject *result = NULL;
2410 int year = GET_YEAR(date);
2411 int month = GET_MONTH(date);
2412 int deltadays = GET_TD_DAYS(delta);
2413 /* C-level overflow is impossible because |deltadays| < 1e9. */
2414 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2416 if (normalize_date(&year, &month, &day) >= 0)
2417 result = new_date(year, month, day);
2418 return result;
2421 static PyObject *
2422 date_add(PyObject *left, PyObject *right)
2424 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2425 Py_INCREF(Py_NotImplemented);
2426 return Py_NotImplemented;
2428 if (PyDate_Check(left)) {
2429 /* date + ??? */
2430 if (PyDelta_Check(right))
2431 /* date + delta */
2432 return add_date_timedelta((PyDateTime_Date *) left,
2433 (PyDateTime_Delta *) right,
2436 else {
2437 /* ??? + date
2438 * 'right' must be one of us, or we wouldn't have been called
2440 if (PyDelta_Check(left))
2441 /* delta + date */
2442 return add_date_timedelta((PyDateTime_Date *) right,
2443 (PyDateTime_Delta *) left,
2446 Py_INCREF(Py_NotImplemented);
2447 return Py_NotImplemented;
2450 static PyObject *
2451 date_subtract(PyObject *left, PyObject *right)
2453 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2454 Py_INCREF(Py_NotImplemented);
2455 return Py_NotImplemented;
2457 if (PyDate_Check(left)) {
2458 if (PyDate_Check(right)) {
2459 /* date - date */
2460 int left_ord = ymd_to_ord(GET_YEAR(left),
2461 GET_MONTH(left),
2462 GET_DAY(left));
2463 int right_ord = ymd_to_ord(GET_YEAR(right),
2464 GET_MONTH(right),
2465 GET_DAY(right));
2466 return new_delta(left_ord - right_ord, 0, 0, 0);
2468 if (PyDelta_Check(right)) {
2469 /* date - delta */
2470 return add_date_timedelta((PyDateTime_Date *) left,
2471 (PyDateTime_Delta *) right,
2475 Py_INCREF(Py_NotImplemented);
2476 return Py_NotImplemented;
2480 /* Various ways to turn a date into a string. */
2482 static PyObject *
2483 date_repr(PyDateTime_Date *self)
2485 char buffer[1028];
2486 const char *type_name;
2488 type_name = Py_TYPE(self)->tp_name;
2489 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2490 type_name,
2491 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2493 return PyString_FromString(buffer);
2496 static PyObject *
2497 date_isoformat(PyDateTime_Date *self)
2499 char buffer[128];
2501 isoformat_date(self, buffer, sizeof(buffer));
2502 return PyString_FromString(buffer);
2505 /* str() calls the appropriate isoformat() method. */
2506 static PyObject *
2507 date_str(PyDateTime_Date *self)
2509 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2513 static PyObject *
2514 date_ctime(PyDateTime_Date *self)
2516 return format_ctime(self, 0, 0, 0);
2519 static PyObject *
2520 date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2522 /* This method can be inherited, and needs to call the
2523 * timetuple() method appropriate to self's class.
2525 PyObject *result;
2526 PyObject *tuple;
2527 const char *format;
2528 Py_ssize_t format_len;
2529 static char *keywords[] = {"format", NULL};
2531 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2532 &format, &format_len))
2533 return NULL;
2535 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2536 if (tuple == NULL)
2537 return NULL;
2538 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
2539 (PyObject *)self);
2540 Py_DECREF(tuple);
2541 return result;
2544 static PyObject *
2545 date_format(PyDateTime_Date *self, PyObject *args)
2547 PyObject *format;
2549 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2550 return NULL;
2552 /* Check for str or unicode */
2553 if (PyString_Check(format)) {
2554 /* If format is zero length, return str(self) */
2555 if (PyString_GET_SIZE(format) == 0)
2556 return PyObject_Str((PyObject *)self);
2557 } else if (PyUnicode_Check(format)) {
2558 /* If format is zero length, return str(self) */
2559 if (PyUnicode_GET_SIZE(format) == 0)
2560 return PyObject_Unicode((PyObject *)self);
2561 } else {
2562 PyErr_Format(PyExc_ValueError,
2563 "__format__ expects str or unicode, not %.200s",
2564 Py_TYPE(format)->tp_name);
2565 return NULL;
2567 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2570 /* ISO methods. */
2572 static PyObject *
2573 date_isoweekday(PyDateTime_Date *self)
2575 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2577 return PyInt_FromLong(dow + 1);
2580 static PyObject *
2581 date_isocalendar(PyDateTime_Date *self)
2583 int year = GET_YEAR(self);
2584 int week1_monday = iso_week1_monday(year);
2585 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2586 int week;
2587 int day;
2589 week = divmod(today - week1_monday, 7, &day);
2590 if (week < 0) {
2591 --year;
2592 week1_monday = iso_week1_monday(year);
2593 week = divmod(today - week1_monday, 7, &day);
2595 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2596 ++year;
2597 week = 0;
2599 return Py_BuildValue("iii", year, week + 1, day + 1);
2602 /* Miscellaneous methods. */
2604 /* This is more natural as a tp_compare, but doesn't work then: for whatever
2605 * reason, Python's try_3way_compare ignores tp_compare unless
2606 * PyInstance_Check returns true, but these aren't old-style classes.
2608 static PyObject *
2609 date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2611 int diff = 42; /* nonsense */
2613 if (PyDate_Check(other))
2614 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2615 _PyDateTime_DATE_DATASIZE);
2617 else if (PyObject_HasAttrString(other, "timetuple")) {
2618 /* A hook for other kinds of date objects. */
2619 Py_INCREF(Py_NotImplemented);
2620 return Py_NotImplemented;
2622 else if (op == Py_EQ || op == Py_NE)
2623 diff = 1; /* any non-zero value will do */
2625 else /* stop this from falling back to address comparison */
2626 return cmperror((PyObject *)self, other);
2628 return diff_to_bool(diff, op);
2631 static PyObject *
2632 date_timetuple(PyDateTime_Date *self)
2634 return build_struct_time(GET_YEAR(self),
2635 GET_MONTH(self),
2636 GET_DAY(self),
2637 0, 0, 0, -1);
2640 static PyObject *
2641 date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2643 PyObject *clone;
2644 PyObject *tuple;
2645 int year = GET_YEAR(self);
2646 int month = GET_MONTH(self);
2647 int day = GET_DAY(self);
2649 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2650 &year, &month, &day))
2651 return NULL;
2652 tuple = Py_BuildValue("iii", year, month, day);
2653 if (tuple == NULL)
2654 return NULL;
2655 clone = date_new(Py_TYPE(self), tuple, NULL);
2656 Py_DECREF(tuple);
2657 return clone;
2660 static PyObject *date_getstate(PyDateTime_Date *self);
2662 static long
2663 date_hash(PyDateTime_Date *self)
2665 if (self->hashcode == -1) {
2666 PyObject *temp = date_getstate(self);
2667 if (temp != NULL) {
2668 self->hashcode = PyObject_Hash(temp);
2669 Py_DECREF(temp);
2672 return self->hashcode;
2675 static PyObject *
2676 date_toordinal(PyDateTime_Date *self)
2678 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2679 GET_DAY(self)));
2682 static PyObject *
2683 date_weekday(PyDateTime_Date *self)
2685 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2687 return PyInt_FromLong(dow);
2690 /* Pickle support, a simple use of __reduce__. */
2692 /* __getstate__ isn't exposed */
2693 static PyObject *
2694 date_getstate(PyDateTime_Date *self)
2696 return Py_BuildValue(
2697 "(N)",
2698 PyString_FromStringAndSize((char *)self->data,
2699 _PyDateTime_DATE_DATASIZE));
2702 static PyObject *
2703 date_reduce(PyDateTime_Date *self, PyObject *arg)
2705 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
2708 static PyMethodDef date_methods[] = {
2710 /* Class methods: */
2712 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2713 METH_CLASS,
2714 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2715 "time.time()).")},
2717 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2718 METH_CLASS,
2719 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2720 "ordinal.")},
2722 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2723 PyDoc_STR("Current date or datetime: same as "
2724 "self.__class__.fromtimestamp(time.time()).")},
2726 /* Instance methods: */
2728 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2729 PyDoc_STR("Return ctime() style string.")},
2731 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2732 PyDoc_STR("format -> strftime() style string.")},
2734 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2735 PyDoc_STR("Formats self with strftime.")},
2737 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2738 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2740 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2741 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2742 "weekday.")},
2744 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2745 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2747 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2748 PyDoc_STR("Return the day of the week represented by the date.\n"
2749 "Monday == 1 ... Sunday == 7")},
2751 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2752 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2753 "1 is day 1.")},
2755 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2756 PyDoc_STR("Return the day of the week represented by the date.\n"
2757 "Monday == 0 ... Sunday == 6")},
2759 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2760 PyDoc_STR("Return date with new specified fields.")},
2762 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2763 PyDoc_STR("__reduce__() -> (cls, state)")},
2765 {NULL, NULL}
2768 static char date_doc[] =
2769 PyDoc_STR("date(year, month, day) --> date object");
2771 static PyNumberMethods date_as_number = {
2772 date_add, /* nb_add */
2773 date_subtract, /* nb_subtract */
2774 0, /* nb_multiply */
2775 0, /* nb_divide */
2776 0, /* nb_remainder */
2777 0, /* nb_divmod */
2778 0, /* nb_power */
2779 0, /* nb_negative */
2780 0, /* nb_positive */
2781 0, /* nb_absolute */
2782 0, /* nb_nonzero */
2785 static PyTypeObject PyDateTime_DateType = {
2786 PyVarObject_HEAD_INIT(NULL, 0)
2787 "datetime.date", /* tp_name */
2788 sizeof(PyDateTime_Date), /* tp_basicsize */
2789 0, /* tp_itemsize */
2790 0, /* tp_dealloc */
2791 0, /* tp_print */
2792 0, /* tp_getattr */
2793 0, /* tp_setattr */
2794 0, /* tp_compare */
2795 (reprfunc)date_repr, /* tp_repr */
2796 &date_as_number, /* tp_as_number */
2797 0, /* tp_as_sequence */
2798 0, /* tp_as_mapping */
2799 (hashfunc)date_hash, /* tp_hash */
2800 0, /* tp_call */
2801 (reprfunc)date_str, /* tp_str */
2802 PyObject_GenericGetAttr, /* tp_getattro */
2803 0, /* tp_setattro */
2804 0, /* tp_as_buffer */
2805 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2806 Py_TPFLAGS_BASETYPE, /* tp_flags */
2807 date_doc, /* tp_doc */
2808 0, /* tp_traverse */
2809 0, /* tp_clear */
2810 (richcmpfunc)date_richcompare, /* tp_richcompare */
2811 0, /* tp_weaklistoffset */
2812 0, /* tp_iter */
2813 0, /* tp_iternext */
2814 date_methods, /* tp_methods */
2815 0, /* tp_members */
2816 date_getset, /* tp_getset */
2817 0, /* tp_base */
2818 0, /* tp_dict */
2819 0, /* tp_descr_get */
2820 0, /* tp_descr_set */
2821 0, /* tp_dictoffset */
2822 0, /* tp_init */
2823 0, /* tp_alloc */
2824 date_new, /* tp_new */
2825 0, /* tp_free */
2829 * PyDateTime_TZInfo implementation.
2832 /* This is a pure abstract base class, so doesn't do anything beyond
2833 * raising NotImplemented exceptions. Real tzinfo classes need
2834 * to derive from this. This is mostly for clarity, and for efficiency in
2835 * datetime and time constructors (their tzinfo arguments need to
2836 * be subclasses of this tzinfo class, which is easy and quick to check).
2838 * Note: For reasons having to do with pickling of subclasses, we have
2839 * to allow tzinfo objects to be instantiated. This wasn't an issue
2840 * in the Python implementation (__init__() could raise NotImplementedError
2841 * there without ill effect), but doing so in the C implementation hit a
2842 * brick wall.
2845 static PyObject *
2846 tzinfo_nogo(const char* methodname)
2848 PyErr_Format(PyExc_NotImplementedError,
2849 "a tzinfo subclass must implement %s()",
2850 methodname);
2851 return NULL;
2854 /* Methods. A subclass must implement these. */
2856 static PyObject *
2857 tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2859 return tzinfo_nogo("tzname");
2862 static PyObject *
2863 tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2865 return tzinfo_nogo("utcoffset");
2868 static PyObject *
2869 tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2871 return tzinfo_nogo("dst");
2874 static PyObject *
2875 tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2877 int y, m, d, hh, mm, ss, us;
2879 PyObject *result;
2880 int off, dst;
2881 int none;
2882 int delta;
2884 if (! PyDateTime_Check(dt)) {
2885 PyErr_SetString(PyExc_TypeError,
2886 "fromutc: argument must be a datetime");
2887 return NULL;
2889 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2890 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2891 "is not self");
2892 return NULL;
2895 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2896 if (off == -1 && PyErr_Occurred())
2897 return NULL;
2898 if (none) {
2899 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2900 "utcoffset() result required");
2901 return NULL;
2904 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2905 if (dst == -1 && PyErr_Occurred())
2906 return NULL;
2907 if (none) {
2908 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2909 "dst() result required");
2910 return NULL;
2913 y = GET_YEAR(dt);
2914 m = GET_MONTH(dt);
2915 d = GET_DAY(dt);
2916 hh = DATE_GET_HOUR(dt);
2917 mm = DATE_GET_MINUTE(dt);
2918 ss = DATE_GET_SECOND(dt);
2919 us = DATE_GET_MICROSECOND(dt);
2921 delta = off - dst;
2922 mm += delta;
2923 if ((mm < 0 || mm >= 60) &&
2924 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2925 return NULL;
2926 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2927 if (result == NULL)
2928 return result;
2930 dst = call_dst(dt->tzinfo, result, &none);
2931 if (dst == -1 && PyErr_Occurred())
2932 goto Fail;
2933 if (none)
2934 goto Inconsistent;
2935 if (dst == 0)
2936 return result;
2938 mm += dst;
2939 if ((mm < 0 || mm >= 60) &&
2940 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2941 goto Fail;
2942 Py_DECREF(result);
2943 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2944 return result;
2946 Inconsistent:
2947 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2948 "inconsistent results; cannot convert");
2950 /* fall thru to failure */
2951 Fail:
2952 Py_DECREF(result);
2953 return NULL;
2957 * Pickle support. This is solely so that tzinfo subclasses can use
2958 * pickling -- tzinfo itself is supposed to be uninstantiable.
2961 static PyObject *
2962 tzinfo_reduce(PyObject *self)
2964 PyObject *args, *state, *tmp;
2965 PyObject *getinitargs, *getstate;
2967 tmp = PyTuple_New(0);
2968 if (tmp == NULL)
2969 return NULL;
2971 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2972 if (getinitargs != NULL) {
2973 args = PyObject_CallObject(getinitargs, tmp);
2974 Py_DECREF(getinitargs);
2975 if (args == NULL) {
2976 Py_DECREF(tmp);
2977 return NULL;
2980 else {
2981 PyErr_Clear();
2982 args = tmp;
2983 Py_INCREF(args);
2986 getstate = PyObject_GetAttrString(self, "__getstate__");
2987 if (getstate != NULL) {
2988 state = PyObject_CallObject(getstate, tmp);
2989 Py_DECREF(getstate);
2990 if (state == NULL) {
2991 Py_DECREF(args);
2992 Py_DECREF(tmp);
2993 return NULL;
2996 else {
2997 PyObject **dictptr;
2998 PyErr_Clear();
2999 state = Py_None;
3000 dictptr = _PyObject_GetDictPtr(self);
3001 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3002 state = *dictptr;
3003 Py_INCREF(state);
3006 Py_DECREF(tmp);
3008 if (state == Py_None) {
3009 Py_DECREF(state);
3010 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3012 else
3013 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
3016 static PyMethodDef tzinfo_methods[] = {
3018 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3019 PyDoc_STR("datetime -> string name of time zone.")},
3021 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
3022 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3023 "west of UTC).")},
3025 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3026 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3028 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
3029 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3031 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3032 PyDoc_STR("-> (cls, state)")},
3034 {NULL, NULL}
3037 static char tzinfo_doc[] =
3038 PyDoc_STR("Abstract base class for time zone info objects.");
3040 statichere PyTypeObject PyDateTime_TZInfoType = {
3041 PyObject_HEAD_INIT(NULL)
3042 0, /* ob_size */
3043 "datetime.tzinfo", /* tp_name */
3044 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3045 0, /* tp_itemsize */
3046 0, /* tp_dealloc */
3047 0, /* tp_print */
3048 0, /* tp_getattr */
3049 0, /* tp_setattr */
3050 0, /* tp_compare */
3051 0, /* tp_repr */
3052 0, /* tp_as_number */
3053 0, /* tp_as_sequence */
3054 0, /* tp_as_mapping */
3055 0, /* tp_hash */
3056 0, /* tp_call */
3057 0, /* tp_str */
3058 PyObject_GenericGetAttr, /* tp_getattro */
3059 0, /* tp_setattro */
3060 0, /* tp_as_buffer */
3061 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3062 Py_TPFLAGS_BASETYPE, /* tp_flags */
3063 tzinfo_doc, /* tp_doc */
3064 0, /* tp_traverse */
3065 0, /* tp_clear */
3066 0, /* tp_richcompare */
3067 0, /* tp_weaklistoffset */
3068 0, /* tp_iter */
3069 0, /* tp_iternext */
3070 tzinfo_methods, /* tp_methods */
3071 0, /* tp_members */
3072 0, /* tp_getset */
3073 0, /* tp_base */
3074 0, /* tp_dict */
3075 0, /* tp_descr_get */
3076 0, /* tp_descr_set */
3077 0, /* tp_dictoffset */
3078 0, /* tp_init */
3079 0, /* tp_alloc */
3080 PyType_GenericNew, /* tp_new */
3081 0, /* tp_free */
3085 * PyDateTime_Time implementation.
3088 /* Accessor properties.
3091 static PyObject *
3092 time_hour(PyDateTime_Time *self, void *unused)
3094 return PyInt_FromLong(TIME_GET_HOUR(self));
3097 static PyObject *
3098 time_minute(PyDateTime_Time *self, void *unused)
3100 return PyInt_FromLong(TIME_GET_MINUTE(self));
3103 /* The name time_second conflicted with some platform header file. */
3104 static PyObject *
3105 py_time_second(PyDateTime_Time *self, void *unused)
3107 return PyInt_FromLong(TIME_GET_SECOND(self));
3110 static PyObject *
3111 time_microsecond(PyDateTime_Time *self, void *unused)
3113 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3116 static PyObject *
3117 time_tzinfo(PyDateTime_Time *self, void *unused)
3119 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3120 Py_INCREF(result);
3121 return result;
3124 static PyGetSetDef time_getset[] = {
3125 {"hour", (getter)time_hour},
3126 {"minute", (getter)time_minute},
3127 {"second", (getter)py_time_second},
3128 {"microsecond", (getter)time_microsecond},
3129 {"tzinfo", (getter)time_tzinfo},
3130 {NULL}
3134 * Constructors.
3137 static char *time_kws[] = {"hour", "minute", "second", "microsecond",
3138 "tzinfo", NULL};
3140 static PyObject *
3141 time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3143 PyObject *self = NULL;
3144 PyObject *state;
3145 int hour = 0;
3146 int minute = 0;
3147 int second = 0;
3148 int usecond = 0;
3149 PyObject *tzinfo = Py_None;
3151 /* Check for invocation from pickle with __getstate__ state */
3152 if (PyTuple_GET_SIZE(args) >= 1 &&
3153 PyTuple_GET_SIZE(args) <= 2 &&
3154 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3155 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3156 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
3158 PyDateTime_Time *me;
3159 char aware;
3161 if (PyTuple_GET_SIZE(args) == 2) {
3162 tzinfo = PyTuple_GET_ITEM(args, 1);
3163 if (check_tzinfo_subclass(tzinfo) < 0) {
3164 PyErr_SetString(PyExc_TypeError, "bad "
3165 "tzinfo state arg");
3166 return NULL;
3169 aware = (char)(tzinfo != Py_None);
3170 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3171 if (me != NULL) {
3172 char *pdata = PyString_AS_STRING(state);
3174 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3175 me->hashcode = -1;
3176 me->hastzinfo = aware;
3177 if (aware) {
3178 Py_INCREF(tzinfo);
3179 me->tzinfo = tzinfo;
3182 return (PyObject *)me;
3185 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3186 &hour, &minute, &second, &usecond,
3187 &tzinfo)) {
3188 if (check_time_args(hour, minute, second, usecond) < 0)
3189 return NULL;
3190 if (check_tzinfo_subclass(tzinfo) < 0)
3191 return NULL;
3192 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3193 type);
3195 return self;
3199 * Destructor.
3202 static void
3203 time_dealloc(PyDateTime_Time *self)
3205 if (HASTZINFO(self)) {
3206 Py_XDECREF(self->tzinfo);
3208 Py_TYPE(self)->tp_free((PyObject *)self);
3212 * Indirect access to tzinfo methods.
3215 /* These are all METH_NOARGS, so don't need to check the arglist. */
3216 static PyObject *
3217 time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
3218 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3219 "utcoffset", Py_None);
3222 static PyObject *
3223 time_dst(PyDateTime_Time *self, PyObject *unused) {
3224 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3225 "dst", Py_None);
3228 static PyObject *
3229 time_tzname(PyDateTime_Time *self, PyObject *unused) {
3230 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3231 Py_None);
3235 * Various ways to turn a time into a string.
3238 static PyObject *
3239 time_repr(PyDateTime_Time *self)
3241 char buffer[100];
3242 const char *type_name = Py_TYPE(self)->tp_name;
3243 int h = TIME_GET_HOUR(self);
3244 int m = TIME_GET_MINUTE(self);
3245 int s = TIME_GET_SECOND(self);
3246 int us = TIME_GET_MICROSECOND(self);
3247 PyObject *result = NULL;
3249 if (us)
3250 PyOS_snprintf(buffer, sizeof(buffer),
3251 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
3252 else if (s)
3253 PyOS_snprintf(buffer, sizeof(buffer),
3254 "%s(%d, %d, %d)", type_name, h, m, s);
3255 else
3256 PyOS_snprintf(buffer, sizeof(buffer),
3257 "%s(%d, %d)", type_name, h, m);
3258 result = PyString_FromString(buffer);
3259 if (result != NULL && HASTZINFO(self))
3260 result = append_keyword_tzinfo(result, self->tzinfo);
3261 return result;
3264 static PyObject *
3265 time_str(PyDateTime_Time *self)
3267 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3270 static PyObject *
3271 time_isoformat(PyDateTime_Time *self, PyObject *unused)
3273 char buf[100];
3274 PyObject *result;
3275 /* Reuse the time format code from the datetime type. */
3276 PyDateTime_DateTime datetime;
3277 PyDateTime_DateTime *pdatetime = &datetime;
3279 /* Copy over just the time bytes. */
3280 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3281 self->data,
3282 _PyDateTime_TIME_DATASIZE);
3284 isoformat_time(pdatetime, buf, sizeof(buf));
3285 result = PyString_FromString(buf);
3286 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3287 return result;
3289 /* We need to append the UTC offset. */
3290 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3291 Py_None) < 0) {
3292 Py_DECREF(result);
3293 return NULL;
3295 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3296 return result;
3299 static PyObject *
3300 time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3302 PyObject *result;
3303 PyObject *tuple;
3304 const char *format;
3305 Py_ssize_t format_len;
3306 static char *keywords[] = {"format", NULL};
3308 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3309 &format, &format_len))
3310 return NULL;
3312 /* Python's strftime does insane things with the year part of the
3313 * timetuple. The year is forced to (the otherwise nonsensical)
3314 * 1900 to worm around that.
3316 tuple = Py_BuildValue("iiiiiiiii",
3317 1900, 1, 1, /* year, month, day */
3318 TIME_GET_HOUR(self),
3319 TIME_GET_MINUTE(self),
3320 TIME_GET_SECOND(self),
3321 0, 1, -1); /* weekday, daynum, dst */
3322 if (tuple == NULL)
3323 return NULL;
3324 assert(PyTuple_Size(tuple) == 9);
3325 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3326 Py_None);
3327 Py_DECREF(tuple);
3328 return result;
3332 * Miscellaneous methods.
3335 /* This is more natural as a tp_compare, but doesn't work then: for whatever
3336 * reason, Python's try_3way_compare ignores tp_compare unless
3337 * PyInstance_Check returns true, but these aren't old-style classes.
3339 static PyObject *
3340 time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3342 int diff;
3343 naivety n1, n2;
3344 int offset1, offset2;
3346 if (! PyTime_Check(other)) {
3347 if (op == Py_EQ || op == Py_NE) {
3348 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3349 Py_INCREF(result);
3350 return result;
3352 /* Stop this from falling back to address comparison. */
3353 return cmperror((PyObject *)self, other);
3355 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3356 other, &offset2, &n2, Py_None) < 0)
3357 return NULL;
3358 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3359 /* If they're both naive, or both aware and have the same offsets,
3360 * we get off cheap. Note that if they're both naive, offset1 ==
3361 * offset2 == 0 at this point.
3363 if (n1 == n2 && offset1 == offset2) {
3364 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3365 _PyDateTime_TIME_DATASIZE);
3366 return diff_to_bool(diff, op);
3369 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3370 assert(offset1 != offset2); /* else last "if" handled it */
3371 /* Convert everything except microseconds to seconds. These
3372 * can't overflow (no more than the # of seconds in 2 days).
3374 offset1 = TIME_GET_HOUR(self) * 3600 +
3375 (TIME_GET_MINUTE(self) - offset1) * 60 +
3376 TIME_GET_SECOND(self);
3377 offset2 = TIME_GET_HOUR(other) * 3600 +
3378 (TIME_GET_MINUTE(other) - offset2) * 60 +
3379 TIME_GET_SECOND(other);
3380 diff = offset1 - offset2;
3381 if (diff == 0)
3382 diff = TIME_GET_MICROSECOND(self) -
3383 TIME_GET_MICROSECOND(other);
3384 return diff_to_bool(diff, op);
3387 assert(n1 != n2);
3388 PyErr_SetString(PyExc_TypeError,
3389 "can't compare offset-naive and "
3390 "offset-aware times");
3391 return NULL;
3394 static long
3395 time_hash(PyDateTime_Time *self)
3397 if (self->hashcode == -1) {
3398 naivety n;
3399 int offset;
3400 PyObject *temp;
3402 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3403 assert(n != OFFSET_UNKNOWN);
3404 if (n == OFFSET_ERROR)
3405 return -1;
3407 /* Reduce this to a hash of another object. */
3408 if (offset == 0)
3409 temp = PyString_FromStringAndSize((char *)self->data,
3410 _PyDateTime_TIME_DATASIZE);
3411 else {
3412 int hour;
3413 int minute;
3415 assert(n == OFFSET_AWARE);
3416 assert(HASTZINFO(self));
3417 hour = divmod(TIME_GET_HOUR(self) * 60 +
3418 TIME_GET_MINUTE(self) - offset,
3420 &minute);
3421 if (0 <= hour && hour < 24)
3422 temp = new_time(hour, minute,
3423 TIME_GET_SECOND(self),
3424 TIME_GET_MICROSECOND(self),
3425 Py_None);
3426 else
3427 temp = Py_BuildValue("iiii",
3428 hour, minute,
3429 TIME_GET_SECOND(self),
3430 TIME_GET_MICROSECOND(self));
3432 if (temp != NULL) {
3433 self->hashcode = PyObject_Hash(temp);
3434 Py_DECREF(temp);
3437 return self->hashcode;
3440 static PyObject *
3441 time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3443 PyObject *clone;
3444 PyObject *tuple;
3445 int hh = TIME_GET_HOUR(self);
3446 int mm = TIME_GET_MINUTE(self);
3447 int ss = TIME_GET_SECOND(self);
3448 int us = TIME_GET_MICROSECOND(self);
3449 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
3451 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3452 time_kws,
3453 &hh, &mm, &ss, &us, &tzinfo))
3454 return NULL;
3455 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3456 if (tuple == NULL)
3457 return NULL;
3458 clone = time_new(Py_TYPE(self), tuple, NULL);
3459 Py_DECREF(tuple);
3460 return clone;
3463 static int
3464 time_nonzero(PyDateTime_Time *self)
3466 int offset;
3467 int none;
3469 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3470 /* Since utcoffset is in whole minutes, nothing can
3471 * alter the conclusion that this is nonzero.
3473 return 1;
3475 offset = 0;
3476 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3477 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3478 if (offset == -1 && PyErr_Occurred())
3479 return -1;
3481 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3484 /* Pickle support, a simple use of __reduce__. */
3486 /* Let basestate be the non-tzinfo data string.
3487 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3488 * So it's a tuple in any (non-error) case.
3489 * __getstate__ isn't exposed.
3491 static PyObject *
3492 time_getstate(PyDateTime_Time *self)
3494 PyObject *basestate;
3495 PyObject *result = NULL;
3497 basestate = PyString_FromStringAndSize((char *)self->data,
3498 _PyDateTime_TIME_DATASIZE);
3499 if (basestate != NULL) {
3500 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3501 result = PyTuple_Pack(1, basestate);
3502 else
3503 result = PyTuple_Pack(2, basestate, self->tzinfo);
3504 Py_DECREF(basestate);
3506 return result;
3509 static PyObject *
3510 time_reduce(PyDateTime_Time *self, PyObject *arg)
3512 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
3515 static PyMethodDef time_methods[] = {
3517 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3518 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3519 "[+HH:MM].")},
3521 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3522 PyDoc_STR("format -> strftime() style string.")},
3524 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3525 PyDoc_STR("Formats self with strftime.")},
3527 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3528 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3530 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3531 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3533 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3534 PyDoc_STR("Return self.tzinfo.dst(self).")},
3536 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3537 PyDoc_STR("Return time with new specified fields.")},
3539 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3540 PyDoc_STR("__reduce__() -> (cls, state)")},
3542 {NULL, NULL}
3545 static char time_doc[] =
3546 PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3548 All arguments are optional. tzinfo may be None, or an instance of\n\
3549 a tzinfo subclass. The remaining arguments may be ints or longs.\n");
3551 static PyNumberMethods time_as_number = {
3552 0, /* nb_add */
3553 0, /* nb_subtract */
3554 0, /* nb_multiply */
3555 0, /* nb_divide */
3556 0, /* nb_remainder */
3557 0, /* nb_divmod */
3558 0, /* nb_power */
3559 0, /* nb_negative */
3560 0, /* nb_positive */
3561 0, /* nb_absolute */
3562 (inquiry)time_nonzero, /* nb_nonzero */
3565 statichere PyTypeObject PyDateTime_TimeType = {
3566 PyObject_HEAD_INIT(NULL)
3567 0, /* ob_size */
3568 "datetime.time", /* tp_name */
3569 sizeof(PyDateTime_Time), /* tp_basicsize */
3570 0, /* tp_itemsize */
3571 (destructor)time_dealloc, /* tp_dealloc */
3572 0, /* tp_print */
3573 0, /* tp_getattr */
3574 0, /* tp_setattr */
3575 0, /* tp_compare */
3576 (reprfunc)time_repr, /* tp_repr */
3577 &time_as_number, /* tp_as_number */
3578 0, /* tp_as_sequence */
3579 0, /* tp_as_mapping */
3580 (hashfunc)time_hash, /* tp_hash */
3581 0, /* tp_call */
3582 (reprfunc)time_str, /* tp_str */
3583 PyObject_GenericGetAttr, /* tp_getattro */
3584 0, /* tp_setattro */
3585 0, /* tp_as_buffer */
3586 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3587 Py_TPFLAGS_BASETYPE, /* tp_flags */
3588 time_doc, /* tp_doc */
3589 0, /* tp_traverse */
3590 0, /* tp_clear */
3591 (richcmpfunc)time_richcompare, /* tp_richcompare */
3592 0, /* tp_weaklistoffset */
3593 0, /* tp_iter */
3594 0, /* tp_iternext */
3595 time_methods, /* tp_methods */
3596 0, /* tp_members */
3597 time_getset, /* tp_getset */
3598 0, /* tp_base */
3599 0, /* tp_dict */
3600 0, /* tp_descr_get */
3601 0, /* tp_descr_set */
3602 0, /* tp_dictoffset */
3603 0, /* tp_init */
3604 time_alloc, /* tp_alloc */
3605 time_new, /* tp_new */
3606 0, /* tp_free */
3610 * PyDateTime_DateTime implementation.
3613 /* Accessor properties. Properties for day, month, and year are inherited
3614 * from date.
3617 static PyObject *
3618 datetime_hour(PyDateTime_DateTime *self, void *unused)
3620 return PyInt_FromLong(DATE_GET_HOUR(self));
3623 static PyObject *
3624 datetime_minute(PyDateTime_DateTime *self, void *unused)
3626 return PyInt_FromLong(DATE_GET_MINUTE(self));
3629 static PyObject *
3630 datetime_second(PyDateTime_DateTime *self, void *unused)
3632 return PyInt_FromLong(DATE_GET_SECOND(self));
3635 static PyObject *
3636 datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3638 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3641 static PyObject *
3642 datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3644 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3645 Py_INCREF(result);
3646 return result;
3649 static PyGetSetDef datetime_getset[] = {
3650 {"hour", (getter)datetime_hour},
3651 {"minute", (getter)datetime_minute},
3652 {"second", (getter)datetime_second},
3653 {"microsecond", (getter)datetime_microsecond},
3654 {"tzinfo", (getter)datetime_tzinfo},
3655 {NULL}
3659 * Constructors.
3662 static char *datetime_kws[] = {
3663 "year", "month", "day", "hour", "minute", "second",
3664 "microsecond", "tzinfo", NULL
3667 static PyObject *
3668 datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3670 PyObject *self = NULL;
3671 PyObject *state;
3672 int year;
3673 int month;
3674 int day;
3675 int hour = 0;
3676 int minute = 0;
3677 int second = 0;
3678 int usecond = 0;
3679 PyObject *tzinfo = Py_None;
3681 /* Check for invocation from pickle with __getstate__ state */
3682 if (PyTuple_GET_SIZE(args) >= 1 &&
3683 PyTuple_GET_SIZE(args) <= 2 &&
3684 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3685 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3686 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
3688 PyDateTime_DateTime *me;
3689 char aware;
3691 if (PyTuple_GET_SIZE(args) == 2) {
3692 tzinfo = PyTuple_GET_ITEM(args, 1);
3693 if (check_tzinfo_subclass(tzinfo) < 0) {
3694 PyErr_SetString(PyExc_TypeError, "bad "
3695 "tzinfo state arg");
3696 return NULL;
3699 aware = (char)(tzinfo != Py_None);
3700 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3701 if (me != NULL) {
3702 char *pdata = PyString_AS_STRING(state);
3704 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3705 me->hashcode = -1;
3706 me->hastzinfo = aware;
3707 if (aware) {
3708 Py_INCREF(tzinfo);
3709 me->tzinfo = tzinfo;
3712 return (PyObject *)me;
3715 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3716 &year, &month, &day, &hour, &minute,
3717 &second, &usecond, &tzinfo)) {
3718 if (check_date_args(year, month, day) < 0)
3719 return NULL;
3720 if (check_time_args(hour, minute, second, usecond) < 0)
3721 return NULL;
3722 if (check_tzinfo_subclass(tzinfo) < 0)
3723 return NULL;
3724 self = new_datetime_ex(year, month, day,
3725 hour, minute, second, usecond,
3726 tzinfo, type);
3728 return self;
3731 /* TM_FUNC is the shared type of localtime() and gmtime(). */
3732 typedef struct tm *(*TM_FUNC)(const time_t *timer);
3734 /* Internal helper.
3735 * Build datetime from a time_t and a distinct count of microseconds.
3736 * Pass localtime or gmtime for f, to control the interpretation of timet.
3738 static PyObject *
3739 datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3740 PyObject *tzinfo)
3742 struct tm *tm;
3743 PyObject *result = NULL;
3745 tm = f(&timet);
3746 if (tm) {
3747 /* The platform localtime/gmtime may insert leap seconds,
3748 * indicated by tm->tm_sec > 59. We don't care about them,
3749 * except to the extent that passing them on to the datetime
3750 * constructor would raise ValueError for a reason that
3751 * made no sense to the user.
3753 if (tm->tm_sec > 59)
3754 tm->tm_sec = 59;
3755 result = PyObject_CallFunction(cls, "iiiiiiiO",
3756 tm->tm_year + 1900,
3757 tm->tm_mon + 1,
3758 tm->tm_mday,
3759 tm->tm_hour,
3760 tm->tm_min,
3761 tm->tm_sec,
3763 tzinfo);
3765 else
3766 PyErr_SetString(PyExc_ValueError,
3767 "timestamp out of range for "
3768 "platform localtime()/gmtime() function");
3769 return result;
3772 /* Internal helper.
3773 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3774 * to control the interpretation of the timestamp. Since a double doesn't
3775 * have enough bits to cover a datetime's full range of precision, it's
3776 * better to call datetime_from_timet_and_us provided you have a way
3777 * to get that much precision (e.g., C time() isn't good enough).
3779 static PyObject *
3780 datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3781 PyObject *tzinfo)
3783 time_t timet;
3784 double fraction;
3785 int us;
3787 timet = _PyTime_DoubleToTimet(timestamp);
3788 if (timet == (time_t)-1 && PyErr_Occurred())
3789 return NULL;
3790 fraction = timestamp - (double)timet;
3791 us = (int)round_to_long(fraction * 1e6);
3792 if (us < 0) {
3793 /* Truncation towards zero is not what we wanted
3794 for negative numbers (Python's mod semantics) */
3795 timet -= 1;
3796 us += 1000000;
3798 /* If timestamp is less than one microsecond smaller than a
3799 * full second, round up. Otherwise, ValueErrors are raised
3800 * for some floats. */
3801 if (us == 1000000) {
3802 timet += 1;
3803 us = 0;
3805 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3808 /* Internal helper.
3809 * Build most accurate possible datetime for current time. Pass localtime or
3810 * gmtime for f as appropriate.
3812 static PyObject *
3813 datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3815 #ifdef HAVE_GETTIMEOFDAY
3816 struct timeval t;
3818 #ifdef GETTIMEOFDAY_NO_TZ
3819 gettimeofday(&t);
3820 #else
3821 gettimeofday(&t, (struct timezone *)NULL);
3822 #endif
3823 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3824 tzinfo);
3826 #else /* ! HAVE_GETTIMEOFDAY */
3827 /* No flavor of gettimeofday exists on this platform. Python's
3828 * time.time() does a lot of other platform tricks to get the
3829 * best time it can on the platform, and we're not going to do
3830 * better than that (if we could, the better code would belong
3831 * in time.time()!) We're limited by the precision of a double,
3832 * though.
3834 PyObject *time;
3835 double dtime;
3837 time = time_time();
3838 if (time == NULL)
3839 return NULL;
3840 dtime = PyFloat_AsDouble(time);
3841 Py_DECREF(time);
3842 if (dtime == -1.0 && PyErr_Occurred())
3843 return NULL;
3844 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3845 #endif /* ! HAVE_GETTIMEOFDAY */
3848 /* Return best possible local time -- this isn't constrained by the
3849 * precision of a timestamp.
3851 static PyObject *
3852 datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
3854 PyObject *self;
3855 PyObject *tzinfo = Py_None;
3856 static char *keywords[] = {"tz", NULL};
3858 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3859 &tzinfo))
3860 return NULL;
3861 if (check_tzinfo_subclass(tzinfo) < 0)
3862 return NULL;
3864 self = datetime_best_possible(cls,
3865 tzinfo == Py_None ? localtime : gmtime,
3866 tzinfo);
3867 if (self != NULL && tzinfo != Py_None) {
3868 /* Convert UTC to tzinfo's zone. */
3869 PyObject *temp = self;
3870 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3871 Py_DECREF(temp);
3873 return self;
3876 /* Return best possible UTC time -- this isn't constrained by the
3877 * precision of a timestamp.
3879 static PyObject *
3880 datetime_utcnow(PyObject *cls, PyObject *dummy)
3882 return datetime_best_possible(cls, gmtime, Py_None);
3885 /* Return new local datetime from timestamp (Python timestamp -- a double). */
3886 static PyObject *
3887 datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
3889 PyObject *self;
3890 double timestamp;
3891 PyObject *tzinfo = Py_None;
3892 static char *keywords[] = {"timestamp", "tz", NULL};
3894 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3895 keywords, &timestamp, &tzinfo))
3896 return NULL;
3897 if (check_tzinfo_subclass(tzinfo) < 0)
3898 return NULL;
3900 self = datetime_from_timestamp(cls,
3901 tzinfo == Py_None ? localtime : gmtime,
3902 timestamp,
3903 tzinfo);
3904 if (self != NULL && tzinfo != Py_None) {
3905 /* Convert UTC to tzinfo's zone. */
3906 PyObject *temp = self;
3907 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3908 Py_DECREF(temp);
3910 return self;
3913 /* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3914 static PyObject *
3915 datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3917 double timestamp;
3918 PyObject *result = NULL;
3920 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3921 result = datetime_from_timestamp(cls, gmtime, timestamp,
3922 Py_None);
3923 return result;
3926 /* Return new datetime from time.strptime(). */
3927 static PyObject *
3928 datetime_strptime(PyObject *cls, PyObject *args)
3930 static PyObject *module = NULL;
3931 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3932 const char *string, *format;
3934 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3935 return NULL;
3937 if (module == NULL &&
3938 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3939 return NULL;
3941 /* _strptime._strptime returns a two-element tuple. The first
3942 element is a time.struct_time object. The second is the
3943 microseconds (which are not defined for time.struct_time). */
3944 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
3945 if (obj != NULL) {
3946 int i, good_timetuple = 1;
3947 long int ia[7];
3948 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3949 st = PySequence_GetItem(obj, 0);
3950 frac = PySequence_GetItem(obj, 1);
3951 if (st == NULL || frac == NULL)
3952 good_timetuple = 0;
3953 /* copy y/m/d/h/m/s values out of the
3954 time.struct_time */
3955 if (good_timetuple &&
3956 PySequence_Check(st) &&
3957 PySequence_Size(st) >= 6) {
3958 for (i=0; i < 6; i++) {
3959 PyObject *p = PySequence_GetItem(st, i);
3960 if (p == NULL) {
3961 good_timetuple = 0;
3962 break;
3964 if (PyInt_Check(p))
3965 ia[i] = PyInt_AsLong(p);
3966 else
3967 good_timetuple = 0;
3968 Py_DECREF(p);
3971 else
3972 good_timetuple = 0;
3973 /* follow that up with a little dose of microseconds */
3974 if (good_timetuple && PyInt_Check(frac))
3975 ia[6] = PyInt_AsLong(frac);
3976 else
3977 good_timetuple = 0;
3979 else
3980 good_timetuple = 0;
3981 if (good_timetuple)
3982 result = PyObject_CallFunction(cls, "iiiiiii",
3983 ia[0], ia[1], ia[2],
3984 ia[3], ia[4], ia[5],
3985 ia[6]);
3986 else
3987 PyErr_SetString(PyExc_ValueError,
3988 "unexpected value from _strptime._strptime");
3990 Py_XDECREF(obj);
3991 Py_XDECREF(st);
3992 Py_XDECREF(frac);
3993 return result;
3996 /* Return new datetime from date/datetime and time arguments. */
3997 static PyObject *
3998 datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4000 static char *keywords[] = {"date", "time", NULL};
4001 PyObject *date;
4002 PyObject *time;
4003 PyObject *result = NULL;
4005 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4006 &PyDateTime_DateType, &date,
4007 &PyDateTime_TimeType, &time)) {
4008 PyObject *tzinfo = Py_None;
4010 if (HASTZINFO(time))
4011 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4012 result = PyObject_CallFunction(cls, "iiiiiiiO",
4013 GET_YEAR(date),
4014 GET_MONTH(date),
4015 GET_DAY(date),
4016 TIME_GET_HOUR(time),
4017 TIME_GET_MINUTE(time),
4018 TIME_GET_SECOND(time),
4019 TIME_GET_MICROSECOND(time),
4020 tzinfo);
4022 return result;
4026 * Destructor.
4029 static void
4030 datetime_dealloc(PyDateTime_DateTime *self)
4032 if (HASTZINFO(self)) {
4033 Py_XDECREF(self->tzinfo);
4035 Py_TYPE(self)->tp_free((PyObject *)self);
4039 * Indirect access to tzinfo methods.
4042 /* These are all METH_NOARGS, so don't need to check the arglist. */
4043 static PyObject *
4044 datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
4045 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4046 "utcoffset", (PyObject *)self);
4049 static PyObject *
4050 datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
4051 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4052 "dst", (PyObject *)self);
4055 static PyObject *
4056 datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
4057 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4058 (PyObject *)self);
4062 * datetime arithmetic.
4065 /* factor must be 1 (to add) or -1 (to subtract). The result inherits
4066 * the tzinfo state of date.
4068 static PyObject *
4069 add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4070 int factor)
4072 /* Note that the C-level additions can't overflow, because of
4073 * invariant bounds on the member values.
4075 int year = GET_YEAR(date);
4076 int month = GET_MONTH(date);
4077 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4078 int hour = DATE_GET_HOUR(date);
4079 int minute = DATE_GET_MINUTE(date);
4080 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4081 int microsecond = DATE_GET_MICROSECOND(date) +
4082 GET_TD_MICROSECONDS(delta) * factor;
4084 assert(factor == 1 || factor == -1);
4085 if (normalize_datetime(&year, &month, &day,
4086 &hour, &minute, &second, &microsecond) < 0)
4087 return NULL;
4088 else
4089 return new_datetime(year, month, day,
4090 hour, minute, second, microsecond,
4091 HASTZINFO(date) ? date->tzinfo : Py_None);
4094 static PyObject *
4095 datetime_add(PyObject *left, PyObject *right)
4097 if (PyDateTime_Check(left)) {
4098 /* datetime + ??? */
4099 if (PyDelta_Check(right))
4100 /* datetime + delta */
4101 return add_datetime_timedelta(
4102 (PyDateTime_DateTime *)left,
4103 (PyDateTime_Delta *)right,
4106 else if (PyDelta_Check(left)) {
4107 /* delta + datetime */
4108 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4109 (PyDateTime_Delta *) left,
4112 Py_INCREF(Py_NotImplemented);
4113 return Py_NotImplemented;
4116 static PyObject *
4117 datetime_subtract(PyObject *left, PyObject *right)
4119 PyObject *result = Py_NotImplemented;
4121 if (PyDateTime_Check(left)) {
4122 /* datetime - ??? */
4123 if (PyDateTime_Check(right)) {
4124 /* datetime - datetime */
4125 naivety n1, n2;
4126 int offset1, offset2;
4127 int delta_d, delta_s, delta_us;
4129 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4130 right, &offset2, &n2,
4131 right) < 0)
4132 return NULL;
4133 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4134 if (n1 != n2) {
4135 PyErr_SetString(PyExc_TypeError,
4136 "can't subtract offset-naive and "
4137 "offset-aware datetimes");
4138 return NULL;
4140 delta_d = ymd_to_ord(GET_YEAR(left),
4141 GET_MONTH(left),
4142 GET_DAY(left)) -
4143 ymd_to_ord(GET_YEAR(right),
4144 GET_MONTH(right),
4145 GET_DAY(right));
4146 /* These can't overflow, since the values are
4147 * normalized. At most this gives the number of
4148 * seconds in one day.
4150 delta_s = (DATE_GET_HOUR(left) -
4151 DATE_GET_HOUR(right)) * 3600 +
4152 (DATE_GET_MINUTE(left) -
4153 DATE_GET_MINUTE(right)) * 60 +
4154 (DATE_GET_SECOND(left) -
4155 DATE_GET_SECOND(right));
4156 delta_us = DATE_GET_MICROSECOND(left) -
4157 DATE_GET_MICROSECOND(right);
4158 /* (left - offset1) - (right - offset2) =
4159 * (left - right) + (offset2 - offset1)
4161 delta_s += (offset2 - offset1) * 60;
4162 result = new_delta(delta_d, delta_s, delta_us, 1);
4164 else if (PyDelta_Check(right)) {
4165 /* datetime - delta */
4166 result = add_datetime_timedelta(
4167 (PyDateTime_DateTime *)left,
4168 (PyDateTime_Delta *)right,
4169 -1);
4173 if (result == Py_NotImplemented)
4174 Py_INCREF(result);
4175 return result;
4178 /* Various ways to turn a datetime into a string. */
4180 static PyObject *
4181 datetime_repr(PyDateTime_DateTime *self)
4183 char buffer[1000];
4184 const char *type_name = Py_TYPE(self)->tp_name;
4185 PyObject *baserepr;
4187 if (DATE_GET_MICROSECOND(self)) {
4188 PyOS_snprintf(buffer, sizeof(buffer),
4189 "%s(%d, %d, %d, %d, %d, %d, %d)",
4190 type_name,
4191 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4192 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4193 DATE_GET_SECOND(self),
4194 DATE_GET_MICROSECOND(self));
4196 else if (DATE_GET_SECOND(self)) {
4197 PyOS_snprintf(buffer, sizeof(buffer),
4198 "%s(%d, %d, %d, %d, %d, %d)",
4199 type_name,
4200 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4201 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4202 DATE_GET_SECOND(self));
4204 else {
4205 PyOS_snprintf(buffer, sizeof(buffer),
4206 "%s(%d, %d, %d, %d, %d)",
4207 type_name,
4208 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4209 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4211 baserepr = PyString_FromString(buffer);
4212 if (baserepr == NULL || ! HASTZINFO(self))
4213 return baserepr;
4214 return append_keyword_tzinfo(baserepr, self->tzinfo);
4217 static PyObject *
4218 datetime_str(PyDateTime_DateTime *self)
4220 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4223 static PyObject *
4224 datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4226 char sep = 'T';
4227 static char *keywords[] = {"sep", NULL};
4228 char buffer[100];
4229 char *cp;
4230 PyObject *result;
4232 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4233 &sep))
4234 return NULL;
4235 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4236 assert(cp != NULL);
4237 *cp++ = sep;
4238 cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4239 result = PyString_FromStringAndSize(buffer, cp - buffer);
4240 if (result == NULL || ! HASTZINFO(self))
4241 return result;
4243 /* We need to append the UTC offset. */
4244 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4245 (PyObject *)self) < 0) {
4246 Py_DECREF(result);
4247 return NULL;
4249 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
4250 return result;
4253 static PyObject *
4254 datetime_ctime(PyDateTime_DateTime *self)
4256 return format_ctime((PyDateTime_Date *)self,
4257 DATE_GET_HOUR(self),
4258 DATE_GET_MINUTE(self),
4259 DATE_GET_SECOND(self));
4262 /* Miscellaneous methods. */
4264 /* This is more natural as a tp_compare, but doesn't work then: for whatever
4265 * reason, Python's try_3way_compare ignores tp_compare unless
4266 * PyInstance_Check returns true, but these aren't old-style classes.
4268 static PyObject *
4269 datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4271 int diff;
4272 naivety n1, n2;
4273 int offset1, offset2;
4275 if (! PyDateTime_Check(other)) {
4276 /* If other has a "timetuple" attr, that's an advertised
4277 * hook for other classes to ask to get comparison control.
4278 * However, date instances have a timetuple attr, and we
4279 * don't want to allow that comparison. Because datetime
4280 * is a subclass of date, when mixing date and datetime
4281 * in a comparison, Python gives datetime the first shot
4282 * (it's the more specific subtype). So we can stop that
4283 * combination here reliably.
4285 if (PyObject_HasAttrString(other, "timetuple") &&
4286 ! PyDate_Check(other)) {
4287 /* A hook for other kinds of datetime objects. */
4288 Py_INCREF(Py_NotImplemented);
4289 return Py_NotImplemented;
4291 if (op == Py_EQ || op == Py_NE) {
4292 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4293 Py_INCREF(result);
4294 return result;
4296 /* Stop this from falling back to address comparison. */
4297 return cmperror((PyObject *)self, other);
4300 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4301 (PyObject *)self,
4302 other, &offset2, &n2,
4303 other) < 0)
4304 return NULL;
4305 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4306 /* If they're both naive, or both aware and have the same offsets,
4307 * we get off cheap. Note that if they're both naive, offset1 ==
4308 * offset2 == 0 at this point.
4310 if (n1 == n2 && offset1 == offset2) {
4311 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4312 _PyDateTime_DATETIME_DATASIZE);
4313 return diff_to_bool(diff, op);
4316 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4317 PyDateTime_Delta *delta;
4319 assert(offset1 != offset2); /* else last "if" handled it */
4320 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4321 other);
4322 if (delta == NULL)
4323 return NULL;
4324 diff = GET_TD_DAYS(delta);
4325 if (diff == 0)
4326 diff = GET_TD_SECONDS(delta) |
4327 GET_TD_MICROSECONDS(delta);
4328 Py_DECREF(delta);
4329 return diff_to_bool(diff, op);
4332 assert(n1 != n2);
4333 PyErr_SetString(PyExc_TypeError,
4334 "can't compare offset-naive and "
4335 "offset-aware datetimes");
4336 return NULL;
4339 static long
4340 datetime_hash(PyDateTime_DateTime *self)
4342 if (self->hashcode == -1) {
4343 naivety n;
4344 int offset;
4345 PyObject *temp;
4347 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4348 &offset);
4349 assert(n != OFFSET_UNKNOWN);
4350 if (n == OFFSET_ERROR)
4351 return -1;
4353 /* Reduce this to a hash of another object. */
4354 if (n == OFFSET_NAIVE)
4355 temp = PyString_FromStringAndSize(
4356 (char *)self->data,
4357 _PyDateTime_DATETIME_DATASIZE);
4358 else {
4359 int days;
4360 int seconds;
4362 assert(n == OFFSET_AWARE);
4363 assert(HASTZINFO(self));
4364 days = ymd_to_ord(GET_YEAR(self),
4365 GET_MONTH(self),
4366 GET_DAY(self));
4367 seconds = DATE_GET_HOUR(self) * 3600 +
4368 (DATE_GET_MINUTE(self) - offset) * 60 +
4369 DATE_GET_SECOND(self);
4370 temp = new_delta(days,
4371 seconds,
4372 DATE_GET_MICROSECOND(self),
4375 if (temp != NULL) {
4376 self->hashcode = PyObject_Hash(temp);
4377 Py_DECREF(temp);
4380 return self->hashcode;
4383 static PyObject *
4384 datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4386 PyObject *clone;
4387 PyObject *tuple;
4388 int y = GET_YEAR(self);
4389 int m = GET_MONTH(self);
4390 int d = GET_DAY(self);
4391 int hh = DATE_GET_HOUR(self);
4392 int mm = DATE_GET_MINUTE(self);
4393 int ss = DATE_GET_SECOND(self);
4394 int us = DATE_GET_MICROSECOND(self);
4395 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
4397 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4398 datetime_kws,
4399 &y, &m, &d, &hh, &mm, &ss, &us,
4400 &tzinfo))
4401 return NULL;
4402 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4403 if (tuple == NULL)
4404 return NULL;
4405 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4406 Py_DECREF(tuple);
4407 return clone;
4410 static PyObject *
4411 datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4413 int y, m, d, hh, mm, ss, us;
4414 PyObject *result;
4415 int offset, none;
4417 PyObject *tzinfo;
4418 static char *keywords[] = {"tz", NULL};
4420 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4421 &PyDateTime_TZInfoType, &tzinfo))
4422 return NULL;
4424 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4425 goto NeedAware;
4427 /* Conversion to self's own time zone is a NOP. */
4428 if (self->tzinfo == tzinfo) {
4429 Py_INCREF(self);
4430 return (PyObject *)self;
4433 /* Convert self to UTC. */
4434 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4435 if (offset == -1 && PyErr_Occurred())
4436 return NULL;
4437 if (none)
4438 goto NeedAware;
4440 y = GET_YEAR(self);
4441 m = GET_MONTH(self);
4442 d = GET_DAY(self);
4443 hh = DATE_GET_HOUR(self);
4444 mm = DATE_GET_MINUTE(self);
4445 ss = DATE_GET_SECOND(self);
4446 us = DATE_GET_MICROSECOND(self);
4448 mm -= offset;
4449 if ((mm < 0 || mm >= 60) &&
4450 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4451 return NULL;
4453 /* Attach new tzinfo and let fromutc() do the rest. */
4454 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4455 if (result != NULL) {
4456 PyObject *temp = result;
4458 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4459 Py_DECREF(temp);
4461 return result;
4463 NeedAware:
4464 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4465 "a naive datetime");
4466 return NULL;
4469 static PyObject *
4470 datetime_timetuple(PyDateTime_DateTime *self)
4472 int dstflag = -1;
4474 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4475 int none;
4477 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4478 if (dstflag == -1 && PyErr_Occurred())
4479 return NULL;
4481 if (none)
4482 dstflag = -1;
4483 else if (dstflag != 0)
4484 dstflag = 1;
4487 return build_struct_time(GET_YEAR(self),
4488 GET_MONTH(self),
4489 GET_DAY(self),
4490 DATE_GET_HOUR(self),
4491 DATE_GET_MINUTE(self),
4492 DATE_GET_SECOND(self),
4493 dstflag);
4496 static PyObject *
4497 datetime_getdate(PyDateTime_DateTime *self)
4499 return new_date(GET_YEAR(self),
4500 GET_MONTH(self),
4501 GET_DAY(self));
4504 static PyObject *
4505 datetime_gettime(PyDateTime_DateTime *self)
4507 return new_time(DATE_GET_HOUR(self),
4508 DATE_GET_MINUTE(self),
4509 DATE_GET_SECOND(self),
4510 DATE_GET_MICROSECOND(self),
4511 Py_None);
4514 static PyObject *
4515 datetime_gettimetz(PyDateTime_DateTime *self)
4517 return new_time(DATE_GET_HOUR(self),
4518 DATE_GET_MINUTE(self),
4519 DATE_GET_SECOND(self),
4520 DATE_GET_MICROSECOND(self),
4521 HASTZINFO(self) ? self->tzinfo : Py_None);
4524 static PyObject *
4525 datetime_utctimetuple(PyDateTime_DateTime *self)
4527 int y = GET_YEAR(self);
4528 int m = GET_MONTH(self);
4529 int d = GET_DAY(self);
4530 int hh = DATE_GET_HOUR(self);
4531 int mm = DATE_GET_MINUTE(self);
4532 int ss = DATE_GET_SECOND(self);
4533 int us = 0; /* microseconds are ignored in a timetuple */
4534 int offset = 0;
4536 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4537 int none;
4539 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4540 if (offset == -1 && PyErr_Occurred())
4541 return NULL;
4543 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4544 * 0 in a UTC timetuple regardless of what dst() says.
4546 if (offset) {
4547 /* Subtract offset minutes & normalize. */
4548 int stat;
4550 mm -= offset;
4551 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4552 if (stat < 0) {
4553 /* At the edges, it's possible we overflowed
4554 * beyond MINYEAR or MAXYEAR.
4556 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4557 PyErr_Clear();
4558 else
4559 return NULL;
4562 return build_struct_time(y, m, d, hh, mm, ss, 0);
4565 /* Pickle support, a simple use of __reduce__. */
4567 /* Let basestate be the non-tzinfo data string.
4568 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4569 * So it's a tuple in any (non-error) case.
4570 * __getstate__ isn't exposed.
4572 static PyObject *
4573 datetime_getstate(PyDateTime_DateTime *self)
4575 PyObject *basestate;
4576 PyObject *result = NULL;
4578 basestate = PyString_FromStringAndSize((char *)self->data,
4579 _PyDateTime_DATETIME_DATASIZE);
4580 if (basestate != NULL) {
4581 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4582 result = PyTuple_Pack(1, basestate);
4583 else
4584 result = PyTuple_Pack(2, basestate, self->tzinfo);
4585 Py_DECREF(basestate);
4587 return result;
4590 static PyObject *
4591 datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
4593 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
4596 static PyMethodDef datetime_methods[] = {
4598 /* Class methods: */
4600 {"now", (PyCFunction)datetime_now,
4601 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4602 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4604 {"utcnow", (PyCFunction)datetime_utcnow,
4605 METH_NOARGS | METH_CLASS,
4606 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4608 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4609 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4610 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4612 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4613 METH_VARARGS | METH_CLASS,
4614 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4615 "(like time.time()).")},
4617 {"strptime", (PyCFunction)datetime_strptime,
4618 METH_VARARGS | METH_CLASS,
4619 PyDoc_STR("string, format -> new datetime parsed from a string "
4620 "(like time.strptime()).")},
4622 {"combine", (PyCFunction)datetime_combine,
4623 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4624 PyDoc_STR("date, time -> datetime with same date and time fields")},
4626 /* Instance methods: */
4628 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4629 PyDoc_STR("Return date object with same year, month and day.")},
4631 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4632 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4634 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4635 PyDoc_STR("Return time object with same time and tzinfo.")},
4637 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4638 PyDoc_STR("Return ctime() style string.")},
4640 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4641 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4643 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4644 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4646 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4647 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4648 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4649 "sep is used to separate the year from the time, and "
4650 "defaults to 'T'.")},
4652 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4653 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4655 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4656 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4658 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4659 PyDoc_STR("Return self.tzinfo.dst(self).")},
4661 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4662 PyDoc_STR("Return datetime with new specified fields.")},
4664 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4665 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4667 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4668 PyDoc_STR("__reduce__() -> (cls, state)")},
4670 {NULL, NULL}
4673 static char datetime_doc[] =
4674 PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4676 The year, month and day arguments are required. tzinfo may be None, or an\n\
4677 instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
4679 static PyNumberMethods datetime_as_number = {
4680 datetime_add, /* nb_add */
4681 datetime_subtract, /* nb_subtract */
4682 0, /* nb_multiply */
4683 0, /* nb_divide */
4684 0, /* nb_remainder */
4685 0, /* nb_divmod */
4686 0, /* nb_power */
4687 0, /* nb_negative */
4688 0, /* nb_positive */
4689 0, /* nb_absolute */
4690 0, /* nb_nonzero */
4693 statichere PyTypeObject PyDateTime_DateTimeType = {
4694 PyObject_HEAD_INIT(NULL)
4695 0, /* ob_size */
4696 "datetime.datetime", /* tp_name */
4697 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4698 0, /* tp_itemsize */
4699 (destructor)datetime_dealloc, /* tp_dealloc */
4700 0, /* tp_print */
4701 0, /* tp_getattr */
4702 0, /* tp_setattr */
4703 0, /* tp_compare */
4704 (reprfunc)datetime_repr, /* tp_repr */
4705 &datetime_as_number, /* tp_as_number */
4706 0, /* tp_as_sequence */
4707 0, /* tp_as_mapping */
4708 (hashfunc)datetime_hash, /* tp_hash */
4709 0, /* tp_call */
4710 (reprfunc)datetime_str, /* tp_str */
4711 PyObject_GenericGetAttr, /* tp_getattro */
4712 0, /* tp_setattro */
4713 0, /* tp_as_buffer */
4714 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4715 Py_TPFLAGS_BASETYPE, /* tp_flags */
4716 datetime_doc, /* tp_doc */
4717 0, /* tp_traverse */
4718 0, /* tp_clear */
4719 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
4720 0, /* tp_weaklistoffset */
4721 0, /* tp_iter */
4722 0, /* tp_iternext */
4723 datetime_methods, /* tp_methods */
4724 0, /* tp_members */
4725 datetime_getset, /* tp_getset */
4726 &PyDateTime_DateType, /* tp_base */
4727 0, /* tp_dict */
4728 0, /* tp_descr_get */
4729 0, /* tp_descr_set */
4730 0, /* tp_dictoffset */
4731 0, /* tp_init */
4732 datetime_alloc, /* tp_alloc */
4733 datetime_new, /* tp_new */
4734 0, /* tp_free */
4737 /* ---------------------------------------------------------------------------
4738 * Module methods and initialization.
4741 static PyMethodDef module_methods[] = {
4742 {NULL, NULL}
4745 /* C API. Clients get at this via PyDateTime_IMPORT, defined in
4746 * datetime.h.
4748 static PyDateTime_CAPI CAPI = {
4749 &PyDateTime_DateType,
4750 &PyDateTime_DateTimeType,
4751 &PyDateTime_TimeType,
4752 &PyDateTime_DeltaType,
4753 &PyDateTime_TZInfoType,
4754 new_date_ex,
4755 new_datetime_ex,
4756 new_time_ex,
4757 new_delta_ex,
4758 datetime_fromtimestamp,
4759 date_fromtimestamp
4763 PyMODINIT_FUNC
4764 initdatetime(void)
4766 PyObject *m; /* a module object */
4767 PyObject *d; /* its dict */
4768 PyObject *x;
4770 m = Py_InitModule3("datetime", module_methods,
4771 "Fast implementation of the datetime type.");
4772 if (m == NULL)
4773 return;
4775 if (PyType_Ready(&PyDateTime_DateType) < 0)
4776 return;
4777 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4778 return;
4779 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4780 return;
4781 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4782 return;
4783 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4784 return;
4786 /* timedelta values */
4787 d = PyDateTime_DeltaType.tp_dict;
4789 x = new_delta(0, 0, 1, 0);
4790 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4791 return;
4792 Py_DECREF(x);
4794 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4795 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4796 return;
4797 Py_DECREF(x);
4799 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4800 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4801 return;
4802 Py_DECREF(x);
4804 /* date values */
4805 d = PyDateTime_DateType.tp_dict;
4807 x = new_date(1, 1, 1);
4808 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4809 return;
4810 Py_DECREF(x);
4812 x = new_date(MAXYEAR, 12, 31);
4813 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4814 return;
4815 Py_DECREF(x);
4817 x = new_delta(1, 0, 0, 0);
4818 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4819 return;
4820 Py_DECREF(x);
4822 /* time values */
4823 d = PyDateTime_TimeType.tp_dict;
4825 x = new_time(0, 0, 0, 0, Py_None);
4826 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4827 return;
4828 Py_DECREF(x);
4830 x = new_time(23, 59, 59, 999999, Py_None);
4831 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4832 return;
4833 Py_DECREF(x);
4835 x = new_delta(0, 0, 1, 0);
4836 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4837 return;
4838 Py_DECREF(x);
4840 /* datetime values */
4841 d = PyDateTime_DateTimeType.tp_dict;
4843 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4844 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4845 return;
4846 Py_DECREF(x);
4848 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4849 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4850 return;
4851 Py_DECREF(x);
4853 x = new_delta(0, 0, 1, 0);
4854 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4855 return;
4856 Py_DECREF(x);
4858 /* module initialization */
4859 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4860 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4862 Py_INCREF(&PyDateTime_DateType);
4863 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4865 Py_INCREF(&PyDateTime_DateTimeType);
4866 PyModule_AddObject(m, "datetime",
4867 (PyObject *)&PyDateTime_DateTimeType);
4869 Py_INCREF(&PyDateTime_TimeType);
4870 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4872 Py_INCREF(&PyDateTime_DeltaType);
4873 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4875 Py_INCREF(&PyDateTime_TZInfoType);
4876 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4878 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
4879 if (x == NULL)
4880 return;
4881 PyModule_AddObject(m, "datetime_CAPI", x);
4883 /* A 4-year cycle has an extra leap day over what we'd get from
4884 * pasting together 4 single years.
4886 assert(DI4Y == 4 * 365 + 1);
4887 assert(DI4Y == days_before_year(4+1));
4889 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4890 * get from pasting together 4 100-year cycles.
4892 assert(DI400Y == 4 * DI100Y + 1);
4893 assert(DI400Y == days_before_year(400+1));
4895 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4896 * pasting together 25 4-year cycles.
4898 assert(DI100Y == 25 * DI4Y - 1);
4899 assert(DI100Y == days_before_year(100+1));
4901 us_per_us = PyInt_FromLong(1);
4902 us_per_ms = PyInt_FromLong(1000);
4903 us_per_second = PyInt_FromLong(1000000);
4904 us_per_minute = PyInt_FromLong(60000000);
4905 seconds_per_day = PyInt_FromLong(24 * 3600);
4906 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4907 us_per_minute == NULL || seconds_per_day == NULL)
4908 return;
4910 /* The rest are too big for 32-bit ints, but even
4911 * us_per_week fits in 40 bits, so doubles should be exact.
4913 us_per_hour = PyLong_FromDouble(3600000000.0);
4914 us_per_day = PyLong_FromDouble(86400000000.0);
4915 us_per_week = PyLong_FromDouble(604800000000.0);
4916 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4917 return;
4920 /* ---------------------------------------------------------------------------
4921 Some time zone algebra. For a datetime x, let
4922 x.n = x stripped of its timezone -- its naive time.
4923 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4924 return None
4925 x.d = x.dst(), and assuming that doesn't raise an exception or
4926 return None
4927 x.s = x's standard offset, x.o - x.d
4929 Now some derived rules, where k is a duration (timedelta).
4931 1. x.o = x.s + x.d
4932 This follows from the definition of x.s.
4934 2. If x and y have the same tzinfo member, x.s = y.s.
4935 This is actually a requirement, an assumption we need to make about
4936 sane tzinfo classes.
4938 3. The naive UTC time corresponding to x is x.n - x.o.
4939 This is again a requirement for a sane tzinfo class.
4941 4. (x+k).s = x.s
4942 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
4944 5. (x+k).n = x.n + k
4945 Again follows from how arithmetic is defined.
4947 Now we can explain tz.fromutc(x). Let's assume it's an interesting case
4948 (meaning that the various tzinfo methods exist, and don't blow up or return
4949 None when called).
4951 The function wants to return a datetime y with timezone tz, equivalent to x.
4952 x is already in UTC.
4954 By #3, we want
4956 y.n - y.o = x.n [1]
4958 The algorithm starts by attaching tz to x.n, and calling that y. So
4959 x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4960 becomes true; in effect, we want to solve [2] for k:
4962 (y+k).n - (y+k).o = x.n [2]
4964 By #1, this is the same as
4966 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
4968 By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4969 Substituting that into [3],
4971 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4972 k - (y+k).s - (y+k).d = 0; rearranging,
4973 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4974 k = y.s - (y+k).d
4976 On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4977 approximate k by ignoring the (y+k).d term at first. Note that k can't be
4978 very large, since all offset-returning methods return a duration of magnitude
4979 less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4980 be 0, so ignoring it has no consequence then.
4982 In any case, the new value is
4984 z = y + y.s [4]
4986 It's helpful to step back at look at [4] from a higher level: it's simply
4987 mapping from UTC to tz's standard time.
4989 At this point, if
4991 z.n - z.o = x.n [5]
4993 we have an equivalent time, and are almost done. The insecurity here is
4994 at the start of daylight time. Picture US Eastern for concreteness. The wall
4995 time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
4996 sense then. The docs ask that an Eastern tzinfo class consider such a time to
4997 be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4998 on the day DST starts. We want to return the 1:MM EST spelling because that's
4999 the only spelling that makes sense on the local wall clock.
5001 In fact, if [5] holds at this point, we do have the standard-time spelling,
5002 but that takes a bit of proof. We first prove a stronger result. What's the
5003 difference between the LHS and RHS of [5]? Let
5005 diff = x.n - (z.n - z.o) [6]
5008 z.n = by [4]
5009 (y + y.s).n = by #5
5010 y.n + y.s = since y.n = x.n
5011 x.n + y.s = since z and y are have the same tzinfo member,
5012 y.s = z.s by #2
5013 x.n + z.s
5015 Plugging that back into [6] gives
5017 diff =
5018 x.n - ((x.n + z.s) - z.o) = expanding
5019 x.n - x.n - z.s + z.o = cancelling
5020 - z.s + z.o = by #2
5023 So diff = z.d.
5025 If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
5026 spelling we wanted in the endcase described above. We're done. Contrarily,
5027 if z.d = 0, then we have a UTC equivalent, and are also done.
5029 If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5030 add to z (in effect, z is in tz's standard time, and we need to shift the
5031 local clock into tz's daylight time).
5035 z' = z + z.d = z + diff [7]
5037 and we can again ask whether
5039 z'.n - z'.o = x.n [8]
5041 If so, we're done. If not, the tzinfo class is insane, according to the
5042 assumptions we've made. This also requires a bit of proof. As before, let's
5043 compute the difference between the LHS and RHS of [8] (and skipping some of
5044 the justifications for the kinds of substitutions we've done several times
5045 already):
5047 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5048 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5049 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5050 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5051 - z.n + z.n - z.o + z'.o = cancel z.n
5052 - z.o + z'.o = #1 twice
5053 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5054 z'.d - z.d
5056 So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
5057 we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5058 return z', not bothering to compute z'.d.
5060 How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5061 a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5062 would have to change the result dst() returns: we start in DST, and moving
5063 a little further into it takes us out of DST.
5065 There isn't a sane case where this can happen. The closest it gets is at
5066 the end of DST, where there's an hour in UTC with no spelling in a hybrid
5067 tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5068 that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5069 UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5070 time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5071 clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5072 standard time. Since that's what the local clock *does*, we want to map both
5073 UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
5074 in local time, but so it goes -- it's the way the local clock works.
5076 When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5077 so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5078 z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
5079 (correctly) concludes that z' is not UTC-equivalent to x.
5081 Because we know z.d said z was in daylight time (else [5] would have held and
5082 we would have stopped then), and we know z.d != z'.d (else [8] would have held
5083 and we would have stopped then), and there are only 2 possible values dst() can
5084 return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5085 but the reasoning doesn't depend on the example -- it depends on there being
5086 two possible dst() outcomes, one zero and the other non-zero). Therefore
5087 z' must be in standard time, and is the spelling we want in this case.
5089 Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5090 concerned (because it takes z' as being in standard time rather than the
5091 daylight time we intend here), but returning it gives the real-life "local
5092 clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5095 When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5096 the 1:MM standard time spelling we want.
5098 So how can this break? One of the assumptions must be violated. Two
5099 possibilities:
5101 1) [2] effectively says that y.s is invariant across all y belong to a given
5102 time zone. This isn't true if, for political reasons or continental drift,
5103 a region decides to change its base offset from UTC.
5105 2) There may be versions of "double daylight" time where the tail end of
5106 the analysis gives up a step too early. I haven't thought about that
5107 enough to say.
5109 In any case, it's clear that the default fromutc() is strong enough to handle
5110 "almost all" time zones: so long as the standard offset is invariant, it
5111 doesn't matter if daylight time transition points change from year to year, or
5112 if daylight time is skipped in some years; it doesn't matter how large or
5113 small dst() may get within its bounds; and it doesn't even matter if some
5114 perverse time zone returns a negative dst()). So a breaking case must be
5115 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
5116 --------------------------------------------------------------------------- */