1 /* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
5 #define PY_SSIZE_T_CLEAN
8 #include "modsupport.h"
9 #include "structmember.h"
13 #include "timefuncs.h"
15 /* Differentiate between building the core module and building extension
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).
30 # error "datetime.c requires that C int have at least 32 bits"
36 /* Nine decimal digits is easy to communicate, and leaves enough room
37 * so that two delta days can be added w/o fear of overflowing a signed
38 * 32-bit int, and with plenty of room left over to absorb any possible
39 * carries from adding seconds.
41 #define MAX_DELTA_DAYS 999999999
43 /* Rename the long macros in datetime.h to more reasonable short names. */
44 #define GET_YEAR PyDateTime_GET_YEAR
45 #define GET_MONTH PyDateTime_GET_MONTH
46 #define GET_DAY PyDateTime_GET_DAY
47 #define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
48 #define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
49 #define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
50 #define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
52 /* Date accessors for date and datetime. */
53 #define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
54 ((o)->data[1] = ((v) & 0x00ff)))
55 #define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
56 #define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
58 /* Date/Time accessors for datetime. */
59 #define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
60 #define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
61 #define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
62 #define DATE_SET_MICROSECOND(o, v) \
63 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
64 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
65 ((o)->data[9] = ((v) & 0x0000ff)))
67 /* Time accessors for time. */
68 #define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
69 #define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
70 #define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
71 #define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
72 #define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
73 #define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
74 #define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
75 #define TIME_SET_MICROSECOND(o, v) \
76 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
77 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
78 ((o)->data[5] = ((v) & 0x0000ff)))
80 /* Delta accessors for timedelta. */
81 #define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
82 #define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
83 #define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
85 #define SET_TD_DAYS(o, v) ((o)->days = (v))
86 #define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
87 #define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
89 /* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
92 #define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
94 /* M is a char or int claiming to be a valid month. The macro is equivalent
95 * to the two-sided Python test
98 #define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
100 /* Forward declarations. */
101 static PyTypeObject PyDateTime_DateType
;
102 static PyTypeObject PyDateTime_DateTimeType
;
103 static PyTypeObject PyDateTime_DeltaType
;
104 static PyTypeObject PyDateTime_TimeType
;
105 static PyTypeObject PyDateTime_TZInfoType
;
107 /* ---------------------------------------------------------------------------
111 /* k = i+j overflows iff k differs in sign from both inputs,
112 * iff k^i has sign bit set and k^j has sign bit set,
113 * iff (k^i)&(k^j) has sign bit set.
115 #define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
116 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
118 /* Compute Python divmod(x, y), returning the quotient and storing the
119 * remainder into *r. The quotient is the floor of x/y, and that's
120 * the real point of this. C will probably truncate instead (C99
121 * requires truncation; C89 left it implementation-defined).
122 * Simplification: we *require* that y > 0 here. That's appropriate
123 * for all the uses made of it. This simplifies the code and makes
124 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
128 divmod(int x
, int y
, int *r
)
139 assert(0 <= *r
&& *r
< y
);
143 /* Round a double to the nearest long. |x| must be small enough to fit
144 * in a C long; this is not checked.
147 round_to_long(double x
)
156 /* ---------------------------------------------------------------------------
157 * General calendrical helper functions
160 /* For each month ordinal in 1..12, the number of days in that month,
161 * and the number of days before that month in the same year. These
162 * are correct for non-leap years only.
164 static int _days_in_month
[] = {
165 0, /* unused; this vector uses 1-based indexing */
166 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
169 static int _days_before_month
[] = {
170 0, /* unused; this vector uses 1-based indexing */
171 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
174 /* year -> 1 if leap year, else 0. */
178 /* Cast year to unsigned. The result is the same either way, but
179 * C can generate faster code for unsigned mod than for signed
180 * mod (especially for % 4 -- a good compiler should just grab
181 * the last 2 bits when the LHS is unsigned).
183 const unsigned int ayear
= (unsigned int)year
;
184 return ayear
% 4 == 0 && (ayear
% 100 != 0 || ayear
% 400 == 0);
187 /* year, month -> number of days in that month in that year */
189 days_in_month(int year
, int month
)
193 if (month
== 2 && is_leap(year
))
196 return _days_in_month
[month
];
199 /* year, month -> number of days in year preceeding first day of month */
201 days_before_month(int year
, int month
)
207 days
= _days_before_month
[month
];
208 if (month
> 2 && is_leap(year
))
213 /* year -> number of days before January 1st of year. Remember that we
214 * start with year 1, so days_before_year(1) == 0.
217 days_before_year(int year
)
220 /* This is incorrect if year <= 0; we really want the floor
221 * here. But so long as MINYEAR is 1, the smallest year this
222 * can see is 0 (this can happen in some normalization endcases),
223 * so we'll just special-case that.
227 return y
*365 + y
/4 - y
/100 + y
/400;
234 /* Number of days in 4, 100, and 400 year cycles. That these have
235 * the correct values is asserted in the module init function.
237 #define DI4Y 1461 /* days_before_year(5); days in 4 years */
238 #define DI100Y 36524 /* days_before_year(101); days in 100 years */
239 #define DI400Y 146097 /* days_before_year(401); days in 400 years */
241 /* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
243 ord_to_ymd(int ordinal
, int *year
, int *month
, int *day
)
245 int n
, n1
, n4
, n100
, n400
, leapyear
, preceding
;
247 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
248 * leap years repeats exactly every 400 years. The basic strategy is
249 * to find the closest 400-year boundary at or before ordinal, then
250 * work with the offset from that boundary to ordinal. Life is much
251 * clearer if we subtract 1 from ordinal first -- then the values
252 * of ordinal at 400-year boundaries are exactly those divisible
256 * -- --- ---- ---------- ----------------
257 * 31 Dec -400 -DI400Y -DI400Y -1
258 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
262 * 1 Jan 001 1 0 400-year boundary
266 * 31 Dec 400 DI400Y DI400Y -1
267 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
269 assert(ordinal
>= 1);
271 n400
= ordinal
/ DI400Y
;
272 n
= ordinal
% DI400Y
;
273 *year
= n400
* 400 + 1;
275 /* Now n is the (non-negative) offset, in days, from January 1 of
276 * year, to the desired date. Now compute how many 100-year cycles
278 * Note that it's possible for n100 to equal 4! In that case 4 full
279 * 100-year cycles precede the desired day, which implies the
280 * desired day is December 31 at the end of a 400-year cycle.
285 /* Now compute how many 4-year cycles precede it. */
289 /* And now how many single years. Again n1 can be 4, and again
290 * meaning that the desired day is December 31 at the end of the
296 *year
+= n100
* 100 + n4
* 4 + n1
;
297 if (n1
== 4 || n100
== 4) {
305 /* Now the year is correct, and n is the offset from January 1. We
306 * find the month via an estimate that's either exact or one too
309 leapyear
= n1
== 3 && (n4
!= 24 || n100
== 3);
310 assert(leapyear
== is_leap(*year
));
311 *month
= (n
+ 50) >> 5;
312 preceding
= (_days_before_month
[*month
] + (*month
> 2 && leapyear
));
314 /* estimate is too large */
316 preceding
-= days_in_month(*year
, *month
);
320 assert(n
< days_in_month(*year
, *month
));
325 /* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
327 ymd_to_ord(int year
, int month
, int day
)
329 return days_before_year(year
) + days_before_month(year
, month
) + day
;
332 /* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
334 weekday(int year
, int month
, int day
)
336 return (ymd_to_ord(year
, month
, day
) + 6) % 7;
339 /* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
340 * first calendar week containing a Thursday.
343 iso_week1_monday(int year
)
345 int first_day
= ymd_to_ord(year
, 1, 1); /* ord of 1/1 */
346 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
347 int first_weekday
= (first_day
+ 6) % 7;
348 /* ordinal of closest Monday at or before 1/1 */
349 int week1_monday
= first_day
- first_weekday
;
351 if (first_weekday
> 3) /* if 1/1 was Fri, Sat, Sun */
356 /* ---------------------------------------------------------------------------
360 /* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
361 * If not, raise OverflowError and return -1.
364 check_delta_day_range(int days
)
366 if (-MAX_DELTA_DAYS
<= days
&& days
<= MAX_DELTA_DAYS
)
368 PyErr_Format(PyExc_OverflowError
,
369 "days=%d; must have magnitude <= %d",
370 days
, MAX_DELTA_DAYS
);
374 /* Check that date arguments are in range. Return 0 if they are. If they
375 * aren't, raise ValueError and return -1.
378 check_date_args(int year
, int month
, int day
)
381 if (year
< MINYEAR
|| year
> MAXYEAR
) {
382 PyErr_SetString(PyExc_ValueError
,
383 "year is out of range");
386 if (month
< 1 || month
> 12) {
387 PyErr_SetString(PyExc_ValueError
,
388 "month must be in 1..12");
391 if (day
< 1 || day
> days_in_month(year
, month
)) {
392 PyErr_SetString(PyExc_ValueError
,
393 "day is out of range for month");
399 /* Check that time arguments are in range. Return 0 if they are. If they
400 * aren't, raise ValueError and return -1.
403 check_time_args(int h
, int m
, int s
, int us
)
405 if (h
< 0 || h
> 23) {
406 PyErr_SetString(PyExc_ValueError
,
407 "hour must be in 0..23");
410 if (m
< 0 || m
> 59) {
411 PyErr_SetString(PyExc_ValueError
,
412 "minute must be in 0..59");
415 if (s
< 0 || s
> 59) {
416 PyErr_SetString(PyExc_ValueError
,
417 "second must be in 0..59");
420 if (us
< 0 || us
> 999999) {
421 PyErr_SetString(PyExc_ValueError
,
422 "microsecond must be in 0..999999");
428 /* ---------------------------------------------------------------------------
429 * Normalization utilities.
432 /* One step of a mixed-radix conversion. A "hi" unit is equivalent to
433 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
434 * at least factor, enough of *lo is converted into "hi" units so that
435 * 0 <= *lo < factor. The input values must be such that int overflow
439 normalize_pair(int *hi
, int *lo
, int factor
)
443 if (*lo
< 0 || *lo
>= factor
) {
444 const int num_hi
= divmod(*lo
, factor
, lo
);
445 const int new_hi
= *hi
+ num_hi
;
446 assert(! SIGNED_ADD_OVERFLOWED(new_hi
, *hi
, num_hi
));
449 assert(0 <= *lo
&& *lo
< factor
);
452 /* Fiddle days (d), seconds (s), and microseconds (us) so that
455 * The input values must be such that the internals don't overflow.
456 * The way this routine is used, we don't get close.
459 normalize_d_s_us(int *d
, int *s
, int *us
)
461 if (*us
< 0 || *us
>= 1000000) {
462 normalize_pair(s
, us
, 1000000);
463 /* |s| can't be bigger than about
464 * |original s| + |original us|/1000000 now.
468 if (*s
< 0 || *s
>= 24*3600) {
469 normalize_pair(d
, s
, 24*3600);
470 /* |d| can't be bigger than about
472 * (|original s| + |original us|/1000000) / (24*3600) now.
475 assert(0 <= *s
&& *s
< 24*3600);
476 assert(0 <= *us
&& *us
< 1000000);
479 /* Fiddle years (y), months (m), and days (d) so that
481 * 1 <= *d <= days_in_month(*y, *m)
482 * The input values must be such that the internals don't overflow.
483 * The way this routine is used, we don't get close.
486 normalize_y_m_d(int *y
, int *m
, int *d
)
488 int dim
; /* # of days in month */
490 /* This gets muddy: the proper range for day can't be determined
491 * without knowing the correct month and year, but if day is, e.g.,
492 * plus or minus a million, the current month and year values make
493 * no sense (and may also be out of bounds themselves).
494 * Saying 12 months == 1 year should be non-controversial.
496 if (*m
< 1 || *m
> 12) {
498 normalize_pair(y
, m
, 12);
500 /* |y| can't be bigger than about
501 * |original y| + |original m|/12 now.
504 assert(1 <= *m
&& *m
<= 12);
506 /* Now only day can be out of bounds (year may also be out of bounds
507 * for a datetime object, but we don't care about that here).
508 * If day is out of bounds, what to do is arguable, but at least the
509 * method here is principled and explainable.
511 dim
= days_in_month(*y
, *m
);
512 if (*d
< 1 || *d
> dim
) {
513 /* Move day-1 days from the first of the month. First try to
514 * get off cheap if we're only one day out of range
515 * (adjustments for timezone alone can't be worse than that).
520 *d
= days_in_month(*y
, *m
);
527 else if (*d
== dim
+ 1) {
528 /* move forward a day */
537 int ordinal
= ymd_to_ord(*y
, *m
, 1) +
539 ord_to_ymd(ordinal
, y
, m
, d
);
546 /* Fiddle out-of-bounds months and days so that the result makes some kind
547 * of sense. The parameters are both inputs and outputs. Returns < 0 on
548 * failure, where failure means the adjusted year is out of bounds.
551 normalize_date(int *year
, int *month
, int *day
)
555 normalize_y_m_d(year
, month
, day
);
556 if (MINYEAR
<= *year
&& *year
<= MAXYEAR
)
559 PyErr_SetString(PyExc_OverflowError
,
560 "date value out of range");
566 /* Force all the datetime fields into range. The parameters are both
567 * inputs and outputs. Returns < 0 on error.
570 normalize_datetime(int *year
, int *month
, int *day
,
571 int *hour
, int *minute
, int *second
,
574 normalize_pair(second
, microsecond
, 1000000);
575 normalize_pair(minute
, second
, 60);
576 normalize_pair(hour
, minute
, 60);
577 normalize_pair(day
, hour
, 24);
578 return normalize_date(year
, month
, day
);
581 /* ---------------------------------------------------------------------------
582 * Basic object allocation: tp_alloc implementations. These allocate
583 * Python objects of the right size and type, and do the Python object-
584 * initialization bit. If there's not enough memory, they return NULL after
585 * setting MemoryError. All data members remain uninitialized trash.
587 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
588 * member is needed. This is ugly, imprecise, and possibly insecure.
589 * tp_basicsize for the time and datetime types is set to the size of the
590 * struct that has room for the tzinfo member, so subclasses in Python will
591 * allocate enough space for a tzinfo member whether or not one is actually
592 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
593 * part is that PyType_GenericAlloc() (which subclasses in Python end up
594 * using) just happens today to effectively ignore the nitems argument
595 * when tp_itemsize is 0, which it is for these type objects. If that
596 * changes, perhaps the callers of tp_alloc slots in this file should
597 * be changed to force a 0 nitems argument unless the type being allocated
598 * is a base type implemented in this file (so that tp_alloc is time_alloc
599 * or datetime_alloc below, which know about the nitems abuse).
603 time_alloc(PyTypeObject
*type
, Py_ssize_t aware
)
608 PyObject_MALLOC(aware
?
609 sizeof(PyDateTime_Time
) :
610 sizeof(_PyDateTime_BaseTime
));
612 return (PyObject
*)PyErr_NoMemory();
613 PyObject_INIT(self
, type
);
618 datetime_alloc(PyTypeObject
*type
, Py_ssize_t aware
)
623 PyObject_MALLOC(aware
?
624 sizeof(PyDateTime_DateTime
) :
625 sizeof(_PyDateTime_BaseDateTime
));
627 return (PyObject
*)PyErr_NoMemory();
628 PyObject_INIT(self
, type
);
632 /* ---------------------------------------------------------------------------
633 * Helpers for setting object fields. These work on pointers to the
634 * appropriate base class.
637 /* For date and datetime. */
639 set_date_fields(PyDateTime_Date
*self
, int y
, int m
, int d
)
647 /* ---------------------------------------------------------------------------
648 * Create various objects, mostly without range checking.
651 /* Create a date instance with no range checking. */
653 new_date_ex(int year
, int month
, int day
, PyTypeObject
*type
)
655 PyDateTime_Date
*self
;
657 self
= (PyDateTime_Date
*) (type
->tp_alloc(type
, 0));
659 set_date_fields(self
, year
, month
, day
);
660 return (PyObject
*) self
;
663 #define new_date(year, month, day) \
664 new_date_ex(year, month, day, &PyDateTime_DateType)
666 /* Create a datetime instance with no range checking. */
668 new_datetime_ex(int year
, int month
, int day
, int hour
, int minute
,
669 int second
, int usecond
, PyObject
*tzinfo
, PyTypeObject
*type
)
671 PyDateTime_DateTime
*self
;
672 char aware
= tzinfo
!= Py_None
;
674 self
= (PyDateTime_DateTime
*) (type
->tp_alloc(type
, aware
));
676 self
->hastzinfo
= aware
;
677 set_date_fields((PyDateTime_Date
*)self
, year
, month
, day
);
678 DATE_SET_HOUR(self
, hour
);
679 DATE_SET_MINUTE(self
, minute
);
680 DATE_SET_SECOND(self
, second
);
681 DATE_SET_MICROSECOND(self
, usecond
);
684 self
->tzinfo
= tzinfo
;
687 return (PyObject
*)self
;
690 #define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
691 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
692 &PyDateTime_DateTimeType)
694 /* Create a time instance with no range checking. */
696 new_time_ex(int hour
, int minute
, int second
, int usecond
,
697 PyObject
*tzinfo
, PyTypeObject
*type
)
699 PyDateTime_Time
*self
;
700 char aware
= tzinfo
!= Py_None
;
702 self
= (PyDateTime_Time
*) (type
->tp_alloc(type
, aware
));
704 self
->hastzinfo
= aware
;
706 TIME_SET_HOUR(self
, hour
);
707 TIME_SET_MINUTE(self
, minute
);
708 TIME_SET_SECOND(self
, second
);
709 TIME_SET_MICROSECOND(self
, usecond
);
712 self
->tzinfo
= tzinfo
;
715 return (PyObject
*)self
;
718 #define new_time(hh, mm, ss, us, tzinfo) \
719 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
721 /* Create a timedelta instance. Normalize the members iff normalize is
722 * true. Passing false is a speed optimization, if you know for sure
723 * that seconds and microseconds are already in their proper ranges. In any
724 * case, raises OverflowError and returns NULL if the normalized days is out
728 new_delta_ex(int days
, int seconds
, int microseconds
, int normalize
,
731 PyDateTime_Delta
*self
;
734 normalize_d_s_us(&days
, &seconds
, µseconds
);
735 assert(0 <= seconds
&& seconds
< 24*3600);
736 assert(0 <= microseconds
&& microseconds
< 1000000);
738 if (check_delta_day_range(days
) < 0)
741 self
= (PyDateTime_Delta
*) (type
->tp_alloc(type
, 0));
744 SET_TD_DAYS(self
, days
);
745 SET_TD_SECONDS(self
, seconds
);
746 SET_TD_MICROSECONDS(self
, microseconds
);
748 return (PyObject
*) self
;
751 #define new_delta(d, s, us, normalize) \
752 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
754 /* ---------------------------------------------------------------------------
758 /* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
759 * raise TypeError and return -1.
762 check_tzinfo_subclass(PyObject
*p
)
764 if (p
== Py_None
|| PyTZInfo_Check(p
))
766 PyErr_Format(PyExc_TypeError
,
767 "tzinfo argument must be None or of a tzinfo subclass, "
769 Py_TYPE(p
)->tp_name
);
773 /* Return tzinfo.methname(tzinfoarg), without any checking of results.
774 * If tzinfo is None, returns None.
777 call_tzinfo_method(PyObject
*tzinfo
, char *methname
, PyObject
*tzinfoarg
)
781 assert(tzinfo
&& methname
&& tzinfoarg
);
782 assert(check_tzinfo_subclass(tzinfo
) >= 0);
783 if (tzinfo
== Py_None
) {
788 result
= PyObject_CallMethod(tzinfo
, methname
, "O", tzinfoarg
);
792 /* If self has a tzinfo member, return a BORROWED reference to it. Else
793 * return NULL, which is NOT AN ERROR. There are no error returns here,
794 * and the caller must not decref the result.
797 get_tzinfo_member(PyObject
*self
)
799 PyObject
*tzinfo
= NULL
;
801 if (PyDateTime_Check(self
) && HASTZINFO(self
))
802 tzinfo
= ((PyDateTime_DateTime
*)self
)->tzinfo
;
803 else if (PyTime_Check(self
) && HASTZINFO(self
))
804 tzinfo
= ((PyDateTime_Time
*)self
)->tzinfo
;
809 /* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
810 * result. tzinfo must be an instance of the tzinfo class. If the method
811 * returns None, this returns 0 and sets *none to 1. If the method doesn't
812 * return None or timedelta, TypeError is raised and this returns -1. If it
813 * returnsa timedelta and the value is out of range or isn't a whole number
814 * of minutes, ValueError is raised and this returns -1.
815 * Else *none is set to 0 and the integer method result is returned.
818 call_utc_tzinfo_method(PyObject
*tzinfo
, char *name
, PyObject
*tzinfoarg
,
824 assert(tzinfo
!= NULL
);
825 assert(PyTZInfo_Check(tzinfo
));
826 assert(tzinfoarg
!= NULL
);
829 u
= call_tzinfo_method(tzinfo
, name
, tzinfoarg
);
833 else if (u
== Py_None
) {
837 else if (PyDelta_Check(u
)) {
838 const int days
= GET_TD_DAYS(u
);
839 if (days
< -1 || days
> 0)
840 result
= 24*60; /* trigger ValueError below */
842 /* next line can't overflow because we know days
845 int ss
= days
* 24 * 3600 + GET_TD_SECONDS(u
);
846 result
= divmod(ss
, 60, &ss
);
847 if (ss
|| GET_TD_MICROSECONDS(u
)) {
848 PyErr_Format(PyExc_ValueError
,
849 "tzinfo.%s() must return a "
850 "whole number of minutes",
857 PyErr_Format(PyExc_TypeError
,
858 "tzinfo.%s() must return None or "
859 "timedelta, not '%s'",
860 name
, Py_TYPE(u
)->tp_name
);
864 if (result
< -1439 || result
> 1439) {
865 PyErr_Format(PyExc_ValueError
,
866 "tzinfo.%s() returned %d; must be in "
874 /* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
875 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
876 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
877 * doesn't return None or timedelta, TypeError is raised and this returns -1.
878 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
879 * # of minutes), ValueError is raised and this returns -1. Else *none is
880 * set to 0 and the offset is returned (as int # of minutes east of UTC).
883 call_utcoffset(PyObject
*tzinfo
, PyObject
*tzinfoarg
, int *none
)
885 return call_utc_tzinfo_method(tzinfo
, "utcoffset", tzinfoarg
, none
);
888 /* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
891 offset_as_timedelta(PyObject
*tzinfo
, char *name
, PyObject
*tzinfoarg
) {
894 assert(tzinfo
&& name
&& tzinfoarg
);
895 if (tzinfo
== Py_None
) {
901 int offset
= call_utc_tzinfo_method(tzinfo
, name
, tzinfoarg
,
903 if (offset
< 0 && PyErr_Occurred())
910 result
= new_delta(0, offset
* 60, 0, 1);
915 /* Call tzinfo.dst(tzinfoarg), and extract an integer from the
916 * result. tzinfo must be an instance of the tzinfo class. If dst()
917 * returns None, call_dst returns 0 and sets *none to 1. If dst()
918 & doesn't return None or timedelta, TypeError is raised and this
919 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
920 * ValueError is raised and this returns -1. Else *none is set to 0 and
921 * the offset is returned (as an int # of minutes east of UTC).
924 call_dst(PyObject
*tzinfo
, PyObject
*tzinfoarg
, int *none
)
926 return call_utc_tzinfo_method(tzinfo
, "dst", tzinfoarg
, none
);
929 /* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
930 * an instance of the tzinfo class or None. If tzinfo isn't None, and
931 * tzname() doesn't return None or a string, TypeError is raised and this
935 call_tzname(PyObject
*tzinfo
, PyObject
*tzinfoarg
)
939 assert(tzinfo
!= NULL
);
940 assert(check_tzinfo_subclass(tzinfo
) >= 0);
941 assert(tzinfoarg
!= NULL
);
943 if (tzinfo
== Py_None
) {
948 result
= PyObject_CallMethod(tzinfo
, "tzname", "O", tzinfoarg
);
950 if (result
!= NULL
&& result
!= Py_None
&& ! PyString_Check(result
)) {
951 PyErr_Format(PyExc_TypeError
, "tzinfo.tzname() must "
952 "return None or a string, not '%s'",
953 Py_TYPE(result
)->tp_name
);
961 /* an exception has been set; the caller should pass it on */
964 /* type isn't date, datetime, or time subclass */
968 * datetime with !hastzinfo
969 * datetime with None tzinfo,
970 * datetime where utcoffset() returns None
971 * time with !hastzinfo
972 * time with None tzinfo,
973 * time where utcoffset() returns None
977 /* time or datetime where utcoffset() doesn't return None */
981 /* Classify an object as to whether it's naive or offset-aware. See
982 * the "naivety" typedef for details. If the type is aware, *offset is set
983 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
984 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
985 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
988 classify_utcoffset(PyObject
*op
, PyObject
*tzinfoarg
, int *offset
)
993 assert(tzinfoarg
!= NULL
);
995 tzinfo
= get_tzinfo_member(op
); /* NULL means no tzinfo, not error */
996 if (tzinfo
== Py_None
)
998 if (tzinfo
== NULL
) {
999 /* note that a datetime passes the PyDate_Check test */
1000 return (PyTime_Check(op
) || PyDate_Check(op
)) ?
1001 OFFSET_NAIVE
: OFFSET_UNKNOWN
;
1003 *offset
= call_utcoffset(tzinfo
, tzinfoarg
, &none
);
1004 if (*offset
== -1 && PyErr_Occurred())
1005 return OFFSET_ERROR
;
1006 return none
? OFFSET_NAIVE
: OFFSET_AWARE
;
1009 /* Classify two objects as to whether they're naive or offset-aware.
1010 * This isn't quite the same as calling classify_utcoffset() twice: for
1011 * binary operations (comparison and subtraction), we generally want to
1012 * ignore the tzinfo members if they're identical. This is by design,
1013 * so that results match "naive" expectations when mixing objects from a
1014 * single timezone. So in that case, this sets both offsets to 0 and
1015 * both naiveties to OFFSET_NAIVE.
1016 * The function returns 0 if everything's OK, and -1 on error.
1019 classify_two_utcoffsets(PyObject
*o1
, int *offset1
, naivety
*n1
,
1020 PyObject
*tzinfoarg1
,
1021 PyObject
*o2
, int *offset2
, naivety
*n2
,
1022 PyObject
*tzinfoarg2
)
1024 if (get_tzinfo_member(o1
) == get_tzinfo_member(o2
)) {
1025 *offset1
= *offset2
= 0;
1026 *n1
= *n2
= OFFSET_NAIVE
;
1029 *n1
= classify_utcoffset(o1
, tzinfoarg1
, offset1
);
1030 if (*n1
== OFFSET_ERROR
)
1032 *n2
= classify_utcoffset(o2
, tzinfoarg2
, offset2
);
1033 if (*n2
== OFFSET_ERROR
)
1039 /* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1041 * ", tzinfo=" + repr(tzinfo)
1042 * before the closing ")".
1045 append_keyword_tzinfo(PyObject
*repr
, PyObject
*tzinfo
)
1049 assert(PyString_Check(repr
));
1051 if (tzinfo
== Py_None
)
1053 /* Get rid of the trailing ')'. */
1054 assert(PyString_AsString(repr
)[PyString_Size(repr
)-1] == ')');
1055 temp
= PyString_FromStringAndSize(PyString_AsString(repr
),
1056 PyString_Size(repr
) - 1);
1062 /* Append ", tzinfo=". */
1063 PyString_ConcatAndDel(&repr
, PyString_FromString(", tzinfo="));
1065 /* Append repr(tzinfo). */
1066 PyString_ConcatAndDel(&repr
, PyObject_Repr(tzinfo
));
1068 /* Add a closing paren. */
1069 PyString_ConcatAndDel(&repr
, PyString_FromString(")"));
1073 /* ---------------------------------------------------------------------------
1074 * String format helpers.
1078 format_ctime(PyDateTime_Date
*date
, int hours
, int minutes
, int seconds
)
1080 static const char *DayNames
[] = {
1081 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1083 static const char *MonthNames
[] = {
1084 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1085 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1089 int wday
= weekday(GET_YEAR(date
), GET_MONTH(date
), GET_DAY(date
));
1091 PyOS_snprintf(buffer
, sizeof(buffer
), "%s %s %2d %02d:%02d:%02d %04d",
1092 DayNames
[wday
], MonthNames
[GET_MONTH(date
) - 1],
1093 GET_DAY(date
), hours
, minutes
, seconds
,
1095 return PyString_FromString(buffer
);
1098 /* Add an hours & minutes UTC offset string to buf. buf has no more than
1099 * buflen bytes remaining. The UTC offset is gotten by calling
1100 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1101 * *buf, and that's all. Else the returned value is checked for sanity (an
1102 * integer in range), and if that's OK it's converted to an hours & minutes
1103 * string of the form
1105 * Returns 0 if everything is OK. If the return value from utcoffset() is
1106 * bogus, an appropriate exception is set and -1 is returned.
1109 format_utcoffset(char *buf
, size_t buflen
, const char *sep
,
1110 PyObject
*tzinfo
, PyObject
*tzinfoarg
)
1118 assert(buflen
>= 1);
1120 offset
= call_utcoffset(tzinfo
, tzinfoarg
, &none
);
1121 if (offset
== -1 && PyErr_Occurred())
1132 hours
= divmod(offset
, 60, &minutes
);
1133 PyOS_snprintf(buf
, buflen
, "%c%02d%s%02d", sign
, hours
, sep
, minutes
);
1138 make_freplacement(PyObject
*object
)
1140 char freplacement
[64];
1141 if (PyTime_Check(object
))
1142 sprintf(freplacement
, "%06d", TIME_GET_MICROSECOND(object
));
1143 else if (PyDateTime_Check(object
))
1144 sprintf(freplacement
, "%06d", DATE_GET_MICROSECOND(object
));
1146 sprintf(freplacement
, "%06d", 0);
1148 return PyString_FromStringAndSize(freplacement
, strlen(freplacement
));
1151 /* I sure don't want to reproduce the strftime code from the time module,
1152 * so this imports the module and calls it. All the hair is due to
1153 * giving special meanings to the %z, %Z and %f format codes via a
1154 * preprocessing step on the format string.
1155 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1159 wrap_strftime(PyObject
*object
, const char *format
, size_t format_len
,
1160 PyObject
*timetuple
, PyObject
*tzinfoarg
)
1162 PyObject
*result
= NULL
; /* guilty until proved innocent */
1164 PyObject
*zreplacement
= NULL
; /* py string, replacement for %z */
1165 PyObject
*Zreplacement
= NULL
; /* py string, replacement for %Z */
1166 PyObject
*freplacement
= NULL
; /* py string, replacement for %f */
1168 const char *pin
; /* pointer to next char in input format */
1169 char ch
; /* next char in input format */
1171 PyObject
*newfmt
= NULL
; /* py string, the output format */
1172 char *pnew
; /* pointer to available byte in output format */
1173 size_t totalnew
; /* number bytes total in output format buffer,
1174 exclusive of trailing \0 */
1175 size_t usednew
; /* number bytes used so far in output format buffer */
1177 const char *ptoappend
; /* ptr to string to append to output buffer */
1178 size_t ntoappend
; /* # of bytes to append to output buffer */
1180 assert(object
&& format
&& timetuple
);
1182 /* Give up if the year is before 1900.
1183 * Python strftime() plays games with the year, and different
1184 * games depending on whether envar PYTHON2K is set. This makes
1185 * years before 1900 a nightmare, even if the platform strftime
1186 * supports them (and not all do).
1187 * We could get a lot farther here by avoiding Python's strftime
1188 * wrapper and calling the C strftime() directly, but that isn't
1189 * an option in the Python implementation of this module.
1193 PyObject
*pyyear
= PySequence_GetItem(timetuple
, 0);
1194 if (pyyear
== NULL
) return NULL
;
1195 assert(PyInt_Check(pyyear
));
1196 year
= PyInt_AsLong(pyyear
);
1199 PyErr_Format(PyExc_ValueError
, "year=%ld is before "
1200 "1900; the datetime strftime() "
1201 "methods require year >= 1900",
1207 /* Scan the input format, looking for %z/%Z/%f escapes, building
1208 * a new format. Since computing the replacements for those codes
1209 * is expensive, don't unless they're actually used.
1211 if (format_len
> INT_MAX
- 1) {
1216 totalnew
= format_len
+ 1; /* realistic if no %z/%Z/%f */
1217 newfmt
= PyString_FromStringAndSize(NULL
, totalnew
);
1218 if (newfmt
== NULL
) goto Done
;
1219 pnew
= PyString_AsString(newfmt
);
1223 while ((ch
= *pin
++) != '\0') {
1225 ptoappend
= pin
- 1;
1228 else if ((ch
= *pin
++) == '\0') {
1229 /* There's a lone trailing %; doesn't make sense. */
1230 PyErr_SetString(PyExc_ValueError
, "strftime format "
1234 /* A % has been seen and ch is the character after it. */
1235 else if (ch
== 'z') {
1236 if (zreplacement
== NULL
) {
1237 /* format utcoffset */
1239 PyObject
*tzinfo
= get_tzinfo_member(object
);
1240 zreplacement
= PyString_FromString("");
1241 if (zreplacement
== NULL
) goto Done
;
1242 if (tzinfo
!= Py_None
&& tzinfo
!= NULL
) {
1243 assert(tzinfoarg
!= NULL
);
1244 if (format_utcoffset(buf
,
1250 Py_DECREF(zreplacement
);
1251 zreplacement
= PyString_FromString(buf
);
1252 if (zreplacement
== NULL
) goto Done
;
1255 assert(zreplacement
!= NULL
);
1256 ptoappend
= PyString_AS_STRING(zreplacement
);
1257 ntoappend
= PyString_GET_SIZE(zreplacement
);
1259 else if (ch
== 'Z') {
1261 if (Zreplacement
== NULL
) {
1262 PyObject
*tzinfo
= get_tzinfo_member(object
);
1263 Zreplacement
= PyString_FromString("");
1264 if (Zreplacement
== NULL
) goto Done
;
1265 if (tzinfo
!= Py_None
&& tzinfo
!= NULL
) {
1267 assert(tzinfoarg
!= NULL
);
1268 temp
= call_tzname(tzinfo
, tzinfoarg
);
1269 if (temp
== NULL
) goto Done
;
1270 if (temp
!= Py_None
) {
1271 assert(PyString_Check(temp
));
1272 /* Since the tzname is getting
1273 * stuffed into the format, we
1274 * have to double any % signs
1275 * so that strftime doesn't
1276 * treat them as format codes.
1278 Py_DECREF(Zreplacement
);
1279 Zreplacement
= PyObject_CallMethod(
1283 if (Zreplacement
== NULL
)
1285 if (!PyString_Check(Zreplacement
)) {
1286 PyErr_SetString(PyExc_TypeError
, "tzname.replace() did not return a string");
1294 assert(Zreplacement
!= NULL
);
1295 ptoappend
= PyString_AS_STRING(Zreplacement
);
1296 ntoappend
= PyString_GET_SIZE(Zreplacement
);
1298 else if (ch
== 'f') {
1299 /* format microseconds */
1300 if (freplacement
== NULL
) {
1301 freplacement
= make_freplacement(object
);
1302 if (freplacement
== NULL
)
1305 assert(freplacement
!= NULL
);
1306 assert(PyString_Check(freplacement
));
1307 ptoappend
= PyString_AS_STRING(freplacement
);
1308 ntoappend
= PyString_GET_SIZE(freplacement
);
1311 /* percent followed by neither z nor Z */
1312 ptoappend
= pin
- 2;
1316 /* Append the ntoappend chars starting at ptoappend to
1319 assert(ptoappend
!= NULL
);
1320 assert(ntoappend
>= 0);
1323 while (usednew
+ ntoappend
> totalnew
) {
1324 size_t bigger
= totalnew
<< 1;
1325 if ((bigger
>> 1) != totalnew
) { /* overflow */
1329 if (_PyString_Resize(&newfmt
, bigger
) < 0)
1332 pnew
= PyString_AsString(newfmt
) + usednew
;
1334 memcpy(pnew
, ptoappend
, ntoappend
);
1336 usednew
+= ntoappend
;
1337 assert(usednew
<= totalnew
);
1340 if (_PyString_Resize(&newfmt
, usednew
) < 0)
1343 PyObject
*time
= PyImport_ImportModuleNoBlock("time");
1346 result
= PyObject_CallMethod(time
, "strftime", "OO",
1351 Py_XDECREF(freplacement
);
1352 Py_XDECREF(zreplacement
);
1353 Py_XDECREF(Zreplacement
);
1359 isoformat_date(PyDateTime_Date
*dt
, char buffer
[], int bufflen
)
1362 x
= PyOS_snprintf(buffer
, bufflen
,
1364 GET_YEAR(dt
), GET_MONTH(dt
), GET_DAY(dt
));
1369 isoformat_time(PyDateTime_DateTime
*dt
, char buffer
[], int bufflen
)
1371 int us
= DATE_GET_MICROSECOND(dt
);
1373 PyOS_snprintf(buffer
, bufflen
,
1374 "%02d:%02d:%02d", /* 8 characters */
1376 DATE_GET_MINUTE(dt
),
1377 DATE_GET_SECOND(dt
));
1379 PyOS_snprintf(buffer
+ 8, bufflen
- 8, ".%06d", us
);
1382 /* ---------------------------------------------------------------------------
1383 * Wrap functions from the time module. These aren't directly available
1384 * from C. Perhaps they should be.
1387 /* Call time.time() and return its result (a Python float). */
1391 PyObject
*result
= NULL
;
1392 PyObject
*time
= PyImport_ImportModuleNoBlock("time");
1395 result
= PyObject_CallMethod(time
, "time", "()");
1401 /* Build a time.struct_time. The weekday and day number are automatically
1402 * computed from the y,m,d args.
1405 build_struct_time(int y
, int m
, int d
, int hh
, int mm
, int ss
, int dstflag
)
1408 PyObject
*result
= NULL
;
1410 time
= PyImport_ImportModuleNoBlock("time");
1412 result
= PyObject_CallMethod(time
, "struct_time",
1417 days_before_month(y
, m
) + d
,
1424 /* ---------------------------------------------------------------------------
1425 * Miscellaneous helpers.
1428 /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1429 * The comparisons here all most naturally compute a cmp()-like result.
1430 * This little helper turns that into a bool result for rich comparisons.
1433 diff_to_bool(int diff
, int op
)
1439 case Py_EQ
: istrue
= diff
== 0; break;
1440 case Py_NE
: istrue
= diff
!= 0; break;
1441 case Py_LE
: istrue
= diff
<= 0; break;
1442 case Py_GE
: istrue
= diff
>= 0; break;
1443 case Py_LT
: istrue
= diff
< 0; break;
1444 case Py_GT
: istrue
= diff
> 0; break;
1446 assert(! "op unknown");
1447 istrue
= 0; /* To shut up compiler */
1449 result
= istrue
? Py_True
: Py_False
;
1454 /* Raises a "can't compare" TypeError and returns NULL. */
1456 cmperror(PyObject
*a
, PyObject
*b
)
1458 PyErr_Format(PyExc_TypeError
,
1459 "can't compare %s to %s",
1460 Py_TYPE(a
)->tp_name
, Py_TYPE(b
)->tp_name
);
1464 /* ---------------------------------------------------------------------------
1465 * Cached Python objects; these are set by the module init function.
1468 /* Conversion factors. */
1469 static PyObject
*us_per_us
= NULL
; /* 1 */
1470 static PyObject
*us_per_ms
= NULL
; /* 1000 */
1471 static PyObject
*us_per_second
= NULL
; /* 1000000 */
1472 static PyObject
*us_per_minute
= NULL
; /* 1e6 * 60 as Python int */
1473 static PyObject
*us_per_hour
= NULL
; /* 1e6 * 3600 as Python long */
1474 static PyObject
*us_per_day
= NULL
; /* 1e6 * 3600 * 24 as Python long */
1475 static PyObject
*us_per_week
= NULL
; /* 1e6*3600*24*7 as Python long */
1476 static PyObject
*seconds_per_day
= NULL
; /* 3600*24 as Python int */
1478 /* ---------------------------------------------------------------------------
1479 * Class implementations.
1483 * PyDateTime_Delta implementation.
1486 /* Convert a timedelta to a number of us,
1487 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1488 * as a Python int or long.
1489 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1490 * due to ubiquitous overflow possibilities.
1493 delta_to_microseconds(PyDateTime_Delta
*self
)
1495 PyObject
*x1
= NULL
;
1496 PyObject
*x2
= NULL
;
1497 PyObject
*x3
= NULL
;
1498 PyObject
*result
= NULL
;
1500 x1
= PyInt_FromLong(GET_TD_DAYS(self
));
1503 x2
= PyNumber_Multiply(x1
, seconds_per_day
); /* days in seconds */
1509 /* x2 has days in seconds */
1510 x1
= PyInt_FromLong(GET_TD_SECONDS(self
)); /* seconds */
1513 x3
= PyNumber_Add(x1
, x2
); /* days and seconds in seconds */
1520 /* x3 has days+seconds in seconds */
1521 x1
= PyNumber_Multiply(x3
, us_per_second
); /* us */
1527 /* x1 has days+seconds in us */
1528 x2
= PyInt_FromLong(GET_TD_MICROSECONDS(self
));
1531 result
= PyNumber_Add(x1
, x2
);
1540 /* Convert a number of us (as a Python int or long) to a timedelta.
1543 microseconds_to_delta_ex(PyObject
*pyus
, PyTypeObject
*type
)
1550 PyObject
*tuple
= NULL
;
1551 PyObject
*num
= NULL
;
1552 PyObject
*result
= NULL
;
1554 tuple
= PyNumber_Divmod(pyus
, us_per_second
);
1558 num
= PyTuple_GetItem(tuple
, 1); /* us */
1561 temp
= PyLong_AsLong(num
);
1563 if (temp
== -1 && PyErr_Occurred())
1565 assert(0 <= temp
&& temp
< 1000000);
1568 /* The divisor was positive, so this must be an error. */
1569 assert(PyErr_Occurred());
1573 num
= PyTuple_GetItem(tuple
, 0); /* leftover seconds */
1579 tuple
= PyNumber_Divmod(num
, seconds_per_day
);
1584 num
= PyTuple_GetItem(tuple
, 1); /* seconds */
1587 temp
= PyLong_AsLong(num
);
1589 if (temp
== -1 && PyErr_Occurred())
1591 assert(0 <= temp
&& temp
< 24*3600);
1595 /* The divisor was positive, so this must be an error. */
1596 assert(PyErr_Occurred());
1600 num
= PyTuple_GetItem(tuple
, 0); /* leftover days */
1604 temp
= PyLong_AsLong(num
);
1605 if (temp
== -1 && PyErr_Occurred())
1608 if ((long)d
!= temp
) {
1609 PyErr_SetString(PyExc_OverflowError
, "normalized days too "
1610 "large to fit in a C int");
1613 result
= new_delta_ex(d
, s
, us
, 0, type
);
1621 #define microseconds_to_delta(pymicros) \
1622 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1625 multiply_int_timedelta(PyObject
*intobj
, PyDateTime_Delta
*delta
)
1631 pyus_in
= delta_to_microseconds(delta
);
1632 if (pyus_in
== NULL
)
1635 pyus_out
= PyNumber_Multiply(pyus_in
, intobj
);
1637 if (pyus_out
== NULL
)
1640 result
= microseconds_to_delta(pyus_out
);
1641 Py_DECREF(pyus_out
);
1646 divide_timedelta_int(PyDateTime_Delta
*delta
, PyObject
*intobj
)
1652 pyus_in
= delta_to_microseconds(delta
);
1653 if (pyus_in
== NULL
)
1656 pyus_out
= PyNumber_FloorDivide(pyus_in
, intobj
);
1658 if (pyus_out
== NULL
)
1661 result
= microseconds_to_delta(pyus_out
);
1662 Py_DECREF(pyus_out
);
1667 delta_add(PyObject
*left
, PyObject
*right
)
1669 PyObject
*result
= Py_NotImplemented
;
1671 if (PyDelta_Check(left
) && PyDelta_Check(right
)) {
1673 /* The C-level additions can't overflow because of the
1676 int days
= GET_TD_DAYS(left
) + GET_TD_DAYS(right
);
1677 int seconds
= GET_TD_SECONDS(left
) + GET_TD_SECONDS(right
);
1678 int microseconds
= GET_TD_MICROSECONDS(left
) +
1679 GET_TD_MICROSECONDS(right
);
1680 result
= new_delta(days
, seconds
, microseconds
, 1);
1683 if (result
== Py_NotImplemented
)
1689 delta_negative(PyDateTime_Delta
*self
)
1691 return new_delta(-GET_TD_DAYS(self
),
1692 -GET_TD_SECONDS(self
),
1693 -GET_TD_MICROSECONDS(self
),
1698 delta_positive(PyDateTime_Delta
*self
)
1700 /* Could optimize this (by returning self) if this isn't a
1701 * subclass -- but who uses unary + ? Approximately nobody.
1703 return new_delta(GET_TD_DAYS(self
),
1704 GET_TD_SECONDS(self
),
1705 GET_TD_MICROSECONDS(self
),
1710 delta_abs(PyDateTime_Delta
*self
)
1714 assert(GET_TD_MICROSECONDS(self
) >= 0);
1715 assert(GET_TD_SECONDS(self
) >= 0);
1717 if (GET_TD_DAYS(self
) < 0)
1718 result
= delta_negative(self
);
1720 result
= delta_positive(self
);
1726 delta_subtract(PyObject
*left
, PyObject
*right
)
1728 PyObject
*result
= Py_NotImplemented
;
1730 if (PyDelta_Check(left
) && PyDelta_Check(right
)) {
1732 PyObject
*minus_right
= PyNumber_Negative(right
);
1734 result
= delta_add(left
, minus_right
);
1735 Py_DECREF(minus_right
);
1741 if (result
== Py_NotImplemented
)
1746 /* This is more natural as a tp_compare, but doesn't work then: for whatever
1747 * reason, Python's try_3way_compare ignores tp_compare unless
1748 * PyInstance_Check returns true, but these aren't old-style classes.
1751 delta_richcompare(PyDateTime_Delta
*self
, PyObject
*other
, int op
)
1753 int diff
= 42; /* nonsense */
1755 if (PyDelta_Check(other
)) {
1756 diff
= GET_TD_DAYS(self
) - GET_TD_DAYS(other
);
1758 diff
= GET_TD_SECONDS(self
) - GET_TD_SECONDS(other
);
1760 diff
= GET_TD_MICROSECONDS(self
) -
1761 GET_TD_MICROSECONDS(other
);
1764 else if (op
== Py_EQ
|| op
== Py_NE
)
1765 diff
= 1; /* any non-zero value will do */
1767 else /* stop this from falling back to address comparison */
1768 return cmperror((PyObject
*)self
, other
);
1770 return diff_to_bool(diff
, op
);
1773 static PyObject
*delta_getstate(PyDateTime_Delta
*self
);
1776 delta_hash(PyDateTime_Delta
*self
)
1778 if (self
->hashcode
== -1) {
1779 PyObject
*temp
= delta_getstate(self
);
1781 self
->hashcode
= PyObject_Hash(temp
);
1785 return self
->hashcode
;
1789 delta_multiply(PyObject
*left
, PyObject
*right
)
1791 PyObject
*result
= Py_NotImplemented
;
1793 if (PyDelta_Check(left
)) {
1795 if (PyInt_Check(right
) || PyLong_Check(right
))
1796 result
= multiply_int_timedelta(right
,
1797 (PyDateTime_Delta
*) left
);
1799 else if (PyInt_Check(left
) || PyLong_Check(left
))
1800 result
= multiply_int_timedelta(left
,
1801 (PyDateTime_Delta
*) right
);
1803 if (result
== Py_NotImplemented
)
1809 delta_divide(PyObject
*left
, PyObject
*right
)
1811 PyObject
*result
= Py_NotImplemented
;
1813 if (PyDelta_Check(left
)) {
1815 if (PyInt_Check(right
) || PyLong_Check(right
))
1816 result
= divide_timedelta_int(
1817 (PyDateTime_Delta
*)left
,
1821 if (result
== Py_NotImplemented
)
1826 /* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1827 * timedelta constructor. sofar is the # of microseconds accounted for
1828 * so far, and there are factor microseconds per current unit, the number
1829 * of which is given by num. num * factor is added to sofar in a
1830 * numerically careful way, and that's the result. Any fractional
1831 * microseconds left over (this can happen if num is a float type) are
1832 * added into *leftover.
1833 * Note that there are many ways this can give an error (NULL) return.
1836 accum(const char* tag
, PyObject
*sofar
, PyObject
*num
, PyObject
*factor
,
1842 assert(num
!= NULL
);
1844 if (PyInt_Check(num
) || PyLong_Check(num
)) {
1845 prod
= PyNumber_Multiply(num
, factor
);
1848 sum
= PyNumber_Add(sofar
, prod
);
1853 if (PyFloat_Check(num
)) {
1860 /* The Plan: decompose num into an integer part and a
1861 * fractional part, num = intpart + fracpart.
1862 * Then num * factor ==
1863 * intpart * factor + fracpart * factor
1864 * and the LHS can be computed exactly in long arithmetic.
1865 * The RHS is again broken into an int part and frac part.
1866 * and the frac part is added into *leftover.
1868 dnum
= PyFloat_AsDouble(num
);
1869 if (dnum
== -1.0 && PyErr_Occurred())
1871 fracpart
= modf(dnum
, &intpart
);
1872 x
= PyLong_FromDouble(intpart
);
1876 prod
= PyNumber_Multiply(x
, factor
);
1881 sum
= PyNumber_Add(sofar
, prod
);
1886 if (fracpart
== 0.0)
1888 /* So far we've lost no information. Dealing with the
1889 * fractional part requires float arithmetic, and may
1890 * lose a little info.
1892 assert(PyInt_Check(factor
) || PyLong_Check(factor
));
1893 if (PyInt_Check(factor
))
1894 dnum
= (double)PyInt_AsLong(factor
);
1896 dnum
= PyLong_AsDouble(factor
);
1899 fracpart
= modf(dnum
, &intpart
);
1900 x
= PyLong_FromDouble(intpart
);
1906 y
= PyNumber_Add(sum
, x
);
1909 *leftover
+= fracpart
;
1913 PyErr_Format(PyExc_TypeError
,
1914 "unsupported type for timedelta %s component: %s",
1915 tag
, Py_TYPE(num
)->tp_name
);
1920 delta_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
1922 PyObject
*self
= NULL
;
1924 /* Argument objects. */
1925 PyObject
*day
= NULL
;
1926 PyObject
*second
= NULL
;
1927 PyObject
*us
= NULL
;
1928 PyObject
*ms
= NULL
;
1929 PyObject
*minute
= NULL
;
1930 PyObject
*hour
= NULL
;
1931 PyObject
*week
= NULL
;
1933 PyObject
*x
= NULL
; /* running sum of microseconds */
1934 PyObject
*y
= NULL
; /* temp sum of microseconds */
1935 double leftover_us
= 0.0;
1937 static char *keywords
[] = {
1938 "days", "seconds", "microseconds", "milliseconds",
1939 "minutes", "hours", "weeks", NULL
1942 if (PyArg_ParseTupleAndKeywords(args
, kw
, "|OOOOOOO:__new__",
1945 &ms
, &minute
, &hour
, &week
) == 0)
1948 x
= PyInt_FromLong(0);
1959 y
= accum("microseconds", x
, us
, us_per_us
, &leftover_us
);
1963 y
= accum("milliseconds", x
, ms
, us_per_ms
, &leftover_us
);
1967 y
= accum("seconds", x
, second
, us_per_second
, &leftover_us
);
1971 y
= accum("minutes", x
, minute
, us_per_minute
, &leftover_us
);
1975 y
= accum("hours", x
, hour
, us_per_hour
, &leftover_us
);
1979 y
= accum("days", x
, day
, us_per_day
, &leftover_us
);
1983 y
= accum("weeks", x
, week
, us_per_week
, &leftover_us
);
1987 /* Round to nearest whole # of us, and add into x. */
1988 PyObject
*temp
= PyLong_FromLong(round_to_long(leftover_us
));
1993 y
= PyNumber_Add(x
, temp
);
1998 self
= microseconds_to_delta_ex(x
, type
);
2007 delta_nonzero(PyDateTime_Delta
*self
)
2009 return (GET_TD_DAYS(self
) != 0
2010 || GET_TD_SECONDS(self
) != 0
2011 || GET_TD_MICROSECONDS(self
) != 0);
2015 delta_repr(PyDateTime_Delta
*self
)
2017 if (GET_TD_MICROSECONDS(self
) != 0)
2018 return PyString_FromFormat("%s(%d, %d, %d)",
2019 Py_TYPE(self
)->tp_name
,
2021 GET_TD_SECONDS(self
),
2022 GET_TD_MICROSECONDS(self
));
2023 if (GET_TD_SECONDS(self
) != 0)
2024 return PyString_FromFormat("%s(%d, %d)",
2025 Py_TYPE(self
)->tp_name
,
2027 GET_TD_SECONDS(self
));
2029 return PyString_FromFormat("%s(%d)",
2030 Py_TYPE(self
)->tp_name
,
2035 delta_str(PyDateTime_Delta
*self
)
2037 int days
= GET_TD_DAYS(self
);
2038 int seconds
= GET_TD_SECONDS(self
);
2039 int us
= GET_TD_MICROSECONDS(self
);
2044 size_t buflen
= sizeof(buf
);
2047 minutes
= divmod(seconds
, 60, &seconds
);
2048 hours
= divmod(minutes
, 60, &minutes
);
2051 n
= PyOS_snprintf(pbuf
, buflen
, "%d day%s, ", days
,
2052 (days
== 1 || days
== -1) ? "" : "s");
2053 if (n
< 0 || (size_t)n
>= buflen
)
2056 buflen
-= (size_t)n
;
2059 n
= PyOS_snprintf(pbuf
, buflen
, "%d:%02d:%02d",
2060 hours
, minutes
, seconds
);
2061 if (n
< 0 || (size_t)n
>= buflen
)
2064 buflen
-= (size_t)n
;
2067 n
= PyOS_snprintf(pbuf
, buflen
, ".%06d", us
);
2068 if (n
< 0 || (size_t)n
>= buflen
)
2073 return PyString_FromStringAndSize(buf
, pbuf
- buf
);
2076 PyErr_SetString(PyExc_SystemError
, "goofy result from PyOS_snprintf");
2080 /* Pickle support, a simple use of __reduce__. */
2082 /* __getstate__ isn't exposed */
2084 delta_getstate(PyDateTime_Delta
*self
)
2086 return Py_BuildValue("iii", GET_TD_DAYS(self
),
2087 GET_TD_SECONDS(self
),
2088 GET_TD_MICROSECONDS(self
));
2092 delta_total_seconds(PyObject
*self
)
2094 return PyFloat_FromDouble(GET_TD_MICROSECONDS(self
) / 1000000.0 +
2095 GET_TD_SECONDS(self
) +
2096 GET_TD_DAYS(self
) * 24.0 * 3600.0);
2100 delta_reduce(PyDateTime_Delta
* self
)
2102 return Py_BuildValue("ON", Py_TYPE(self
), delta_getstate(self
));
2105 #define OFFSET(field) offsetof(PyDateTime_Delta, field)
2107 static PyMemberDef delta_members
[] = {
2109 {"days", T_INT
, OFFSET(days
), READONLY
,
2110 PyDoc_STR("Number of days.")},
2112 {"seconds", T_INT
, OFFSET(seconds
), READONLY
,
2113 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2115 {"microseconds", T_INT
, OFFSET(microseconds
), READONLY
,
2116 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2120 static PyMethodDef delta_methods
[] = {
2121 {"total_seconds", (PyCFunction
)delta_total_seconds
, METH_NOARGS
,
2122 PyDoc_STR("Total seconds in the duration.")},
2124 {"__reduce__", (PyCFunction
)delta_reduce
, METH_NOARGS
,
2125 PyDoc_STR("__reduce__() -> (cls, state)")},
2130 static char delta_doc
[] =
2131 PyDoc_STR("Difference between two datetime values.");
2133 static PyNumberMethods delta_as_number
= {
2134 delta_add
, /* nb_add */
2135 delta_subtract
, /* nb_subtract */
2136 delta_multiply
, /* nb_multiply */
2137 delta_divide
, /* nb_divide */
2138 0, /* nb_remainder */
2141 (unaryfunc
)delta_negative
, /* nb_negative */
2142 (unaryfunc
)delta_positive
, /* nb_positive */
2143 (unaryfunc
)delta_abs
, /* nb_absolute */
2144 (inquiry
)delta_nonzero
, /* nb_nonzero */
2157 0, /*nb_inplace_add*/
2158 0, /*nb_inplace_subtract*/
2159 0, /*nb_inplace_multiply*/
2160 0, /*nb_inplace_divide*/
2161 0, /*nb_inplace_remainder*/
2162 0, /*nb_inplace_power*/
2163 0, /*nb_inplace_lshift*/
2164 0, /*nb_inplace_rshift*/
2165 0, /*nb_inplace_and*/
2166 0, /*nb_inplace_xor*/
2167 0, /*nb_inplace_or*/
2168 delta_divide
, /* nb_floor_divide */
2169 0, /* nb_true_divide */
2170 0, /* nb_inplace_floor_divide */
2171 0, /* nb_inplace_true_divide */
2174 static PyTypeObject PyDateTime_DeltaType
= {
2175 PyVarObject_HEAD_INIT(NULL
, 0)
2176 "datetime.timedelta", /* tp_name */
2177 sizeof(PyDateTime_Delta
), /* tp_basicsize */
2178 0, /* tp_itemsize */
2184 (reprfunc
)delta_repr
, /* tp_repr */
2185 &delta_as_number
, /* tp_as_number */
2186 0, /* tp_as_sequence */
2187 0, /* tp_as_mapping */
2188 (hashfunc
)delta_hash
, /* tp_hash */
2190 (reprfunc
)delta_str
, /* tp_str */
2191 PyObject_GenericGetAttr
, /* tp_getattro */
2192 0, /* tp_setattro */
2193 0, /* tp_as_buffer */
2194 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
2195 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2196 delta_doc
, /* tp_doc */
2197 0, /* tp_traverse */
2199 (richcmpfunc
)delta_richcompare
, /* tp_richcompare */
2200 0, /* tp_weaklistoffset */
2202 0, /* tp_iternext */
2203 delta_methods
, /* tp_methods */
2204 delta_members
, /* tp_members */
2208 0, /* tp_descr_get */
2209 0, /* tp_descr_set */
2210 0, /* tp_dictoffset */
2213 delta_new
, /* tp_new */
2218 * PyDateTime_Date implementation.
2221 /* Accessor properties. */
2224 date_year(PyDateTime_Date
*self
, void *unused
)
2226 return PyInt_FromLong(GET_YEAR(self
));
2230 date_month(PyDateTime_Date
*self
, void *unused
)
2232 return PyInt_FromLong(GET_MONTH(self
));
2236 date_day(PyDateTime_Date
*self
, void *unused
)
2238 return PyInt_FromLong(GET_DAY(self
));
2241 static PyGetSetDef date_getset
[] = {
2242 {"year", (getter
)date_year
},
2243 {"month", (getter
)date_month
},
2244 {"day", (getter
)date_day
},
2250 static char *date_kws
[] = {"year", "month", "day", NULL
};
2253 date_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
2255 PyObject
*self
= NULL
;
2261 /* Check for invocation from pickle with __getstate__ state */
2262 if (PyTuple_GET_SIZE(args
) == 1 &&
2263 PyString_Check(state
= PyTuple_GET_ITEM(args
, 0)) &&
2264 PyString_GET_SIZE(state
) == _PyDateTime_DATE_DATASIZE
&&
2265 MONTH_IS_SANE(PyString_AS_STRING(state
)[2]))
2267 PyDateTime_Date
*me
;
2269 me
= (PyDateTime_Date
*) (type
->tp_alloc(type
, 0));
2271 char *pdata
= PyString_AS_STRING(state
);
2272 memcpy(me
->data
, pdata
, _PyDateTime_DATE_DATASIZE
);
2275 return (PyObject
*)me
;
2278 if (PyArg_ParseTupleAndKeywords(args
, kw
, "iii", date_kws
,
2279 &year
, &month
, &day
)) {
2280 if (check_date_args(year
, month
, day
) < 0)
2282 self
= new_date_ex(year
, month
, day
, type
);
2287 /* Return new date from localtime(t). */
2289 date_local_from_time_t(PyObject
*cls
, double ts
)
2293 PyObject
*result
= NULL
;
2295 t
= _PyTime_DoubleToTimet(ts
);
2296 if (t
== (time_t)-1 && PyErr_Occurred())
2300 result
= PyObject_CallFunction(cls
, "iii",
2305 PyErr_SetString(PyExc_ValueError
,
2306 "timestamp out of range for "
2307 "platform localtime() function");
2311 /* Return new date from current time.
2312 * We say this is equivalent to fromtimestamp(time.time()), and the
2313 * only way to be sure of that is to *call* time.time(). That's not
2314 * generally the same as calling C's time.
2317 date_today(PyObject
*cls
, PyObject
*dummy
)
2326 /* Note well: today() is a class method, so this may not call
2327 * date.fromtimestamp. For example, it may call
2328 * datetime.fromtimestamp. That's why we need all the accuracy
2329 * time.time() delivers; if someone were gonzo about optimization,
2330 * date.today() could get away with plain C time().
2332 result
= PyObject_CallMethod(cls
, "fromtimestamp", "O", time
);
2337 /* Return new date from given timestamp (Python timestamp -- a double). */
2339 date_fromtimestamp(PyObject
*cls
, PyObject
*args
)
2342 PyObject
*result
= NULL
;
2344 if (PyArg_ParseTuple(args
, "d:fromtimestamp", ×tamp
))
2345 result
= date_local_from_time_t(cls
, timestamp
);
2349 /* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2350 * the ordinal is out of range.
2353 date_fromordinal(PyObject
*cls
, PyObject
*args
)
2355 PyObject
*result
= NULL
;
2358 if (PyArg_ParseTuple(args
, "i:fromordinal", &ordinal
)) {
2364 PyErr_SetString(PyExc_ValueError
, "ordinal must be "
2367 ord_to_ymd(ordinal
, &year
, &month
, &day
);
2368 result
= PyObject_CallFunction(cls
, "iii",
2379 /* date + timedelta -> date. If arg negate is true, subtract the timedelta
2383 add_date_timedelta(PyDateTime_Date
*date
, PyDateTime_Delta
*delta
, int negate
)
2385 PyObject
*result
= NULL
;
2386 int year
= GET_YEAR(date
);
2387 int month
= GET_MONTH(date
);
2388 int deltadays
= GET_TD_DAYS(delta
);
2389 /* C-level overflow is impossible because |deltadays| < 1e9. */
2390 int day
= GET_DAY(date
) + (negate
? -deltadays
: deltadays
);
2392 if (normalize_date(&year
, &month
, &day
) >= 0)
2393 result
= new_date(year
, month
, day
);
2398 date_add(PyObject
*left
, PyObject
*right
)
2400 if (PyDateTime_Check(left
) || PyDateTime_Check(right
)) {
2401 Py_INCREF(Py_NotImplemented
);
2402 return Py_NotImplemented
;
2404 if (PyDate_Check(left
)) {
2406 if (PyDelta_Check(right
))
2408 return add_date_timedelta((PyDateTime_Date
*) left
,
2409 (PyDateTime_Delta
*) right
,
2414 * 'right' must be one of us, or we wouldn't have been called
2416 if (PyDelta_Check(left
))
2418 return add_date_timedelta((PyDateTime_Date
*) right
,
2419 (PyDateTime_Delta
*) left
,
2422 Py_INCREF(Py_NotImplemented
);
2423 return Py_NotImplemented
;
2427 date_subtract(PyObject
*left
, PyObject
*right
)
2429 if (PyDateTime_Check(left
) || PyDateTime_Check(right
)) {
2430 Py_INCREF(Py_NotImplemented
);
2431 return Py_NotImplemented
;
2433 if (PyDate_Check(left
)) {
2434 if (PyDate_Check(right
)) {
2436 int left_ord
= ymd_to_ord(GET_YEAR(left
),
2439 int right_ord
= ymd_to_ord(GET_YEAR(right
),
2442 return new_delta(left_ord
- right_ord
, 0, 0, 0);
2444 if (PyDelta_Check(right
)) {
2446 return add_date_timedelta((PyDateTime_Date
*) left
,
2447 (PyDateTime_Delta
*) right
,
2451 Py_INCREF(Py_NotImplemented
);
2452 return Py_NotImplemented
;
2456 /* Various ways to turn a date into a string. */
2459 date_repr(PyDateTime_Date
*self
)
2462 const char *type_name
;
2464 type_name
= Py_TYPE(self
)->tp_name
;
2465 PyOS_snprintf(buffer
, sizeof(buffer
), "%s(%d, %d, %d)",
2467 GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
));
2469 return PyString_FromString(buffer
);
2473 date_isoformat(PyDateTime_Date
*self
)
2477 isoformat_date(self
, buffer
, sizeof(buffer
));
2478 return PyString_FromString(buffer
);
2481 /* str() calls the appropriate isoformat() method. */
2483 date_str(PyDateTime_Date
*self
)
2485 return PyObject_CallMethod((PyObject
*)self
, "isoformat", "()");
2490 date_ctime(PyDateTime_Date
*self
)
2492 return format_ctime(self
, 0, 0, 0);
2496 date_strftime(PyDateTime_Date
*self
, PyObject
*args
, PyObject
*kw
)
2498 /* This method can be inherited, and needs to call the
2499 * timetuple() method appropriate to self's class.
2504 Py_ssize_t format_len
;
2505 static char *keywords
[] = {"format", NULL
};
2507 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "s#:strftime", keywords
,
2508 &format
, &format_len
))
2511 tuple
= PyObject_CallMethod((PyObject
*)self
, "timetuple", "()");
2514 result
= wrap_strftime((PyObject
*)self
, format
, format_len
, tuple
,
2521 date_format(PyDateTime_Date
*self
, PyObject
*args
)
2525 if (!PyArg_ParseTuple(args
, "O:__format__", &format
))
2528 /* Check for str or unicode */
2529 if (PyString_Check(format
)) {
2530 /* If format is zero length, return str(self) */
2531 if (PyString_GET_SIZE(format
) == 0)
2532 return PyObject_Str((PyObject
*)self
);
2533 } else if (PyUnicode_Check(format
)) {
2534 /* If format is zero length, return str(self) */
2535 if (PyUnicode_GET_SIZE(format
) == 0)
2536 return PyObject_Unicode((PyObject
*)self
);
2538 PyErr_Format(PyExc_ValueError
,
2539 "__format__ expects str or unicode, not %.200s",
2540 Py_TYPE(format
)->tp_name
);
2543 return PyObject_CallMethod((PyObject
*)self
, "strftime", "O", format
);
2549 date_isoweekday(PyDateTime_Date
*self
)
2551 int dow
= weekday(GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
));
2553 return PyInt_FromLong(dow
+ 1);
2557 date_isocalendar(PyDateTime_Date
*self
)
2559 int year
= GET_YEAR(self
);
2560 int week1_monday
= iso_week1_monday(year
);
2561 int today
= ymd_to_ord(year
, GET_MONTH(self
), GET_DAY(self
));
2565 week
= divmod(today
- week1_monday
, 7, &day
);
2568 week1_monday
= iso_week1_monday(year
);
2569 week
= divmod(today
- week1_monday
, 7, &day
);
2571 else if (week
>= 52 && today
>= iso_week1_monday(year
+ 1)) {
2575 return Py_BuildValue("iii", year
, week
+ 1, day
+ 1);
2578 /* Miscellaneous methods. */
2580 /* This is more natural as a tp_compare, but doesn't work then: for whatever
2581 * reason, Python's try_3way_compare ignores tp_compare unless
2582 * PyInstance_Check returns true, but these aren't old-style classes.
2585 date_richcompare(PyDateTime_Date
*self
, PyObject
*other
, int op
)
2587 int diff
= 42; /* nonsense */
2589 if (PyDate_Check(other
))
2590 diff
= memcmp(self
->data
, ((PyDateTime_Date
*)other
)->data
,
2591 _PyDateTime_DATE_DATASIZE
);
2593 else if (PyObject_HasAttrString(other
, "timetuple")) {
2594 /* A hook for other kinds of date objects. */
2595 Py_INCREF(Py_NotImplemented
);
2596 return Py_NotImplemented
;
2598 else if (op
== Py_EQ
|| op
== Py_NE
)
2599 diff
= 1; /* any non-zero value will do */
2601 else /* stop this from falling back to address comparison */
2602 return cmperror((PyObject
*)self
, other
);
2604 return diff_to_bool(diff
, op
);
2608 date_timetuple(PyDateTime_Date
*self
)
2610 return build_struct_time(GET_YEAR(self
),
2617 date_replace(PyDateTime_Date
*self
, PyObject
*args
, PyObject
*kw
)
2621 int year
= GET_YEAR(self
);
2622 int month
= GET_MONTH(self
);
2623 int day
= GET_DAY(self
);
2625 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "|iii:replace", date_kws
,
2626 &year
, &month
, &day
))
2628 tuple
= Py_BuildValue("iii", year
, month
, day
);
2631 clone
= date_new(Py_TYPE(self
), tuple
, NULL
);
2636 static PyObject
*date_getstate(PyDateTime_Date
*self
);
2639 date_hash(PyDateTime_Date
*self
)
2641 if (self
->hashcode
== -1) {
2642 PyObject
*temp
= date_getstate(self
);
2644 self
->hashcode
= PyObject_Hash(temp
);
2648 return self
->hashcode
;
2652 date_toordinal(PyDateTime_Date
*self
)
2654 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self
), GET_MONTH(self
),
2659 date_weekday(PyDateTime_Date
*self
)
2661 int dow
= weekday(GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
));
2663 return PyInt_FromLong(dow
);
2666 /* Pickle support, a simple use of __reduce__. */
2668 /* __getstate__ isn't exposed */
2670 date_getstate(PyDateTime_Date
*self
)
2672 return Py_BuildValue(
2674 PyString_FromStringAndSize((char *)self
->data
,
2675 _PyDateTime_DATE_DATASIZE
));
2679 date_reduce(PyDateTime_Date
*self
, PyObject
*arg
)
2681 return Py_BuildValue("(ON)", Py_TYPE(self
), date_getstate(self
));
2684 static PyMethodDef date_methods
[] = {
2686 /* Class methods: */
2688 {"fromtimestamp", (PyCFunction
)date_fromtimestamp
, METH_VARARGS
|
2690 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2693 {"fromordinal", (PyCFunction
)date_fromordinal
, METH_VARARGS
|
2695 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2698 {"today", (PyCFunction
)date_today
, METH_NOARGS
| METH_CLASS
,
2699 PyDoc_STR("Current date or datetime: same as "
2700 "self.__class__.fromtimestamp(time.time()).")},
2702 /* Instance methods: */
2704 {"ctime", (PyCFunction
)date_ctime
, METH_NOARGS
,
2705 PyDoc_STR("Return ctime() style string.")},
2707 {"strftime", (PyCFunction
)date_strftime
, METH_VARARGS
| METH_KEYWORDS
,
2708 PyDoc_STR("format -> strftime() style string.")},
2710 {"__format__", (PyCFunction
)date_format
, METH_VARARGS
,
2711 PyDoc_STR("Formats self with strftime.")},
2713 {"timetuple", (PyCFunction
)date_timetuple
, METH_NOARGS
,
2714 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2716 {"isocalendar", (PyCFunction
)date_isocalendar
, METH_NOARGS
,
2717 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2720 {"isoformat", (PyCFunction
)date_isoformat
, METH_NOARGS
,
2721 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2723 {"isoweekday", (PyCFunction
)date_isoweekday
, METH_NOARGS
,
2724 PyDoc_STR("Return the day of the week represented by the date.\n"
2725 "Monday == 1 ... Sunday == 7")},
2727 {"toordinal", (PyCFunction
)date_toordinal
, METH_NOARGS
,
2728 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2731 {"weekday", (PyCFunction
)date_weekday
, METH_NOARGS
,
2732 PyDoc_STR("Return the day of the week represented by the date.\n"
2733 "Monday == 0 ... Sunday == 6")},
2735 {"replace", (PyCFunction
)date_replace
, METH_VARARGS
| METH_KEYWORDS
,
2736 PyDoc_STR("Return date with new specified fields.")},
2738 {"__reduce__", (PyCFunction
)date_reduce
, METH_NOARGS
,
2739 PyDoc_STR("__reduce__() -> (cls, state)")},
2744 static char date_doc
[] =
2745 PyDoc_STR("date(year, month, day) --> date object");
2747 static PyNumberMethods date_as_number
= {
2748 date_add
, /* nb_add */
2749 date_subtract
, /* nb_subtract */
2750 0, /* nb_multiply */
2752 0, /* nb_remainder */
2755 0, /* nb_negative */
2756 0, /* nb_positive */
2757 0, /* nb_absolute */
2761 static PyTypeObject PyDateTime_DateType
= {
2762 PyVarObject_HEAD_INIT(NULL
, 0)
2763 "datetime.date", /* tp_name */
2764 sizeof(PyDateTime_Date
), /* tp_basicsize */
2765 0, /* tp_itemsize */
2771 (reprfunc
)date_repr
, /* tp_repr */
2772 &date_as_number
, /* tp_as_number */
2773 0, /* tp_as_sequence */
2774 0, /* tp_as_mapping */
2775 (hashfunc
)date_hash
, /* tp_hash */
2777 (reprfunc
)date_str
, /* tp_str */
2778 PyObject_GenericGetAttr
, /* tp_getattro */
2779 0, /* tp_setattro */
2780 0, /* tp_as_buffer */
2781 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
2782 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2783 date_doc
, /* tp_doc */
2784 0, /* tp_traverse */
2786 (richcmpfunc
)date_richcompare
, /* tp_richcompare */
2787 0, /* tp_weaklistoffset */
2789 0, /* tp_iternext */
2790 date_methods
, /* tp_methods */
2792 date_getset
, /* tp_getset */
2795 0, /* tp_descr_get */
2796 0, /* tp_descr_set */
2797 0, /* tp_dictoffset */
2800 date_new
, /* tp_new */
2805 * PyDateTime_TZInfo implementation.
2808 /* This is a pure abstract base class, so doesn't do anything beyond
2809 * raising NotImplemented exceptions. Real tzinfo classes need
2810 * to derive from this. This is mostly for clarity, and for efficiency in
2811 * datetime and time constructors (their tzinfo arguments need to
2812 * be subclasses of this tzinfo class, which is easy and quick to check).
2814 * Note: For reasons having to do with pickling of subclasses, we have
2815 * to allow tzinfo objects to be instantiated. This wasn't an issue
2816 * in the Python implementation (__init__() could raise NotImplementedError
2817 * there without ill effect), but doing so in the C implementation hit a
2822 tzinfo_nogo(const char* methodname
)
2824 PyErr_Format(PyExc_NotImplementedError
,
2825 "a tzinfo subclass must implement %s()",
2830 /* Methods. A subclass must implement these. */
2833 tzinfo_tzname(PyDateTime_TZInfo
*self
, PyObject
*dt
)
2835 return tzinfo_nogo("tzname");
2839 tzinfo_utcoffset(PyDateTime_TZInfo
*self
, PyObject
*dt
)
2841 return tzinfo_nogo("utcoffset");
2845 tzinfo_dst(PyDateTime_TZInfo
*self
, PyObject
*dt
)
2847 return tzinfo_nogo("dst");
2851 tzinfo_fromutc(PyDateTime_TZInfo
*self
, PyDateTime_DateTime
*dt
)
2853 int y
, m
, d
, hh
, mm
, ss
, us
;
2860 if (! PyDateTime_Check(dt
)) {
2861 PyErr_SetString(PyExc_TypeError
,
2862 "fromutc: argument must be a datetime");
2865 if (! HASTZINFO(dt
) || dt
->tzinfo
!= (PyObject
*)self
) {
2866 PyErr_SetString(PyExc_ValueError
, "fromutc: dt.tzinfo "
2871 off
= call_utcoffset(dt
->tzinfo
, (PyObject
*)dt
, &none
);
2872 if (off
== -1 && PyErr_Occurred())
2875 PyErr_SetString(PyExc_ValueError
, "fromutc: non-None "
2876 "utcoffset() result required");
2880 dst
= call_dst(dt
->tzinfo
, (PyObject
*)dt
, &none
);
2881 if (dst
== -1 && PyErr_Occurred())
2884 PyErr_SetString(PyExc_ValueError
, "fromutc: non-None "
2885 "dst() result required");
2892 hh
= DATE_GET_HOUR(dt
);
2893 mm
= DATE_GET_MINUTE(dt
);
2894 ss
= DATE_GET_SECOND(dt
);
2895 us
= DATE_GET_MICROSECOND(dt
);
2899 if ((mm
< 0 || mm
>= 60) &&
2900 normalize_datetime(&y
, &m
, &d
, &hh
, &mm
, &ss
, &us
) < 0)
2902 result
= new_datetime(y
, m
, d
, hh
, mm
, ss
, us
, dt
->tzinfo
);
2906 dst
= call_dst(dt
->tzinfo
, result
, &none
);
2907 if (dst
== -1 && PyErr_Occurred())
2915 if ((mm
< 0 || mm
>= 60) &&
2916 normalize_datetime(&y
, &m
, &d
, &hh
, &mm
, &ss
, &us
) < 0)
2919 result
= new_datetime(y
, m
, d
, hh
, mm
, ss
, us
, dt
->tzinfo
);
2923 PyErr_SetString(PyExc_ValueError
, "fromutc: tz.dst() gave"
2924 "inconsistent results; cannot convert");
2926 /* fall thru to failure */
2933 * Pickle support. This is solely so that tzinfo subclasses can use
2934 * pickling -- tzinfo itself is supposed to be uninstantiable.
2938 tzinfo_reduce(PyObject
*self
)
2940 PyObject
*args
, *state
, *tmp
;
2941 PyObject
*getinitargs
, *getstate
;
2943 tmp
= PyTuple_New(0);
2947 getinitargs
= PyObject_GetAttrString(self
, "__getinitargs__");
2948 if (getinitargs
!= NULL
) {
2949 args
= PyObject_CallObject(getinitargs
, tmp
);
2950 Py_DECREF(getinitargs
);
2962 getstate
= PyObject_GetAttrString(self
, "__getstate__");
2963 if (getstate
!= NULL
) {
2964 state
= PyObject_CallObject(getstate
, tmp
);
2965 Py_DECREF(getstate
);
2966 if (state
== NULL
) {
2976 dictptr
= _PyObject_GetDictPtr(self
);
2977 if (dictptr
&& *dictptr
&& PyDict_Size(*dictptr
))
2984 if (state
== Py_None
) {
2986 return Py_BuildValue("(ON)", Py_TYPE(self
), args
);
2989 return Py_BuildValue("(ONN)", Py_TYPE(self
), args
, state
);
2992 static PyMethodDef tzinfo_methods
[] = {
2994 {"tzname", (PyCFunction
)tzinfo_tzname
, METH_O
,
2995 PyDoc_STR("datetime -> string name of time zone.")},
2997 {"utcoffset", (PyCFunction
)tzinfo_utcoffset
, METH_O
,
2998 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3001 {"dst", (PyCFunction
)tzinfo_dst
, METH_O
,
3002 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3004 {"fromutc", (PyCFunction
)tzinfo_fromutc
, METH_O
,
3005 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3007 {"__reduce__", (PyCFunction
)tzinfo_reduce
, METH_NOARGS
,
3008 PyDoc_STR("-> (cls, state)")},
3013 static char tzinfo_doc
[] =
3014 PyDoc_STR("Abstract base class for time zone info objects.");
3016 statichere PyTypeObject PyDateTime_TZInfoType
= {
3017 PyObject_HEAD_INIT(NULL
)
3019 "datetime.tzinfo", /* tp_name */
3020 sizeof(PyDateTime_TZInfo
), /* tp_basicsize */
3021 0, /* tp_itemsize */
3028 0, /* tp_as_number */
3029 0, /* tp_as_sequence */
3030 0, /* tp_as_mapping */
3034 PyObject_GenericGetAttr
, /* tp_getattro */
3035 0, /* tp_setattro */
3036 0, /* tp_as_buffer */
3037 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
3038 Py_TPFLAGS_BASETYPE
, /* tp_flags */
3039 tzinfo_doc
, /* tp_doc */
3040 0, /* tp_traverse */
3042 0, /* tp_richcompare */
3043 0, /* tp_weaklistoffset */
3045 0, /* tp_iternext */
3046 tzinfo_methods
, /* tp_methods */
3051 0, /* tp_descr_get */
3052 0, /* tp_descr_set */
3053 0, /* tp_dictoffset */
3056 PyType_GenericNew
, /* tp_new */
3061 * PyDateTime_Time implementation.
3064 /* Accessor properties.
3068 time_hour(PyDateTime_Time
*self
, void *unused
)
3070 return PyInt_FromLong(TIME_GET_HOUR(self
));
3074 time_minute(PyDateTime_Time
*self
, void *unused
)
3076 return PyInt_FromLong(TIME_GET_MINUTE(self
));
3079 /* The name time_second conflicted with some platform header file. */
3081 py_time_second(PyDateTime_Time
*self
, void *unused
)
3083 return PyInt_FromLong(TIME_GET_SECOND(self
));
3087 time_microsecond(PyDateTime_Time
*self
, void *unused
)
3089 return PyInt_FromLong(TIME_GET_MICROSECOND(self
));
3093 time_tzinfo(PyDateTime_Time
*self
, void *unused
)
3095 PyObject
*result
= HASTZINFO(self
) ? self
->tzinfo
: Py_None
;
3100 static PyGetSetDef time_getset
[] = {
3101 {"hour", (getter
)time_hour
},
3102 {"minute", (getter
)time_minute
},
3103 {"second", (getter
)py_time_second
},
3104 {"microsecond", (getter
)time_microsecond
},
3105 {"tzinfo", (getter
)time_tzinfo
},
3113 static char *time_kws
[] = {"hour", "minute", "second", "microsecond",
3117 time_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
3119 PyObject
*self
= NULL
;
3125 PyObject
*tzinfo
= Py_None
;
3127 /* Check for invocation from pickle with __getstate__ state */
3128 if (PyTuple_GET_SIZE(args
) >= 1 &&
3129 PyTuple_GET_SIZE(args
) <= 2 &&
3130 PyString_Check(state
= PyTuple_GET_ITEM(args
, 0)) &&
3131 PyString_GET_SIZE(state
) == _PyDateTime_TIME_DATASIZE
&&
3132 ((unsigned char) (PyString_AS_STRING(state
)[0])) < 24)
3134 PyDateTime_Time
*me
;
3137 if (PyTuple_GET_SIZE(args
) == 2) {
3138 tzinfo
= PyTuple_GET_ITEM(args
, 1);
3139 if (check_tzinfo_subclass(tzinfo
) < 0) {
3140 PyErr_SetString(PyExc_TypeError
, "bad "
3141 "tzinfo state arg");
3145 aware
= (char)(tzinfo
!= Py_None
);
3146 me
= (PyDateTime_Time
*) (type
->tp_alloc(type
, aware
));
3148 char *pdata
= PyString_AS_STRING(state
);
3150 memcpy(me
->data
, pdata
, _PyDateTime_TIME_DATASIZE
);
3152 me
->hastzinfo
= aware
;
3155 me
->tzinfo
= tzinfo
;
3158 return (PyObject
*)me
;
3161 if (PyArg_ParseTupleAndKeywords(args
, kw
, "|iiiiO", time_kws
,
3162 &hour
, &minute
, &second
, &usecond
,
3164 if (check_time_args(hour
, minute
, second
, usecond
) < 0)
3166 if (check_tzinfo_subclass(tzinfo
) < 0)
3168 self
= new_time_ex(hour
, minute
, second
, usecond
, tzinfo
,
3179 time_dealloc(PyDateTime_Time
*self
)
3181 if (HASTZINFO(self
)) {
3182 Py_XDECREF(self
->tzinfo
);
3184 Py_TYPE(self
)->tp_free((PyObject
*)self
);
3188 * Indirect access to tzinfo methods.
3191 /* These are all METH_NOARGS, so don't need to check the arglist. */
3193 time_utcoffset(PyDateTime_Time
*self
, PyObject
*unused
) {
3194 return offset_as_timedelta(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
3195 "utcoffset", Py_None
);
3199 time_dst(PyDateTime_Time
*self
, PyObject
*unused
) {
3200 return offset_as_timedelta(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
3205 time_tzname(PyDateTime_Time
*self
, PyObject
*unused
) {
3206 return call_tzname(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
3211 * Various ways to turn a time into a string.
3215 time_repr(PyDateTime_Time
*self
)
3218 const char *type_name
= Py_TYPE(self
)->tp_name
;
3219 int h
= TIME_GET_HOUR(self
);
3220 int m
= TIME_GET_MINUTE(self
);
3221 int s
= TIME_GET_SECOND(self
);
3222 int us
= TIME_GET_MICROSECOND(self
);
3223 PyObject
*result
= NULL
;
3226 PyOS_snprintf(buffer
, sizeof(buffer
),
3227 "%s(%d, %d, %d, %d)", type_name
, h
, m
, s
, us
);
3229 PyOS_snprintf(buffer
, sizeof(buffer
),
3230 "%s(%d, %d, %d)", type_name
, h
, m
, s
);
3232 PyOS_snprintf(buffer
, sizeof(buffer
),
3233 "%s(%d, %d)", type_name
, h
, m
);
3234 result
= PyString_FromString(buffer
);
3235 if (result
!= NULL
&& HASTZINFO(self
))
3236 result
= append_keyword_tzinfo(result
, self
->tzinfo
);
3241 time_str(PyDateTime_Time
*self
)
3243 return PyObject_CallMethod((PyObject
*)self
, "isoformat", "()");
3247 time_isoformat(PyDateTime_Time
*self
, PyObject
*unused
)
3251 /* Reuse the time format code from the datetime type. */
3252 PyDateTime_DateTime datetime
;
3253 PyDateTime_DateTime
*pdatetime
= &datetime
;
3255 /* Copy over just the time bytes. */
3256 memcpy(pdatetime
->data
+ _PyDateTime_DATE_DATASIZE
,
3258 _PyDateTime_TIME_DATASIZE
);
3260 isoformat_time(pdatetime
, buf
, sizeof(buf
));
3261 result
= PyString_FromString(buf
);
3262 if (result
== NULL
|| ! HASTZINFO(self
) || self
->tzinfo
== Py_None
)
3265 /* We need to append the UTC offset. */
3266 if (format_utcoffset(buf
, sizeof(buf
), ":", self
->tzinfo
,
3271 PyString_ConcatAndDel(&result
, PyString_FromString(buf
));
3276 time_strftime(PyDateTime_Time
*self
, PyObject
*args
, PyObject
*kw
)
3281 Py_ssize_t format_len
;
3282 static char *keywords
[] = {"format", NULL
};
3284 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "s#:strftime", keywords
,
3285 &format
, &format_len
))
3288 /* Python's strftime does insane things with the year part of the
3289 * timetuple. The year is forced to (the otherwise nonsensical)
3290 * 1900 to worm around that.
3292 tuple
= Py_BuildValue("iiiiiiiii",
3293 1900, 1, 1, /* year, month, day */
3294 TIME_GET_HOUR(self
),
3295 TIME_GET_MINUTE(self
),
3296 TIME_GET_SECOND(self
),
3297 0, 1, -1); /* weekday, daynum, dst */
3300 assert(PyTuple_Size(tuple
) == 9);
3301 result
= wrap_strftime((PyObject
*)self
, format
, format_len
, tuple
,
3308 * Miscellaneous methods.
3311 /* This is more natural as a tp_compare, but doesn't work then: for whatever
3312 * reason, Python's try_3way_compare ignores tp_compare unless
3313 * PyInstance_Check returns true, but these aren't old-style classes.
3316 time_richcompare(PyDateTime_Time
*self
, PyObject
*other
, int op
)
3320 int offset1
, offset2
;
3322 if (! PyTime_Check(other
)) {
3323 if (op
== Py_EQ
|| op
== Py_NE
) {
3324 PyObject
*result
= op
== Py_EQ
? Py_False
: Py_True
;
3328 /* Stop this from falling back to address comparison. */
3329 return cmperror((PyObject
*)self
, other
);
3331 if (classify_two_utcoffsets((PyObject
*)self
, &offset1
, &n1
, Py_None
,
3332 other
, &offset2
, &n2
, Py_None
) < 0)
3334 assert(n1
!= OFFSET_UNKNOWN
&& n2
!= OFFSET_UNKNOWN
);
3335 /* If they're both naive, or both aware and have the same offsets,
3336 * we get off cheap. Note that if they're both naive, offset1 ==
3337 * offset2 == 0 at this point.
3339 if (n1
== n2
&& offset1
== offset2
) {
3340 diff
= memcmp(self
->data
, ((PyDateTime_Time
*)other
)->data
,
3341 _PyDateTime_TIME_DATASIZE
);
3342 return diff_to_bool(diff
, op
);
3345 if (n1
== OFFSET_AWARE
&& n2
== OFFSET_AWARE
) {
3346 assert(offset1
!= offset2
); /* else last "if" handled it */
3347 /* Convert everything except microseconds to seconds. These
3348 * can't overflow (no more than the # of seconds in 2 days).
3350 offset1
= TIME_GET_HOUR(self
) * 3600 +
3351 (TIME_GET_MINUTE(self
) - offset1
) * 60 +
3352 TIME_GET_SECOND(self
);
3353 offset2
= TIME_GET_HOUR(other
) * 3600 +
3354 (TIME_GET_MINUTE(other
) - offset2
) * 60 +
3355 TIME_GET_SECOND(other
);
3356 diff
= offset1
- offset2
;
3358 diff
= TIME_GET_MICROSECOND(self
) -
3359 TIME_GET_MICROSECOND(other
);
3360 return diff_to_bool(diff
, op
);
3364 PyErr_SetString(PyExc_TypeError
,
3365 "can't compare offset-naive and "
3366 "offset-aware times");
3371 time_hash(PyDateTime_Time
*self
)
3373 if (self
->hashcode
== -1) {
3378 n
= classify_utcoffset((PyObject
*)self
, Py_None
, &offset
);
3379 assert(n
!= OFFSET_UNKNOWN
);
3380 if (n
== OFFSET_ERROR
)
3383 /* Reduce this to a hash of another object. */
3385 temp
= PyString_FromStringAndSize((char *)self
->data
,
3386 _PyDateTime_TIME_DATASIZE
);
3391 assert(n
== OFFSET_AWARE
);
3392 assert(HASTZINFO(self
));
3393 hour
= divmod(TIME_GET_HOUR(self
) * 60 +
3394 TIME_GET_MINUTE(self
) - offset
,
3397 if (0 <= hour
&& hour
< 24)
3398 temp
= new_time(hour
, minute
,
3399 TIME_GET_SECOND(self
),
3400 TIME_GET_MICROSECOND(self
),
3403 temp
= Py_BuildValue("iiii",
3405 TIME_GET_SECOND(self
),
3406 TIME_GET_MICROSECOND(self
));
3409 self
->hashcode
= PyObject_Hash(temp
);
3413 return self
->hashcode
;
3417 time_replace(PyDateTime_Time
*self
, PyObject
*args
, PyObject
*kw
)
3421 int hh
= TIME_GET_HOUR(self
);
3422 int mm
= TIME_GET_MINUTE(self
);
3423 int ss
= TIME_GET_SECOND(self
);
3424 int us
= TIME_GET_MICROSECOND(self
);
3425 PyObject
*tzinfo
= HASTZINFO(self
) ? self
->tzinfo
: Py_None
;
3427 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "|iiiiO:replace",
3429 &hh
, &mm
, &ss
, &us
, &tzinfo
))
3431 tuple
= Py_BuildValue("iiiiO", hh
, mm
, ss
, us
, tzinfo
);
3434 clone
= time_new(Py_TYPE(self
), tuple
, NULL
);
3440 time_nonzero(PyDateTime_Time
*self
)
3445 if (TIME_GET_SECOND(self
) || TIME_GET_MICROSECOND(self
)) {
3446 /* Since utcoffset is in whole minutes, nothing can
3447 * alter the conclusion that this is nonzero.
3452 if (HASTZINFO(self
) && self
->tzinfo
!= Py_None
) {
3453 offset
= call_utcoffset(self
->tzinfo
, Py_None
, &none
);
3454 if (offset
== -1 && PyErr_Occurred())
3457 return (TIME_GET_MINUTE(self
) - offset
+ TIME_GET_HOUR(self
)*60) != 0;
3460 /* Pickle support, a simple use of __reduce__. */
3462 /* Let basestate be the non-tzinfo data string.
3463 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3464 * So it's a tuple in any (non-error) case.
3465 * __getstate__ isn't exposed.
3468 time_getstate(PyDateTime_Time
*self
)
3470 PyObject
*basestate
;
3471 PyObject
*result
= NULL
;
3473 basestate
= PyString_FromStringAndSize((char *)self
->data
,
3474 _PyDateTime_TIME_DATASIZE
);
3475 if (basestate
!= NULL
) {
3476 if (! HASTZINFO(self
) || self
->tzinfo
== Py_None
)
3477 result
= PyTuple_Pack(1, basestate
);
3479 result
= PyTuple_Pack(2, basestate
, self
->tzinfo
);
3480 Py_DECREF(basestate
);
3486 time_reduce(PyDateTime_Time
*self
, PyObject
*arg
)
3488 return Py_BuildValue("(ON)", Py_TYPE(self
), time_getstate(self
));
3491 static PyMethodDef time_methods
[] = {
3493 {"isoformat", (PyCFunction
)time_isoformat
, METH_NOARGS
,
3494 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3497 {"strftime", (PyCFunction
)time_strftime
, METH_VARARGS
| METH_KEYWORDS
,
3498 PyDoc_STR("format -> strftime() style string.")},
3500 {"__format__", (PyCFunction
)date_format
, METH_VARARGS
,
3501 PyDoc_STR("Formats self with strftime.")},
3503 {"utcoffset", (PyCFunction
)time_utcoffset
, METH_NOARGS
,
3504 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3506 {"tzname", (PyCFunction
)time_tzname
, METH_NOARGS
,
3507 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3509 {"dst", (PyCFunction
)time_dst
, METH_NOARGS
,
3510 PyDoc_STR("Return self.tzinfo.dst(self).")},
3512 {"replace", (PyCFunction
)time_replace
, METH_VARARGS
| METH_KEYWORDS
,
3513 PyDoc_STR("Return time with new specified fields.")},
3515 {"__reduce__", (PyCFunction
)time_reduce
, METH_NOARGS
,
3516 PyDoc_STR("__reduce__() -> (cls, state)")},
3521 static char time_doc
[] =
3522 PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3524 All arguments are optional. tzinfo may be None, or an instance of\n\
3525 a tzinfo subclass. The remaining arguments may be ints or longs.\n");
3527 static PyNumberMethods time_as_number
= {
3529 0, /* nb_subtract */
3530 0, /* nb_multiply */
3532 0, /* nb_remainder */
3535 0, /* nb_negative */
3536 0, /* nb_positive */
3537 0, /* nb_absolute */
3538 (inquiry
)time_nonzero
, /* nb_nonzero */
3541 statichere PyTypeObject PyDateTime_TimeType
= {
3542 PyObject_HEAD_INIT(NULL
)
3544 "datetime.time", /* tp_name */
3545 sizeof(PyDateTime_Time
), /* tp_basicsize */
3546 0, /* tp_itemsize */
3547 (destructor
)time_dealloc
, /* tp_dealloc */
3552 (reprfunc
)time_repr
, /* tp_repr */
3553 &time_as_number
, /* tp_as_number */
3554 0, /* tp_as_sequence */
3555 0, /* tp_as_mapping */
3556 (hashfunc
)time_hash
, /* tp_hash */
3558 (reprfunc
)time_str
, /* tp_str */
3559 PyObject_GenericGetAttr
, /* tp_getattro */
3560 0, /* tp_setattro */
3561 0, /* tp_as_buffer */
3562 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
3563 Py_TPFLAGS_BASETYPE
, /* tp_flags */
3564 time_doc
, /* tp_doc */
3565 0, /* tp_traverse */
3567 (richcmpfunc
)time_richcompare
, /* tp_richcompare */
3568 0, /* tp_weaklistoffset */
3570 0, /* tp_iternext */
3571 time_methods
, /* tp_methods */
3573 time_getset
, /* tp_getset */
3576 0, /* tp_descr_get */
3577 0, /* tp_descr_set */
3578 0, /* tp_dictoffset */
3580 time_alloc
, /* tp_alloc */
3581 time_new
, /* tp_new */
3586 * PyDateTime_DateTime implementation.
3589 /* Accessor properties. Properties for day, month, and year are inherited
3594 datetime_hour(PyDateTime_DateTime
*self
, void *unused
)
3596 return PyInt_FromLong(DATE_GET_HOUR(self
));
3600 datetime_minute(PyDateTime_DateTime
*self
, void *unused
)
3602 return PyInt_FromLong(DATE_GET_MINUTE(self
));
3606 datetime_second(PyDateTime_DateTime
*self
, void *unused
)
3608 return PyInt_FromLong(DATE_GET_SECOND(self
));
3612 datetime_microsecond(PyDateTime_DateTime
*self
, void *unused
)
3614 return PyInt_FromLong(DATE_GET_MICROSECOND(self
));
3618 datetime_tzinfo(PyDateTime_DateTime
*self
, void *unused
)
3620 PyObject
*result
= HASTZINFO(self
) ? self
->tzinfo
: Py_None
;
3625 static PyGetSetDef datetime_getset
[] = {
3626 {"hour", (getter
)datetime_hour
},
3627 {"minute", (getter
)datetime_minute
},
3628 {"second", (getter
)datetime_second
},
3629 {"microsecond", (getter
)datetime_microsecond
},
3630 {"tzinfo", (getter
)datetime_tzinfo
},
3638 static char *datetime_kws
[] = {
3639 "year", "month", "day", "hour", "minute", "second",
3640 "microsecond", "tzinfo", NULL
3644 datetime_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
3646 PyObject
*self
= NULL
;
3655 PyObject
*tzinfo
= Py_None
;
3657 /* Check for invocation from pickle with __getstate__ state */
3658 if (PyTuple_GET_SIZE(args
) >= 1 &&
3659 PyTuple_GET_SIZE(args
) <= 2 &&
3660 PyString_Check(state
= PyTuple_GET_ITEM(args
, 0)) &&
3661 PyString_GET_SIZE(state
) == _PyDateTime_DATETIME_DATASIZE
&&
3662 MONTH_IS_SANE(PyString_AS_STRING(state
)[2]))
3664 PyDateTime_DateTime
*me
;
3667 if (PyTuple_GET_SIZE(args
) == 2) {
3668 tzinfo
= PyTuple_GET_ITEM(args
, 1);
3669 if (check_tzinfo_subclass(tzinfo
) < 0) {
3670 PyErr_SetString(PyExc_TypeError
, "bad "
3671 "tzinfo state arg");
3675 aware
= (char)(tzinfo
!= Py_None
);
3676 me
= (PyDateTime_DateTime
*) (type
->tp_alloc(type
, aware
));
3678 char *pdata
= PyString_AS_STRING(state
);
3680 memcpy(me
->data
, pdata
, _PyDateTime_DATETIME_DATASIZE
);
3682 me
->hastzinfo
= aware
;
3685 me
->tzinfo
= tzinfo
;
3688 return (PyObject
*)me
;
3691 if (PyArg_ParseTupleAndKeywords(args
, kw
, "iii|iiiiO", datetime_kws
,
3692 &year
, &month
, &day
, &hour
, &minute
,
3693 &second
, &usecond
, &tzinfo
)) {
3694 if (check_date_args(year
, month
, day
) < 0)
3696 if (check_time_args(hour
, minute
, second
, usecond
) < 0)
3698 if (check_tzinfo_subclass(tzinfo
) < 0)
3700 self
= new_datetime_ex(year
, month
, day
,
3701 hour
, minute
, second
, usecond
,
3707 /* TM_FUNC is the shared type of localtime() and gmtime(). */
3708 typedef struct tm
*(*TM_FUNC
)(const time_t *timer
);
3711 * Build datetime from a time_t and a distinct count of microseconds.
3712 * Pass localtime or gmtime for f, to control the interpretation of timet.
3715 datetime_from_timet_and_us(PyObject
*cls
, TM_FUNC f
, time_t timet
, int us
,
3719 PyObject
*result
= NULL
;
3723 /* The platform localtime/gmtime may insert leap seconds,
3724 * indicated by tm->tm_sec > 59. We don't care about them,
3725 * except to the extent that passing them on to the datetime
3726 * constructor would raise ValueError for a reason that
3727 * made no sense to the user.
3729 if (tm
->tm_sec
> 59)
3731 result
= PyObject_CallFunction(cls
, "iiiiiiiO",
3742 PyErr_SetString(PyExc_ValueError
,
3743 "timestamp out of range for "
3744 "platform localtime()/gmtime() function");
3749 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3750 * to control the interpretation of the timestamp. Since a double doesn't
3751 * have enough bits to cover a datetime's full range of precision, it's
3752 * better to call datetime_from_timet_and_us provided you have a way
3753 * to get that much precision (e.g., C time() isn't good enough).
3756 datetime_from_timestamp(PyObject
*cls
, TM_FUNC f
, double timestamp
,
3763 timet
= _PyTime_DoubleToTimet(timestamp
);
3764 if (timet
== (time_t)-1 && PyErr_Occurred())
3766 fraction
= timestamp
- (double)timet
;
3767 us
= (int)round_to_long(fraction
* 1e6
);
3769 /* Truncation towards zero is not what we wanted
3770 for negative numbers (Python's mod semantics) */
3774 /* If timestamp is less than one microsecond smaller than a
3775 * full second, round up. Otherwise, ValueErrors are raised
3776 * for some floats. */
3777 if (us
== 1000000) {
3781 return datetime_from_timet_and_us(cls
, f
, timet
, us
, tzinfo
);
3785 * Build most accurate possible datetime for current time. Pass localtime or
3786 * gmtime for f as appropriate.
3789 datetime_best_possible(PyObject
*cls
, TM_FUNC f
, PyObject
*tzinfo
)
3791 #ifdef HAVE_GETTIMEOFDAY
3794 #ifdef GETTIMEOFDAY_NO_TZ
3797 gettimeofday(&t
, (struct timezone
*)NULL
);
3799 return datetime_from_timet_and_us(cls
, f
, t
.tv_sec
, (int)t
.tv_usec
,
3802 #else /* ! HAVE_GETTIMEOFDAY */
3803 /* No flavor of gettimeofday exists on this platform. Python's
3804 * time.time() does a lot of other platform tricks to get the
3805 * best time it can on the platform, and we're not going to do
3806 * better than that (if we could, the better code would belong
3807 * in time.time()!) We're limited by the precision of a double,
3816 dtime
= PyFloat_AsDouble(time
);
3818 if (dtime
== -1.0 && PyErr_Occurred())
3820 return datetime_from_timestamp(cls
, f
, dtime
, tzinfo
);
3821 #endif /* ! HAVE_GETTIMEOFDAY */
3824 /* Return best possible local time -- this isn't constrained by the
3825 * precision of a timestamp.
3828 datetime_now(PyObject
*cls
, PyObject
*args
, PyObject
*kw
)
3831 PyObject
*tzinfo
= Py_None
;
3832 static char *keywords
[] = {"tz", NULL
};
3834 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "|O:now", keywords
,
3837 if (check_tzinfo_subclass(tzinfo
) < 0)
3840 self
= datetime_best_possible(cls
,
3841 tzinfo
== Py_None
? localtime
: gmtime
,
3843 if (self
!= NULL
&& tzinfo
!= Py_None
) {
3844 /* Convert UTC to tzinfo's zone. */
3845 PyObject
*temp
= self
;
3846 self
= PyObject_CallMethod(tzinfo
, "fromutc", "O", self
);
3852 /* Return best possible UTC time -- this isn't constrained by the
3853 * precision of a timestamp.
3856 datetime_utcnow(PyObject
*cls
, PyObject
*dummy
)
3858 return datetime_best_possible(cls
, gmtime
, Py_None
);
3861 /* Return new local datetime from timestamp (Python timestamp -- a double). */
3863 datetime_fromtimestamp(PyObject
*cls
, PyObject
*args
, PyObject
*kw
)
3867 PyObject
*tzinfo
= Py_None
;
3868 static char *keywords
[] = {"timestamp", "tz", NULL
};
3870 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "d|O:fromtimestamp",
3871 keywords
, ×tamp
, &tzinfo
))
3873 if (check_tzinfo_subclass(tzinfo
) < 0)
3876 self
= datetime_from_timestamp(cls
,
3877 tzinfo
== Py_None
? localtime
: gmtime
,
3880 if (self
!= NULL
&& tzinfo
!= Py_None
) {
3881 /* Convert UTC to tzinfo's zone. */
3882 PyObject
*temp
= self
;
3883 self
= PyObject_CallMethod(tzinfo
, "fromutc", "O", self
);
3889 /* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3891 datetime_utcfromtimestamp(PyObject
*cls
, PyObject
*args
)
3894 PyObject
*result
= NULL
;
3896 if (PyArg_ParseTuple(args
, "d:utcfromtimestamp", ×tamp
))
3897 result
= datetime_from_timestamp(cls
, gmtime
, timestamp
,
3902 /* Return new datetime from time.strptime(). */
3904 datetime_strptime(PyObject
*cls
, PyObject
*args
)
3906 static PyObject
*module
= NULL
;
3907 PyObject
*result
= NULL
, *obj
, *st
= NULL
, *frac
= NULL
;
3908 const char *string
, *format
;
3910 if (!PyArg_ParseTuple(args
, "ss:strptime", &string
, &format
))
3913 if (module
== NULL
&&
3914 (module
= PyImport_ImportModuleNoBlock("_strptime")) == NULL
)
3917 /* _strptime._strptime returns a two-element tuple. The first
3918 element is a time.struct_time object. The second is the
3919 microseconds (which are not defined for time.struct_time). */
3920 obj
= PyObject_CallMethod(module
, "_strptime", "ss", string
, format
);
3922 int i
, good_timetuple
= 1;
3924 if (PySequence_Check(obj
) && PySequence_Size(obj
) == 2) {
3925 st
= PySequence_GetItem(obj
, 0);
3926 frac
= PySequence_GetItem(obj
, 1);
3927 if (st
== NULL
|| frac
== NULL
)
3929 /* copy y/m/d/h/m/s values out of the
3931 if (good_timetuple
&&
3932 PySequence_Check(st
) &&
3933 PySequence_Size(st
) >= 6) {
3934 for (i
=0; i
< 6; i
++) {
3935 PyObject
*p
= PySequence_GetItem(st
, i
);
3941 ia
[i
] = PyInt_AsLong(p
);
3949 /* follow that up with a little dose of microseconds */
3950 if (PyInt_Check(frac
))
3951 ia
[6] = PyInt_AsLong(frac
);
3958 result
= PyObject_CallFunction(cls
, "iiiiiii",
3959 ia
[0], ia
[1], ia
[2],
3960 ia
[3], ia
[4], ia
[5],
3963 PyErr_SetString(PyExc_ValueError
,
3964 "unexpected value from _strptime._strptime");
3972 /* Return new datetime from date/datetime and time arguments. */
3974 datetime_combine(PyObject
*cls
, PyObject
*args
, PyObject
*kw
)
3976 static char *keywords
[] = {"date", "time", NULL
};
3979 PyObject
*result
= NULL
;
3981 if (PyArg_ParseTupleAndKeywords(args
, kw
, "O!O!:combine", keywords
,
3982 &PyDateTime_DateType
, &date
,
3983 &PyDateTime_TimeType
, &time
)) {
3984 PyObject
*tzinfo
= Py_None
;
3986 if (HASTZINFO(time
))
3987 tzinfo
= ((PyDateTime_Time
*)time
)->tzinfo
;
3988 result
= PyObject_CallFunction(cls
, "iiiiiiiO",
3992 TIME_GET_HOUR(time
),
3993 TIME_GET_MINUTE(time
),
3994 TIME_GET_SECOND(time
),
3995 TIME_GET_MICROSECOND(time
),
4006 datetime_dealloc(PyDateTime_DateTime
*self
)
4008 if (HASTZINFO(self
)) {
4009 Py_XDECREF(self
->tzinfo
);
4011 Py_TYPE(self
)->tp_free((PyObject
*)self
);
4015 * Indirect access to tzinfo methods.
4018 /* These are all METH_NOARGS, so don't need to check the arglist. */
4020 datetime_utcoffset(PyDateTime_DateTime
*self
, PyObject
*unused
) {
4021 return offset_as_timedelta(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
4022 "utcoffset", (PyObject
*)self
);
4026 datetime_dst(PyDateTime_DateTime
*self
, PyObject
*unused
) {
4027 return offset_as_timedelta(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
4028 "dst", (PyObject
*)self
);
4032 datetime_tzname(PyDateTime_DateTime
*self
, PyObject
*unused
) {
4033 return call_tzname(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
4038 * datetime arithmetic.
4041 /* factor must be 1 (to add) or -1 (to subtract). The result inherits
4042 * the tzinfo state of date.
4045 add_datetime_timedelta(PyDateTime_DateTime
*date
, PyDateTime_Delta
*delta
,
4048 /* Note that the C-level additions can't overflow, because of
4049 * invariant bounds on the member values.
4051 int year
= GET_YEAR(date
);
4052 int month
= GET_MONTH(date
);
4053 int day
= GET_DAY(date
) + GET_TD_DAYS(delta
) * factor
;
4054 int hour
= DATE_GET_HOUR(date
);
4055 int minute
= DATE_GET_MINUTE(date
);
4056 int second
= DATE_GET_SECOND(date
) + GET_TD_SECONDS(delta
) * factor
;
4057 int microsecond
= DATE_GET_MICROSECOND(date
) +
4058 GET_TD_MICROSECONDS(delta
) * factor
;
4060 assert(factor
== 1 || factor
== -1);
4061 if (normalize_datetime(&year
, &month
, &day
,
4062 &hour
, &minute
, &second
, µsecond
) < 0)
4065 return new_datetime(year
, month
, day
,
4066 hour
, minute
, second
, microsecond
,
4067 HASTZINFO(date
) ? date
->tzinfo
: Py_None
);
4071 datetime_add(PyObject
*left
, PyObject
*right
)
4073 if (PyDateTime_Check(left
)) {
4074 /* datetime + ??? */
4075 if (PyDelta_Check(right
))
4076 /* datetime + delta */
4077 return add_datetime_timedelta(
4078 (PyDateTime_DateTime
*)left
,
4079 (PyDateTime_Delta
*)right
,
4082 else if (PyDelta_Check(left
)) {
4083 /* delta + datetime */
4084 return add_datetime_timedelta((PyDateTime_DateTime
*) right
,
4085 (PyDateTime_Delta
*) left
,
4088 Py_INCREF(Py_NotImplemented
);
4089 return Py_NotImplemented
;
4093 datetime_subtract(PyObject
*left
, PyObject
*right
)
4095 PyObject
*result
= Py_NotImplemented
;
4097 if (PyDateTime_Check(left
)) {
4098 /* datetime - ??? */
4099 if (PyDateTime_Check(right
)) {
4100 /* datetime - datetime */
4102 int offset1
, offset2
;
4103 int delta_d
, delta_s
, delta_us
;
4105 if (classify_two_utcoffsets(left
, &offset1
, &n1
, left
,
4106 right
, &offset2
, &n2
,
4109 assert(n1
!= OFFSET_UNKNOWN
&& n2
!= OFFSET_UNKNOWN
);
4111 PyErr_SetString(PyExc_TypeError
,
4112 "can't subtract offset-naive and "
4113 "offset-aware datetimes");
4116 delta_d
= ymd_to_ord(GET_YEAR(left
),
4119 ymd_to_ord(GET_YEAR(right
),
4122 /* These can't overflow, since the values are
4123 * normalized. At most this gives the number of
4124 * seconds in one day.
4126 delta_s
= (DATE_GET_HOUR(left
) -
4127 DATE_GET_HOUR(right
)) * 3600 +
4128 (DATE_GET_MINUTE(left
) -
4129 DATE_GET_MINUTE(right
)) * 60 +
4130 (DATE_GET_SECOND(left
) -
4131 DATE_GET_SECOND(right
));
4132 delta_us
= DATE_GET_MICROSECOND(left
) -
4133 DATE_GET_MICROSECOND(right
);
4134 /* (left - offset1) - (right - offset2) =
4135 * (left - right) + (offset2 - offset1)
4137 delta_s
+= (offset2
- offset1
) * 60;
4138 result
= new_delta(delta_d
, delta_s
, delta_us
, 1);
4140 else if (PyDelta_Check(right
)) {
4141 /* datetime - delta */
4142 result
= add_datetime_timedelta(
4143 (PyDateTime_DateTime
*)left
,
4144 (PyDateTime_Delta
*)right
,
4149 if (result
== Py_NotImplemented
)
4154 /* Various ways to turn a datetime into a string. */
4157 datetime_repr(PyDateTime_DateTime
*self
)
4160 const char *type_name
= Py_TYPE(self
)->tp_name
;
4163 if (DATE_GET_MICROSECOND(self
)) {
4164 PyOS_snprintf(buffer
, sizeof(buffer
),
4165 "%s(%d, %d, %d, %d, %d, %d, %d)",
4167 GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
),
4168 DATE_GET_HOUR(self
), DATE_GET_MINUTE(self
),
4169 DATE_GET_SECOND(self
),
4170 DATE_GET_MICROSECOND(self
));
4172 else if (DATE_GET_SECOND(self
)) {
4173 PyOS_snprintf(buffer
, sizeof(buffer
),
4174 "%s(%d, %d, %d, %d, %d, %d)",
4176 GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
),
4177 DATE_GET_HOUR(self
), DATE_GET_MINUTE(self
),
4178 DATE_GET_SECOND(self
));
4181 PyOS_snprintf(buffer
, sizeof(buffer
),
4182 "%s(%d, %d, %d, %d, %d)",
4184 GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
),
4185 DATE_GET_HOUR(self
), DATE_GET_MINUTE(self
));
4187 baserepr
= PyString_FromString(buffer
);
4188 if (baserepr
== NULL
|| ! HASTZINFO(self
))
4190 return append_keyword_tzinfo(baserepr
, self
->tzinfo
);
4194 datetime_str(PyDateTime_DateTime
*self
)
4196 return PyObject_CallMethod((PyObject
*)self
, "isoformat", "(s)", " ");
4200 datetime_isoformat(PyDateTime_DateTime
*self
, PyObject
*args
, PyObject
*kw
)
4203 static char *keywords
[] = {"sep", NULL
};
4208 if (!PyArg_ParseTupleAndKeywords(args
, kw
, "|c:isoformat", keywords
,
4211 cp
= isoformat_date((PyDateTime_Date
*)self
, buffer
, sizeof(buffer
));
4214 isoformat_time(self
, cp
, sizeof(buffer
) - (cp
- buffer
));
4215 result
= PyString_FromString(buffer
);
4216 if (result
== NULL
|| ! HASTZINFO(self
))
4219 /* We need to append the UTC offset. */
4220 if (format_utcoffset(buffer
, sizeof(buffer
), ":", self
->tzinfo
,
4221 (PyObject
*)self
) < 0) {
4225 PyString_ConcatAndDel(&result
, PyString_FromString(buffer
));
4230 datetime_ctime(PyDateTime_DateTime
*self
)
4232 return format_ctime((PyDateTime_Date
*)self
,
4233 DATE_GET_HOUR(self
),
4234 DATE_GET_MINUTE(self
),
4235 DATE_GET_SECOND(self
));
4238 /* Miscellaneous methods. */
4240 /* This is more natural as a tp_compare, but doesn't work then: for whatever
4241 * reason, Python's try_3way_compare ignores tp_compare unless
4242 * PyInstance_Check returns true, but these aren't old-style classes.
4245 datetime_richcompare(PyDateTime_DateTime
*self
, PyObject
*other
, int op
)
4249 int offset1
, offset2
;
4251 if (! PyDateTime_Check(other
)) {
4252 /* If other has a "timetuple" attr, that's an advertised
4253 * hook for other classes to ask to get comparison control.
4254 * However, date instances have a timetuple attr, and we
4255 * don't want to allow that comparison. Because datetime
4256 * is a subclass of date, when mixing date and datetime
4257 * in a comparison, Python gives datetime the first shot
4258 * (it's the more specific subtype). So we can stop that
4259 * combination here reliably.
4261 if (PyObject_HasAttrString(other
, "timetuple") &&
4262 ! PyDate_Check(other
)) {
4263 /* A hook for other kinds of datetime objects. */
4264 Py_INCREF(Py_NotImplemented
);
4265 return Py_NotImplemented
;
4267 if (op
== Py_EQ
|| op
== Py_NE
) {
4268 PyObject
*result
= op
== Py_EQ
? Py_False
: Py_True
;
4272 /* Stop this from falling back to address comparison. */
4273 return cmperror((PyObject
*)self
, other
);
4276 if (classify_two_utcoffsets((PyObject
*)self
, &offset1
, &n1
,
4278 other
, &offset2
, &n2
,
4281 assert(n1
!= OFFSET_UNKNOWN
&& n2
!= OFFSET_UNKNOWN
);
4282 /* If they're both naive, or both aware and have the same offsets,
4283 * we get off cheap. Note that if they're both naive, offset1 ==
4284 * offset2 == 0 at this point.
4286 if (n1
== n2
&& offset1
== offset2
) {
4287 diff
= memcmp(self
->data
, ((PyDateTime_DateTime
*)other
)->data
,
4288 _PyDateTime_DATETIME_DATASIZE
);
4289 return diff_to_bool(diff
, op
);
4292 if (n1
== OFFSET_AWARE
&& n2
== OFFSET_AWARE
) {
4293 PyDateTime_Delta
*delta
;
4295 assert(offset1
!= offset2
); /* else last "if" handled it */
4296 delta
= (PyDateTime_Delta
*)datetime_subtract((PyObject
*)self
,
4300 diff
= GET_TD_DAYS(delta
);
4302 diff
= GET_TD_SECONDS(delta
) |
4303 GET_TD_MICROSECONDS(delta
);
4305 return diff_to_bool(diff
, op
);
4309 PyErr_SetString(PyExc_TypeError
,
4310 "can't compare offset-naive and "
4311 "offset-aware datetimes");
4316 datetime_hash(PyDateTime_DateTime
*self
)
4318 if (self
->hashcode
== -1) {
4323 n
= classify_utcoffset((PyObject
*)self
, (PyObject
*)self
,
4325 assert(n
!= OFFSET_UNKNOWN
);
4326 if (n
== OFFSET_ERROR
)
4329 /* Reduce this to a hash of another object. */
4330 if (n
== OFFSET_NAIVE
)
4331 temp
= PyString_FromStringAndSize(
4333 _PyDateTime_DATETIME_DATASIZE
);
4338 assert(n
== OFFSET_AWARE
);
4339 assert(HASTZINFO(self
));
4340 days
= ymd_to_ord(GET_YEAR(self
),
4343 seconds
= DATE_GET_HOUR(self
) * 3600 +
4344 (DATE_GET_MINUTE(self
) - offset
) * 60 +
4345 DATE_GET_SECOND(self
);
4346 temp
= new_delta(days
,
4348 DATE_GET_MICROSECOND(self
),
4352 self
->hashcode
= PyObject_Hash(temp
);
4356 return self
->hashcode
;
4360 datetime_replace(PyDateTime_DateTime
*self
, PyObject
*args
, PyObject
*kw
)
4364 int y
= GET_YEAR(self
);
4365 int m
= GET_MONTH(self
);
4366 int d
= GET_DAY(self
);
4367 int hh
= DATE_GET_HOUR(self
);
4368 int mm
= DATE_GET_MINUTE(self
);
4369 int ss
= DATE_GET_SECOND(self
);
4370 int us
= DATE_GET_MICROSECOND(self
);
4371 PyObject
*tzinfo
= HASTZINFO(self
) ? self
->tzinfo
: Py_None
;
4373 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "|iiiiiiiO:replace",
4375 &y
, &m
, &d
, &hh
, &mm
, &ss
, &us
,
4378 tuple
= Py_BuildValue("iiiiiiiO", y
, m
, d
, hh
, mm
, ss
, us
, tzinfo
);
4381 clone
= datetime_new(Py_TYPE(self
), tuple
, NULL
);
4387 datetime_astimezone(PyDateTime_DateTime
*self
, PyObject
*args
, PyObject
*kw
)
4389 int y
, m
, d
, hh
, mm
, ss
, us
;
4394 static char *keywords
[] = {"tz", NULL
};
4396 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "O!:astimezone", keywords
,
4397 &PyDateTime_TZInfoType
, &tzinfo
))
4400 if (!HASTZINFO(self
) || self
->tzinfo
== Py_None
)
4403 /* Conversion to self's own time zone is a NOP. */
4404 if (self
->tzinfo
== tzinfo
) {
4406 return (PyObject
*)self
;
4409 /* Convert self to UTC. */
4410 offset
= call_utcoffset(self
->tzinfo
, (PyObject
*)self
, &none
);
4411 if (offset
== -1 && PyErr_Occurred())
4417 m
= GET_MONTH(self
);
4419 hh
= DATE_GET_HOUR(self
);
4420 mm
= DATE_GET_MINUTE(self
);
4421 ss
= DATE_GET_SECOND(self
);
4422 us
= DATE_GET_MICROSECOND(self
);
4425 if ((mm
< 0 || mm
>= 60) &&
4426 normalize_datetime(&y
, &m
, &d
, &hh
, &mm
, &ss
, &us
) < 0)
4429 /* Attach new tzinfo and let fromutc() do the rest. */
4430 result
= new_datetime(y
, m
, d
, hh
, mm
, ss
, us
, tzinfo
);
4431 if (result
!= NULL
) {
4432 PyObject
*temp
= result
;
4434 result
= PyObject_CallMethod(tzinfo
, "fromutc", "O", temp
);
4440 PyErr_SetString(PyExc_ValueError
, "astimezone() cannot be applied to "
4441 "a naive datetime");
4446 datetime_timetuple(PyDateTime_DateTime
*self
)
4450 if (HASTZINFO(self
) && self
->tzinfo
!= Py_None
) {
4453 dstflag
= call_dst(self
->tzinfo
, (PyObject
*)self
, &none
);
4454 if (dstflag
== -1 && PyErr_Occurred())
4459 else if (dstflag
!= 0)
4463 return build_struct_time(GET_YEAR(self
),
4466 DATE_GET_HOUR(self
),
4467 DATE_GET_MINUTE(self
),
4468 DATE_GET_SECOND(self
),
4473 datetime_getdate(PyDateTime_DateTime
*self
)
4475 return new_date(GET_YEAR(self
),
4481 datetime_gettime(PyDateTime_DateTime
*self
)
4483 return new_time(DATE_GET_HOUR(self
),
4484 DATE_GET_MINUTE(self
),
4485 DATE_GET_SECOND(self
),
4486 DATE_GET_MICROSECOND(self
),
4491 datetime_gettimetz(PyDateTime_DateTime
*self
)
4493 return new_time(DATE_GET_HOUR(self
),
4494 DATE_GET_MINUTE(self
),
4495 DATE_GET_SECOND(self
),
4496 DATE_GET_MICROSECOND(self
),
4497 HASTZINFO(self
) ? self
->tzinfo
: Py_None
);
4501 datetime_utctimetuple(PyDateTime_DateTime
*self
)
4503 int y
= GET_YEAR(self
);
4504 int m
= GET_MONTH(self
);
4505 int d
= GET_DAY(self
);
4506 int hh
= DATE_GET_HOUR(self
);
4507 int mm
= DATE_GET_MINUTE(self
);
4508 int ss
= DATE_GET_SECOND(self
);
4509 int us
= 0; /* microseconds are ignored in a timetuple */
4512 if (HASTZINFO(self
) && self
->tzinfo
!= Py_None
) {
4515 offset
= call_utcoffset(self
->tzinfo
, (PyObject
*)self
, &none
);
4516 if (offset
== -1 && PyErr_Occurred())
4519 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4520 * 0 in a UTC timetuple regardless of what dst() says.
4523 /* Subtract offset minutes & normalize. */
4527 stat
= normalize_datetime(&y
, &m
, &d
, &hh
, &mm
, &ss
, &us
);
4529 /* At the edges, it's possible we overflowed
4530 * beyond MINYEAR or MAXYEAR.
4532 if (PyErr_ExceptionMatches(PyExc_OverflowError
))
4538 return build_struct_time(y
, m
, d
, hh
, mm
, ss
, 0);
4541 /* Pickle support, a simple use of __reduce__. */
4543 /* Let basestate be the non-tzinfo data string.
4544 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4545 * So it's a tuple in any (non-error) case.
4546 * __getstate__ isn't exposed.
4549 datetime_getstate(PyDateTime_DateTime
*self
)
4551 PyObject
*basestate
;
4552 PyObject
*result
= NULL
;
4554 basestate
= PyString_FromStringAndSize((char *)self
->data
,
4555 _PyDateTime_DATETIME_DATASIZE
);
4556 if (basestate
!= NULL
) {
4557 if (! HASTZINFO(self
) || self
->tzinfo
== Py_None
)
4558 result
= PyTuple_Pack(1, basestate
);
4560 result
= PyTuple_Pack(2, basestate
, self
->tzinfo
);
4561 Py_DECREF(basestate
);
4567 datetime_reduce(PyDateTime_DateTime
*self
, PyObject
*arg
)
4569 return Py_BuildValue("(ON)", Py_TYPE(self
), datetime_getstate(self
));
4572 static PyMethodDef datetime_methods
[] = {
4574 /* Class methods: */
4576 {"now", (PyCFunction
)datetime_now
,
4577 METH_VARARGS
| METH_KEYWORDS
| METH_CLASS
,
4578 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4580 {"utcnow", (PyCFunction
)datetime_utcnow
,
4581 METH_NOARGS
| METH_CLASS
,
4582 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4584 {"fromtimestamp", (PyCFunction
)datetime_fromtimestamp
,
4585 METH_VARARGS
| METH_KEYWORDS
| METH_CLASS
,
4586 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4588 {"utcfromtimestamp", (PyCFunction
)datetime_utcfromtimestamp
,
4589 METH_VARARGS
| METH_CLASS
,
4590 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4591 "(like time.time()).")},
4593 {"strptime", (PyCFunction
)datetime_strptime
,
4594 METH_VARARGS
| METH_CLASS
,
4595 PyDoc_STR("string, format -> new datetime parsed from a string "
4596 "(like time.strptime()).")},
4598 {"combine", (PyCFunction
)datetime_combine
,
4599 METH_VARARGS
| METH_KEYWORDS
| METH_CLASS
,
4600 PyDoc_STR("date, time -> datetime with same date and time fields")},
4602 /* Instance methods: */
4604 {"date", (PyCFunction
)datetime_getdate
, METH_NOARGS
,
4605 PyDoc_STR("Return date object with same year, month and day.")},
4607 {"time", (PyCFunction
)datetime_gettime
, METH_NOARGS
,
4608 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4610 {"timetz", (PyCFunction
)datetime_gettimetz
, METH_NOARGS
,
4611 PyDoc_STR("Return time object with same time and tzinfo.")},
4613 {"ctime", (PyCFunction
)datetime_ctime
, METH_NOARGS
,
4614 PyDoc_STR("Return ctime() style string.")},
4616 {"timetuple", (PyCFunction
)datetime_timetuple
, METH_NOARGS
,
4617 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4619 {"utctimetuple", (PyCFunction
)datetime_utctimetuple
, METH_NOARGS
,
4620 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4622 {"isoformat", (PyCFunction
)datetime_isoformat
, METH_VARARGS
| METH_KEYWORDS
,
4623 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4624 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4625 "sep is used to separate the year from the time, and "
4626 "defaults to 'T'.")},
4628 {"utcoffset", (PyCFunction
)datetime_utcoffset
, METH_NOARGS
,
4629 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4631 {"tzname", (PyCFunction
)datetime_tzname
, METH_NOARGS
,
4632 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4634 {"dst", (PyCFunction
)datetime_dst
, METH_NOARGS
,
4635 PyDoc_STR("Return self.tzinfo.dst(self).")},
4637 {"replace", (PyCFunction
)datetime_replace
, METH_VARARGS
| METH_KEYWORDS
,
4638 PyDoc_STR("Return datetime with new specified fields.")},
4640 {"astimezone", (PyCFunction
)datetime_astimezone
, METH_VARARGS
| METH_KEYWORDS
,
4641 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4643 {"__reduce__", (PyCFunction
)datetime_reduce
, METH_NOARGS
,
4644 PyDoc_STR("__reduce__() -> (cls, state)")},
4649 static char datetime_doc
[] =
4650 PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4652 The year, month and day arguments are required. tzinfo may be None, or an\n\
4653 instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
4655 static PyNumberMethods datetime_as_number
= {
4656 datetime_add
, /* nb_add */
4657 datetime_subtract
, /* nb_subtract */
4658 0, /* nb_multiply */
4660 0, /* nb_remainder */
4663 0, /* nb_negative */
4664 0, /* nb_positive */
4665 0, /* nb_absolute */
4669 statichere PyTypeObject PyDateTime_DateTimeType
= {
4670 PyObject_HEAD_INIT(NULL
)
4672 "datetime.datetime", /* tp_name */
4673 sizeof(PyDateTime_DateTime
), /* tp_basicsize */
4674 0, /* tp_itemsize */
4675 (destructor
)datetime_dealloc
, /* tp_dealloc */
4680 (reprfunc
)datetime_repr
, /* tp_repr */
4681 &datetime_as_number
, /* tp_as_number */
4682 0, /* tp_as_sequence */
4683 0, /* tp_as_mapping */
4684 (hashfunc
)datetime_hash
, /* tp_hash */
4686 (reprfunc
)datetime_str
, /* tp_str */
4687 PyObject_GenericGetAttr
, /* tp_getattro */
4688 0, /* tp_setattro */
4689 0, /* tp_as_buffer */
4690 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
4691 Py_TPFLAGS_BASETYPE
, /* tp_flags */
4692 datetime_doc
, /* tp_doc */
4693 0, /* tp_traverse */
4695 (richcmpfunc
)datetime_richcompare
, /* tp_richcompare */
4696 0, /* tp_weaklistoffset */
4698 0, /* tp_iternext */
4699 datetime_methods
, /* tp_methods */
4701 datetime_getset
, /* tp_getset */
4702 &PyDateTime_DateType
, /* tp_base */
4704 0, /* tp_descr_get */
4705 0, /* tp_descr_set */
4706 0, /* tp_dictoffset */
4708 datetime_alloc
, /* tp_alloc */
4709 datetime_new
, /* tp_new */
4713 /* ---------------------------------------------------------------------------
4714 * Module methods and initialization.
4717 static PyMethodDef module_methods
[] = {
4721 /* C API. Clients get at this via PyDateTime_IMPORT, defined in
4724 static PyDateTime_CAPI CAPI
= {
4725 &PyDateTime_DateType
,
4726 &PyDateTime_DateTimeType
,
4727 &PyDateTime_TimeType
,
4728 &PyDateTime_DeltaType
,
4729 &PyDateTime_TZInfoType
,
4734 datetime_fromtimestamp
,
4742 PyObject
*m
; /* a module object */
4743 PyObject
*d
; /* its dict */
4746 m
= Py_InitModule3("datetime", module_methods
,
4747 "Fast implementation of the datetime type.");
4751 if (PyType_Ready(&PyDateTime_DateType
) < 0)
4753 if (PyType_Ready(&PyDateTime_DateTimeType
) < 0)
4755 if (PyType_Ready(&PyDateTime_DeltaType
) < 0)
4757 if (PyType_Ready(&PyDateTime_TimeType
) < 0)
4759 if (PyType_Ready(&PyDateTime_TZInfoType
) < 0)
4762 /* timedelta values */
4763 d
= PyDateTime_DeltaType
.tp_dict
;
4765 x
= new_delta(0, 0, 1, 0);
4766 if (x
== NULL
|| PyDict_SetItemString(d
, "resolution", x
) < 0)
4770 x
= new_delta(-MAX_DELTA_DAYS
, 0, 0, 0);
4771 if (x
== NULL
|| PyDict_SetItemString(d
, "min", x
) < 0)
4775 x
= new_delta(MAX_DELTA_DAYS
, 24*3600-1, 1000000-1, 0);
4776 if (x
== NULL
|| PyDict_SetItemString(d
, "max", x
) < 0)
4781 d
= PyDateTime_DateType
.tp_dict
;
4783 x
= new_date(1, 1, 1);
4784 if (x
== NULL
|| PyDict_SetItemString(d
, "min", x
) < 0)
4788 x
= new_date(MAXYEAR
, 12, 31);
4789 if (x
== NULL
|| PyDict_SetItemString(d
, "max", x
) < 0)
4793 x
= new_delta(1, 0, 0, 0);
4794 if (x
== NULL
|| PyDict_SetItemString(d
, "resolution", x
) < 0)
4799 d
= PyDateTime_TimeType
.tp_dict
;
4801 x
= new_time(0, 0, 0, 0, Py_None
);
4802 if (x
== NULL
|| PyDict_SetItemString(d
, "min", x
) < 0)
4806 x
= new_time(23, 59, 59, 999999, Py_None
);
4807 if (x
== NULL
|| PyDict_SetItemString(d
, "max", x
) < 0)
4811 x
= new_delta(0, 0, 1, 0);
4812 if (x
== NULL
|| PyDict_SetItemString(d
, "resolution", x
) < 0)
4816 /* datetime values */
4817 d
= PyDateTime_DateTimeType
.tp_dict
;
4819 x
= new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None
);
4820 if (x
== NULL
|| PyDict_SetItemString(d
, "min", x
) < 0)
4824 x
= new_datetime(MAXYEAR
, 12, 31, 23, 59, 59, 999999, Py_None
);
4825 if (x
== NULL
|| PyDict_SetItemString(d
, "max", x
) < 0)
4829 x
= new_delta(0, 0, 1, 0);
4830 if (x
== NULL
|| PyDict_SetItemString(d
, "resolution", x
) < 0)
4834 /* module initialization */
4835 PyModule_AddIntConstant(m
, "MINYEAR", MINYEAR
);
4836 PyModule_AddIntConstant(m
, "MAXYEAR", MAXYEAR
);
4838 Py_INCREF(&PyDateTime_DateType
);
4839 PyModule_AddObject(m
, "date", (PyObject
*) &PyDateTime_DateType
);
4841 Py_INCREF(&PyDateTime_DateTimeType
);
4842 PyModule_AddObject(m
, "datetime",
4843 (PyObject
*)&PyDateTime_DateTimeType
);
4845 Py_INCREF(&PyDateTime_TimeType
);
4846 PyModule_AddObject(m
, "time", (PyObject
*) &PyDateTime_TimeType
);
4848 Py_INCREF(&PyDateTime_DeltaType
);
4849 PyModule_AddObject(m
, "timedelta", (PyObject
*) &PyDateTime_DeltaType
);
4851 Py_INCREF(&PyDateTime_TZInfoType
);
4852 PyModule_AddObject(m
, "tzinfo", (PyObject
*) &PyDateTime_TZInfoType
);
4854 x
= PyCObject_FromVoidPtrAndDesc(&CAPI
, (void*) DATETIME_API_MAGIC
,
4858 PyModule_AddObject(m
, "datetime_CAPI", x
);
4860 /* A 4-year cycle has an extra leap day over what we'd get from
4861 * pasting together 4 single years.
4863 assert(DI4Y
== 4 * 365 + 1);
4864 assert(DI4Y
== days_before_year(4+1));
4866 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4867 * get from pasting together 4 100-year cycles.
4869 assert(DI400Y
== 4 * DI100Y
+ 1);
4870 assert(DI400Y
== days_before_year(400+1));
4872 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4873 * pasting together 25 4-year cycles.
4875 assert(DI100Y
== 25 * DI4Y
- 1);
4876 assert(DI100Y
== days_before_year(100+1));
4878 us_per_us
= PyInt_FromLong(1);
4879 us_per_ms
= PyInt_FromLong(1000);
4880 us_per_second
= PyInt_FromLong(1000000);
4881 us_per_minute
= PyInt_FromLong(60000000);
4882 seconds_per_day
= PyInt_FromLong(24 * 3600);
4883 if (us_per_us
== NULL
|| us_per_ms
== NULL
|| us_per_second
== NULL
||
4884 us_per_minute
== NULL
|| seconds_per_day
== NULL
)
4887 /* The rest are too big for 32-bit ints, but even
4888 * us_per_week fits in 40 bits, so doubles should be exact.
4890 us_per_hour
= PyLong_FromDouble(3600000000.0);
4891 us_per_day
= PyLong_FromDouble(86400000000.0);
4892 us_per_week
= PyLong_FromDouble(604800000000.0);
4893 if (us_per_hour
== NULL
|| us_per_day
== NULL
|| us_per_week
== NULL
)
4897 /* ---------------------------------------------------------------------------
4898 Some time zone algebra. For a datetime x, let
4899 x.n = x stripped of its timezone -- its naive time.
4900 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4902 x.d = x.dst(), and assuming that doesn't raise an exception or
4904 x.s = x's standard offset, x.o - x.d
4906 Now some derived rules, where k is a duration (timedelta).
4909 This follows from the definition of x.s.
4911 2. If x and y have the same tzinfo member, x.s = y.s.
4912 This is actually a requirement, an assumption we need to make about
4913 sane tzinfo classes.
4915 3. The naive UTC time corresponding to x is x.n - x.o.
4916 This is again a requirement for a sane tzinfo class.
4919 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
4921 5. (x+k).n = x.n + k
4922 Again follows from how arithmetic is defined.
4924 Now we can explain tz.fromutc(x). Let's assume it's an interesting case
4925 (meaning that the various tzinfo methods exist, and don't blow up or return
4928 The function wants to return a datetime y with timezone tz, equivalent to x.
4929 x is already in UTC.
4935 The algorithm starts by attaching tz to x.n, and calling that y. So
4936 x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4937 becomes true; in effect, we want to solve [2] for k:
4939 (y+k).n - (y+k).o = x.n [2]
4941 By #1, this is the same as
4943 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
4945 By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4946 Substituting that into [3],
4948 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4949 k - (y+k).s - (y+k).d = 0; rearranging,
4950 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4953 On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4954 approximate k by ignoring the (y+k).d term at first. Note that k can't be
4955 very large, since all offset-returning methods return a duration of magnitude
4956 less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4957 be 0, so ignoring it has no consequence then.
4959 In any case, the new value is
4963 It's helpful to step back at look at [4] from a higher level: it's simply
4964 mapping from UTC to tz's standard time.
4970 we have an equivalent time, and are almost done. The insecurity here is
4971 at the start of daylight time. Picture US Eastern for concreteness. The wall
4972 time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
4973 sense then. The docs ask that an Eastern tzinfo class consider such a time to
4974 be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4975 on the day DST starts. We want to return the 1:MM EST spelling because that's
4976 the only spelling that makes sense on the local wall clock.
4978 In fact, if [5] holds at this point, we do have the standard-time spelling,
4979 but that takes a bit of proof. We first prove a stronger result. What's the
4980 difference between the LHS and RHS of [5]? Let
4982 diff = x.n - (z.n - z.o) [6]
4987 y.n + y.s = since y.n = x.n
4988 x.n + y.s = since z and y are have the same tzinfo member,
4992 Plugging that back into [6] gives
4995 x.n - ((x.n + z.s) - z.o) = expanding
4996 x.n - x.n - z.s + z.o = cancelling
5002 If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
5003 spelling we wanted in the endcase described above. We're done. Contrarily,
5004 if z.d = 0, then we have a UTC equivalent, and are also done.
5006 If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5007 add to z (in effect, z is in tz's standard time, and we need to shift the
5008 local clock into tz's daylight time).
5012 z' = z + z.d = z + diff [7]
5014 and we can again ask whether
5016 z'.n - z'.o = x.n [8]
5018 If so, we're done. If not, the tzinfo class is insane, according to the
5019 assumptions we've made. This also requires a bit of proof. As before, let's
5020 compute the difference between the LHS and RHS of [8] (and skipping some of
5021 the justifications for the kinds of substitutions we've done several times
5024 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5025 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5026 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5027 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5028 - z.n + z.n - z.o + z'.o = cancel z.n
5029 - z.o + z'.o = #1 twice
5030 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5033 So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
5034 we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5035 return z', not bothering to compute z'.d.
5037 How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5038 a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5039 would have to change the result dst() returns: we start in DST, and moving
5040 a little further into it takes us out of DST.
5042 There isn't a sane case where this can happen. The closest it gets is at
5043 the end of DST, where there's an hour in UTC with no spelling in a hybrid
5044 tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5045 that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5046 UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5047 time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5048 clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5049 standard time. Since that's what the local clock *does*, we want to map both
5050 UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
5051 in local time, but so it goes -- it's the way the local clock works.
5053 When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5054 so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5055 z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
5056 (correctly) concludes that z' is not UTC-equivalent to x.
5058 Because we know z.d said z was in daylight time (else [5] would have held and
5059 we would have stopped then), and we know z.d != z'.d (else [8] would have held
5060 and we would have stopped then), and there are only 2 possible values dst() can
5061 return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5062 but the reasoning doesn't depend on the example -- it depends on there being
5063 two possible dst() outcomes, one zero and the other non-zero). Therefore
5064 z' must be in standard time, and is the spelling we want in this case.
5066 Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5067 concerned (because it takes z' as being in standard time rather than the
5068 daylight time we intend here), but returning it gives the real-life "local
5069 clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5072 When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5073 the 1:MM standard time spelling we want.
5075 So how can this break? One of the assumptions must be violated. Two
5078 1) [2] effectively says that y.s is invariant across all y belong to a given
5079 time zone. This isn't true if, for political reasons or continental drift,
5080 a region decides to change its base offset from UTC.
5082 2) There may be versions of "double daylight" time where the tail end of
5083 the analysis gives up a step too early. I haven't thought about that
5086 In any case, it's clear that the default fromutc() is strong enough to handle
5087 "almost all" time zones: so long as the standard offset is invariant, it
5088 doesn't matter if daylight time transition points change from year to year, or
5089 if daylight time is skipped in some years; it doesn't matter how large or
5090 small dst() may get within its bounds; and it doesn't even matter if some
5091 perverse time zone returns a negative dst()). So a breaking case must be
5092 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
5093 --------------------------------------------------------------------------- */