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
));
1365 assert(bufflen
>= x
);
1370 isoformat_time(PyDateTime_DateTime
*dt
, char buffer
[], int bufflen
)
1373 int us
= DATE_GET_MICROSECOND(dt
);
1375 x
= PyOS_snprintf(buffer
, bufflen
,
1378 DATE_GET_MINUTE(dt
),
1379 DATE_GET_SECOND(dt
));
1380 assert(bufflen
>= x
);
1382 x
+= PyOS_snprintf(buffer
+ x
, bufflen
- x
, ".%06d", us
);
1383 assert(bufflen
>= x
);
1387 /* ---------------------------------------------------------------------------
1388 * Wrap functions from the time module. These aren't directly available
1389 * from C. Perhaps they should be.
1392 /* Call time.time() and return its result (a Python float). */
1396 PyObject
*result
= NULL
;
1397 PyObject
*time
= PyImport_ImportModuleNoBlock("time");
1400 result
= PyObject_CallMethod(time
, "time", "()");
1406 /* Build a time.struct_time. The weekday and day number are automatically
1407 * computed from the y,m,d args.
1410 build_struct_time(int y
, int m
, int d
, int hh
, int mm
, int ss
, int dstflag
)
1413 PyObject
*result
= NULL
;
1415 time
= PyImport_ImportModuleNoBlock("time");
1417 result
= PyObject_CallMethod(time
, "struct_time",
1422 days_before_month(y
, m
) + d
,
1429 /* ---------------------------------------------------------------------------
1430 * Miscellaneous helpers.
1433 /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1434 * The comparisons here all most naturally compute a cmp()-like result.
1435 * This little helper turns that into a bool result for rich comparisons.
1438 diff_to_bool(int diff
, int op
)
1444 case Py_EQ
: istrue
= diff
== 0; break;
1445 case Py_NE
: istrue
= diff
!= 0; break;
1446 case Py_LE
: istrue
= diff
<= 0; break;
1447 case Py_GE
: istrue
= diff
>= 0; break;
1448 case Py_LT
: istrue
= diff
< 0; break;
1449 case Py_GT
: istrue
= diff
> 0; break;
1451 assert(! "op unknown");
1452 istrue
= 0; /* To shut up compiler */
1454 result
= istrue
? Py_True
: Py_False
;
1459 /* Raises a "can't compare" TypeError and returns NULL. */
1461 cmperror(PyObject
*a
, PyObject
*b
)
1463 PyErr_Format(PyExc_TypeError
,
1464 "can't compare %s to %s",
1465 Py_TYPE(a
)->tp_name
, Py_TYPE(b
)->tp_name
);
1469 /* ---------------------------------------------------------------------------
1470 * Cached Python objects; these are set by the module init function.
1473 /* Conversion factors. */
1474 static PyObject
*us_per_us
= NULL
; /* 1 */
1475 static PyObject
*us_per_ms
= NULL
; /* 1000 */
1476 static PyObject
*us_per_second
= NULL
; /* 1000000 */
1477 static PyObject
*us_per_minute
= NULL
; /* 1e6 * 60 as Python int */
1478 static PyObject
*us_per_hour
= NULL
; /* 1e6 * 3600 as Python long */
1479 static PyObject
*us_per_day
= NULL
; /* 1e6 * 3600 * 24 as Python long */
1480 static PyObject
*us_per_week
= NULL
; /* 1e6*3600*24*7 as Python long */
1481 static PyObject
*seconds_per_day
= NULL
; /* 3600*24 as Python int */
1483 /* ---------------------------------------------------------------------------
1484 * Class implementations.
1488 * PyDateTime_Delta implementation.
1491 /* Convert a timedelta to a number of us,
1492 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1493 * as a Python int or long.
1494 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1495 * due to ubiquitous overflow possibilities.
1498 delta_to_microseconds(PyDateTime_Delta
*self
)
1500 PyObject
*x1
= NULL
;
1501 PyObject
*x2
= NULL
;
1502 PyObject
*x3
= NULL
;
1503 PyObject
*result
= NULL
;
1505 x1
= PyInt_FromLong(GET_TD_DAYS(self
));
1508 x2
= PyNumber_Multiply(x1
, seconds_per_day
); /* days in seconds */
1514 /* x2 has days in seconds */
1515 x1
= PyInt_FromLong(GET_TD_SECONDS(self
)); /* seconds */
1518 x3
= PyNumber_Add(x1
, x2
); /* days and seconds in seconds */
1525 /* x3 has days+seconds in seconds */
1526 x1
= PyNumber_Multiply(x3
, us_per_second
); /* us */
1532 /* x1 has days+seconds in us */
1533 x2
= PyInt_FromLong(GET_TD_MICROSECONDS(self
));
1536 result
= PyNumber_Add(x1
, x2
);
1545 /* Convert a number of us (as a Python int or long) to a timedelta.
1548 microseconds_to_delta_ex(PyObject
*pyus
, PyTypeObject
*type
)
1555 PyObject
*tuple
= NULL
;
1556 PyObject
*num
= NULL
;
1557 PyObject
*result
= NULL
;
1559 tuple
= PyNumber_Divmod(pyus
, us_per_second
);
1563 num
= PyTuple_GetItem(tuple
, 1); /* us */
1566 temp
= PyLong_AsLong(num
);
1568 if (temp
== -1 && PyErr_Occurred())
1570 assert(0 <= temp
&& temp
< 1000000);
1573 /* The divisor was positive, so this must be an error. */
1574 assert(PyErr_Occurred());
1578 num
= PyTuple_GetItem(tuple
, 0); /* leftover seconds */
1584 tuple
= PyNumber_Divmod(num
, seconds_per_day
);
1589 num
= PyTuple_GetItem(tuple
, 1); /* seconds */
1592 temp
= PyLong_AsLong(num
);
1594 if (temp
== -1 && PyErr_Occurred())
1596 assert(0 <= temp
&& temp
< 24*3600);
1600 /* The divisor was positive, so this must be an error. */
1601 assert(PyErr_Occurred());
1605 num
= PyTuple_GetItem(tuple
, 0); /* leftover days */
1609 temp
= PyLong_AsLong(num
);
1610 if (temp
== -1 && PyErr_Occurred())
1613 if ((long)d
!= temp
) {
1614 PyErr_SetString(PyExc_OverflowError
, "normalized days too "
1615 "large to fit in a C int");
1618 result
= new_delta_ex(d
, s
, us
, 0, type
);
1626 #define microseconds_to_delta(pymicros) \
1627 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1630 multiply_int_timedelta(PyObject
*intobj
, PyDateTime_Delta
*delta
)
1636 pyus_in
= delta_to_microseconds(delta
);
1637 if (pyus_in
== NULL
)
1640 pyus_out
= PyNumber_Multiply(pyus_in
, intobj
);
1642 if (pyus_out
== NULL
)
1645 result
= microseconds_to_delta(pyus_out
);
1646 Py_DECREF(pyus_out
);
1651 divide_timedelta_int(PyDateTime_Delta
*delta
, PyObject
*intobj
)
1657 pyus_in
= delta_to_microseconds(delta
);
1658 if (pyus_in
== NULL
)
1661 pyus_out
= PyNumber_FloorDivide(pyus_in
, intobj
);
1663 if (pyus_out
== NULL
)
1666 result
= microseconds_to_delta(pyus_out
);
1667 Py_DECREF(pyus_out
);
1672 delta_add(PyObject
*left
, PyObject
*right
)
1674 PyObject
*result
= Py_NotImplemented
;
1676 if (PyDelta_Check(left
) && PyDelta_Check(right
)) {
1678 /* The C-level additions can't overflow because of the
1681 int days
= GET_TD_DAYS(left
) + GET_TD_DAYS(right
);
1682 int seconds
= GET_TD_SECONDS(left
) + GET_TD_SECONDS(right
);
1683 int microseconds
= GET_TD_MICROSECONDS(left
) +
1684 GET_TD_MICROSECONDS(right
);
1685 result
= new_delta(days
, seconds
, microseconds
, 1);
1688 if (result
== Py_NotImplemented
)
1694 delta_negative(PyDateTime_Delta
*self
)
1696 return new_delta(-GET_TD_DAYS(self
),
1697 -GET_TD_SECONDS(self
),
1698 -GET_TD_MICROSECONDS(self
),
1703 delta_positive(PyDateTime_Delta
*self
)
1705 /* Could optimize this (by returning self) if this isn't a
1706 * subclass -- but who uses unary + ? Approximately nobody.
1708 return new_delta(GET_TD_DAYS(self
),
1709 GET_TD_SECONDS(self
),
1710 GET_TD_MICROSECONDS(self
),
1715 delta_abs(PyDateTime_Delta
*self
)
1719 assert(GET_TD_MICROSECONDS(self
) >= 0);
1720 assert(GET_TD_SECONDS(self
) >= 0);
1722 if (GET_TD_DAYS(self
) < 0)
1723 result
= delta_negative(self
);
1725 result
= delta_positive(self
);
1731 delta_subtract(PyObject
*left
, PyObject
*right
)
1733 PyObject
*result
= Py_NotImplemented
;
1735 if (PyDelta_Check(left
) && PyDelta_Check(right
)) {
1737 PyObject
*minus_right
= PyNumber_Negative(right
);
1739 result
= delta_add(left
, minus_right
);
1740 Py_DECREF(minus_right
);
1746 if (result
== Py_NotImplemented
)
1751 /* This is more natural as a tp_compare, but doesn't work then: for whatever
1752 * reason, Python's try_3way_compare ignores tp_compare unless
1753 * PyInstance_Check returns true, but these aren't old-style classes.
1756 delta_richcompare(PyDateTime_Delta
*self
, PyObject
*other
, int op
)
1758 int diff
= 42; /* nonsense */
1760 if (PyDelta_Check(other
)) {
1761 diff
= GET_TD_DAYS(self
) - GET_TD_DAYS(other
);
1763 diff
= GET_TD_SECONDS(self
) - GET_TD_SECONDS(other
);
1765 diff
= GET_TD_MICROSECONDS(self
) -
1766 GET_TD_MICROSECONDS(other
);
1769 else if (op
== Py_EQ
|| op
== Py_NE
)
1770 diff
= 1; /* any non-zero value will do */
1772 else /* stop this from falling back to address comparison */
1773 return cmperror((PyObject
*)self
, other
);
1775 return diff_to_bool(diff
, op
);
1778 static PyObject
*delta_getstate(PyDateTime_Delta
*self
);
1781 delta_hash(PyDateTime_Delta
*self
)
1783 if (self
->hashcode
== -1) {
1784 PyObject
*temp
= delta_getstate(self
);
1786 self
->hashcode
= PyObject_Hash(temp
);
1790 return self
->hashcode
;
1794 delta_multiply(PyObject
*left
, PyObject
*right
)
1796 PyObject
*result
= Py_NotImplemented
;
1798 if (PyDelta_Check(left
)) {
1800 if (PyInt_Check(right
) || PyLong_Check(right
))
1801 result
= multiply_int_timedelta(right
,
1802 (PyDateTime_Delta
*) left
);
1804 else if (PyInt_Check(left
) || PyLong_Check(left
))
1805 result
= multiply_int_timedelta(left
,
1806 (PyDateTime_Delta
*) right
);
1808 if (result
== Py_NotImplemented
)
1814 delta_divide(PyObject
*left
, PyObject
*right
)
1816 PyObject
*result
= Py_NotImplemented
;
1818 if (PyDelta_Check(left
)) {
1820 if (PyInt_Check(right
) || PyLong_Check(right
))
1821 result
= divide_timedelta_int(
1822 (PyDateTime_Delta
*)left
,
1826 if (result
== Py_NotImplemented
)
1831 /* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1832 * timedelta constructor. sofar is the # of microseconds accounted for
1833 * so far, and there are factor microseconds per current unit, the number
1834 * of which is given by num. num * factor is added to sofar in a
1835 * numerically careful way, and that's the result. Any fractional
1836 * microseconds left over (this can happen if num is a float type) are
1837 * added into *leftover.
1838 * Note that there are many ways this can give an error (NULL) return.
1841 accum(const char* tag
, PyObject
*sofar
, PyObject
*num
, PyObject
*factor
,
1847 assert(num
!= NULL
);
1849 if (PyInt_Check(num
) || PyLong_Check(num
)) {
1850 prod
= PyNumber_Multiply(num
, factor
);
1853 sum
= PyNumber_Add(sofar
, prod
);
1858 if (PyFloat_Check(num
)) {
1865 /* The Plan: decompose num into an integer part and a
1866 * fractional part, num = intpart + fracpart.
1867 * Then num * factor ==
1868 * intpart * factor + fracpart * factor
1869 * and the LHS can be computed exactly in long arithmetic.
1870 * The RHS is again broken into an int part and frac part.
1871 * and the frac part is added into *leftover.
1873 dnum
= PyFloat_AsDouble(num
);
1874 if (dnum
== -1.0 && PyErr_Occurred())
1876 fracpart
= modf(dnum
, &intpart
);
1877 x
= PyLong_FromDouble(intpart
);
1881 prod
= PyNumber_Multiply(x
, factor
);
1886 sum
= PyNumber_Add(sofar
, prod
);
1891 if (fracpart
== 0.0)
1893 /* So far we've lost no information. Dealing with the
1894 * fractional part requires float arithmetic, and may
1895 * lose a little info.
1897 assert(PyInt_Check(factor
) || PyLong_Check(factor
));
1898 if (PyInt_Check(factor
))
1899 dnum
= (double)PyInt_AsLong(factor
);
1901 dnum
= PyLong_AsDouble(factor
);
1904 fracpart
= modf(dnum
, &intpart
);
1905 x
= PyLong_FromDouble(intpart
);
1911 y
= PyNumber_Add(sum
, x
);
1914 *leftover
+= fracpart
;
1918 PyErr_Format(PyExc_TypeError
,
1919 "unsupported type for timedelta %s component: %s",
1920 tag
, Py_TYPE(num
)->tp_name
);
1925 delta_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
1927 PyObject
*self
= NULL
;
1929 /* Argument objects. */
1930 PyObject
*day
= NULL
;
1931 PyObject
*second
= NULL
;
1932 PyObject
*us
= NULL
;
1933 PyObject
*ms
= NULL
;
1934 PyObject
*minute
= NULL
;
1935 PyObject
*hour
= NULL
;
1936 PyObject
*week
= NULL
;
1938 PyObject
*x
= NULL
; /* running sum of microseconds */
1939 PyObject
*y
= NULL
; /* temp sum of microseconds */
1940 double leftover_us
= 0.0;
1942 static char *keywords
[] = {
1943 "days", "seconds", "microseconds", "milliseconds",
1944 "minutes", "hours", "weeks", NULL
1947 if (PyArg_ParseTupleAndKeywords(args
, kw
, "|OOOOOOO:__new__",
1950 &ms
, &minute
, &hour
, &week
) == 0)
1953 x
= PyInt_FromLong(0);
1964 y
= accum("microseconds", x
, us
, us_per_us
, &leftover_us
);
1968 y
= accum("milliseconds", x
, ms
, us_per_ms
, &leftover_us
);
1972 y
= accum("seconds", x
, second
, us_per_second
, &leftover_us
);
1976 y
= accum("minutes", x
, minute
, us_per_minute
, &leftover_us
);
1980 y
= accum("hours", x
, hour
, us_per_hour
, &leftover_us
);
1984 y
= accum("days", x
, day
, us_per_day
, &leftover_us
);
1988 y
= accum("weeks", x
, week
, us_per_week
, &leftover_us
);
1992 /* Round to nearest whole # of us, and add into x. */
1993 PyObject
*temp
= PyLong_FromLong(round_to_long(leftover_us
));
1998 y
= PyNumber_Add(x
, temp
);
2003 self
= microseconds_to_delta_ex(x
, type
);
2012 delta_nonzero(PyDateTime_Delta
*self
)
2014 return (GET_TD_DAYS(self
) != 0
2015 || GET_TD_SECONDS(self
) != 0
2016 || GET_TD_MICROSECONDS(self
) != 0);
2020 delta_repr(PyDateTime_Delta
*self
)
2022 if (GET_TD_MICROSECONDS(self
) != 0)
2023 return PyString_FromFormat("%s(%d, %d, %d)",
2024 Py_TYPE(self
)->tp_name
,
2026 GET_TD_SECONDS(self
),
2027 GET_TD_MICROSECONDS(self
));
2028 if (GET_TD_SECONDS(self
) != 0)
2029 return PyString_FromFormat("%s(%d, %d)",
2030 Py_TYPE(self
)->tp_name
,
2032 GET_TD_SECONDS(self
));
2034 return PyString_FromFormat("%s(%d)",
2035 Py_TYPE(self
)->tp_name
,
2040 delta_str(PyDateTime_Delta
*self
)
2042 int days
= GET_TD_DAYS(self
);
2043 int seconds
= GET_TD_SECONDS(self
);
2044 int us
= GET_TD_MICROSECONDS(self
);
2049 size_t buflen
= sizeof(buf
);
2052 minutes
= divmod(seconds
, 60, &seconds
);
2053 hours
= divmod(minutes
, 60, &minutes
);
2056 n
= PyOS_snprintf(pbuf
, buflen
, "%d day%s, ", days
,
2057 (days
== 1 || days
== -1) ? "" : "s");
2058 if (n
< 0 || (size_t)n
>= buflen
)
2061 buflen
-= (size_t)n
;
2064 n
= PyOS_snprintf(pbuf
, buflen
, "%d:%02d:%02d",
2065 hours
, minutes
, seconds
);
2066 if (n
< 0 || (size_t)n
>= buflen
)
2069 buflen
-= (size_t)n
;
2072 n
= PyOS_snprintf(pbuf
, buflen
, ".%06d", us
);
2073 if (n
< 0 || (size_t)n
>= buflen
)
2078 return PyString_FromStringAndSize(buf
, pbuf
- buf
);
2081 PyErr_SetString(PyExc_SystemError
, "goofy result from PyOS_snprintf");
2085 /* Pickle support, a simple use of __reduce__. */
2087 /* __getstate__ isn't exposed */
2089 delta_getstate(PyDateTime_Delta
*self
)
2091 return Py_BuildValue("iii", GET_TD_DAYS(self
),
2092 GET_TD_SECONDS(self
),
2093 GET_TD_MICROSECONDS(self
));
2097 delta_total_seconds(PyObject
*self
)
2099 return PyFloat_FromDouble(GET_TD_MICROSECONDS(self
) / 1000000.0 +
2100 GET_TD_SECONDS(self
) +
2101 GET_TD_DAYS(self
) * 24.0 * 3600.0);
2105 delta_reduce(PyDateTime_Delta
* self
)
2107 return Py_BuildValue("ON", Py_TYPE(self
), delta_getstate(self
));
2110 #define OFFSET(field) offsetof(PyDateTime_Delta, field)
2112 static PyMemberDef delta_members
[] = {
2114 {"days", T_INT
, OFFSET(days
), READONLY
,
2115 PyDoc_STR("Number of days.")},
2117 {"seconds", T_INT
, OFFSET(seconds
), READONLY
,
2118 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2120 {"microseconds", T_INT
, OFFSET(microseconds
), READONLY
,
2121 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2125 static PyMethodDef delta_methods
[] = {
2126 {"total_seconds", (PyCFunction
)delta_total_seconds
, METH_NOARGS
,
2127 PyDoc_STR("Total seconds in the duration.")},
2129 {"__reduce__", (PyCFunction
)delta_reduce
, METH_NOARGS
,
2130 PyDoc_STR("__reduce__() -> (cls, state)")},
2135 static char delta_doc
[] =
2136 PyDoc_STR("Difference between two datetime values.");
2138 static PyNumberMethods delta_as_number
= {
2139 delta_add
, /* nb_add */
2140 delta_subtract
, /* nb_subtract */
2141 delta_multiply
, /* nb_multiply */
2142 delta_divide
, /* nb_divide */
2143 0, /* nb_remainder */
2146 (unaryfunc
)delta_negative
, /* nb_negative */
2147 (unaryfunc
)delta_positive
, /* nb_positive */
2148 (unaryfunc
)delta_abs
, /* nb_absolute */
2149 (inquiry
)delta_nonzero
, /* nb_nonzero */
2162 0, /*nb_inplace_add*/
2163 0, /*nb_inplace_subtract*/
2164 0, /*nb_inplace_multiply*/
2165 0, /*nb_inplace_divide*/
2166 0, /*nb_inplace_remainder*/
2167 0, /*nb_inplace_power*/
2168 0, /*nb_inplace_lshift*/
2169 0, /*nb_inplace_rshift*/
2170 0, /*nb_inplace_and*/
2171 0, /*nb_inplace_xor*/
2172 0, /*nb_inplace_or*/
2173 delta_divide
, /* nb_floor_divide */
2174 0, /* nb_true_divide */
2175 0, /* nb_inplace_floor_divide */
2176 0, /* nb_inplace_true_divide */
2179 static PyTypeObject PyDateTime_DeltaType
= {
2180 PyVarObject_HEAD_INIT(NULL
, 0)
2181 "datetime.timedelta", /* tp_name */
2182 sizeof(PyDateTime_Delta
), /* tp_basicsize */
2183 0, /* tp_itemsize */
2189 (reprfunc
)delta_repr
, /* tp_repr */
2190 &delta_as_number
, /* tp_as_number */
2191 0, /* tp_as_sequence */
2192 0, /* tp_as_mapping */
2193 (hashfunc
)delta_hash
, /* tp_hash */
2195 (reprfunc
)delta_str
, /* tp_str */
2196 PyObject_GenericGetAttr
, /* tp_getattro */
2197 0, /* tp_setattro */
2198 0, /* tp_as_buffer */
2199 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
2200 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2201 delta_doc
, /* tp_doc */
2202 0, /* tp_traverse */
2204 (richcmpfunc
)delta_richcompare
, /* tp_richcompare */
2205 0, /* tp_weaklistoffset */
2207 0, /* tp_iternext */
2208 delta_methods
, /* tp_methods */
2209 delta_members
, /* tp_members */
2213 0, /* tp_descr_get */
2214 0, /* tp_descr_set */
2215 0, /* tp_dictoffset */
2218 delta_new
, /* tp_new */
2223 * PyDateTime_Date implementation.
2226 /* Accessor properties. */
2229 date_year(PyDateTime_Date
*self
, void *unused
)
2231 return PyInt_FromLong(GET_YEAR(self
));
2235 date_month(PyDateTime_Date
*self
, void *unused
)
2237 return PyInt_FromLong(GET_MONTH(self
));
2241 date_day(PyDateTime_Date
*self
, void *unused
)
2243 return PyInt_FromLong(GET_DAY(self
));
2246 static PyGetSetDef date_getset
[] = {
2247 {"year", (getter
)date_year
},
2248 {"month", (getter
)date_month
},
2249 {"day", (getter
)date_day
},
2255 static char *date_kws
[] = {"year", "month", "day", NULL
};
2258 date_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
2260 PyObject
*self
= NULL
;
2266 /* Check for invocation from pickle with __getstate__ state */
2267 if (PyTuple_GET_SIZE(args
) == 1 &&
2268 PyString_Check(state
= PyTuple_GET_ITEM(args
, 0)) &&
2269 PyString_GET_SIZE(state
) == _PyDateTime_DATE_DATASIZE
&&
2270 MONTH_IS_SANE(PyString_AS_STRING(state
)[2]))
2272 PyDateTime_Date
*me
;
2274 me
= (PyDateTime_Date
*) (type
->tp_alloc(type
, 0));
2276 char *pdata
= PyString_AS_STRING(state
);
2277 memcpy(me
->data
, pdata
, _PyDateTime_DATE_DATASIZE
);
2280 return (PyObject
*)me
;
2283 if (PyArg_ParseTupleAndKeywords(args
, kw
, "iii", date_kws
,
2284 &year
, &month
, &day
)) {
2285 if (check_date_args(year
, month
, day
) < 0)
2287 self
= new_date_ex(year
, month
, day
, type
);
2292 /* Return new date from localtime(t). */
2294 date_local_from_time_t(PyObject
*cls
, double ts
)
2298 PyObject
*result
= NULL
;
2300 t
= _PyTime_DoubleToTimet(ts
);
2301 if (t
== (time_t)-1 && PyErr_Occurred())
2305 result
= PyObject_CallFunction(cls
, "iii",
2310 PyErr_SetString(PyExc_ValueError
,
2311 "timestamp out of range for "
2312 "platform localtime() function");
2316 /* Return new date from current time.
2317 * We say this is equivalent to fromtimestamp(time.time()), and the
2318 * only way to be sure of that is to *call* time.time(). That's not
2319 * generally the same as calling C's time.
2322 date_today(PyObject
*cls
, PyObject
*dummy
)
2331 /* Note well: today() is a class method, so this may not call
2332 * date.fromtimestamp. For example, it may call
2333 * datetime.fromtimestamp. That's why we need all the accuracy
2334 * time.time() delivers; if someone were gonzo about optimization,
2335 * date.today() could get away with plain C time().
2337 result
= PyObject_CallMethod(cls
, "fromtimestamp", "O", time
);
2342 /* Return new date from given timestamp (Python timestamp -- a double). */
2344 date_fromtimestamp(PyObject
*cls
, PyObject
*args
)
2347 PyObject
*result
= NULL
;
2349 if (PyArg_ParseTuple(args
, "d:fromtimestamp", ×tamp
))
2350 result
= date_local_from_time_t(cls
, timestamp
);
2354 /* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2355 * the ordinal is out of range.
2358 date_fromordinal(PyObject
*cls
, PyObject
*args
)
2360 PyObject
*result
= NULL
;
2363 if (PyArg_ParseTuple(args
, "i:fromordinal", &ordinal
)) {
2369 PyErr_SetString(PyExc_ValueError
, "ordinal must be "
2372 ord_to_ymd(ordinal
, &year
, &month
, &day
);
2373 result
= PyObject_CallFunction(cls
, "iii",
2384 /* date + timedelta -> date. If arg negate is true, subtract the timedelta
2388 add_date_timedelta(PyDateTime_Date
*date
, PyDateTime_Delta
*delta
, int negate
)
2390 PyObject
*result
= NULL
;
2391 int year
= GET_YEAR(date
);
2392 int month
= GET_MONTH(date
);
2393 int deltadays
= GET_TD_DAYS(delta
);
2394 /* C-level overflow is impossible because |deltadays| < 1e9. */
2395 int day
= GET_DAY(date
) + (negate
? -deltadays
: deltadays
);
2397 if (normalize_date(&year
, &month
, &day
) >= 0)
2398 result
= new_date(year
, month
, day
);
2403 date_add(PyObject
*left
, PyObject
*right
)
2405 if (PyDateTime_Check(left
) || PyDateTime_Check(right
)) {
2406 Py_INCREF(Py_NotImplemented
);
2407 return Py_NotImplemented
;
2409 if (PyDate_Check(left
)) {
2411 if (PyDelta_Check(right
))
2413 return add_date_timedelta((PyDateTime_Date
*) left
,
2414 (PyDateTime_Delta
*) right
,
2419 * 'right' must be one of us, or we wouldn't have been called
2421 if (PyDelta_Check(left
))
2423 return add_date_timedelta((PyDateTime_Date
*) right
,
2424 (PyDateTime_Delta
*) left
,
2427 Py_INCREF(Py_NotImplemented
);
2428 return Py_NotImplemented
;
2432 date_subtract(PyObject
*left
, PyObject
*right
)
2434 if (PyDateTime_Check(left
) || PyDateTime_Check(right
)) {
2435 Py_INCREF(Py_NotImplemented
);
2436 return Py_NotImplemented
;
2438 if (PyDate_Check(left
)) {
2439 if (PyDate_Check(right
)) {
2441 int left_ord
= ymd_to_ord(GET_YEAR(left
),
2444 int right_ord
= ymd_to_ord(GET_YEAR(right
),
2447 return new_delta(left_ord
- right_ord
, 0, 0, 0);
2449 if (PyDelta_Check(right
)) {
2451 return add_date_timedelta((PyDateTime_Date
*) left
,
2452 (PyDateTime_Delta
*) right
,
2456 Py_INCREF(Py_NotImplemented
);
2457 return Py_NotImplemented
;
2461 /* Various ways to turn a date into a string. */
2464 date_repr(PyDateTime_Date
*self
)
2467 const char *type_name
;
2469 type_name
= Py_TYPE(self
)->tp_name
;
2470 PyOS_snprintf(buffer
, sizeof(buffer
), "%s(%d, %d, %d)",
2472 GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
));
2474 return PyString_FromString(buffer
);
2478 date_isoformat(PyDateTime_Date
*self
)
2482 isoformat_date(self
, buffer
, sizeof(buffer
));
2483 return PyString_FromString(buffer
);
2486 /* str() calls the appropriate isoformat() method. */
2488 date_str(PyDateTime_Date
*self
)
2490 return PyObject_CallMethod((PyObject
*)self
, "isoformat", "()");
2495 date_ctime(PyDateTime_Date
*self
)
2497 return format_ctime(self
, 0, 0, 0);
2501 date_strftime(PyDateTime_Date
*self
, PyObject
*args
, PyObject
*kw
)
2503 /* This method can be inherited, and needs to call the
2504 * timetuple() method appropriate to self's class.
2509 Py_ssize_t format_len
;
2510 static char *keywords
[] = {"format", NULL
};
2512 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "s#:strftime", keywords
,
2513 &format
, &format_len
))
2516 tuple
= PyObject_CallMethod((PyObject
*)self
, "timetuple", "()");
2519 result
= wrap_strftime((PyObject
*)self
, format
, format_len
, tuple
,
2526 date_format(PyDateTime_Date
*self
, PyObject
*args
)
2530 if (!PyArg_ParseTuple(args
, "O:__format__", &format
))
2533 /* Check for str or unicode */
2534 if (PyString_Check(format
)) {
2535 /* If format is zero length, return str(self) */
2536 if (PyString_GET_SIZE(format
) == 0)
2537 return PyObject_Str((PyObject
*)self
);
2538 } else if (PyUnicode_Check(format
)) {
2539 /* If format is zero length, return str(self) */
2540 if (PyUnicode_GET_SIZE(format
) == 0)
2541 return PyObject_Unicode((PyObject
*)self
);
2543 PyErr_Format(PyExc_ValueError
,
2544 "__format__ expects str or unicode, not %.200s",
2545 Py_TYPE(format
)->tp_name
);
2548 return PyObject_CallMethod((PyObject
*)self
, "strftime", "O", format
);
2554 date_isoweekday(PyDateTime_Date
*self
)
2556 int dow
= weekday(GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
));
2558 return PyInt_FromLong(dow
+ 1);
2562 date_isocalendar(PyDateTime_Date
*self
)
2564 int year
= GET_YEAR(self
);
2565 int week1_monday
= iso_week1_monday(year
);
2566 int today
= ymd_to_ord(year
, GET_MONTH(self
), GET_DAY(self
));
2570 week
= divmod(today
- week1_monday
, 7, &day
);
2573 week1_monday
= iso_week1_monday(year
);
2574 week
= divmod(today
- week1_monday
, 7, &day
);
2576 else if (week
>= 52 && today
>= iso_week1_monday(year
+ 1)) {
2580 return Py_BuildValue("iii", year
, week
+ 1, day
+ 1);
2583 /* Miscellaneous methods. */
2585 /* This is more natural as a tp_compare, but doesn't work then: for whatever
2586 * reason, Python's try_3way_compare ignores tp_compare unless
2587 * PyInstance_Check returns true, but these aren't old-style classes.
2590 date_richcompare(PyDateTime_Date
*self
, PyObject
*other
, int op
)
2592 int diff
= 42; /* nonsense */
2594 if (PyDate_Check(other
))
2595 diff
= memcmp(self
->data
, ((PyDateTime_Date
*)other
)->data
,
2596 _PyDateTime_DATE_DATASIZE
);
2598 else if (PyObject_HasAttrString(other
, "timetuple")) {
2599 /* A hook for other kinds of date objects. */
2600 Py_INCREF(Py_NotImplemented
);
2601 return Py_NotImplemented
;
2603 else if (op
== Py_EQ
|| op
== Py_NE
)
2604 diff
= 1; /* any non-zero value will do */
2606 else /* stop this from falling back to address comparison */
2607 return cmperror((PyObject
*)self
, other
);
2609 return diff_to_bool(diff
, op
);
2613 date_timetuple(PyDateTime_Date
*self
)
2615 return build_struct_time(GET_YEAR(self
),
2622 date_replace(PyDateTime_Date
*self
, PyObject
*args
, PyObject
*kw
)
2626 int year
= GET_YEAR(self
);
2627 int month
= GET_MONTH(self
);
2628 int day
= GET_DAY(self
);
2630 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "|iii:replace", date_kws
,
2631 &year
, &month
, &day
))
2633 tuple
= Py_BuildValue("iii", year
, month
, day
);
2636 clone
= date_new(Py_TYPE(self
), tuple
, NULL
);
2641 static PyObject
*date_getstate(PyDateTime_Date
*self
);
2644 date_hash(PyDateTime_Date
*self
)
2646 if (self
->hashcode
== -1) {
2647 PyObject
*temp
= date_getstate(self
);
2649 self
->hashcode
= PyObject_Hash(temp
);
2653 return self
->hashcode
;
2657 date_toordinal(PyDateTime_Date
*self
)
2659 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self
), GET_MONTH(self
),
2664 date_weekday(PyDateTime_Date
*self
)
2666 int dow
= weekday(GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
));
2668 return PyInt_FromLong(dow
);
2671 /* Pickle support, a simple use of __reduce__. */
2673 /* __getstate__ isn't exposed */
2675 date_getstate(PyDateTime_Date
*self
)
2677 return Py_BuildValue(
2679 PyString_FromStringAndSize((char *)self
->data
,
2680 _PyDateTime_DATE_DATASIZE
));
2684 date_reduce(PyDateTime_Date
*self
, PyObject
*arg
)
2686 return Py_BuildValue("(ON)", Py_TYPE(self
), date_getstate(self
));
2689 static PyMethodDef date_methods
[] = {
2691 /* Class methods: */
2693 {"fromtimestamp", (PyCFunction
)date_fromtimestamp
, METH_VARARGS
|
2695 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2698 {"fromordinal", (PyCFunction
)date_fromordinal
, METH_VARARGS
|
2700 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2703 {"today", (PyCFunction
)date_today
, METH_NOARGS
| METH_CLASS
,
2704 PyDoc_STR("Current date or datetime: same as "
2705 "self.__class__.fromtimestamp(time.time()).")},
2707 /* Instance methods: */
2709 {"ctime", (PyCFunction
)date_ctime
, METH_NOARGS
,
2710 PyDoc_STR("Return ctime() style string.")},
2712 {"strftime", (PyCFunction
)date_strftime
, METH_VARARGS
| METH_KEYWORDS
,
2713 PyDoc_STR("format -> strftime() style string.")},
2715 {"__format__", (PyCFunction
)date_format
, METH_VARARGS
,
2716 PyDoc_STR("Formats self with strftime.")},
2718 {"timetuple", (PyCFunction
)date_timetuple
, METH_NOARGS
,
2719 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2721 {"isocalendar", (PyCFunction
)date_isocalendar
, METH_NOARGS
,
2722 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2725 {"isoformat", (PyCFunction
)date_isoformat
, METH_NOARGS
,
2726 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2728 {"isoweekday", (PyCFunction
)date_isoweekday
, METH_NOARGS
,
2729 PyDoc_STR("Return the day of the week represented by the date.\n"
2730 "Monday == 1 ... Sunday == 7")},
2732 {"toordinal", (PyCFunction
)date_toordinal
, METH_NOARGS
,
2733 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2736 {"weekday", (PyCFunction
)date_weekday
, METH_NOARGS
,
2737 PyDoc_STR("Return the day of the week represented by the date.\n"
2738 "Monday == 0 ... Sunday == 6")},
2740 {"replace", (PyCFunction
)date_replace
, METH_VARARGS
| METH_KEYWORDS
,
2741 PyDoc_STR("Return date with new specified fields.")},
2743 {"__reduce__", (PyCFunction
)date_reduce
, METH_NOARGS
,
2744 PyDoc_STR("__reduce__() -> (cls, state)")},
2749 static char date_doc
[] =
2750 PyDoc_STR("date(year, month, day) --> date object");
2752 static PyNumberMethods date_as_number
= {
2753 date_add
, /* nb_add */
2754 date_subtract
, /* nb_subtract */
2755 0, /* nb_multiply */
2757 0, /* nb_remainder */
2760 0, /* nb_negative */
2761 0, /* nb_positive */
2762 0, /* nb_absolute */
2766 static PyTypeObject PyDateTime_DateType
= {
2767 PyVarObject_HEAD_INIT(NULL
, 0)
2768 "datetime.date", /* tp_name */
2769 sizeof(PyDateTime_Date
), /* tp_basicsize */
2770 0, /* tp_itemsize */
2776 (reprfunc
)date_repr
, /* tp_repr */
2777 &date_as_number
, /* tp_as_number */
2778 0, /* tp_as_sequence */
2779 0, /* tp_as_mapping */
2780 (hashfunc
)date_hash
, /* tp_hash */
2782 (reprfunc
)date_str
, /* tp_str */
2783 PyObject_GenericGetAttr
, /* tp_getattro */
2784 0, /* tp_setattro */
2785 0, /* tp_as_buffer */
2786 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
2787 Py_TPFLAGS_BASETYPE
, /* tp_flags */
2788 date_doc
, /* tp_doc */
2789 0, /* tp_traverse */
2791 (richcmpfunc
)date_richcompare
, /* tp_richcompare */
2792 0, /* tp_weaklistoffset */
2794 0, /* tp_iternext */
2795 date_methods
, /* tp_methods */
2797 date_getset
, /* tp_getset */
2800 0, /* tp_descr_get */
2801 0, /* tp_descr_set */
2802 0, /* tp_dictoffset */
2805 date_new
, /* tp_new */
2810 * PyDateTime_TZInfo implementation.
2813 /* This is a pure abstract base class, so doesn't do anything beyond
2814 * raising NotImplemented exceptions. Real tzinfo classes need
2815 * to derive from this. This is mostly for clarity, and for efficiency in
2816 * datetime and time constructors (their tzinfo arguments need to
2817 * be subclasses of this tzinfo class, which is easy and quick to check).
2819 * Note: For reasons having to do with pickling of subclasses, we have
2820 * to allow tzinfo objects to be instantiated. This wasn't an issue
2821 * in the Python implementation (__init__() could raise NotImplementedError
2822 * there without ill effect), but doing so in the C implementation hit a
2827 tzinfo_nogo(const char* methodname
)
2829 PyErr_Format(PyExc_NotImplementedError
,
2830 "a tzinfo subclass must implement %s()",
2835 /* Methods. A subclass must implement these. */
2838 tzinfo_tzname(PyDateTime_TZInfo
*self
, PyObject
*dt
)
2840 return tzinfo_nogo("tzname");
2844 tzinfo_utcoffset(PyDateTime_TZInfo
*self
, PyObject
*dt
)
2846 return tzinfo_nogo("utcoffset");
2850 tzinfo_dst(PyDateTime_TZInfo
*self
, PyObject
*dt
)
2852 return tzinfo_nogo("dst");
2856 tzinfo_fromutc(PyDateTime_TZInfo
*self
, PyDateTime_DateTime
*dt
)
2858 int y
, m
, d
, hh
, mm
, ss
, us
;
2865 if (! PyDateTime_Check(dt
)) {
2866 PyErr_SetString(PyExc_TypeError
,
2867 "fromutc: argument must be a datetime");
2870 if (! HASTZINFO(dt
) || dt
->tzinfo
!= (PyObject
*)self
) {
2871 PyErr_SetString(PyExc_ValueError
, "fromutc: dt.tzinfo "
2876 off
= call_utcoffset(dt
->tzinfo
, (PyObject
*)dt
, &none
);
2877 if (off
== -1 && PyErr_Occurred())
2880 PyErr_SetString(PyExc_ValueError
, "fromutc: non-None "
2881 "utcoffset() result required");
2885 dst
= call_dst(dt
->tzinfo
, (PyObject
*)dt
, &none
);
2886 if (dst
== -1 && PyErr_Occurred())
2889 PyErr_SetString(PyExc_ValueError
, "fromutc: non-None "
2890 "dst() result required");
2897 hh
= DATE_GET_HOUR(dt
);
2898 mm
= DATE_GET_MINUTE(dt
);
2899 ss
= DATE_GET_SECOND(dt
);
2900 us
= DATE_GET_MICROSECOND(dt
);
2904 if ((mm
< 0 || mm
>= 60) &&
2905 normalize_datetime(&y
, &m
, &d
, &hh
, &mm
, &ss
, &us
) < 0)
2907 result
= new_datetime(y
, m
, d
, hh
, mm
, ss
, us
, dt
->tzinfo
);
2911 dst
= call_dst(dt
->tzinfo
, result
, &none
);
2912 if (dst
== -1 && PyErr_Occurred())
2920 if ((mm
< 0 || mm
>= 60) &&
2921 normalize_datetime(&y
, &m
, &d
, &hh
, &mm
, &ss
, &us
) < 0)
2924 result
= new_datetime(y
, m
, d
, hh
, mm
, ss
, us
, dt
->tzinfo
);
2928 PyErr_SetString(PyExc_ValueError
, "fromutc: tz.dst() gave"
2929 "inconsistent results; cannot convert");
2931 /* fall thru to failure */
2938 * Pickle support. This is solely so that tzinfo subclasses can use
2939 * pickling -- tzinfo itself is supposed to be uninstantiable.
2943 tzinfo_reduce(PyObject
*self
)
2945 PyObject
*args
, *state
, *tmp
;
2946 PyObject
*getinitargs
, *getstate
;
2948 tmp
= PyTuple_New(0);
2952 getinitargs
= PyObject_GetAttrString(self
, "__getinitargs__");
2953 if (getinitargs
!= NULL
) {
2954 args
= PyObject_CallObject(getinitargs
, tmp
);
2955 Py_DECREF(getinitargs
);
2967 getstate
= PyObject_GetAttrString(self
, "__getstate__");
2968 if (getstate
!= NULL
) {
2969 state
= PyObject_CallObject(getstate
, tmp
);
2970 Py_DECREF(getstate
);
2971 if (state
== NULL
) {
2981 dictptr
= _PyObject_GetDictPtr(self
);
2982 if (dictptr
&& *dictptr
&& PyDict_Size(*dictptr
))
2989 if (state
== Py_None
) {
2991 return Py_BuildValue("(ON)", Py_TYPE(self
), args
);
2994 return Py_BuildValue("(ONN)", Py_TYPE(self
), args
, state
);
2997 static PyMethodDef tzinfo_methods
[] = {
2999 {"tzname", (PyCFunction
)tzinfo_tzname
, METH_O
,
3000 PyDoc_STR("datetime -> string name of time zone.")},
3002 {"utcoffset", (PyCFunction
)tzinfo_utcoffset
, METH_O
,
3003 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3006 {"dst", (PyCFunction
)tzinfo_dst
, METH_O
,
3007 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3009 {"fromutc", (PyCFunction
)tzinfo_fromutc
, METH_O
,
3010 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3012 {"__reduce__", (PyCFunction
)tzinfo_reduce
, METH_NOARGS
,
3013 PyDoc_STR("-> (cls, state)")},
3018 static char tzinfo_doc
[] =
3019 PyDoc_STR("Abstract base class for time zone info objects.");
3021 statichere PyTypeObject PyDateTime_TZInfoType
= {
3022 PyObject_HEAD_INIT(NULL
)
3024 "datetime.tzinfo", /* tp_name */
3025 sizeof(PyDateTime_TZInfo
), /* tp_basicsize */
3026 0, /* tp_itemsize */
3033 0, /* tp_as_number */
3034 0, /* tp_as_sequence */
3035 0, /* tp_as_mapping */
3039 PyObject_GenericGetAttr
, /* tp_getattro */
3040 0, /* tp_setattro */
3041 0, /* tp_as_buffer */
3042 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
3043 Py_TPFLAGS_BASETYPE
, /* tp_flags */
3044 tzinfo_doc
, /* tp_doc */
3045 0, /* tp_traverse */
3047 0, /* tp_richcompare */
3048 0, /* tp_weaklistoffset */
3050 0, /* tp_iternext */
3051 tzinfo_methods
, /* tp_methods */
3056 0, /* tp_descr_get */
3057 0, /* tp_descr_set */
3058 0, /* tp_dictoffset */
3061 PyType_GenericNew
, /* tp_new */
3066 * PyDateTime_Time implementation.
3069 /* Accessor properties.
3073 time_hour(PyDateTime_Time
*self
, void *unused
)
3075 return PyInt_FromLong(TIME_GET_HOUR(self
));
3079 time_minute(PyDateTime_Time
*self
, void *unused
)
3081 return PyInt_FromLong(TIME_GET_MINUTE(self
));
3084 /* The name time_second conflicted with some platform header file. */
3086 py_time_second(PyDateTime_Time
*self
, void *unused
)
3088 return PyInt_FromLong(TIME_GET_SECOND(self
));
3092 time_microsecond(PyDateTime_Time
*self
, void *unused
)
3094 return PyInt_FromLong(TIME_GET_MICROSECOND(self
));
3098 time_tzinfo(PyDateTime_Time
*self
, void *unused
)
3100 PyObject
*result
= HASTZINFO(self
) ? self
->tzinfo
: Py_None
;
3105 static PyGetSetDef time_getset
[] = {
3106 {"hour", (getter
)time_hour
},
3107 {"minute", (getter
)time_minute
},
3108 {"second", (getter
)py_time_second
},
3109 {"microsecond", (getter
)time_microsecond
},
3110 {"tzinfo", (getter
)time_tzinfo
},
3118 static char *time_kws
[] = {"hour", "minute", "second", "microsecond",
3122 time_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
3124 PyObject
*self
= NULL
;
3130 PyObject
*tzinfo
= Py_None
;
3132 /* Check for invocation from pickle with __getstate__ state */
3133 if (PyTuple_GET_SIZE(args
) >= 1 &&
3134 PyTuple_GET_SIZE(args
) <= 2 &&
3135 PyString_Check(state
= PyTuple_GET_ITEM(args
, 0)) &&
3136 PyString_GET_SIZE(state
) == _PyDateTime_TIME_DATASIZE
&&
3137 ((unsigned char) (PyString_AS_STRING(state
)[0])) < 24)
3139 PyDateTime_Time
*me
;
3142 if (PyTuple_GET_SIZE(args
) == 2) {
3143 tzinfo
= PyTuple_GET_ITEM(args
, 1);
3144 if (check_tzinfo_subclass(tzinfo
) < 0) {
3145 PyErr_SetString(PyExc_TypeError
, "bad "
3146 "tzinfo state arg");
3150 aware
= (char)(tzinfo
!= Py_None
);
3151 me
= (PyDateTime_Time
*) (type
->tp_alloc(type
, aware
));
3153 char *pdata
= PyString_AS_STRING(state
);
3155 memcpy(me
->data
, pdata
, _PyDateTime_TIME_DATASIZE
);
3157 me
->hastzinfo
= aware
;
3160 me
->tzinfo
= tzinfo
;
3163 return (PyObject
*)me
;
3166 if (PyArg_ParseTupleAndKeywords(args
, kw
, "|iiiiO", time_kws
,
3167 &hour
, &minute
, &second
, &usecond
,
3169 if (check_time_args(hour
, minute
, second
, usecond
) < 0)
3171 if (check_tzinfo_subclass(tzinfo
) < 0)
3173 self
= new_time_ex(hour
, minute
, second
, usecond
, tzinfo
,
3184 time_dealloc(PyDateTime_Time
*self
)
3186 if (HASTZINFO(self
)) {
3187 Py_XDECREF(self
->tzinfo
);
3189 Py_TYPE(self
)->tp_free((PyObject
*)self
);
3193 * Indirect access to tzinfo methods.
3196 /* These are all METH_NOARGS, so don't need to check the arglist. */
3198 time_utcoffset(PyDateTime_Time
*self
, PyObject
*unused
) {
3199 return offset_as_timedelta(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
3200 "utcoffset", Py_None
);
3204 time_dst(PyDateTime_Time
*self
, PyObject
*unused
) {
3205 return offset_as_timedelta(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
3210 time_tzname(PyDateTime_Time
*self
, PyObject
*unused
) {
3211 return call_tzname(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
3216 * Various ways to turn a time into a string.
3220 time_repr(PyDateTime_Time
*self
)
3223 const char *type_name
= Py_TYPE(self
)->tp_name
;
3224 int h
= TIME_GET_HOUR(self
);
3225 int m
= TIME_GET_MINUTE(self
);
3226 int s
= TIME_GET_SECOND(self
);
3227 int us
= TIME_GET_MICROSECOND(self
);
3228 PyObject
*result
= NULL
;
3231 PyOS_snprintf(buffer
, sizeof(buffer
),
3232 "%s(%d, %d, %d, %d)", type_name
, h
, m
, s
, us
);
3234 PyOS_snprintf(buffer
, sizeof(buffer
),
3235 "%s(%d, %d, %d)", type_name
, h
, m
, s
);
3237 PyOS_snprintf(buffer
, sizeof(buffer
),
3238 "%s(%d, %d)", type_name
, h
, m
);
3239 result
= PyString_FromString(buffer
);
3240 if (result
!= NULL
&& HASTZINFO(self
))
3241 result
= append_keyword_tzinfo(result
, self
->tzinfo
);
3246 time_str(PyDateTime_Time
*self
)
3248 return PyObject_CallMethod((PyObject
*)self
, "isoformat", "()");
3252 time_isoformat(PyDateTime_Time
*self
, PyObject
*unused
)
3256 /* Reuse the time format code from the datetime type. */
3257 PyDateTime_DateTime datetime
;
3258 PyDateTime_DateTime
*pdatetime
= &datetime
;
3260 /* Copy over just the time bytes. */
3261 memcpy(pdatetime
->data
+ _PyDateTime_DATE_DATASIZE
,
3263 _PyDateTime_TIME_DATASIZE
);
3265 isoformat_time(pdatetime
, buf
, sizeof(buf
));
3266 result
= PyString_FromString(buf
);
3267 if (result
== NULL
|| ! HASTZINFO(self
) || self
->tzinfo
== Py_None
)
3270 /* We need to append the UTC offset. */
3271 if (format_utcoffset(buf
, sizeof(buf
), ":", self
->tzinfo
,
3276 PyString_ConcatAndDel(&result
, PyString_FromString(buf
));
3281 time_strftime(PyDateTime_Time
*self
, PyObject
*args
, PyObject
*kw
)
3286 Py_ssize_t format_len
;
3287 static char *keywords
[] = {"format", NULL
};
3289 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "s#:strftime", keywords
,
3290 &format
, &format_len
))
3293 /* Python's strftime does insane things with the year part of the
3294 * timetuple. The year is forced to (the otherwise nonsensical)
3295 * 1900 to worm around that.
3297 tuple
= Py_BuildValue("iiiiiiiii",
3298 1900, 1, 1, /* year, month, day */
3299 TIME_GET_HOUR(self
),
3300 TIME_GET_MINUTE(self
),
3301 TIME_GET_SECOND(self
),
3302 0, 1, -1); /* weekday, daynum, dst */
3305 assert(PyTuple_Size(tuple
) == 9);
3306 result
= wrap_strftime((PyObject
*)self
, format
, format_len
, tuple
,
3313 * Miscellaneous methods.
3316 /* This is more natural as a tp_compare, but doesn't work then: for whatever
3317 * reason, Python's try_3way_compare ignores tp_compare unless
3318 * PyInstance_Check returns true, but these aren't old-style classes.
3321 time_richcompare(PyDateTime_Time
*self
, PyObject
*other
, int op
)
3325 int offset1
, offset2
;
3327 if (! PyTime_Check(other
)) {
3328 if (op
== Py_EQ
|| op
== Py_NE
) {
3329 PyObject
*result
= op
== Py_EQ
? Py_False
: Py_True
;
3333 /* Stop this from falling back to address comparison. */
3334 return cmperror((PyObject
*)self
, other
);
3336 if (classify_two_utcoffsets((PyObject
*)self
, &offset1
, &n1
, Py_None
,
3337 other
, &offset2
, &n2
, Py_None
) < 0)
3339 assert(n1
!= OFFSET_UNKNOWN
&& n2
!= OFFSET_UNKNOWN
);
3340 /* If they're both naive, or both aware and have the same offsets,
3341 * we get off cheap. Note that if they're both naive, offset1 ==
3342 * offset2 == 0 at this point.
3344 if (n1
== n2
&& offset1
== offset2
) {
3345 diff
= memcmp(self
->data
, ((PyDateTime_Time
*)other
)->data
,
3346 _PyDateTime_TIME_DATASIZE
);
3347 return diff_to_bool(diff
, op
);
3350 if (n1
== OFFSET_AWARE
&& n2
== OFFSET_AWARE
) {
3351 assert(offset1
!= offset2
); /* else last "if" handled it */
3352 /* Convert everything except microseconds to seconds. These
3353 * can't overflow (no more than the # of seconds in 2 days).
3355 offset1
= TIME_GET_HOUR(self
) * 3600 +
3356 (TIME_GET_MINUTE(self
) - offset1
) * 60 +
3357 TIME_GET_SECOND(self
);
3358 offset2
= TIME_GET_HOUR(other
) * 3600 +
3359 (TIME_GET_MINUTE(other
) - offset2
) * 60 +
3360 TIME_GET_SECOND(other
);
3361 diff
= offset1
- offset2
;
3363 diff
= TIME_GET_MICROSECOND(self
) -
3364 TIME_GET_MICROSECOND(other
);
3365 return diff_to_bool(diff
, op
);
3369 PyErr_SetString(PyExc_TypeError
,
3370 "can't compare offset-naive and "
3371 "offset-aware times");
3376 time_hash(PyDateTime_Time
*self
)
3378 if (self
->hashcode
== -1) {
3383 n
= classify_utcoffset((PyObject
*)self
, Py_None
, &offset
);
3384 assert(n
!= OFFSET_UNKNOWN
);
3385 if (n
== OFFSET_ERROR
)
3388 /* Reduce this to a hash of another object. */
3390 temp
= PyString_FromStringAndSize((char *)self
->data
,
3391 _PyDateTime_TIME_DATASIZE
);
3396 assert(n
== OFFSET_AWARE
);
3397 assert(HASTZINFO(self
));
3398 hour
= divmod(TIME_GET_HOUR(self
) * 60 +
3399 TIME_GET_MINUTE(self
) - offset
,
3402 if (0 <= hour
&& hour
< 24)
3403 temp
= new_time(hour
, minute
,
3404 TIME_GET_SECOND(self
),
3405 TIME_GET_MICROSECOND(self
),
3408 temp
= Py_BuildValue("iiii",
3410 TIME_GET_SECOND(self
),
3411 TIME_GET_MICROSECOND(self
));
3414 self
->hashcode
= PyObject_Hash(temp
);
3418 return self
->hashcode
;
3422 time_replace(PyDateTime_Time
*self
, PyObject
*args
, PyObject
*kw
)
3426 int hh
= TIME_GET_HOUR(self
);
3427 int mm
= TIME_GET_MINUTE(self
);
3428 int ss
= TIME_GET_SECOND(self
);
3429 int us
= TIME_GET_MICROSECOND(self
);
3430 PyObject
*tzinfo
= HASTZINFO(self
) ? self
->tzinfo
: Py_None
;
3432 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "|iiiiO:replace",
3434 &hh
, &mm
, &ss
, &us
, &tzinfo
))
3436 tuple
= Py_BuildValue("iiiiO", hh
, mm
, ss
, us
, tzinfo
);
3439 clone
= time_new(Py_TYPE(self
), tuple
, NULL
);
3445 time_nonzero(PyDateTime_Time
*self
)
3450 if (TIME_GET_SECOND(self
) || TIME_GET_MICROSECOND(self
)) {
3451 /* Since utcoffset is in whole minutes, nothing can
3452 * alter the conclusion that this is nonzero.
3457 if (HASTZINFO(self
) && self
->tzinfo
!= Py_None
) {
3458 offset
= call_utcoffset(self
->tzinfo
, Py_None
, &none
);
3459 if (offset
== -1 && PyErr_Occurred())
3462 return (TIME_GET_MINUTE(self
) - offset
+ TIME_GET_HOUR(self
)*60) != 0;
3465 /* Pickle support, a simple use of __reduce__. */
3467 /* Let basestate be the non-tzinfo data string.
3468 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3469 * So it's a tuple in any (non-error) case.
3470 * __getstate__ isn't exposed.
3473 time_getstate(PyDateTime_Time
*self
)
3475 PyObject
*basestate
;
3476 PyObject
*result
= NULL
;
3478 basestate
= PyString_FromStringAndSize((char *)self
->data
,
3479 _PyDateTime_TIME_DATASIZE
);
3480 if (basestate
!= NULL
) {
3481 if (! HASTZINFO(self
) || self
->tzinfo
== Py_None
)
3482 result
= PyTuple_Pack(1, basestate
);
3484 result
= PyTuple_Pack(2, basestate
, self
->tzinfo
);
3485 Py_DECREF(basestate
);
3491 time_reduce(PyDateTime_Time
*self
, PyObject
*arg
)
3493 return Py_BuildValue("(ON)", Py_TYPE(self
), time_getstate(self
));
3496 static PyMethodDef time_methods
[] = {
3498 {"isoformat", (PyCFunction
)time_isoformat
, METH_NOARGS
,
3499 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3502 {"strftime", (PyCFunction
)time_strftime
, METH_VARARGS
| METH_KEYWORDS
,
3503 PyDoc_STR("format -> strftime() style string.")},
3505 {"__format__", (PyCFunction
)date_format
, METH_VARARGS
,
3506 PyDoc_STR("Formats self with strftime.")},
3508 {"utcoffset", (PyCFunction
)time_utcoffset
, METH_NOARGS
,
3509 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3511 {"tzname", (PyCFunction
)time_tzname
, METH_NOARGS
,
3512 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3514 {"dst", (PyCFunction
)time_dst
, METH_NOARGS
,
3515 PyDoc_STR("Return self.tzinfo.dst(self).")},
3517 {"replace", (PyCFunction
)time_replace
, METH_VARARGS
| METH_KEYWORDS
,
3518 PyDoc_STR("Return time with new specified fields.")},
3520 {"__reduce__", (PyCFunction
)time_reduce
, METH_NOARGS
,
3521 PyDoc_STR("__reduce__() -> (cls, state)")},
3526 static char time_doc
[] =
3527 PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3529 All arguments are optional. tzinfo may be None, or an instance of\n\
3530 a tzinfo subclass. The remaining arguments may be ints or longs.\n");
3532 static PyNumberMethods time_as_number
= {
3534 0, /* nb_subtract */
3535 0, /* nb_multiply */
3537 0, /* nb_remainder */
3540 0, /* nb_negative */
3541 0, /* nb_positive */
3542 0, /* nb_absolute */
3543 (inquiry
)time_nonzero
, /* nb_nonzero */
3546 statichere PyTypeObject PyDateTime_TimeType
= {
3547 PyObject_HEAD_INIT(NULL
)
3549 "datetime.time", /* tp_name */
3550 sizeof(PyDateTime_Time
), /* tp_basicsize */
3551 0, /* tp_itemsize */
3552 (destructor
)time_dealloc
, /* tp_dealloc */
3557 (reprfunc
)time_repr
, /* tp_repr */
3558 &time_as_number
, /* tp_as_number */
3559 0, /* tp_as_sequence */
3560 0, /* tp_as_mapping */
3561 (hashfunc
)time_hash
, /* tp_hash */
3563 (reprfunc
)time_str
, /* tp_str */
3564 PyObject_GenericGetAttr
, /* tp_getattro */
3565 0, /* tp_setattro */
3566 0, /* tp_as_buffer */
3567 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
3568 Py_TPFLAGS_BASETYPE
, /* tp_flags */
3569 time_doc
, /* tp_doc */
3570 0, /* tp_traverse */
3572 (richcmpfunc
)time_richcompare
, /* tp_richcompare */
3573 0, /* tp_weaklistoffset */
3575 0, /* tp_iternext */
3576 time_methods
, /* tp_methods */
3578 time_getset
, /* tp_getset */
3581 0, /* tp_descr_get */
3582 0, /* tp_descr_set */
3583 0, /* tp_dictoffset */
3585 time_alloc
, /* tp_alloc */
3586 time_new
, /* tp_new */
3591 * PyDateTime_DateTime implementation.
3594 /* Accessor properties. Properties for day, month, and year are inherited
3599 datetime_hour(PyDateTime_DateTime
*self
, void *unused
)
3601 return PyInt_FromLong(DATE_GET_HOUR(self
));
3605 datetime_minute(PyDateTime_DateTime
*self
, void *unused
)
3607 return PyInt_FromLong(DATE_GET_MINUTE(self
));
3611 datetime_second(PyDateTime_DateTime
*self
, void *unused
)
3613 return PyInt_FromLong(DATE_GET_SECOND(self
));
3617 datetime_microsecond(PyDateTime_DateTime
*self
, void *unused
)
3619 return PyInt_FromLong(DATE_GET_MICROSECOND(self
));
3623 datetime_tzinfo(PyDateTime_DateTime
*self
, void *unused
)
3625 PyObject
*result
= HASTZINFO(self
) ? self
->tzinfo
: Py_None
;
3630 static PyGetSetDef datetime_getset
[] = {
3631 {"hour", (getter
)datetime_hour
},
3632 {"minute", (getter
)datetime_minute
},
3633 {"second", (getter
)datetime_second
},
3634 {"microsecond", (getter
)datetime_microsecond
},
3635 {"tzinfo", (getter
)datetime_tzinfo
},
3643 static char *datetime_kws
[] = {
3644 "year", "month", "day", "hour", "minute", "second",
3645 "microsecond", "tzinfo", NULL
3649 datetime_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kw
)
3651 PyObject
*self
= NULL
;
3660 PyObject
*tzinfo
= Py_None
;
3662 /* Check for invocation from pickle with __getstate__ state */
3663 if (PyTuple_GET_SIZE(args
) >= 1 &&
3664 PyTuple_GET_SIZE(args
) <= 2 &&
3665 PyString_Check(state
= PyTuple_GET_ITEM(args
, 0)) &&
3666 PyString_GET_SIZE(state
) == _PyDateTime_DATETIME_DATASIZE
&&
3667 MONTH_IS_SANE(PyString_AS_STRING(state
)[2]))
3669 PyDateTime_DateTime
*me
;
3672 if (PyTuple_GET_SIZE(args
) == 2) {
3673 tzinfo
= PyTuple_GET_ITEM(args
, 1);
3674 if (check_tzinfo_subclass(tzinfo
) < 0) {
3675 PyErr_SetString(PyExc_TypeError
, "bad "
3676 "tzinfo state arg");
3680 aware
= (char)(tzinfo
!= Py_None
);
3681 me
= (PyDateTime_DateTime
*) (type
->tp_alloc(type
, aware
));
3683 char *pdata
= PyString_AS_STRING(state
);
3685 memcpy(me
->data
, pdata
, _PyDateTime_DATETIME_DATASIZE
);
3687 me
->hastzinfo
= aware
;
3690 me
->tzinfo
= tzinfo
;
3693 return (PyObject
*)me
;
3696 if (PyArg_ParseTupleAndKeywords(args
, kw
, "iii|iiiiO", datetime_kws
,
3697 &year
, &month
, &day
, &hour
, &minute
,
3698 &second
, &usecond
, &tzinfo
)) {
3699 if (check_date_args(year
, month
, day
) < 0)
3701 if (check_time_args(hour
, minute
, second
, usecond
) < 0)
3703 if (check_tzinfo_subclass(tzinfo
) < 0)
3705 self
= new_datetime_ex(year
, month
, day
,
3706 hour
, minute
, second
, usecond
,
3712 /* TM_FUNC is the shared type of localtime() and gmtime(). */
3713 typedef struct tm
*(*TM_FUNC
)(const time_t *timer
);
3716 * Build datetime from a time_t and a distinct count of microseconds.
3717 * Pass localtime or gmtime for f, to control the interpretation of timet.
3720 datetime_from_timet_and_us(PyObject
*cls
, TM_FUNC f
, time_t timet
, int us
,
3724 PyObject
*result
= NULL
;
3728 /* The platform localtime/gmtime may insert leap seconds,
3729 * indicated by tm->tm_sec > 59. We don't care about them,
3730 * except to the extent that passing them on to the datetime
3731 * constructor would raise ValueError for a reason that
3732 * made no sense to the user.
3734 if (tm
->tm_sec
> 59)
3736 result
= PyObject_CallFunction(cls
, "iiiiiiiO",
3747 PyErr_SetString(PyExc_ValueError
,
3748 "timestamp out of range for "
3749 "platform localtime()/gmtime() function");
3754 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3755 * to control the interpretation of the timestamp. Since a double doesn't
3756 * have enough bits to cover a datetime's full range of precision, it's
3757 * better to call datetime_from_timet_and_us provided you have a way
3758 * to get that much precision (e.g., C time() isn't good enough).
3761 datetime_from_timestamp(PyObject
*cls
, TM_FUNC f
, double timestamp
,
3768 timet
= _PyTime_DoubleToTimet(timestamp
);
3769 if (timet
== (time_t)-1 && PyErr_Occurred())
3771 fraction
= timestamp
- (double)timet
;
3772 us
= (int)round_to_long(fraction
* 1e6
);
3774 /* Truncation towards zero is not what we wanted
3775 for negative numbers (Python's mod semantics) */
3779 /* If timestamp is less than one microsecond smaller than a
3780 * full second, round up. Otherwise, ValueErrors are raised
3781 * for some floats. */
3782 if (us
== 1000000) {
3786 return datetime_from_timet_and_us(cls
, f
, timet
, us
, tzinfo
);
3790 * Build most accurate possible datetime for current time. Pass localtime or
3791 * gmtime for f as appropriate.
3794 datetime_best_possible(PyObject
*cls
, TM_FUNC f
, PyObject
*tzinfo
)
3796 #ifdef HAVE_GETTIMEOFDAY
3799 #ifdef GETTIMEOFDAY_NO_TZ
3802 gettimeofday(&t
, (struct timezone
*)NULL
);
3804 return datetime_from_timet_and_us(cls
, f
, t
.tv_sec
, (int)t
.tv_usec
,
3807 #else /* ! HAVE_GETTIMEOFDAY */
3808 /* No flavor of gettimeofday exists on this platform. Python's
3809 * time.time() does a lot of other platform tricks to get the
3810 * best time it can on the platform, and we're not going to do
3811 * better than that (if we could, the better code would belong
3812 * in time.time()!) We're limited by the precision of a double,
3821 dtime
= PyFloat_AsDouble(time
);
3823 if (dtime
== -1.0 && PyErr_Occurred())
3825 return datetime_from_timestamp(cls
, f
, dtime
, tzinfo
);
3826 #endif /* ! HAVE_GETTIMEOFDAY */
3829 /* Return best possible local time -- this isn't constrained by the
3830 * precision of a timestamp.
3833 datetime_now(PyObject
*cls
, PyObject
*args
, PyObject
*kw
)
3836 PyObject
*tzinfo
= Py_None
;
3837 static char *keywords
[] = {"tz", NULL
};
3839 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "|O:now", keywords
,
3842 if (check_tzinfo_subclass(tzinfo
) < 0)
3845 self
= datetime_best_possible(cls
,
3846 tzinfo
== Py_None
? localtime
: gmtime
,
3848 if (self
!= NULL
&& tzinfo
!= Py_None
) {
3849 /* Convert UTC to tzinfo's zone. */
3850 PyObject
*temp
= self
;
3851 self
= PyObject_CallMethod(tzinfo
, "fromutc", "O", self
);
3857 /* Return best possible UTC time -- this isn't constrained by the
3858 * precision of a timestamp.
3861 datetime_utcnow(PyObject
*cls
, PyObject
*dummy
)
3863 return datetime_best_possible(cls
, gmtime
, Py_None
);
3866 /* Return new local datetime from timestamp (Python timestamp -- a double). */
3868 datetime_fromtimestamp(PyObject
*cls
, PyObject
*args
, PyObject
*kw
)
3872 PyObject
*tzinfo
= Py_None
;
3873 static char *keywords
[] = {"timestamp", "tz", NULL
};
3875 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "d|O:fromtimestamp",
3876 keywords
, ×tamp
, &tzinfo
))
3878 if (check_tzinfo_subclass(tzinfo
) < 0)
3881 self
= datetime_from_timestamp(cls
,
3882 tzinfo
== Py_None
? localtime
: gmtime
,
3885 if (self
!= NULL
&& tzinfo
!= Py_None
) {
3886 /* Convert UTC to tzinfo's zone. */
3887 PyObject
*temp
= self
;
3888 self
= PyObject_CallMethod(tzinfo
, "fromutc", "O", self
);
3894 /* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3896 datetime_utcfromtimestamp(PyObject
*cls
, PyObject
*args
)
3899 PyObject
*result
= NULL
;
3901 if (PyArg_ParseTuple(args
, "d:utcfromtimestamp", ×tamp
))
3902 result
= datetime_from_timestamp(cls
, gmtime
, timestamp
,
3907 /* Return new datetime from time.strptime(). */
3909 datetime_strptime(PyObject
*cls
, PyObject
*args
)
3911 static PyObject
*module
= NULL
;
3912 PyObject
*result
= NULL
, *obj
, *st
= NULL
, *frac
= NULL
;
3913 const char *string
, *format
;
3915 if (!PyArg_ParseTuple(args
, "ss:strptime", &string
, &format
))
3918 if (module
== NULL
&&
3919 (module
= PyImport_ImportModuleNoBlock("_strptime")) == NULL
)
3922 /* _strptime._strptime returns a two-element tuple. The first
3923 element is a time.struct_time object. The second is the
3924 microseconds (which are not defined for time.struct_time). */
3925 obj
= PyObject_CallMethod(module
, "_strptime", "ss", string
, format
);
3927 int i
, good_timetuple
= 1;
3929 if (PySequence_Check(obj
) && PySequence_Size(obj
) == 2) {
3930 st
= PySequence_GetItem(obj
, 0);
3931 frac
= PySequence_GetItem(obj
, 1);
3932 if (st
== NULL
|| frac
== NULL
)
3934 /* copy y/m/d/h/m/s values out of the
3936 if (good_timetuple
&&
3937 PySequence_Check(st
) &&
3938 PySequence_Size(st
) >= 6) {
3939 for (i
=0; i
< 6; i
++) {
3940 PyObject
*p
= PySequence_GetItem(st
, i
);
3946 ia
[i
] = PyInt_AsLong(p
);
3954 /* follow that up with a little dose of microseconds */
3955 if (PyInt_Check(frac
))
3956 ia
[6] = PyInt_AsLong(frac
);
3963 result
= PyObject_CallFunction(cls
, "iiiiiii",
3964 ia
[0], ia
[1], ia
[2],
3965 ia
[3], ia
[4], ia
[5],
3968 PyErr_SetString(PyExc_ValueError
,
3969 "unexpected value from _strptime._strptime");
3977 /* Return new datetime from date/datetime and time arguments. */
3979 datetime_combine(PyObject
*cls
, PyObject
*args
, PyObject
*kw
)
3981 static char *keywords
[] = {"date", "time", NULL
};
3984 PyObject
*result
= NULL
;
3986 if (PyArg_ParseTupleAndKeywords(args
, kw
, "O!O!:combine", keywords
,
3987 &PyDateTime_DateType
, &date
,
3988 &PyDateTime_TimeType
, &time
)) {
3989 PyObject
*tzinfo
= Py_None
;
3991 if (HASTZINFO(time
))
3992 tzinfo
= ((PyDateTime_Time
*)time
)->tzinfo
;
3993 result
= PyObject_CallFunction(cls
, "iiiiiiiO",
3997 TIME_GET_HOUR(time
),
3998 TIME_GET_MINUTE(time
),
3999 TIME_GET_SECOND(time
),
4000 TIME_GET_MICROSECOND(time
),
4011 datetime_dealloc(PyDateTime_DateTime
*self
)
4013 if (HASTZINFO(self
)) {
4014 Py_XDECREF(self
->tzinfo
);
4016 Py_TYPE(self
)->tp_free((PyObject
*)self
);
4020 * Indirect access to tzinfo methods.
4023 /* These are all METH_NOARGS, so don't need to check the arglist. */
4025 datetime_utcoffset(PyDateTime_DateTime
*self
, PyObject
*unused
) {
4026 return offset_as_timedelta(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
4027 "utcoffset", (PyObject
*)self
);
4031 datetime_dst(PyDateTime_DateTime
*self
, PyObject
*unused
) {
4032 return offset_as_timedelta(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
4033 "dst", (PyObject
*)self
);
4037 datetime_tzname(PyDateTime_DateTime
*self
, PyObject
*unused
) {
4038 return call_tzname(HASTZINFO(self
) ? self
->tzinfo
: Py_None
,
4043 * datetime arithmetic.
4046 /* factor must be 1 (to add) or -1 (to subtract). The result inherits
4047 * the tzinfo state of date.
4050 add_datetime_timedelta(PyDateTime_DateTime
*date
, PyDateTime_Delta
*delta
,
4053 /* Note that the C-level additions can't overflow, because of
4054 * invariant bounds on the member values.
4056 int year
= GET_YEAR(date
);
4057 int month
= GET_MONTH(date
);
4058 int day
= GET_DAY(date
) + GET_TD_DAYS(delta
) * factor
;
4059 int hour
= DATE_GET_HOUR(date
);
4060 int minute
= DATE_GET_MINUTE(date
);
4061 int second
= DATE_GET_SECOND(date
) + GET_TD_SECONDS(delta
) * factor
;
4062 int microsecond
= DATE_GET_MICROSECOND(date
) +
4063 GET_TD_MICROSECONDS(delta
) * factor
;
4065 assert(factor
== 1 || factor
== -1);
4066 if (normalize_datetime(&year
, &month
, &day
,
4067 &hour
, &minute
, &second
, µsecond
) < 0)
4070 return new_datetime(year
, month
, day
,
4071 hour
, minute
, second
, microsecond
,
4072 HASTZINFO(date
) ? date
->tzinfo
: Py_None
);
4076 datetime_add(PyObject
*left
, PyObject
*right
)
4078 if (PyDateTime_Check(left
)) {
4079 /* datetime + ??? */
4080 if (PyDelta_Check(right
))
4081 /* datetime + delta */
4082 return add_datetime_timedelta(
4083 (PyDateTime_DateTime
*)left
,
4084 (PyDateTime_Delta
*)right
,
4087 else if (PyDelta_Check(left
)) {
4088 /* delta + datetime */
4089 return add_datetime_timedelta((PyDateTime_DateTime
*) right
,
4090 (PyDateTime_Delta
*) left
,
4093 Py_INCREF(Py_NotImplemented
);
4094 return Py_NotImplemented
;
4098 datetime_subtract(PyObject
*left
, PyObject
*right
)
4100 PyObject
*result
= Py_NotImplemented
;
4102 if (PyDateTime_Check(left
)) {
4103 /* datetime - ??? */
4104 if (PyDateTime_Check(right
)) {
4105 /* datetime - datetime */
4107 int offset1
, offset2
;
4108 int delta_d
, delta_s
, delta_us
;
4110 if (classify_two_utcoffsets(left
, &offset1
, &n1
, left
,
4111 right
, &offset2
, &n2
,
4114 assert(n1
!= OFFSET_UNKNOWN
&& n2
!= OFFSET_UNKNOWN
);
4116 PyErr_SetString(PyExc_TypeError
,
4117 "can't subtract offset-naive and "
4118 "offset-aware datetimes");
4121 delta_d
= ymd_to_ord(GET_YEAR(left
),
4124 ymd_to_ord(GET_YEAR(right
),
4127 /* These can't overflow, since the values are
4128 * normalized. At most this gives the number of
4129 * seconds in one day.
4131 delta_s
= (DATE_GET_HOUR(left
) -
4132 DATE_GET_HOUR(right
)) * 3600 +
4133 (DATE_GET_MINUTE(left
) -
4134 DATE_GET_MINUTE(right
)) * 60 +
4135 (DATE_GET_SECOND(left
) -
4136 DATE_GET_SECOND(right
));
4137 delta_us
= DATE_GET_MICROSECOND(left
) -
4138 DATE_GET_MICROSECOND(right
);
4139 /* (left - offset1) - (right - offset2) =
4140 * (left - right) + (offset2 - offset1)
4142 delta_s
+= (offset2
- offset1
) * 60;
4143 result
= new_delta(delta_d
, delta_s
, delta_us
, 1);
4145 else if (PyDelta_Check(right
)) {
4146 /* datetime - delta */
4147 result
= add_datetime_timedelta(
4148 (PyDateTime_DateTime
*)left
,
4149 (PyDateTime_Delta
*)right
,
4154 if (result
== Py_NotImplemented
)
4159 /* Various ways to turn a datetime into a string. */
4162 datetime_repr(PyDateTime_DateTime
*self
)
4165 const char *type_name
= Py_TYPE(self
)->tp_name
;
4168 if (DATE_GET_MICROSECOND(self
)) {
4169 PyOS_snprintf(buffer
, sizeof(buffer
),
4170 "%s(%d, %d, %d, %d, %d, %d, %d)",
4172 GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
),
4173 DATE_GET_HOUR(self
), DATE_GET_MINUTE(self
),
4174 DATE_GET_SECOND(self
),
4175 DATE_GET_MICROSECOND(self
));
4177 else if (DATE_GET_SECOND(self
)) {
4178 PyOS_snprintf(buffer
, sizeof(buffer
),
4179 "%s(%d, %d, %d, %d, %d, %d)",
4181 GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
),
4182 DATE_GET_HOUR(self
), DATE_GET_MINUTE(self
),
4183 DATE_GET_SECOND(self
));
4186 PyOS_snprintf(buffer
, sizeof(buffer
),
4187 "%s(%d, %d, %d, %d, %d)",
4189 GET_YEAR(self
), GET_MONTH(self
), GET_DAY(self
),
4190 DATE_GET_HOUR(self
), DATE_GET_MINUTE(self
));
4192 baserepr
= PyString_FromString(buffer
);
4193 if (baserepr
== NULL
|| ! HASTZINFO(self
))
4195 return append_keyword_tzinfo(baserepr
, self
->tzinfo
);
4199 datetime_str(PyDateTime_DateTime
*self
)
4201 return PyObject_CallMethod((PyObject
*)self
, "isoformat", "(s)", " ");
4205 datetime_isoformat(PyDateTime_DateTime
*self
, PyObject
*args
, PyObject
*kw
)
4208 static char *keywords
[] = {"sep", NULL
};
4213 if (!PyArg_ParseTupleAndKeywords(args
, kw
, "|c:isoformat", keywords
,
4216 cp
= isoformat_date((PyDateTime_Date
*)self
, buffer
, sizeof(buffer
));
4219 cp
= isoformat_time(self
, cp
, sizeof(buffer
) - (cp
- buffer
));
4220 result
= PyString_FromStringAndSize(buffer
, cp
- buffer
);
4221 if (result
== NULL
|| ! HASTZINFO(self
))
4224 /* We need to append the UTC offset. */
4225 if (format_utcoffset(buffer
, sizeof(buffer
), ":", self
->tzinfo
,
4226 (PyObject
*)self
) < 0) {
4230 PyString_ConcatAndDel(&result
, PyString_FromString(buffer
));
4235 datetime_ctime(PyDateTime_DateTime
*self
)
4237 return format_ctime((PyDateTime_Date
*)self
,
4238 DATE_GET_HOUR(self
),
4239 DATE_GET_MINUTE(self
),
4240 DATE_GET_SECOND(self
));
4243 /* Miscellaneous methods. */
4245 /* This is more natural as a tp_compare, but doesn't work then: for whatever
4246 * reason, Python's try_3way_compare ignores tp_compare unless
4247 * PyInstance_Check returns true, but these aren't old-style classes.
4250 datetime_richcompare(PyDateTime_DateTime
*self
, PyObject
*other
, int op
)
4254 int offset1
, offset2
;
4256 if (! PyDateTime_Check(other
)) {
4257 /* If other has a "timetuple" attr, that's an advertised
4258 * hook for other classes to ask to get comparison control.
4259 * However, date instances have a timetuple attr, and we
4260 * don't want to allow that comparison. Because datetime
4261 * is a subclass of date, when mixing date and datetime
4262 * in a comparison, Python gives datetime the first shot
4263 * (it's the more specific subtype). So we can stop that
4264 * combination here reliably.
4266 if (PyObject_HasAttrString(other
, "timetuple") &&
4267 ! PyDate_Check(other
)) {
4268 /* A hook for other kinds of datetime objects. */
4269 Py_INCREF(Py_NotImplemented
);
4270 return Py_NotImplemented
;
4272 if (op
== Py_EQ
|| op
== Py_NE
) {
4273 PyObject
*result
= op
== Py_EQ
? Py_False
: Py_True
;
4277 /* Stop this from falling back to address comparison. */
4278 return cmperror((PyObject
*)self
, other
);
4281 if (classify_two_utcoffsets((PyObject
*)self
, &offset1
, &n1
,
4283 other
, &offset2
, &n2
,
4286 assert(n1
!= OFFSET_UNKNOWN
&& n2
!= OFFSET_UNKNOWN
);
4287 /* If they're both naive, or both aware and have the same offsets,
4288 * we get off cheap. Note that if they're both naive, offset1 ==
4289 * offset2 == 0 at this point.
4291 if (n1
== n2
&& offset1
== offset2
) {
4292 diff
= memcmp(self
->data
, ((PyDateTime_DateTime
*)other
)->data
,
4293 _PyDateTime_DATETIME_DATASIZE
);
4294 return diff_to_bool(diff
, op
);
4297 if (n1
== OFFSET_AWARE
&& n2
== OFFSET_AWARE
) {
4298 PyDateTime_Delta
*delta
;
4300 assert(offset1
!= offset2
); /* else last "if" handled it */
4301 delta
= (PyDateTime_Delta
*)datetime_subtract((PyObject
*)self
,
4305 diff
= GET_TD_DAYS(delta
);
4307 diff
= GET_TD_SECONDS(delta
) |
4308 GET_TD_MICROSECONDS(delta
);
4310 return diff_to_bool(diff
, op
);
4314 PyErr_SetString(PyExc_TypeError
,
4315 "can't compare offset-naive and "
4316 "offset-aware datetimes");
4321 datetime_hash(PyDateTime_DateTime
*self
)
4323 if (self
->hashcode
== -1) {
4328 n
= classify_utcoffset((PyObject
*)self
, (PyObject
*)self
,
4330 assert(n
!= OFFSET_UNKNOWN
);
4331 if (n
== OFFSET_ERROR
)
4334 /* Reduce this to a hash of another object. */
4335 if (n
== OFFSET_NAIVE
)
4336 temp
= PyString_FromStringAndSize(
4338 _PyDateTime_DATETIME_DATASIZE
);
4343 assert(n
== OFFSET_AWARE
);
4344 assert(HASTZINFO(self
));
4345 days
= ymd_to_ord(GET_YEAR(self
),
4348 seconds
= DATE_GET_HOUR(self
) * 3600 +
4349 (DATE_GET_MINUTE(self
) - offset
) * 60 +
4350 DATE_GET_SECOND(self
);
4351 temp
= new_delta(days
,
4353 DATE_GET_MICROSECOND(self
),
4357 self
->hashcode
= PyObject_Hash(temp
);
4361 return self
->hashcode
;
4365 datetime_replace(PyDateTime_DateTime
*self
, PyObject
*args
, PyObject
*kw
)
4369 int y
= GET_YEAR(self
);
4370 int m
= GET_MONTH(self
);
4371 int d
= GET_DAY(self
);
4372 int hh
= DATE_GET_HOUR(self
);
4373 int mm
= DATE_GET_MINUTE(self
);
4374 int ss
= DATE_GET_SECOND(self
);
4375 int us
= DATE_GET_MICROSECOND(self
);
4376 PyObject
*tzinfo
= HASTZINFO(self
) ? self
->tzinfo
: Py_None
;
4378 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "|iiiiiiiO:replace",
4380 &y
, &m
, &d
, &hh
, &mm
, &ss
, &us
,
4383 tuple
= Py_BuildValue("iiiiiiiO", y
, m
, d
, hh
, mm
, ss
, us
, tzinfo
);
4386 clone
= datetime_new(Py_TYPE(self
), tuple
, NULL
);
4392 datetime_astimezone(PyDateTime_DateTime
*self
, PyObject
*args
, PyObject
*kw
)
4394 int y
, m
, d
, hh
, mm
, ss
, us
;
4399 static char *keywords
[] = {"tz", NULL
};
4401 if (! PyArg_ParseTupleAndKeywords(args
, kw
, "O!:astimezone", keywords
,
4402 &PyDateTime_TZInfoType
, &tzinfo
))
4405 if (!HASTZINFO(self
) || self
->tzinfo
== Py_None
)
4408 /* Conversion to self's own time zone is a NOP. */
4409 if (self
->tzinfo
== tzinfo
) {
4411 return (PyObject
*)self
;
4414 /* Convert self to UTC. */
4415 offset
= call_utcoffset(self
->tzinfo
, (PyObject
*)self
, &none
);
4416 if (offset
== -1 && PyErr_Occurred())
4422 m
= GET_MONTH(self
);
4424 hh
= DATE_GET_HOUR(self
);
4425 mm
= DATE_GET_MINUTE(self
);
4426 ss
= DATE_GET_SECOND(self
);
4427 us
= DATE_GET_MICROSECOND(self
);
4430 if ((mm
< 0 || mm
>= 60) &&
4431 normalize_datetime(&y
, &m
, &d
, &hh
, &mm
, &ss
, &us
) < 0)
4434 /* Attach new tzinfo and let fromutc() do the rest. */
4435 result
= new_datetime(y
, m
, d
, hh
, mm
, ss
, us
, tzinfo
);
4436 if (result
!= NULL
) {
4437 PyObject
*temp
= result
;
4439 result
= PyObject_CallMethod(tzinfo
, "fromutc", "O", temp
);
4445 PyErr_SetString(PyExc_ValueError
, "astimezone() cannot be applied to "
4446 "a naive datetime");
4451 datetime_timetuple(PyDateTime_DateTime
*self
)
4455 if (HASTZINFO(self
) && self
->tzinfo
!= Py_None
) {
4458 dstflag
= call_dst(self
->tzinfo
, (PyObject
*)self
, &none
);
4459 if (dstflag
== -1 && PyErr_Occurred())
4464 else if (dstflag
!= 0)
4468 return build_struct_time(GET_YEAR(self
),
4471 DATE_GET_HOUR(self
),
4472 DATE_GET_MINUTE(self
),
4473 DATE_GET_SECOND(self
),
4478 datetime_getdate(PyDateTime_DateTime
*self
)
4480 return new_date(GET_YEAR(self
),
4486 datetime_gettime(PyDateTime_DateTime
*self
)
4488 return new_time(DATE_GET_HOUR(self
),
4489 DATE_GET_MINUTE(self
),
4490 DATE_GET_SECOND(self
),
4491 DATE_GET_MICROSECOND(self
),
4496 datetime_gettimetz(PyDateTime_DateTime
*self
)
4498 return new_time(DATE_GET_HOUR(self
),
4499 DATE_GET_MINUTE(self
),
4500 DATE_GET_SECOND(self
),
4501 DATE_GET_MICROSECOND(self
),
4502 HASTZINFO(self
) ? self
->tzinfo
: Py_None
);
4506 datetime_utctimetuple(PyDateTime_DateTime
*self
)
4508 int y
= GET_YEAR(self
);
4509 int m
= GET_MONTH(self
);
4510 int d
= GET_DAY(self
);
4511 int hh
= DATE_GET_HOUR(self
);
4512 int mm
= DATE_GET_MINUTE(self
);
4513 int ss
= DATE_GET_SECOND(self
);
4514 int us
= 0; /* microseconds are ignored in a timetuple */
4517 if (HASTZINFO(self
) && self
->tzinfo
!= Py_None
) {
4520 offset
= call_utcoffset(self
->tzinfo
, (PyObject
*)self
, &none
);
4521 if (offset
== -1 && PyErr_Occurred())
4524 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4525 * 0 in a UTC timetuple regardless of what dst() says.
4528 /* Subtract offset minutes & normalize. */
4532 stat
= normalize_datetime(&y
, &m
, &d
, &hh
, &mm
, &ss
, &us
);
4534 /* At the edges, it's possible we overflowed
4535 * beyond MINYEAR or MAXYEAR.
4537 if (PyErr_ExceptionMatches(PyExc_OverflowError
))
4543 return build_struct_time(y
, m
, d
, hh
, mm
, ss
, 0);
4546 /* Pickle support, a simple use of __reduce__. */
4548 /* Let basestate be the non-tzinfo data string.
4549 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4550 * So it's a tuple in any (non-error) case.
4551 * __getstate__ isn't exposed.
4554 datetime_getstate(PyDateTime_DateTime
*self
)
4556 PyObject
*basestate
;
4557 PyObject
*result
= NULL
;
4559 basestate
= PyString_FromStringAndSize((char *)self
->data
,
4560 _PyDateTime_DATETIME_DATASIZE
);
4561 if (basestate
!= NULL
) {
4562 if (! HASTZINFO(self
) || self
->tzinfo
== Py_None
)
4563 result
= PyTuple_Pack(1, basestate
);
4565 result
= PyTuple_Pack(2, basestate
, self
->tzinfo
);
4566 Py_DECREF(basestate
);
4572 datetime_reduce(PyDateTime_DateTime
*self
, PyObject
*arg
)
4574 return Py_BuildValue("(ON)", Py_TYPE(self
), datetime_getstate(self
));
4577 static PyMethodDef datetime_methods
[] = {
4579 /* Class methods: */
4581 {"now", (PyCFunction
)datetime_now
,
4582 METH_VARARGS
| METH_KEYWORDS
| METH_CLASS
,
4583 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4585 {"utcnow", (PyCFunction
)datetime_utcnow
,
4586 METH_NOARGS
| METH_CLASS
,
4587 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4589 {"fromtimestamp", (PyCFunction
)datetime_fromtimestamp
,
4590 METH_VARARGS
| METH_KEYWORDS
| METH_CLASS
,
4591 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4593 {"utcfromtimestamp", (PyCFunction
)datetime_utcfromtimestamp
,
4594 METH_VARARGS
| METH_CLASS
,
4595 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4596 "(like time.time()).")},
4598 {"strptime", (PyCFunction
)datetime_strptime
,
4599 METH_VARARGS
| METH_CLASS
,
4600 PyDoc_STR("string, format -> new datetime parsed from a string "
4601 "(like time.strptime()).")},
4603 {"combine", (PyCFunction
)datetime_combine
,
4604 METH_VARARGS
| METH_KEYWORDS
| METH_CLASS
,
4605 PyDoc_STR("date, time -> datetime with same date and time fields")},
4607 /* Instance methods: */
4609 {"date", (PyCFunction
)datetime_getdate
, METH_NOARGS
,
4610 PyDoc_STR("Return date object with same year, month and day.")},
4612 {"time", (PyCFunction
)datetime_gettime
, METH_NOARGS
,
4613 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4615 {"timetz", (PyCFunction
)datetime_gettimetz
, METH_NOARGS
,
4616 PyDoc_STR("Return time object with same time and tzinfo.")},
4618 {"ctime", (PyCFunction
)datetime_ctime
, METH_NOARGS
,
4619 PyDoc_STR("Return ctime() style string.")},
4621 {"timetuple", (PyCFunction
)datetime_timetuple
, METH_NOARGS
,
4622 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4624 {"utctimetuple", (PyCFunction
)datetime_utctimetuple
, METH_NOARGS
,
4625 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4627 {"isoformat", (PyCFunction
)datetime_isoformat
, METH_VARARGS
| METH_KEYWORDS
,
4628 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4629 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4630 "sep is used to separate the year from the time, and "
4631 "defaults to 'T'.")},
4633 {"utcoffset", (PyCFunction
)datetime_utcoffset
, METH_NOARGS
,
4634 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4636 {"tzname", (PyCFunction
)datetime_tzname
, METH_NOARGS
,
4637 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4639 {"dst", (PyCFunction
)datetime_dst
, METH_NOARGS
,
4640 PyDoc_STR("Return self.tzinfo.dst(self).")},
4642 {"replace", (PyCFunction
)datetime_replace
, METH_VARARGS
| METH_KEYWORDS
,
4643 PyDoc_STR("Return datetime with new specified fields.")},
4645 {"astimezone", (PyCFunction
)datetime_astimezone
, METH_VARARGS
| METH_KEYWORDS
,
4646 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4648 {"__reduce__", (PyCFunction
)datetime_reduce
, METH_NOARGS
,
4649 PyDoc_STR("__reduce__() -> (cls, state)")},
4654 static char datetime_doc
[] =
4655 PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4657 The year, month and day arguments are required. tzinfo may be None, or an\n\
4658 instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
4660 static PyNumberMethods datetime_as_number
= {
4661 datetime_add
, /* nb_add */
4662 datetime_subtract
, /* nb_subtract */
4663 0, /* nb_multiply */
4665 0, /* nb_remainder */
4668 0, /* nb_negative */
4669 0, /* nb_positive */
4670 0, /* nb_absolute */
4674 statichere PyTypeObject PyDateTime_DateTimeType
= {
4675 PyObject_HEAD_INIT(NULL
)
4677 "datetime.datetime", /* tp_name */
4678 sizeof(PyDateTime_DateTime
), /* tp_basicsize */
4679 0, /* tp_itemsize */
4680 (destructor
)datetime_dealloc
, /* tp_dealloc */
4685 (reprfunc
)datetime_repr
, /* tp_repr */
4686 &datetime_as_number
, /* tp_as_number */
4687 0, /* tp_as_sequence */
4688 0, /* tp_as_mapping */
4689 (hashfunc
)datetime_hash
, /* tp_hash */
4691 (reprfunc
)datetime_str
, /* tp_str */
4692 PyObject_GenericGetAttr
, /* tp_getattro */
4693 0, /* tp_setattro */
4694 0, /* tp_as_buffer */
4695 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
4696 Py_TPFLAGS_BASETYPE
, /* tp_flags */
4697 datetime_doc
, /* tp_doc */
4698 0, /* tp_traverse */
4700 (richcmpfunc
)datetime_richcompare
, /* tp_richcompare */
4701 0, /* tp_weaklistoffset */
4703 0, /* tp_iternext */
4704 datetime_methods
, /* tp_methods */
4706 datetime_getset
, /* tp_getset */
4707 &PyDateTime_DateType
, /* tp_base */
4709 0, /* tp_descr_get */
4710 0, /* tp_descr_set */
4711 0, /* tp_dictoffset */
4713 datetime_alloc
, /* tp_alloc */
4714 datetime_new
, /* tp_new */
4718 /* ---------------------------------------------------------------------------
4719 * Module methods and initialization.
4722 static PyMethodDef module_methods
[] = {
4726 /* C API. Clients get at this via PyDateTime_IMPORT, defined in
4729 static PyDateTime_CAPI CAPI
= {
4730 &PyDateTime_DateType
,
4731 &PyDateTime_DateTimeType
,
4732 &PyDateTime_TimeType
,
4733 &PyDateTime_DeltaType
,
4734 &PyDateTime_TZInfoType
,
4739 datetime_fromtimestamp
,
4747 PyObject
*m
; /* a module object */
4748 PyObject
*d
; /* its dict */
4751 m
= Py_InitModule3("datetime", module_methods
,
4752 "Fast implementation of the datetime type.");
4756 if (PyType_Ready(&PyDateTime_DateType
) < 0)
4758 if (PyType_Ready(&PyDateTime_DateTimeType
) < 0)
4760 if (PyType_Ready(&PyDateTime_DeltaType
) < 0)
4762 if (PyType_Ready(&PyDateTime_TimeType
) < 0)
4764 if (PyType_Ready(&PyDateTime_TZInfoType
) < 0)
4767 /* timedelta values */
4768 d
= PyDateTime_DeltaType
.tp_dict
;
4770 x
= new_delta(0, 0, 1, 0);
4771 if (x
== NULL
|| PyDict_SetItemString(d
, "resolution", x
) < 0)
4775 x
= new_delta(-MAX_DELTA_DAYS
, 0, 0, 0);
4776 if (x
== NULL
|| PyDict_SetItemString(d
, "min", x
) < 0)
4780 x
= new_delta(MAX_DELTA_DAYS
, 24*3600-1, 1000000-1, 0);
4781 if (x
== NULL
|| PyDict_SetItemString(d
, "max", x
) < 0)
4786 d
= PyDateTime_DateType
.tp_dict
;
4788 x
= new_date(1, 1, 1);
4789 if (x
== NULL
|| PyDict_SetItemString(d
, "min", x
) < 0)
4793 x
= new_date(MAXYEAR
, 12, 31);
4794 if (x
== NULL
|| PyDict_SetItemString(d
, "max", x
) < 0)
4798 x
= new_delta(1, 0, 0, 0);
4799 if (x
== NULL
|| PyDict_SetItemString(d
, "resolution", x
) < 0)
4804 d
= PyDateTime_TimeType
.tp_dict
;
4806 x
= new_time(0, 0, 0, 0, Py_None
);
4807 if (x
== NULL
|| PyDict_SetItemString(d
, "min", x
) < 0)
4811 x
= new_time(23, 59, 59, 999999, Py_None
);
4812 if (x
== NULL
|| PyDict_SetItemString(d
, "max", x
) < 0)
4816 x
= new_delta(0, 0, 1, 0);
4817 if (x
== NULL
|| PyDict_SetItemString(d
, "resolution", x
) < 0)
4821 /* datetime values */
4822 d
= PyDateTime_DateTimeType
.tp_dict
;
4824 x
= new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None
);
4825 if (x
== NULL
|| PyDict_SetItemString(d
, "min", x
) < 0)
4829 x
= new_datetime(MAXYEAR
, 12, 31, 23, 59, 59, 999999, Py_None
);
4830 if (x
== NULL
|| PyDict_SetItemString(d
, "max", x
) < 0)
4834 x
= new_delta(0, 0, 1, 0);
4835 if (x
== NULL
|| PyDict_SetItemString(d
, "resolution", x
) < 0)
4839 /* module initialization */
4840 PyModule_AddIntConstant(m
, "MINYEAR", MINYEAR
);
4841 PyModule_AddIntConstant(m
, "MAXYEAR", MAXYEAR
);
4843 Py_INCREF(&PyDateTime_DateType
);
4844 PyModule_AddObject(m
, "date", (PyObject
*) &PyDateTime_DateType
);
4846 Py_INCREF(&PyDateTime_DateTimeType
);
4847 PyModule_AddObject(m
, "datetime",
4848 (PyObject
*)&PyDateTime_DateTimeType
);
4850 Py_INCREF(&PyDateTime_TimeType
);
4851 PyModule_AddObject(m
, "time", (PyObject
*) &PyDateTime_TimeType
);
4853 Py_INCREF(&PyDateTime_DeltaType
);
4854 PyModule_AddObject(m
, "timedelta", (PyObject
*) &PyDateTime_DeltaType
);
4856 Py_INCREF(&PyDateTime_TZInfoType
);
4857 PyModule_AddObject(m
, "tzinfo", (PyObject
*) &PyDateTime_TZInfoType
);
4859 x
= PyCObject_FromVoidPtrAndDesc(&CAPI
, (void*) DATETIME_API_MAGIC
,
4863 PyModule_AddObject(m
, "datetime_CAPI", x
);
4865 /* A 4-year cycle has an extra leap day over what we'd get from
4866 * pasting together 4 single years.
4868 assert(DI4Y
== 4 * 365 + 1);
4869 assert(DI4Y
== days_before_year(4+1));
4871 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4872 * get from pasting together 4 100-year cycles.
4874 assert(DI400Y
== 4 * DI100Y
+ 1);
4875 assert(DI400Y
== days_before_year(400+1));
4877 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4878 * pasting together 25 4-year cycles.
4880 assert(DI100Y
== 25 * DI4Y
- 1);
4881 assert(DI100Y
== days_before_year(100+1));
4883 us_per_us
= PyInt_FromLong(1);
4884 us_per_ms
= PyInt_FromLong(1000);
4885 us_per_second
= PyInt_FromLong(1000000);
4886 us_per_minute
= PyInt_FromLong(60000000);
4887 seconds_per_day
= PyInt_FromLong(24 * 3600);
4888 if (us_per_us
== NULL
|| us_per_ms
== NULL
|| us_per_second
== NULL
||
4889 us_per_minute
== NULL
|| seconds_per_day
== NULL
)
4892 /* The rest are too big for 32-bit ints, but even
4893 * us_per_week fits in 40 bits, so doubles should be exact.
4895 us_per_hour
= PyLong_FromDouble(3600000000.0);
4896 us_per_day
= PyLong_FromDouble(86400000000.0);
4897 us_per_week
= PyLong_FromDouble(604800000000.0);
4898 if (us_per_hour
== NULL
|| us_per_day
== NULL
|| us_per_week
== NULL
)
4902 /* ---------------------------------------------------------------------------
4903 Some time zone algebra. For a datetime x, let
4904 x.n = x stripped of its timezone -- its naive time.
4905 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4907 x.d = x.dst(), and assuming that doesn't raise an exception or
4909 x.s = x's standard offset, x.o - x.d
4911 Now some derived rules, where k is a duration (timedelta).
4914 This follows from the definition of x.s.
4916 2. If x and y have the same tzinfo member, x.s = y.s.
4917 This is actually a requirement, an assumption we need to make about
4918 sane tzinfo classes.
4920 3. The naive UTC time corresponding to x is x.n - x.o.
4921 This is again a requirement for a sane tzinfo class.
4924 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
4926 5. (x+k).n = x.n + k
4927 Again follows from how arithmetic is defined.
4929 Now we can explain tz.fromutc(x). Let's assume it's an interesting case
4930 (meaning that the various tzinfo methods exist, and don't blow up or return
4933 The function wants to return a datetime y with timezone tz, equivalent to x.
4934 x is already in UTC.
4940 The algorithm starts by attaching tz to x.n, and calling that y. So
4941 x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4942 becomes true; in effect, we want to solve [2] for k:
4944 (y+k).n - (y+k).o = x.n [2]
4946 By #1, this is the same as
4948 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
4950 By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4951 Substituting that into [3],
4953 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4954 k - (y+k).s - (y+k).d = 0; rearranging,
4955 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4958 On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4959 approximate k by ignoring the (y+k).d term at first. Note that k can't be
4960 very large, since all offset-returning methods return a duration of magnitude
4961 less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4962 be 0, so ignoring it has no consequence then.
4964 In any case, the new value is
4968 It's helpful to step back at look at [4] from a higher level: it's simply
4969 mapping from UTC to tz's standard time.
4975 we have an equivalent time, and are almost done. The insecurity here is
4976 at the start of daylight time. Picture US Eastern for concreteness. The wall
4977 time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
4978 sense then. The docs ask that an Eastern tzinfo class consider such a time to
4979 be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4980 on the day DST starts. We want to return the 1:MM EST spelling because that's
4981 the only spelling that makes sense on the local wall clock.
4983 In fact, if [5] holds at this point, we do have the standard-time spelling,
4984 but that takes a bit of proof. We first prove a stronger result. What's the
4985 difference between the LHS and RHS of [5]? Let
4987 diff = x.n - (z.n - z.o) [6]
4992 y.n + y.s = since y.n = x.n
4993 x.n + y.s = since z and y are have the same tzinfo member,
4997 Plugging that back into [6] gives
5000 x.n - ((x.n + z.s) - z.o) = expanding
5001 x.n - x.n - z.s + z.o = cancelling
5007 If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
5008 spelling we wanted in the endcase described above. We're done. Contrarily,
5009 if z.d = 0, then we have a UTC equivalent, and are also done.
5011 If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5012 add to z (in effect, z is in tz's standard time, and we need to shift the
5013 local clock into tz's daylight time).
5017 z' = z + z.d = z + diff [7]
5019 and we can again ask whether
5021 z'.n - z'.o = x.n [8]
5023 If so, we're done. If not, the tzinfo class is insane, according to the
5024 assumptions we've made. This also requires a bit of proof. As before, let's
5025 compute the difference between the LHS and RHS of [8] (and skipping some of
5026 the justifications for the kinds of substitutions we've done several times
5029 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5030 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5031 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5032 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5033 - z.n + z.n - z.o + z'.o = cancel z.n
5034 - z.o + z'.o = #1 twice
5035 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5038 So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
5039 we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5040 return z', not bothering to compute z'.d.
5042 How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5043 a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5044 would have to change the result dst() returns: we start in DST, and moving
5045 a little further into it takes us out of DST.
5047 There isn't a sane case where this can happen. The closest it gets is at
5048 the end of DST, where there's an hour in UTC with no spelling in a hybrid
5049 tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5050 that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5051 UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5052 time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5053 clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5054 standard time. Since that's what the local clock *does*, we want to map both
5055 UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
5056 in local time, but so it goes -- it's the way the local clock works.
5058 When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5059 so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5060 z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
5061 (correctly) concludes that z' is not UTC-equivalent to x.
5063 Because we know z.d said z was in daylight time (else [5] would have held and
5064 we would have stopped then), and we know z.d != z'.d (else [8] would have held
5065 and we would have stopped then), and there are only 2 possible values dst() can
5066 return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5067 but the reasoning doesn't depend on the example -- it depends on there being
5068 two possible dst() outcomes, one zero and the other non-zero). Therefore
5069 z' must be in standard time, and is the spelling we want in this case.
5071 Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5072 concerned (because it takes z' as being in standard time rather than the
5073 daylight time we intend here), but returning it gives the real-life "local
5074 clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5077 When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5078 the 1:MM standard time spelling we want.
5080 So how can this break? One of the assumptions must be violated. Two
5083 1) [2] effectively says that y.s is invariant across all y belong to a given
5084 time zone. This isn't true if, for political reasons or continental drift,
5085 a region decides to change its base offset from UTC.
5087 2) There may be versions of "double daylight" time where the tail end of
5088 the analysis gives up a step too early. I haven't thought about that
5091 In any case, it's clear that the default fromutc() is strong enough to handle
5092 "almost all" time zones: so long as the standard offset is invariant, it
5093 doesn't matter if daylight time transition points change from year to year, or
5094 if daylight time is skipped in some years; it doesn't matter how large or
5095 small dst() may get within its bounds; and it doesn't even matter if some
5096 perverse time zone returns a negative dst()). So a breaking case must be
5097 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
5098 --------------------------------------------------------------------------- */