12a799bf77a83adef010ff4751e5195702f159f39Tim Peters/*  C implementation for the date/time type documented at
22a799bf77a83adef010ff4751e5195702f159f39Tim Peters *  http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
32a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
42a799bf77a83adef010ff4751e5195702f159f39Tim Peters
5137d824148f9322c741b16d90ada72fc558b9a1cGregory P. Smith#define PY_SSIZE_T_CLEAN
6137d824148f9322c741b16d90ada72fc558b9a1cGregory P. Smith
72a799bf77a83adef010ff4751e5195702f159f39Tim Peters#include "Python.h"
82a799bf77a83adef010ff4751e5195702f159f39Tim Peters#include "modsupport.h"
92a799bf77a83adef010ff4751e5195702f159f39Tim Peters#include "structmember.h"
102a799bf77a83adef010ff4751e5195702f159f39Tim Peters
112a799bf77a83adef010ff4751e5195702f159f39Tim Peters#include <time.h>
122a799bf77a83adef010ff4751e5195702f159f39Tim Peters
131b6f7a9057874ecd2793059f210de87837fe1911Tim Peters#include "timefuncs.h"
149ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters
159ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters/* Differentiate between building the core module and building extension
169ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters * modules.
179ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters */
187a0da19087bfd5e01bcada885b4d0786749b99cfKristján Valur Jónsson#ifndef Py_BUILD_CORE
199ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters#define Py_BUILD_CORE
207a0da19087bfd5e01bcada885b4d0786749b99cfKristján Valur Jónsson#endif
212a799bf77a83adef010ff4751e5195702f159f39Tim Peters#include "datetime.h"
229ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters#undef Py_BUILD_CORE
232a799bf77a83adef010ff4751e5195702f159f39Tim Peters
242a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* We require that C int be at least 32 bits, and use int virtually
252a799bf77a83adef010ff4751e5195702f159f39Tim Peters * everywhere.  In just a few cases we use a temp long, where a Python
262a799bf77a83adef010ff4751e5195702f159f39Tim Peters * API returns a C long.  In such cases, we have to ensure that the
272a799bf77a83adef010ff4751e5195702f159f39Tim Peters * final result fits in a C int (this can be an issue on 64-bit boxes).
282a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
292a799bf77a83adef010ff4751e5195702f159f39Tim Peters#if SIZEOF_INT < 4
30c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#       error "datetime.c requires that C int have at least 32 bits"
312a799bf77a83adef010ff4751e5195702f159f39Tim Peters#endif
322a799bf77a83adef010ff4751e5195702f159f39Tim Peters
332a799bf77a83adef010ff4751e5195702f159f39Tim Peters#define MINYEAR 1
342a799bf77a83adef010ff4751e5195702f159f39Tim Peters#define MAXYEAR 9999
359292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
362a799bf77a83adef010ff4751e5195702f159f39Tim Peters
372a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Nine decimal digits is easy to communicate, and leaves enough room
382a799bf77a83adef010ff4751e5195702f159f39Tim Peters * so that two delta days can be added w/o fear of overflowing a signed
392a799bf77a83adef010ff4751e5195702f159f39Tim Peters * 32-bit int, and with plenty of room left over to absorb any possible
402a799bf77a83adef010ff4751e5195702f159f39Tim Peters * carries from adding seconds.
412a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
422a799bf77a83adef010ff4751e5195702f159f39Tim Peters#define MAX_DELTA_DAYS 999999999
432a799bf77a83adef010ff4751e5195702f159f39Tim Peters
442a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Rename the long macros in datetime.h to more reasonable short names. */
45c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define GET_YEAR                PyDateTime_GET_YEAR
46c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define GET_MONTH               PyDateTime_GET_MONTH
47c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define GET_DAY                 PyDateTime_GET_DAY
48c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DATE_GET_HOUR           PyDateTime_DATE_GET_HOUR
49c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DATE_GET_MINUTE         PyDateTime_DATE_GET_MINUTE
50c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DATE_GET_SECOND         PyDateTime_DATE_GET_SECOND
51c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DATE_GET_MICROSECOND    PyDateTime_DATE_GET_MICROSECOND
522a799bf77a83adef010ff4751e5195702f159f39Tim Peters
532a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Date accessors for date and datetime. */
54c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define SET_YEAR(o, v)          (((o)->data[0] = ((v) & 0xff00) >> 8), \
55c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 ((o)->data[1] = ((v) & 0x00ff)))
56c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define SET_MONTH(o, v)         (PyDateTime_GET_MONTH(o) = (v))
57c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define SET_DAY(o, v)           (PyDateTime_GET_DAY(o) = (v))
582a799bf77a83adef010ff4751e5195702f159f39Tim Peters
592a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Date/Time accessors for datetime. */
60c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DATE_SET_HOUR(o, v)     (PyDateTime_DATE_GET_HOUR(o) = (v))
61c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DATE_SET_MINUTE(o, v)   (PyDateTime_DATE_GET_MINUTE(o) = (v))
62c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DATE_SET_SECOND(o, v)   (PyDateTime_DATE_GET_SECOND(o) = (v))
63c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DATE_SET_MICROSECOND(o, v)      \
64c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (((o)->data[7] = ((v) & 0xff0000) >> 16), \
65c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
66c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     ((o)->data[9] = ((v) & 0x0000ff)))
672a799bf77a83adef010ff4751e5195702f159f39Tim Peters
682a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Time accessors for time. */
69c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define TIME_GET_HOUR           PyDateTime_TIME_GET_HOUR
70c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define TIME_GET_MINUTE         PyDateTime_TIME_GET_MINUTE
71c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define TIME_GET_SECOND         PyDateTime_TIME_GET_SECOND
72c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define TIME_GET_MICROSECOND    PyDateTime_TIME_GET_MICROSECOND
73c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define TIME_SET_HOUR(o, v)     (PyDateTime_TIME_GET_HOUR(o) = (v))
74c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define TIME_SET_MINUTE(o, v)   (PyDateTime_TIME_GET_MINUTE(o) = (v))
75c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define TIME_SET_SECOND(o, v)   (PyDateTime_TIME_GET_SECOND(o) = (v))
76c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define TIME_SET_MICROSECOND(o, v)      \
77c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (((o)->data[3] = ((v) & 0xff0000) >> 16), \
78c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
79c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     ((o)->data[5] = ((v) & 0x0000ff)))
802a799bf77a83adef010ff4751e5195702f159f39Tim Peters
812a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Delta accessors for timedelta. */
82c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define GET_TD_DAYS(o)          (((PyDateTime_Delta *)(o))->days)
83c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define GET_TD_SECONDS(o)       (((PyDateTime_Delta *)(o))->seconds)
84c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define GET_TD_MICROSECONDS(o)  (((PyDateTime_Delta *)(o))->microseconds)
852a799bf77a83adef010ff4751e5195702f159f39Tim Peters
86c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define SET_TD_DAYS(o, v)       ((o)->days = (v))
87c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define SET_TD_SECONDS(o, v)    ((o)->seconds = (v))
882a799bf77a83adef010ff4751e5195702f159f39Tim Peters#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
892a799bf77a83adef010ff4751e5195702f159f39Tim Peters
90a032d2eb7f547a8850f78f825c00298206f53f69Tim Peters/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
91a032d2eb7f547a8850f78f825c00298206f53f69Tim Peters * p->hastzinfo.
92a032d2eb7f547a8850f78f825c00298206f53f69Tim Peters */
93c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define HASTZINFO(p)            (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
94a032d2eb7f547a8850f78f825c00298206f53f69Tim Peters
953f60629242a13c9d5fb425294a33d22b7cf2b802Tim Peters/* M is a char or int claiming to be a valid month.  The macro is equivalent
963f60629242a13c9d5fb425294a33d22b7cf2b802Tim Peters * to the two-sided Python test
97c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou *      1 <= M <= 12
983f60629242a13c9d5fb425294a33d22b7cf2b802Tim Peters */
993f60629242a13c9d5fb425294a33d22b7cf2b802Tim Peters#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
1003f60629242a13c9d5fb425294a33d22b7cf2b802Tim Peters
1012a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Forward declarations. */
1022a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyTypeObject PyDateTime_DateType;
1032a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyTypeObject PyDateTime_DateTimeType;
1042a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyTypeObject PyDateTime_DeltaType;
1052a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyTypeObject PyDateTime_TimeType;
1062a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyTypeObject PyDateTime_TZInfoType;
1072a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1082a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
1092a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Math utilities.
1102a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
1112a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1122a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* k = i+j overflows iff k differs in sign from both inputs,
1132a799bf77a83adef010ff4751e5195702f159f39Tim Peters * iff k^i has sign bit set and k^j has sign bit set,
1142a799bf77a83adef010ff4751e5195702f159f39Tim Peters * iff (k^i)&(k^j) has sign bit set.
1152a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
1162a799bf77a83adef010ff4751e5195702f159f39Tim Peters#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
117c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
1182a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1192a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Compute Python divmod(x, y), returning the quotient and storing the
1202a799bf77a83adef010ff4751e5195702f159f39Tim Peters * remainder into *r.  The quotient is the floor of x/y, and that's
1212a799bf77a83adef010ff4751e5195702f159f39Tim Peters * the real point of this.  C will probably truncate instead (C99
1222a799bf77a83adef010ff4751e5195702f159f39Tim Peters * requires truncation; C89 left it implementation-defined).
1232a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Simplification:  we *require* that y > 0 here.  That's appropriate
1242a799bf77a83adef010ff4751e5195702f159f39Tim Peters * for all the uses made of it.  This simplifies the code and makes
1252a799bf77a83adef010ff4751e5195702f159f39Tim Peters * the overflow case impossible (divmod(LONG_MIN, -1) is the only
1262a799bf77a83adef010ff4751e5195702f159f39Tim Peters * overflow case).
1272a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
1282a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
1292a799bf77a83adef010ff4751e5195702f159f39Tim Petersdivmod(int x, int y, int *r)
1302a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
131c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int quo;
1322a799bf77a83adef010ff4751e5195702f159f39Tim Peters
133c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(y > 0);
134c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    quo = x / y;
135c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    *r = x - quo * y;
136c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (*r < 0) {
137c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        --quo;
138c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *r += y;
139c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
140c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(0 <= *r && *r < y);
141c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return quo;
1422a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
1432a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1445d644dd25ac3100d0e8bc795ae57a6b8061fefd4Tim Peters/* Round a double to the nearest long.  |x| must be small enough to fit
1455d644dd25ac3100d0e8bc795ae57a6b8061fefd4Tim Peters * in a C long; this is not checked.
1465d644dd25ac3100d0e8bc795ae57a6b8061fefd4Tim Peters */
1475d644dd25ac3100d0e8bc795ae57a6b8061fefd4Tim Petersstatic long
1485d644dd25ac3100d0e8bc795ae57a6b8061fefd4Tim Petersround_to_long(double x)
1495d644dd25ac3100d0e8bc795ae57a6b8061fefd4Tim Peters{
150c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x >= 0.0)
151c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        x = floor(x + 0.5);
152c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
153c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        x = ceil(x - 0.5);
154c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return (long)x;
1555d644dd25ac3100d0e8bc795ae57a6b8061fefd4Tim Peters}
1565d644dd25ac3100d0e8bc795ae57a6b8061fefd4Tim Peters
1572a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
1582a799bf77a83adef010ff4751e5195702f159f39Tim Peters * General calendrical helper functions
1592a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
1602a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1612a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* For each month ordinal in 1..12, the number of days in that month,
1622a799bf77a83adef010ff4751e5195702f159f39Tim Peters * and the number of days before that month in the same year.  These
1632a799bf77a83adef010ff4751e5195702f159f39Tim Peters * are correct for non-leap years only.
1642a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
1652a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int _days_in_month[] = {
166c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0, /* unused; this vector uses 1-based indexing */
167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1682a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
1692a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1702a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int _days_before_month[] = {
171c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0, /* unused; this vector uses 1-based indexing */
172c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
1732a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
1742a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1752a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* year -> 1 if leap year, else 0. */
1762a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
1772a799bf77a83adef010ff4751e5195702f159f39Tim Petersis_leap(int year)
1782a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
179c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Cast year to unsigned.  The result is the same either way, but
180c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * C can generate faster code for unsigned mod than for signed
181c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * mod (especially for % 4 -- a good compiler should just grab
182c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * the last 2 bits when the LHS is unsigned).
183c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
184c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    const unsigned int ayear = (unsigned int)year;
185c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
1862a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
1872a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1882a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* year, month -> number of days in that month in that year */
1892a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
1902a799bf77a83adef010ff4751e5195702f159f39Tim Petersdays_in_month(int year, int month)
1912a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(month >= 1);
193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(month <= 12);
194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (month == 2 && is_leap(year))
195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 29;
196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
197c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return _days_in_month[month];
1982a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
1992a799bf77a83adef010ff4751e5195702f159f39Tim Peters
200b1d867f14965e2369d31a3fcdab5bca34b4d81b4Martin Panter/* year, month -> number of days in year preceding first day of month */
2012a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
2022a799bf77a83adef010ff4751e5195702f159f39Tim Petersdays_before_month(int year, int month)
2032a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
204c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int days;
2052a799bf77a83adef010ff4751e5195702f159f39Tim Peters
206c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(month >= 1);
207c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(month <= 12);
208c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    days = _days_before_month[month];
209c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (month > 2 && is_leap(year))
210c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        ++days;
211c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return days;
2122a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
2132a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2142a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* year -> number of days before January 1st of year.  Remember that we
2152a799bf77a83adef010ff4751e5195702f159f39Tim Peters * start with year 1, so days_before_year(1) == 0.
2162a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
2172a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
2182a799bf77a83adef010ff4751e5195702f159f39Tim Petersdays_before_year(int year)
2192a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
220c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int y = year - 1;
221c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* This is incorrect if year <= 0; we really want the floor
222c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * here.  But so long as MINYEAR is 1, the smallest year this
223c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * can see is 0 (this can happen in some normalization endcases),
224c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * so we'll just special-case that.
225c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
226c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert (year >= 0);
227c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (y >= 0)
228c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return y*365 + y/4 - y/100 + y/400;
229c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else {
230c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(y == -1);
231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -366;
232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2332a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
2342a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2352a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Number of days in 4, 100, and 400 year cycles.  That these have
2362a799bf77a83adef010ff4751e5195702f159f39Tim Peters * the correct values is asserted in the module init function.
2372a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
238c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DI4Y    1461    /* days_before_year(5); days in 4 years */
239c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DI100Y  36524   /* days_before_year(101); days in 100 years */
240c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define DI400Y  146097  /* days_before_year(401); days in 400 years  */
2412a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2422a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
2432a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic void
2442a799bf77a83adef010ff4751e5195702f159f39Tim Petersord_to_ymd(int ordinal, int *year, int *month, int *day)
2452a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
246c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int n, n1, n4, n100, n400, leapyear, preceding;
247c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
248c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* ordinal is a 1-based index, starting at 1-Jan-1.  The pattern of
249c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * leap years repeats exactly every 400 years.  The basic strategy is
250c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * to find the closest 400-year boundary at or before ordinal, then
251c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * work with the offset from that boundary to ordinal.  Life is much
252c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * clearer if we subtract 1 from ordinal first -- then the values
253c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * of ordinal at 400-year boundaries are exactly those divisible
254c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * by DI400Y:
255c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *
256c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *    D  M   Y            n              n-1
257c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *    -- --- ----        ----------     ----------------
258c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *    31 Dec -400        -DI400Y       -DI400Y -1
259c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *     1 Jan -399         -DI400Y +1   -DI400Y      400-year boundary
260c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *    ...
261c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *    30 Dec  000        -1             -2
262c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *    31 Dec  000         0             -1
263c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *     1 Jan  001         1              0          400-year boundary
264c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *     2 Jan  001         2              1
265c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *     3 Jan  001         3              2
266c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *    ...
267c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *    31 Dec  400         DI400Y        DI400Y -1
268c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     *     1 Jan  401         DI400Y +1     DI400Y      400-year boundary
269c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
270c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(ordinal >= 1);
271c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    --ordinal;
272c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n400 = ordinal / DI400Y;
273c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n = ordinal % DI400Y;
274c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    *year = n400 * 400 + 1;
275c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
276c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Now n is the (non-negative) offset, in days, from January 1 of
277c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * year, to the desired date.  Now compute how many 100-year cycles
278c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * precede n.
279c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * Note that it's possible for n100 to equal 4!  In that case 4 full
280c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * 100-year cycles precede the desired day, which implies the
281c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * desired day is December 31 at the end of a 400-year cycle.
282c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
283c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n100 = n / DI100Y;
284c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n = n % DI100Y;
285c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
286c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Now compute how many 4-year cycles precede it. */
287c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n4 = n / DI4Y;
288c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n = n % DI4Y;
289c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
290c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* And now how many single years.  Again n1 can be 4, and again
291c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * meaning that the desired day is December 31 at the end of the
292c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * 4-year cycle.
293c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
294c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n1 = n / 365;
295c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n = n % 365;
296c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
297c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    *year += n100 * 100 + n4 * 4 + n1;
298c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (n1 == 4 || n100 == 4) {
299c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(n == 0);
300c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *year -= 1;
301c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *month = 12;
302c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *day = 31;
303c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
304c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
305c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
306c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Now the year is correct, and n is the offset from January 1.  We
307c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * find the month via an estimate that's either exact or one too
308c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * large.
309c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
310c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
311c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(leapyear == is_leap(*year));
312c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    *month = (n + 50) >> 5;
313c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
314c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (preceding > n) {
315c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* estimate is too large */
316c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *month -= 1;
317c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        preceding -= days_in_month(*year, *month);
318c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
319c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n -= preceding;
320c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(0 <= n);
321c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(n < days_in_month(*year, *month));
322c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
323c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    *day = n + 1;
3242a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
3252a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3262a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
3272a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
3282a799bf77a83adef010ff4751e5195702f159f39Tim Petersymd_to_ord(int year, int month, int day)
3292a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
330c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return days_before_year(year) + days_before_month(year, month) + day;
3312a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
3322a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3332a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Day of week, where Monday==0, ..., Sunday==6.  1/1/1 was a Monday. */
3342a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
3352a799bf77a83adef010ff4751e5195702f159f39Tim Petersweekday(int year, int month, int day)
3362a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
337c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return (ymd_to_ord(year, month, day) + 6) % 7;
3382a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
3392a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3402a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Ordinal of the Monday starting week 1 of the ISO year.  Week 1 is the
3412a799bf77a83adef010ff4751e5195702f159f39Tim Peters * first calendar week containing a Thursday.
3422a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
3432a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
3442a799bf77a83adef010ff4751e5195702f159f39Tim Petersiso_week1_monday(int year)
3452a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
346c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int first_day = ymd_to_ord(year, 1, 1);     /* ord of 1/1 */
347c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
348c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int first_weekday = (first_day + 6) % 7;
349c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* ordinal of closest Monday at or before 1/1 */
350c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int week1_monday  = first_day - first_weekday;
3512a799bf77a83adef010ff4751e5195702f159f39Tim Peters
352c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (first_weekday > 3)      /* if 1/1 was Fri, Sat, Sun */
353c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        week1_monday += 7;
354c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return week1_monday;
3552a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
3562a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3572a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
3582a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Range checkers.
3592a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
3602a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3612a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS.  If so, return 0.
3622a799bf77a83adef010ff4751e5195702f159f39Tim Peters * If not, raise OverflowError and return -1.
3632a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
3642a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
3652a799bf77a83adef010ff4751e5195702f159f39Tim Peterscheck_delta_day_range(int days)
3662a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
367c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
368c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
369c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_Format(PyExc_OverflowError,
370c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 "days=%d; must have magnitude <= %d",
371c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 days, MAX_DELTA_DAYS);
372c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return -1;
3732a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
3742a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3752a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Check that date arguments are in range.  Return 0 if they are.  If they
3762a799bf77a83adef010ff4751e5195702f159f39Tim Peters * aren't, raise ValueError and return -1.
3772a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
3782a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
3792a799bf77a83adef010ff4751e5195702f159f39Tim Peterscheck_date_args(int year, int month, int day)
3802a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3812a799bf77a83adef010ff4751e5195702f159f39Tim Peters
382c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (year < MINYEAR || year > MAXYEAR) {
383c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
384c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "year is out of range");
385c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -1;
386c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
387c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (month < 1 || month > 12) {
388c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
389c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "month must be in 1..12");
390c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -1;
391c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
392c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (day < 1 || day > days_in_month(year, month)) {
393c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
394c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "day is out of range for month");
395c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -1;
396c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
397c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return 0;
3982a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
3992a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4002a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Check that time arguments are in range.  Return 0 if they are.  If they
4012a799bf77a83adef010ff4751e5195702f159f39Tim Peters * aren't, raise ValueError and return -1.
4022a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
4032a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
4042a799bf77a83adef010ff4751e5195702f159f39Tim Peterscheck_time_args(int h, int m, int s, int us)
4052a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
406c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (h < 0 || h > 23) {
407c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
408c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "hour must be in 0..23");
409c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -1;
410c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
411c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (m < 0 || m > 59) {
412c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
413c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "minute must be in 0..59");
414c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -1;
415c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
416c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (s < 0 || s > 59) {
417c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
418c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "second must be in 0..59");
419c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -1;
420c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
421c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us < 0 || us > 999999) {
422c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
423c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "microsecond must be in 0..999999");
424c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -1;
425c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
426c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return 0;
4272a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
4282a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4292a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
4302a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Normalization utilities.
4312a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
4322a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4332a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* One step of a mixed-radix conversion.  A "hi" unit is equivalent to
4342a799bf77a83adef010ff4751e5195702f159f39Tim Peters * factor "lo" units.  factor must be > 0.  If *lo is less than 0, or
4352a799bf77a83adef010ff4751e5195702f159f39Tim Peters * at least factor, enough of *lo is converted into "hi" units so that
4362a799bf77a83adef010ff4751e5195702f159f39Tim Peters * 0 <= *lo < factor.  The input values must be such that int overflow
4372a799bf77a83adef010ff4751e5195702f159f39Tim Peters * is impossible.
4382a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
4392a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic void
4402a799bf77a83adef010ff4751e5195702f159f39Tim Petersnormalize_pair(int *hi, int *lo, int factor)
4412a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
442c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(factor > 0);
443c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(lo != hi);
444c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (*lo < 0 || *lo >= factor) {
445c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        const int num_hi = divmod(*lo, factor, lo);
446c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        const int new_hi = *hi + num_hi;
447c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
448c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *hi = new_hi;
449c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
450c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(0 <= *lo && *lo < factor);
4512a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
4522a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4532a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Fiddle days (d), seconds (s), and microseconds (us) so that
454c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou *      0 <= *s < 24*3600
455c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou *      0 <= *us < 1000000
4562a799bf77a83adef010ff4751e5195702f159f39Tim Peters * The input values must be such that the internals don't overflow.
4572a799bf77a83adef010ff4751e5195702f159f39Tim Peters * The way this routine is used, we don't get close.
4582a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
4592a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic void
4602a799bf77a83adef010ff4751e5195702f159f39Tim Petersnormalize_d_s_us(int *d, int *s, int *us)
4612a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
462c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (*us < 0 || *us >= 1000000) {
463c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        normalize_pair(s, us, 1000000);
464c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* |s| can't be bigger than about
465c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * |original s| + |original us|/1000000 now.
466c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
4672a799bf77a83adef010ff4751e5195702f159f39Tim Peters
468c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
469c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (*s < 0 || *s >= 24*3600) {
470c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        normalize_pair(d, s, 24*3600);
471c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* |d| can't be bigger than about
472c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * |original d| +
473c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * (|original s| + |original us|/1000000) / (24*3600) now.
474c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
475c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
476c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(0 <= *s && *s < 24*3600);
477c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(0 <= *us && *us < 1000000);
4782a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
4792a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4802a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Fiddle years (y), months (m), and days (d) so that
481c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou *      1 <= *m <= 12
482c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou *      1 <= *d <= days_in_month(*y, *m)
4832a799bf77a83adef010ff4751e5195702f159f39Tim Peters * The input values must be such that the internals don't overflow.
4842a799bf77a83adef010ff4751e5195702f159f39Tim Peters * The way this routine is used, we don't get close.
4852a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
4869292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolskystatic int
4872a799bf77a83adef010ff4751e5195702f159f39Tim Petersnormalize_y_m_d(int *y, int *m, int *d)
4882a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
489c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int dim;            /* # of days in month */
490c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
491c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* This gets muddy:  the proper range for day can't be determined
492c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * without knowing the correct month and year, but if day is, e.g.,
493c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * plus or minus a million, the current month and year values make
494c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * no sense (and may also be out of bounds themselves).
495c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * Saying 12 months == 1 year should be non-controversial.
496c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
497c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (*m < 1 || *m > 12) {
498c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        --*m;
499c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        normalize_pair(y, m, 12);
500c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        ++*m;
501c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* |y| can't be bigger than about
502c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * |original y| + |original m|/12 now.
503c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
504c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
505c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(1 <= *m && *m <= 12);
506c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
507c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Now only day can be out of bounds (year may also be out of bounds
508c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * for a datetime object, but we don't care about that here).
509c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * If day is out of bounds, what to do is arguable, but at least the
510c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * method here is principled and explainable.
511c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
512c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    dim = days_in_month(*y, *m);
513c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (*d < 1 || *d > dim) {
514c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Move day-1 days from the first of the month.  First try to
515c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * get off cheap if we're only one day out of range
516c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * (adjustments for timezone alone can't be worse than that).
517c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
518c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (*d == 0) {
519c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            --*m;
520c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (*m > 0)
521c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                *d = days_in_month(*y, *m);
522c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            else {
523c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                --*y;
524c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                *m = 12;
525c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                *d = 31;
526c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
527c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
528c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else if (*d == dim + 1) {
529c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* move forward a day */
530c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ++*m;
531c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            *d = 1;
532c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (*m > 12) {
533c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                *m = 1;
534c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                ++*y;
535c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
536c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
537c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else {
538c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int ordinal = ymd_to_ord(*y, *m, 1) +
539c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      *d - 1;
5409292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky            if (ordinal < 1 || ordinal > MAXORDINAL) {
5419292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky                goto error;
5429292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky            } else {
5439292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky                ord_to_ymd(ordinal, y, m, d);
5449292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky                return 0;
5459292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky            }
546c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
547c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
548c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(*m > 0);
549c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(*d > 0);
5509292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky    if (MINYEAR <= *y && *y <= MAXYEAR)
5519292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky        return 0;
5529292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky error:
5539292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky    PyErr_SetString(PyExc_OverflowError,
5549292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky            "date value out of range");
5559292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky    return -1;
5569292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky
5572a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
5582a799bf77a83adef010ff4751e5195702f159f39Tim Peters
5592a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Fiddle out-of-bounds months and days so that the result makes some kind
5602a799bf77a83adef010ff4751e5195702f159f39Tim Peters * of sense.  The parameters are both inputs and outputs.  Returns < 0 on
5612a799bf77a83adef010ff4751e5195702f159f39Tim Peters * failure, where failure means the adjusted year is out of bounds.
5622a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
5632a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
5642a799bf77a83adef010ff4751e5195702f159f39Tim Petersnormalize_date(int *year, int *month, int *day)
5652a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
5669292ee06672e88172f6d2724eecbfd95bb69cc24Alexander Belopolsky    return normalize_y_m_d(year, month, day);
5672a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
5682a799bf77a83adef010ff4751e5195702f159f39Tim Peters
5692a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Force all the datetime fields into range.  The parameters are both
5702a799bf77a83adef010ff4751e5195702f159f39Tim Peters * inputs and outputs.  Returns < 0 on error.
5712a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
5722a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
5732a799bf77a83adef010ff4751e5195702f159f39Tim Petersnormalize_datetime(int *year, int *month, int *day,
5742a799bf77a83adef010ff4751e5195702f159f39Tim Peters                   int *hour, int *minute, int *second,
5752a799bf77a83adef010ff4751e5195702f159f39Tim Peters                   int *microsecond)
5762a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
577c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    normalize_pair(second, microsecond, 1000000);
578c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    normalize_pair(minute, second, 60);
579c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    normalize_pair(hour, minute, 60);
580c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    normalize_pair(day, hour, 24);
581c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return normalize_date(year, month, day);
5822a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
5832a799bf77a83adef010ff4751e5195702f159f39Tim Peters
5842a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
585b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * Basic object allocation:  tp_alloc implementations.  These allocate
586b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * Python objects of the right size and type, and do the Python object-
587b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * initialization bit.  If there's not enough memory, they return NULL after
588b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * setting MemoryError.  All data members remain uninitialized trash.
589b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters *
590b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
59103eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * member is needed.  This is ugly, imprecise, and possibly insecure.
59203eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * tp_basicsize for the time and datetime types is set to the size of the
59303eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * struct that has room for the tzinfo member, so subclasses in Python will
59403eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * allocate enough space for a tzinfo member whether or not one is actually
59503eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * needed.  That's the "ugly and imprecise" parts.  The "possibly insecure"
59603eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * part is that PyType_GenericAlloc() (which subclasses in Python end up
59703eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * using) just happens today to effectively ignore the nitems argument
59803eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * when tp_itemsize is 0, which it is for these type objects.  If that
59903eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * changes, perhaps the callers of tp_alloc slots in this file should
60003eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * be changed to force a 0 nitems argument unless the type being allocated
60103eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * is a base type implemented in this file (so that tp_alloc is time_alloc
60203eaf8b1aec995809a5a486948bef6f24b8174f4Tim Peters * or datetime_alloc below, which know about the nitems abuse).
603b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters */
604b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
605b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersstatic PyObject *
60618e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwistime_alloc(PyTypeObject *type, Py_ssize_t aware)
607b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters{
608c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *self;
609b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
610c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self = (PyObject *)
611c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject_MALLOC(aware ?
612c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        sizeof(PyDateTime_Time) :
613c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                sizeof(_PyDateTime_BaseTime));
614c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self == NULL)
615c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return (PyObject *)PyErr_NoMemory();
616646b528467b171148143980452d2aa4294cbe5c8Martin Panter    (void)PyObject_INIT(self, type);
617c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self;
618b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters}
619b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
620b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersstatic PyObject *
62118e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisdatetime_alloc(PyTypeObject *type, Py_ssize_t aware)
622b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters{
623c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *self;
624b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
625c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self = (PyObject *)
626c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject_MALLOC(aware ?
627c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        sizeof(PyDateTime_DateTime) :
628c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                sizeof(_PyDateTime_BaseDateTime));
629c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self == NULL)
630c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return (PyObject *)PyErr_NoMemory();
631646b528467b171148143980452d2aa4294cbe5c8Martin Panter    (void)PyObject_INIT(self, type);
632c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self;
633b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters}
634b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
635b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters/* ---------------------------------------------------------------------------
636b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * Helpers for setting object fields.  These work on pointers to the
637b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * appropriate base class.
638b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters */
639b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
640b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters/* For date and datetime. */
641b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersstatic void
642b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersset_date_fields(PyDateTime_Date *self, int y, int m, int d)
643b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters{
644c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self->hashcode = -1;
645c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    SET_YEAR(self, y);
646c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    SET_MONTH(self, m);
647c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    SET_DAY(self, d);
648b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters}
649b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
650b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters/* ---------------------------------------------------------------------------
651b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * Create various objects, mostly without range checking.
652b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters */
653b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
654b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters/* Create a date instance with no range checking. */
655b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersstatic PyObject *
656b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersnew_date_ex(int year, int month, int day, PyTypeObject *type)
657b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters{
658c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyDateTime_Date *self;
659b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
660c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
661c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self != NULL)
662c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        set_date_fields(self, year, month, day);
663c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return (PyObject *) self;
664b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters}
665b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
666b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters#define new_date(year, month, day) \
667c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    new_date_ex(year, month, day, &PyDateTime_DateType)
668b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
669b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters/* Create a datetime instance with no range checking. */
670b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersstatic PyObject *
671b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersnew_datetime_ex(int year, int month, int day, int hour, int minute,
672c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
673c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{
674c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyDateTime_DateTime *self;
675c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char aware = tzinfo != Py_None;
676c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
677c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
678c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self != NULL) {
679c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        self->hastzinfo = aware;
680c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        set_date_fields((PyDateTime_Date *)self, year, month, day);
681c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        DATE_SET_HOUR(self, hour);
682c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        DATE_SET_MINUTE(self, minute);
683c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        DATE_SET_SECOND(self, second);
684c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        DATE_SET_MICROSECOND(self, usecond);
685c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (aware) {
686c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_INCREF(tzinfo);
687c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            self->tzinfo = tzinfo;
688c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
689c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
690c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return (PyObject *)self;
691c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou}
692c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
693c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo)           \
694c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo,            \
695c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    &PyDateTime_DateTimeType)
696b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
697b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters/* Create a time instance with no range checking. */
698b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersstatic PyObject *
699b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersnew_time_ex(int hour, int minute, int second, int usecond,
700c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            PyObject *tzinfo, PyTypeObject *type)
701c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{
702c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyDateTime_Time *self;
703c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char aware = tzinfo != Py_None;
704c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
705c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
706c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self != NULL) {
707c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        self->hastzinfo = aware;
708c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        self->hashcode = -1;
709c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        TIME_SET_HOUR(self, hour);
710c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        TIME_SET_MINUTE(self, minute);
711c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        TIME_SET_SECOND(self, second);
712c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        TIME_SET_MICROSECOND(self, usecond);
713c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (aware) {
714c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_INCREF(tzinfo);
715c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            self->tzinfo = tzinfo;
716c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
717c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
718c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return (PyObject *)self;
719c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou}
720c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
721c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define new_time(hh, mm, ss, us, tzinfo)                \
722c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
723b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
724b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters/* Create a timedelta instance.  Normalize the members iff normalize is
725b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * true.  Passing false is a speed optimization, if you know for sure
726b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * that seconds and microseconds are already in their proper ranges.  In any
727b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * case, raises OverflowError and returns NULL if the normalized days is out
728b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters * of range).
729b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters */
730b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersstatic PyObject *
731b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersnew_delta_ex(int days, int seconds, int microseconds, int normalize,
732c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             PyTypeObject *type)
733b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters{
734c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyDateTime_Delta *self;
735b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
736c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (normalize)
737c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        normalize_d_s_us(&days, &seconds, &microseconds);
738c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(0 <= seconds && seconds < 24*3600);
739c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(0 <= microseconds && microseconds < 1000000);
740b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
741c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (check_delta_day_range(days) < 0)
742c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
743b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
744c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
745c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self != NULL) {
746c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        self->hashcode = -1;
747c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        SET_TD_DAYS(self, days);
748c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        SET_TD_SECONDS(self, seconds);
749c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        SET_TD_MICROSECONDS(self, microseconds);
750c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
751c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return (PyObject *) self;
752b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters}
753b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
754c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define new_delta(d, s, us, normalize)  \
755c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
756b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
757b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters/* ---------------------------------------------------------------------------
7582a799bf77a83adef010ff4751e5195702f159f39Tim Peters * tzinfo helpers.
7592a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
7602a799bf77a83adef010ff4751e5195702f159f39Tim Peters
761855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters/* Ensure that p is None or of a tzinfo subclass.  Return 0 if OK; if not
762855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters * raise TypeError and return -1.
763855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters */
764855fe88b241a512d21b7c716fcae88331ae50a98Tim Petersstatic int
765855fe88b241a512d21b7c716fcae88331ae50a98Tim Peterscheck_tzinfo_subclass(PyObject *p)
766855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters{
767c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (p == Py_None || PyTZInfo_Check(p))
768c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
769c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_Format(PyExc_TypeError,
770c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 "tzinfo argument must be None or of a tzinfo subclass, "
771c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 "not type '%s'",
772c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 Py_TYPE(p)->tp_name);
773c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return -1;
774855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters}
775855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters
776bad8ff089a04372465c3143a3567b9712673c155Tim Peters/* Return tzinfo.methname(tzinfoarg), without any checking of results.
777855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters * If tzinfo is None, returns None.
778855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters */
779855fe88b241a512d21b7c716fcae88331ae50a98Tim Petersstatic PyObject *
780bad8ff089a04372465c3143a3567b9712673c155Tim Peterscall_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
781855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters{
782c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
783855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters
784c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(tzinfo && methname && tzinfoarg);
785c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(check_tzinfo_subclass(tzinfo) >= 0);
786c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tzinfo == Py_None) {
787c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = Py_None;
788c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(result);
789c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
790c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
791c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
792c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
793855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters}
794855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters
7952a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* If self has a tzinfo member, return a BORROWED reference to it.  Else
7962a799bf77a83adef010ff4751e5195702f159f39Tim Peters * return NULL, which is NOT AN ERROR.  There are no error returns here,
7972a799bf77a83adef010ff4751e5195702f159f39Tim Peters * and the caller must not decref the result.
7982a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
7992a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
8002a799bf77a83adef010ff4751e5195702f159f39Tim Petersget_tzinfo_member(PyObject *self)
8012a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
802c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tzinfo = NULL;
8032a799bf77a83adef010ff4751e5195702f159f39Tim Peters
804c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDateTime_Check(self) && HASTZINFO(self))
805c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
806c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (PyTime_Check(self) && HASTZINFO(self))
807c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        tzinfo = ((PyDateTime_Time *)self)->tzinfo;
8082a799bf77a83adef010ff4751e5195702f159f39Tim Peters
809c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return tzinfo;
8102a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
8112a799bf77a83adef010ff4751e5195702f159f39Tim Peters
812bad8ff089a04372465c3143a3567b9712673c155Tim Peters/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
8132a799bf77a83adef010ff4751e5195702f159f39Tim Peters * result.  tzinfo must be an instance of the tzinfo class.  If the method
8142a799bf77a83adef010ff4751e5195702f159f39Tim Peters * returns None, this returns 0 and sets *none to 1.  If the method doesn't
815397301eccb945ea98d03d3022882900a9fd2046fTim Peters * return None or timedelta, TypeError is raised and this returns -1.  If it
816397301eccb945ea98d03d3022882900a9fd2046fTim Peters * returnsa timedelta and the value is out of range or isn't a whole number
817397301eccb945ea98d03d3022882900a9fd2046fTim Peters * of minutes, ValueError is raised and this returns -1.
8182a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Else *none is set to 0 and the integer method result is returned.
8192a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
8202a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
8212a799bf77a83adef010ff4751e5195702f159f39Tim Peterscall_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
822c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       int *none)
823c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{
824c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *u;
825c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int result = -1;
826c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
827c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(tzinfo != NULL);
828c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyTZInfo_Check(tzinfo));
829c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(tzinfoarg != NULL);
830c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
831c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    *none = 0;
832c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    u = call_tzinfo_method(tzinfo, name, tzinfoarg);
833c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (u == NULL)
834c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -1;
835c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
836c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (u == Py_None) {
837c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = 0;
838c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *none = 1;
839c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
840c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (PyDelta_Check(u)) {
841c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        const int days = GET_TD_DAYS(u);
842c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (days < -1 || days > 0)
843c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = 24*60;             /* trigger ValueError below */
844c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else {
845c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* next line can't overflow because we know days
846c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             * is -1 or 0 now
847c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             */
848c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
849c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = divmod(ss, 60, &ss);
850c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (ss || GET_TD_MICROSECONDS(u)) {
851c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyErr_Format(PyExc_ValueError,
852c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             "tzinfo.%s() must return a "
853c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             "whole number of minutes",
854c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             name);
855c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                result = -1;
856c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
857c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
858c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
859c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else {
860c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_Format(PyExc_TypeError,
861c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     "tzinfo.%s() must return None or "
862c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     "timedelta, not '%s'",
863c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     name, Py_TYPE(u)->tp_name);
864c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
865c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
866c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(u);
867c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result < -1439 || result > 1439) {
868c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_Format(PyExc_ValueError,
869c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     "tzinfo.%s() returned %d; must be in "
870c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     "-1439 .. 1439",
871c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     name, result);
872c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = -1;
873c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
874c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
8752a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
8762a799bf77a83adef010ff4751e5195702f159f39Tim Peters
8772a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
8782a799bf77a83adef010ff4751e5195702f159f39Tim Peters * result.  tzinfo must be an instance of the tzinfo class.  If utcoffset()
8792a799bf77a83adef010ff4751e5195702f159f39Tim Peters * returns None, call_utcoffset returns 0 and sets *none to 1.  If uctoffset()
880397301eccb945ea98d03d3022882900a9fd2046fTim Peters * doesn't return None or timedelta, TypeError is raised and this returns -1.
881397301eccb945ea98d03d3022882900a9fd2046fTim Peters * If utcoffset() returns an invalid timedelta (out of range, or not a whole
882397301eccb945ea98d03d3022882900a9fd2046fTim Peters * # of minutes), ValueError is raised and this returns -1.  Else *none is
883397301eccb945ea98d03d3022882900a9fd2046fTim Peters * set to 0 and the offset is returned (as int # of minutes east of UTC).
8842a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
8852a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
8862a799bf77a83adef010ff4751e5195702f159f39Tim Peterscall_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
8872a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
888c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
8892a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
8902a799bf77a83adef010ff4751e5195702f159f39Tim Peters
891bad8ff089a04372465c3143a3567b9712673c155Tim Peters/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
892bad8ff089a04372465c3143a3567b9712673c155Tim Peters */
893855fe88b241a512d21b7c716fcae88331ae50a98Tim Petersstatic PyObject *
894bad8ff089a04372465c3143a3567b9712673c155Tim Petersoffset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
895c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
896c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
897c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(tzinfo && name && tzinfoarg);
898c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tzinfo == Py_None) {
899c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = Py_None;
900c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(result);
901c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
902c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else {
903c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int none;
904c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
905c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                            &none);
906c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (offset < 0 && PyErr_Occurred())
907c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
908c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (none) {
909c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = Py_None;
910c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_INCREF(result);
911c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
912c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else
913c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = new_delta(0, offset * 60, 0, 1);
914c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
915c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
916855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters}
917855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters
9182a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
9192a799bf77a83adef010ff4751e5195702f159f39Tim Peters * result.  tzinfo must be an instance of the tzinfo class.  If dst()
9202a799bf77a83adef010ff4751e5195702f159f39Tim Peters * returns None, call_dst returns 0 and sets *none to 1.  If dst()
921397301eccb945ea98d03d3022882900a9fd2046fTim Peters & doesn't return None or timedelta, TypeError is raised and this
922f0dfc7ac5c2f76baaae0c3b45bc339281cfa2adcWalter Dörwald * returns -1.  If dst() returns an invalid timedelta for a UTC offset,
923397301eccb945ea98d03d3022882900a9fd2046fTim Peters * ValueError is raised and this returns -1.  Else *none is set to 0 and
924397301eccb945ea98d03d3022882900a9fd2046fTim Peters * the offset is returned (as an int # of minutes east of UTC).
9252a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
9262a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
9272a799bf77a83adef010ff4751e5195702f159f39Tim Peterscall_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
9282a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
929c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
9302a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
9312a799bf77a83adef010ff4751e5195702f159f39Tim Peters
932bad8ff089a04372465c3143a3567b9712673c155Tim Peters/* Call tzinfo.tzname(tzinfoarg), and return the result.  tzinfo must be
933855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters * an instance of the tzinfo class or None.  If tzinfo isn't None, and
934bad8ff089a04372465c3143a3567b9712673c155Tim Peters * tzname() doesn't return None or a string, TypeError is raised and this
935855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters * returns NULL.
9362a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
9372a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
938bad8ff089a04372465c3143a3567b9712673c155Tim Peterscall_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
9392a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
940c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
9412a799bf77a83adef010ff4751e5195702f159f39Tim Peters
942c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(tzinfo != NULL);
943c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(check_tzinfo_subclass(tzinfo) >= 0);
944c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(tzinfoarg != NULL);
9452a799bf77a83adef010ff4751e5195702f159f39Tim Peters
946c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tzinfo == Py_None) {
947c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = Py_None;
948c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(result);
949c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
950c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
951c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
952855fe88b241a512d21b7c716fcae88331ae50a98Tim Peters
953c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result != NULL && result != Py_None && ! PyString_Check(result)) {
954c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
955c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     "return None or a string, not '%s'",
956c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     Py_TYPE(result)->tp_name);
957c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(result);
958c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = NULL;
959c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
960c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
9612a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
9622a799bf77a83adef010ff4751e5195702f159f39Tim Peters
9632a799bf77a83adef010ff4751e5195702f159f39Tim Peterstypedef enum {
964c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou              /* an exception has been set; the caller should pass it on */
965c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou          OFFSET_ERROR,
966c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
967c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou          /* type isn't date, datetime, or time subclass */
968c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou          OFFSET_UNKNOWN,
969c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
970c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou          /* date,
971c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           * datetime with !hastzinfo
972c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           * datetime with None tzinfo,
973c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           * datetime where utcoffset() returns None
974c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           * time with !hastzinfo
975c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           * time with None tzinfo,
976c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           * time where utcoffset() returns None
977c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           */
978c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou          OFFSET_NAIVE,
979c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
980c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou          /* time or datetime where utcoffset() doesn't return None */
981c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou          OFFSET_AWARE
9822a799bf77a83adef010ff4751e5195702f159f39Tim Peters} naivety;
9832a799bf77a83adef010ff4751e5195702f159f39Tim Peters
98414b6941197ca0368f78be6d87169047245f915b8Tim Peters/* Classify an object as to whether it's naive or offset-aware.  See
9852a799bf77a83adef010ff4751e5195702f159f39Tim Peters * the "naivety" typedef for details.  If the type is aware, *offset is set
9862a799bf77a83adef010ff4751e5195702f159f39Tim Peters * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
98714b6941197ca0368f78be6d87169047245f915b8Tim Peters * If the type is offset-naive (or unknown, or error), *offset is set to 0.
988e39a80c362869a4262d7af78be365b38c57ae904Tim Peters * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
9892a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
9902a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic naivety
991e39a80c362869a4262d7af78be365b38c57ae904Tim Petersclassify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
9922a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
993c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int none;
994c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tzinfo;
995c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
996c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(tzinfoarg != NULL);
997c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    *offset = 0;
998c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tzinfo = get_tzinfo_member(op);     /* NULL means no tzinfo, not error */
999c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tzinfo == Py_None)
1000c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return OFFSET_NAIVE;
1001c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tzinfo == NULL) {
1002c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* note that a datetime passes the PyDate_Check test */
1003c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return (PyTime_Check(op) || PyDate_Check(op)) ?
1004c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               OFFSET_NAIVE : OFFSET_UNKNOWN;
1005c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1006c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1007c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (*offset == -1 && PyErr_Occurred())
1008c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return OFFSET_ERROR;
1009c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return none ? OFFSET_NAIVE : OFFSET_AWARE;
10102a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
10112a799bf77a83adef010ff4751e5195702f159f39Tim Peters
101200237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters/* Classify two objects as to whether they're naive or offset-aware.
101300237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters * This isn't quite the same as calling classify_utcoffset() twice:  for
101400237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters * binary operations (comparison and subtraction), we generally want to
101500237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters * ignore the tzinfo members if they're identical.  This is by design,
101600237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters * so that results match "naive" expectations when mixing objects from a
101700237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters * single timezone.  So in that case, this sets both offsets to 0 and
101800237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters * both naiveties to OFFSET_NAIVE.
101900237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters * The function returns 0 if everything's OK, and -1 on error.
102000237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters */
102100237037ae5ced7f4921e2d0e6c3d24d685e74afTim Petersstatic int
102200237037ae5ced7f4921e2d0e6c3d24d685e74afTim Petersclassify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
1023c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        PyObject *tzinfoarg1,
1024c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        PyObject *o2, int *offset2, naivety *n2,
1025c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        PyObject *tzinfoarg2)
1026c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{
1027c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1028c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *offset1 = *offset2 = 0;
1029c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *n1 = *n2 = OFFSET_NAIVE;
1030c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1031c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else {
1032c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1033c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (*n1 == OFFSET_ERROR)
1034c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return -1;
1035c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1036c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (*n2 == OFFSET_ERROR)
1037c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return -1;
1038c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1039c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return 0;
104000237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters}
104100237037ae5ced7f4921e2d0e6c3d24d685e74afTim Peters
10422a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* repr is like "someclass(arg1, arg2)".  If tzinfo isn't None,
10432a799bf77a83adef010ff4751e5195702f159f39Tim Peters * stuff
10442a799bf77a83adef010ff4751e5195702f159f39Tim Peters *     ", tzinfo=" + repr(tzinfo)
10452a799bf77a83adef010ff4751e5195702f159f39Tim Peters * before the closing ")".
10462a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
10472a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
10482a799bf77a83adef010ff4751e5195702f159f39Tim Petersappend_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
10492a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1050c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *temp;
10512a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1052c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyString_Check(repr));
1053c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(tzinfo);
1054c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tzinfo == Py_None)
1055c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return repr;
1056c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Get rid of the trailing ')'. */
1057c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1058c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    temp = PyString_FromStringAndSize(PyString_AsString(repr),
1059c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      PyString_Size(repr) - 1);
1060c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(repr);
1061c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (temp == NULL)
1062c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
1063c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    repr = temp;
10642a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1065c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Append ", tzinfo=". */
1066c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
10672a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1068c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Append repr(tzinfo). */
1069c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
10702a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1071c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Add a closing paren. */
1072c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyString_ConcatAndDel(&repr, PyString_FromString(")"));
1073c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return repr;
10742a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
10752a799bf77a83adef010ff4751e5195702f159f39Tim Peters
10762a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
10772a799bf77a83adef010ff4751e5195702f159f39Tim Peters * String format helpers.
10782a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
10792a799bf77a83adef010ff4751e5195702f159f39Tim Peters
10802a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
1081a9bc168f95408be86e79365a075d069465a06434Tim Petersformat_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
10822a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1083c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static const char *DayNames[] = {
1084c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1085c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    };
1086c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static const char *MonthNames[] = {
1087c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1088c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1089c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    };
10902a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1091c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char buffer[128];
1092c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
10932a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1094c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
1095c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  DayNames[wday], MonthNames[GET_MONTH(date) - 1],
1096c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  GET_DAY(date), hours, minutes, seconds,
1097c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  GET_YEAR(date));
1098c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyString_FromString(buffer);
10992a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
11002a799bf77a83adef010ff4751e5195702f159f39Tim Peters
11012a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Add an hours & minutes UTC offset string to buf.  buf has no more than
11022a799bf77a83adef010ff4751e5195702f159f39Tim Peters * buflen bytes remaining.  The UTC offset is gotten by calling
11032a799bf77a83adef010ff4751e5195702f159f39Tim Peters * tzinfo.uctoffset(tzinfoarg).  If that returns None, \0 is stored into
11042a799bf77a83adef010ff4751e5195702f159f39Tim Peters * *buf, and that's all.  Else the returned value is checked for sanity (an
11052a799bf77a83adef010ff4751e5195702f159f39Tim Peters * integer in range), and if that's OK it's converted to an hours & minutes
11062a799bf77a83adef010ff4751e5195702f159f39Tim Peters * string of the form
11072a799bf77a83adef010ff4751e5195702f159f39Tim Peters *   sign HH sep MM
11082a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Returns 0 if everything is OK.  If the return value from utcoffset() is
11092a799bf77a83adef010ff4751e5195702f159f39Tim Peters * bogus, an appropriate exception is set and -1 is returned.
11102a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
11112a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
1112328fff72149a896141209b57b577b4dc57ea5d90Tim Petersformat_utcoffset(char *buf, size_t buflen, const char *sep,
1113c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyObject *tzinfo, PyObject *tzinfoarg)
1114c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{
1115c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int offset;
1116c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int hours;
1117c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int minutes;
1118c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char sign;
1119c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int none;
1120c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1121c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(buflen >= 1);
1122c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1123c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1124c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (offset == -1 && PyErr_Occurred())
1125c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return -1;
1126c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (none) {
1127c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *buf = '\0';
1128c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 0;
1129c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1130c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    sign = '+';
1131c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (offset < 0) {
1132c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        sign = '-';
1133c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        offset = - offset;
1134c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1135c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    hours = divmod(offset, 60, &minutes);
1136c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1137c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return 0;
11382a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
11392a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1140fc070d27316ebb0ed877fade811130ac566bbc14Skip Montanarostatic PyObject *
1141fc070d27316ebb0ed877fade811130ac566bbc14Skip Montanaromake_freplacement(PyObject *object)
1142fc070d27316ebb0ed877fade811130ac566bbc14Skip Montanaro{
1143c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char freplacement[64];
1144c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyTime_Check(object))
1145c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1146c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (PyDateTime_Check(object))
1147c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1148c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
1149c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        sprintf(freplacement, "%06d", 0);
1150fc070d27316ebb0ed877fade811130ac566bbc14Skip Montanaro
1151c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyString_FromStringAndSize(freplacement, strlen(freplacement));
1152fc070d27316ebb0ed877fade811130ac566bbc14Skip Montanaro}
1153fc070d27316ebb0ed877fade811130ac566bbc14Skip Montanaro
11542a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* I sure don't want to reproduce the strftime code from the time module,
11552a799bf77a83adef010ff4751e5195702f159f39Tim Peters * so this imports the module and calls it.  All the hair is due to
1156fc070d27316ebb0ed877fade811130ac566bbc14Skip Montanaro * giving special meanings to the %z, %Z and %f format codes via a
1157fc070d27316ebb0ed877fade811130ac566bbc14Skip Montanaro * preprocessing step on the format string.
1158bad8ff089a04372465c3143a3567b9712673c155Tim Peters * tzinfoarg is the argument to pass to the object's tzinfo method, if
1159bad8ff089a04372465c3143a3567b9712673c155Tim Peters * needed.
11602a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
11612a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
1162137d824148f9322c741b16d90ada72fc558b9a1cGregory P. Smithwrap_strftime(PyObject *object, const char *format, size_t format_len,
1163c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyObject *timetuple, PyObject *tzinfoarg)
1164c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{
1165c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;            /* guilty until proved innocent */
1166c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *zreplacement = NULL;      /* py string, replacement for %z */
1168c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *Zreplacement = NULL;      /* py string, replacement for %Z */
1169c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *freplacement = NULL;      /* py string, replacement for %f */
1170c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1171c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    const char *pin;            /* pointer to next char in input format */
1172c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char ch;                    /* next char in input format */
1173c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1174c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *newfmt = NULL;            /* py string, the output format */
1175c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char *pnew;         /* pointer to available byte in output format */
1176c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    size_t totalnew;            /* number bytes total in output format buffer,
1177c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                               exclusive of trailing \0 */
1178c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    size_t usednew;     /* number bytes used so far in output format buffer */
1179c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1180c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    const char *ptoappend;      /* ptr to string to append to output buffer */
1181c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    size_t ntoappend;           /* # of bytes to append to output buffer */
1182c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1183c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(object && format && timetuple);
1184c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1185c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Give up if the year is before 1900.
1186c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * Python strftime() plays games with the year, and different
1187c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * games depending on whether envar PYTHON2K is set.  This makes
1188c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * years before 1900 a nightmare, even if the platform strftime
1189c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * supports them (and not all do).
1190c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * We could get a lot farther here by avoiding Python's strftime
1191c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * wrapper and calling the C strftime() directly, but that isn't
1192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * an option in the Python implementation of this module.
1193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
1194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {
1195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        long year;
1196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1197c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (pyyear == NULL) return NULL;
1198c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(PyInt_Check(pyyear));
1199c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        year = PyInt_AsLong(pyyear);
1200c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(pyyear);
1201c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (year < 1900) {
1202c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            PyErr_Format(PyExc_ValueError, "year=%ld is before "
1203c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         "1900; the datetime strftime() "
1204c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         "methods require year >= 1900",
1205c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         year);
1206c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
1207c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1208c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1209c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1210c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Scan the input format, looking for %z/%Z/%f escapes, building
1211c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * a new format.  Since computing the replacements for those codes
1212c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * is expensive, don't unless they're actually used.
1213c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
1214c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (format_len > INT_MAX - 1) {
1215c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_NoMemory();
1216c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1217c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1218c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1219c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    totalnew = format_len + 1;          /* realistic if no %z/%Z/%f */
1220c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    newfmt = PyString_FromStringAndSize(NULL, totalnew);
1221c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (newfmt == NULL) goto Done;
1222c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    pnew = PyString_AsString(newfmt);
1223c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    usednew = 0;
1224c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1225c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    pin = format;
1226c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    while ((ch = *pin++) != '\0') {
1227c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (ch != '%') {
1228c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ptoappend = pin - 1;
1229c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ntoappend = 1;
1230c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else if ((ch = *pin++) == '\0') {
1232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* There's a lone trailing %; doesn't make sense. */
1233c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            PyErr_SetString(PyExc_ValueError, "strftime format "
1234c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            "ends with raw %");
1235c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            goto Done;
1236c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1237c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* A % has been seen and ch is the character after it. */
1238c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else if (ch == 'z') {
1239c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (zreplacement == NULL) {
1240c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                /* format utcoffset */
1241c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                char buf[100];
1242c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyObject *tzinfo = get_tzinfo_member(object);
1243c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                zreplacement = PyString_FromString("");
1244c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (zreplacement == NULL) goto Done;
1245c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (tzinfo != Py_None && tzinfo != NULL) {
1246c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    assert(tzinfoarg != NULL);
1247c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    if (format_utcoffset(buf,
1248c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                         sizeof(buf),
1249c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                         "",
1250c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                         tzinfo,
1251c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                         tzinfoarg) < 0)
1252c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        goto Done;
1253c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    Py_DECREF(zreplacement);
1254c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    zreplacement = PyString_FromString(buf);
1255c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    if (zreplacement == NULL) goto Done;
1256c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
1257c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
1258c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(zreplacement != NULL);
1259c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ptoappend = PyString_AS_STRING(zreplacement);
1260c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ntoappend = PyString_GET_SIZE(zreplacement);
1261c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1262c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else if (ch == 'Z') {
1263c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* format tzname */
1264c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (Zreplacement == NULL) {
1265c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyObject *tzinfo = get_tzinfo_member(object);
1266c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                Zreplacement = PyString_FromString("");
1267c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (Zreplacement == NULL) goto Done;
1268c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (tzinfo != Py_None && tzinfo != NULL) {
1269c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    PyObject *temp;
1270c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    assert(tzinfoarg != NULL);
1271c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    temp = call_tzname(tzinfo, tzinfoarg);
1272c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    if (temp == NULL) goto Done;
1273c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    if (temp != Py_None) {
1274c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        assert(PyString_Check(temp));
1275c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        /* Since the tzname is getting
1276c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         * stuffed into the format, we
1277c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         * have to double any % signs
1278c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         * so that strftime doesn't
1279c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         * treat them as format codes.
1280c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         */
1281c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        Py_DECREF(Zreplacement);
1282c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        Zreplacement = PyObject_CallMethod(
1283c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            temp, "replace",
1284c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            "ss", "%", "%%");
1285c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        Py_DECREF(temp);
1286c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        if (Zreplacement == NULL)
1287c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            goto Done;
1288c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        if (!PyString_Check(Zreplacement)) {
1289c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
1290c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            goto Done;
1291c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        }
1292c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    }
1293c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    else
1294c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        Py_DECREF(temp);
1295c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
1296c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
1297c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(Zreplacement != NULL);
1298c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ptoappend = PyString_AS_STRING(Zreplacement);
1299c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ntoappend = PyString_GET_SIZE(Zreplacement);
1300c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1301c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else if (ch == 'f') {
1302c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* format microseconds */
1303c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (freplacement == NULL) {
1304c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                freplacement = make_freplacement(object);
1305c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                if (freplacement == NULL)
1306c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    goto Done;
1307c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
1308c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(freplacement != NULL);
1309c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(PyString_Check(freplacement));
1310c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ptoappend = PyString_AS_STRING(freplacement);
1311c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ntoappend = PyString_GET_SIZE(freplacement);
1312c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1313c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else {
1314c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* percent followed by neither z nor Z */
1315c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ptoappend = pin - 2;
1316c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ntoappend = 2;
1317c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1318c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1319c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Append the ntoappend chars starting at ptoappend to
1320c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * the new format.
1321c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
1322c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(ptoappend != NULL);
1323c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(ntoappend >= 0);
1324c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (ntoappend == 0)
1325c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            continue;
1326c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        while (usednew + ntoappend > totalnew) {
1327c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            size_t bigger = totalnew << 1;
1328c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if ((bigger >> 1) != totalnew) { /* overflow */
1329c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyErr_NoMemory();
1330c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                goto Done;
1331c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
1332c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (_PyString_Resize(&newfmt, bigger) < 0)
1333c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                goto Done;
1334c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            totalnew = bigger;
1335c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            pnew = PyString_AsString(newfmt) + usednew;
1336c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1337c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        memcpy(pnew, ptoappend, ntoappend);
1338c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        pnew += ntoappend;
1339c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        usednew += ntoappend;
1340c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(usednew <= totalnew);
1341c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }  /* end while() */
1342c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1343c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (_PyString_Resize(&newfmt, usednew) < 0)
1344c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1345c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {
1346c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *time = PyImport_ImportModuleNoBlock("time");
1347c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (time == NULL)
1348c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            goto Done;
1349c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = PyObject_CallMethod(time, "strftime", "OO",
1350c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                     newfmt, timetuple);
1351c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(time);
1352c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
13532a799bf77a83adef010ff4751e5195702f159f39Tim Peters Done:
1354c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(freplacement);
1355c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(zreplacement);
1356c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(Zreplacement);
1357c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(newfmt);
1358c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
13592a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
13602a799bf77a83adef010ff4751e5195702f159f39Tim Peters
13612a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic char *
13622a799bf77a83adef010ff4751e5195702f159f39Tim Petersisoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
13632a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1364c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int x;
1365c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = PyOS_snprintf(buffer, bufflen,
1366c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      "%04d-%02d-%02d",
1367c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1368c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(bufflen >= x);
1369c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return buffer + x;
13702a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
13712a799bf77a83adef010ff4751e5195702f159f39Tim Peters
13728645a5c81fde0afe0e00e122b64f6bc586844ec3Amaury Forgeot d'Arcstatic char *
13732a799bf77a83adef010ff4751e5195702f159f39Tim Petersisoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
13742a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1375c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int x;
1376c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int us = DATE_GET_MICROSECOND(dt);
13772a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1378c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = PyOS_snprintf(buffer, bufflen,
1379c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      "%02d:%02d:%02d",
1380c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_HOUR(dt),
1381c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_MINUTE(dt),
1382c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_SECOND(dt));
1383c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(bufflen >= x);
1384c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us)
1385c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us);
1386c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(bufflen >= x);
1387c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return buffer + x;
13882a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
13892a799bf77a83adef010ff4751e5195702f159f39Tim Peters
13902a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
13912a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Wrap functions from the time module.  These aren't directly available
13922a799bf77a83adef010ff4751e5195702f159f39Tim Peters * from C.  Perhaps they should be.
13932a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
13942a799bf77a83adef010ff4751e5195702f159f39Tim Peters
13952a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Call time.time() and return its result (a Python float). */
13962a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
1397bd43e9195ba734073b15b3a1b02e5621e3380ca9Guido van Rossumtime_time(void)
13982a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1399c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
1400c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *time = PyImport_ImportModuleNoBlock("time");
14012a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1402c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (time != NULL) {
1403c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = PyObject_CallMethod(time, "time", "()");
1404c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(time);
1405c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1406c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
14072a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
14082a799bf77a83adef010ff4751e5195702f159f39Tim Peters
14092a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Build a time.struct_time.  The weekday and day number are automatically
14102a799bf77a83adef010ff4751e5195702f159f39Tim Peters * computed from the y,m,d args.
14112a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
14122a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
14132a799bf77a83adef010ff4751e5195702f159f39Tim Petersbuild_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
14142a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1415c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *time;
1416c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
14172a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1418c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time = PyImport_ImportModuleNoBlock("time");
1419c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (time != NULL) {
1420c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = PyObject_CallMethod(time, "struct_time",
1421c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                     "((iiiiiiiii))",
1422c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                     y, m, d,
1423c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                     hh, mm, ss,
1424c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                     weekday(y, m, d),
1425c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                     days_before_month(y, m) + d,
1426c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                     dstflag);
1427c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(time);
1428c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1429c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
14302a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
14312a799bf77a83adef010ff4751e5195702f159f39Tim Peters
14322a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
14332a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Miscellaneous helpers.
14342a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
14352a799bf77a83adef010ff4751e5195702f159f39Tim Peters
14362a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
14372a799bf77a83adef010ff4751e5195702f159f39Tim Peters * The comparisons here all most naturally compute a cmp()-like result.
14382a799bf77a83adef010ff4751e5195702f159f39Tim Peters * This little helper turns that into a bool result for rich comparisons.
14392a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
14402a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
14412a799bf77a83adef010ff4751e5195702f159f39Tim Petersdiff_to_bool(int diff, int op)
14422a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1443c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
1444c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int istrue;
1445c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1446c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    switch (op) {
1447c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case Py_EQ: istrue = diff == 0; break;
1448c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case Py_NE: istrue = diff != 0; break;
1449c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case Py_LE: istrue = diff <= 0; break;
1450c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case Py_GE: istrue = diff >= 0; break;
1451c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case Py_LT: istrue = diff < 0; break;
1452c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        case Py_GT: istrue = diff > 0; break;
1453c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        default:
1454c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(! "op unknown");
1455c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            istrue = 0; /* To shut up compiler */
1456c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1457c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = istrue ? Py_True : Py_False;
1458c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(result);
1459c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
14602a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
14612a799bf77a83adef010ff4751e5195702f159f39Tim Peters
146207534a607bd3d2fd232323811a83279acda10885Tim Peters/* Raises a "can't compare" TypeError and returns NULL. */
146307534a607bd3d2fd232323811a83279acda10885Tim Petersstatic PyObject *
146407534a607bd3d2fd232323811a83279acda10885Tim Peterscmperror(PyObject *a, PyObject *b)
146507534a607bd3d2fd232323811a83279acda10885Tim Peters{
1466c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_Format(PyExc_TypeError,
1467c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 "can't compare %s to %s",
1468c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1469c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return NULL;
147007534a607bd3d2fd232323811a83279acda10885Tim Peters}
147107534a607bd3d2fd232323811a83279acda10885Tim Peters
14722a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
14732a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Cached Python objects; these are set by the module init function.
14742a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
14752a799bf77a83adef010ff4751e5195702f159f39Tim Peters
14762a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Conversion factors. */
1477c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic PyObject *us_per_us = NULL;      /* 1 */
1478c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic PyObject *us_per_ms = NULL;      /* 1000 */
1479c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic PyObject *us_per_second = NULL;  /* 1000000 */
1480c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic PyObject *us_per_minute = NULL;  /* 1e6 * 60 as Python int */
1481c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic PyObject *us_per_hour = NULL;    /* 1e6 * 3600 as Python long */
1482c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic PyObject *us_per_day = NULL;     /* 1e6 * 3600 * 24 as Python long */
1483c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitroustatic PyObject *us_per_week = NULL;    /* 1e6*3600*24*7 as Python long */
14842a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
14852a799bf77a83adef010ff4751e5195702f159f39Tim Peters
14862a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
14872a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Class implementations.
14882a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
14892a799bf77a83adef010ff4751e5195702f159f39Tim Peters
14902a799bf77a83adef010ff4751e5195702f159f39Tim Peters/*
14912a799bf77a83adef010ff4751e5195702f159f39Tim Peters * PyDateTime_Delta implementation.
14922a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
14932a799bf77a83adef010ff4751e5195702f159f39Tim Peters
14942a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Convert a timedelta to a number of us,
1495c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou *      (24*3600*self.days + self.seconds)*1000000 + self.microseconds
14962a799bf77a83adef010ff4751e5195702f159f39Tim Peters * as a Python int or long.
14972a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Doing mixed-radix arithmetic by hand instead is excruciating in C,
14982a799bf77a83adef010ff4751e5195702f159f39Tim Peters * due to ubiquitous overflow possibilities.
14992a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
15002a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
15012a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_to_microseconds(PyDateTime_Delta *self)
15022a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1503c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *x1 = NULL;
1504c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *x2 = NULL;
1505c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *x3 = NULL;
1506c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
1507c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1508c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x1 = PyInt_FromLong(GET_TD_DAYS(self));
1509c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x1 == NULL)
1510c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1511c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x2 = PyNumber_Multiply(x1, seconds_per_day);        /* days in seconds */
1512c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x2 == NULL)
1513c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1514c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x1);
1515c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x1 = NULL;
1516c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1517c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* x2 has days in seconds */
1518c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x1 = PyInt_FromLong(GET_TD_SECONDS(self));          /* seconds */
1519c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x1 == NULL)
1520c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1521c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x3 = PyNumber_Add(x1, x2);          /* days and seconds in seconds */
1522c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x3 == NULL)
1523c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1524c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x1);
1525c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x2);
1526c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x2 = NULL;
1527c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1528c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* x3 has days+seconds in seconds */
1529c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x1 = PyNumber_Multiply(x3, us_per_second);          /* us */
1530c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x1 == NULL)
1531c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1532c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x3);
1533c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x3 = NULL;
1534c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1535c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* x1 has days+seconds in us */
1536c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1537c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x2 == NULL)
1538c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1539c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = PyNumber_Add(x1, x2);
15402a799bf77a83adef010ff4751e5195702f159f39Tim Peters
15412a799bf77a83adef010ff4751e5195702f159f39Tim PetersDone:
1542c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(x1);
1543c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(x2);
1544c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(x3);
1545c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
15462a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
15472a799bf77a83adef010ff4751e5195702f159f39Tim Peters
15482a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Convert a number of us (as a Python int or long) to a timedelta.
15492a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
15502a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
1551b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Petersmicroseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
15522a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1553c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int us;
1554c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int s;
1555c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int d;
1556c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    long temp;
1557c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1558c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tuple = NULL;
1559c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *num = NULL;
1560c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
1561c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1562c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tuple = PyNumber_Divmod(pyus, us_per_second);
1563c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tuple == NULL)
1564c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1565c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1566c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    num = PyTuple_GetItem(tuple, 1);            /* us */
1567c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (num == NULL)
1568c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1569c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    temp = PyLong_AsLong(num);
1570c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    num = NULL;
1571c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (temp == -1 && PyErr_Occurred())
1572c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1573c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(0 <= temp && temp < 1000000);
1574c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us = (int)temp;
1575c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us < 0) {
1576c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* The divisor was positive, so this must be an error. */
1577c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(PyErr_Occurred());
1578c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1579c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1580c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1581c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    num = PyTuple_GetItem(tuple, 0);            /* leftover seconds */
1582c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (num == NULL)
1583c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1584c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(num);
1585c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(tuple);
1586c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1587c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tuple = PyNumber_Divmod(num, seconds_per_day);
1588c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tuple == NULL)
1589c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1590c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(num);
1591c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1592c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    num = PyTuple_GetItem(tuple, 1);            /* seconds */
1593c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (num == NULL)
1594c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1595c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    temp = PyLong_AsLong(num);
1596c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    num = NULL;
1597c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (temp == -1 && PyErr_Occurred())
1598c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1599c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(0 <= temp && temp < 24*3600);
1600c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    s = (int)temp;
1601c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1602c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (s < 0) {
1603c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* The divisor was positive, so this must be an error. */
1604c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(PyErr_Occurred());
1605c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1606c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1607c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1608c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    num = PyTuple_GetItem(tuple, 0);            /* leftover days */
1609c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (num == NULL)
1610c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1611c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(num);
1612c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    temp = PyLong_AsLong(num);
1613c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (temp == -1 && PyErr_Occurred())
1614c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1615c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    d = (int)temp;
1616c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if ((long)d != temp) {
1617c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_OverflowError, "normalized days too "
1618c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "large to fit in a C int");
1619c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1620c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1621c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = new_delta_ex(d, s, us, 0, type);
16222a799bf77a83adef010ff4751e5195702f159f39Tim Peters
16232a799bf77a83adef010ff4751e5195702f159f39Tim PetersDone:
1624c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(tuple);
1625c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(num);
1626c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
16272a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
16282a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1629c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define microseconds_to_delta(pymicros) \
1630c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1631b0c854d6a747cd64ff7b23b8e9f9ef93ff8ac0acTim Peters
16322a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
16332a799bf77a83adef010ff4751e5195702f159f39Tim Petersmultiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
16342a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1635c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *pyus_in;
1636c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *pyus_out;
1637c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
16382a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1639c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    pyus_in = delta_to_microseconds(delta);
1640c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (pyus_in == NULL)
1641c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
16422a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1643c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    pyus_out = PyNumber_Multiply(pyus_in, intobj);
1644c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(pyus_in);
1645c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (pyus_out == NULL)
1646c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
16472a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1648c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = microseconds_to_delta(pyus_out);
1649c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(pyus_out);
1650c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
16512a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
16522a799bf77a83adef010ff4751e5195702f159f39Tim Peters
16532a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
16542a799bf77a83adef010ff4751e5195702f159f39Tim Petersdivide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
16552a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1656c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *pyus_in;
1657c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *pyus_out;
1658c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
16592a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1660c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    pyus_in = delta_to_microseconds(delta);
1661c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (pyus_in == NULL)
1662c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
16632a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1664c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1665c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(pyus_in);
1666c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (pyus_out == NULL)
1667c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
16682a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1669c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = microseconds_to_delta(pyus_out);
1670c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(pyus_out);
1671c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
16722a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
16732a799bf77a83adef010ff4751e5195702f159f39Tim Peters
16742a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
16752a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_add(PyObject *left, PyObject *right)
16762a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1677c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = Py_NotImplemented;
16782a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1679c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDelta_Check(left) && PyDelta_Check(right)) {
1680c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* delta + delta */
1681c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* The C-level additions can't overflow because of the
1682c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * invariant bounds.
1683c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
1684c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1685c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1686c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int microseconds = GET_TD_MICROSECONDS(left) +
1687c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           GET_TD_MICROSECONDS(right);
1688c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = new_delta(days, seconds, microseconds, 1);
1689c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
16902a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1691c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result == Py_NotImplemented)
1692c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(result);
1693c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
16942a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
16952a799bf77a83adef010ff4751e5195702f159f39Tim Peters
16962a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
16972a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_negative(PyDateTime_Delta *self)
16982a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1699c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return new_delta(-GET_TD_DAYS(self),
1700c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     -GET_TD_SECONDS(self),
1701c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     -GET_TD_MICROSECONDS(self),
1702c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     1);
17032a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
17042a799bf77a83adef010ff4751e5195702f159f39Tim Peters
17052a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
17062a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_positive(PyDateTime_Delta *self)
17072a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1708c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Could optimize this (by returning self) if this isn't a
1709c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * subclass -- but who uses unary + ?  Approximately nobody.
1710c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
1711c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return new_delta(GET_TD_DAYS(self),
1712c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     GET_TD_SECONDS(self),
1713c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     GET_TD_MICROSECONDS(self),
1714c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     0);
17152a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
17162a799bf77a83adef010ff4751e5195702f159f39Tim Peters
17172a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
17182a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_abs(PyDateTime_Delta *self)
17192a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1720c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
17212a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1722c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(GET_TD_MICROSECONDS(self) >= 0);
1723c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(GET_TD_SECONDS(self) >= 0);
17242a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1725c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (GET_TD_DAYS(self) < 0)
1726c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = delta_negative(self);
1727c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
1728c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = delta_positive(self);
17292a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1730c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
17312a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
17322a799bf77a83adef010ff4751e5195702f159f39Tim Peters
17332a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
17342a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_subtract(PyObject *left, PyObject *right)
17352a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1736c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = Py_NotImplemented;
17372a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1738c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDelta_Check(left) && PyDelta_Check(right)) {
1739c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* delta - delta */
174007019bcaab87114bc2312f2b916f929c99f3c48bAlexander Belopolsky        /* The C-level additions can't overflow because of the
174107019bcaab87114bc2312f2b916f929c99f3c48bAlexander Belopolsky         * invariant bounds.
174207019bcaab87114bc2312f2b916f929c99f3c48bAlexander Belopolsky         */
174307019bcaab87114bc2312f2b916f929c99f3c48bAlexander Belopolsky        int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
174407019bcaab87114bc2312f2b916f929c99f3c48bAlexander Belopolsky        int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
174507019bcaab87114bc2312f2b916f929c99f3c48bAlexander Belopolsky        int microseconds = GET_TD_MICROSECONDS(left) -
174607019bcaab87114bc2312f2b916f929c99f3c48bAlexander Belopolsky                           GET_TD_MICROSECONDS(right);
174707019bcaab87114bc2312f2b916f929c99f3c48bAlexander Belopolsky        result = new_delta(days, seconds, microseconds, 1);
1748c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
17492a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1750c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result == Py_NotImplemented)
1751c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(result);
1752c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
17532a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
17542a799bf77a83adef010ff4751e5195702f159f39Tim Peters
17552a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* This is more natural as a tp_compare, but doesn't work then:  for whatever
17562a799bf77a83adef010ff4751e5195702f159f39Tim Peters * reason, Python's try_3way_compare ignores tp_compare unless
17572a799bf77a83adef010ff4751e5195702f159f39Tim Peters * PyInstance_Check returns true, but these aren't old-style classes.
17582a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
17592a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
17602a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
17612a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1762c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int diff = 42;      /* nonsense */
17632a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1764c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDelta_Check(other)) {
1765c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1766c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (diff == 0) {
1767c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1768c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (diff == 0)
1769c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                diff = GET_TD_MICROSECONDS(self) -
1770c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       GET_TD_MICROSECONDS(other);
1771c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1772c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1773c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (op == Py_EQ || op == Py_NE)
1774c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        diff = 1;               /* any non-zero value will do */
177507534a607bd3d2fd232323811a83279acda10885Tim Peters
1776c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else /* stop this from falling back to address comparison */
1777c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return cmperror((PyObject *)self, other);
177807534a607bd3d2fd232323811a83279acda10885Tim Peters
1779c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return diff_to_bool(diff, op);
17802a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
17812a799bf77a83adef010ff4751e5195702f159f39Tim Peters
17822a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *delta_getstate(PyDateTime_Delta *self);
17832a799bf77a83adef010ff4751e5195702f159f39Tim Peters
17842a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic long
17852a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_hash(PyDateTime_Delta *self)
17862a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1787c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self->hashcode == -1) {
1788c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *temp = delta_getstate(self);
1789c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (temp != NULL) {
1790c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            self->hashcode = PyObject_Hash(temp);
1791c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_DECREF(temp);
1792c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1793c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1794c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self->hashcode;
17952a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
17962a799bf77a83adef010ff4751e5195702f159f39Tim Peters
17972a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
17982a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_multiply(PyObject *left, PyObject *right)
17992a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1800c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = Py_NotImplemented;
18012a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1802c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDelta_Check(left)) {
1803c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* delta * ??? */
1804c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyInt_Check(right) || PyLong_Check(right))
1805c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = multiply_int_timedelta(right,
1806c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            (PyDateTime_Delta *) left);
1807c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1808c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (PyInt_Check(left) || PyLong_Check(left))
1809c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = multiply_int_timedelta(left,
1810c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        (PyDateTime_Delta *) right);
18112a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1812c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result == Py_NotImplemented)
1813c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(result);
1814c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
18152a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
18162a799bf77a83adef010ff4751e5195702f159f39Tim Peters
18172a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
18182a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_divide(PyObject *left, PyObject *right)
18192a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1820c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = Py_NotImplemented;
18212a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1822c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDelta_Check(left)) {
1823c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* delta * ??? */
1824c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyInt_Check(right) || PyLong_Check(right))
1825c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = divide_timedelta_int(
1826c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            (PyDateTime_Delta *)left,
1827c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            right);
1828c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
18292a799bf77a83adef010ff4751e5195702f159f39Tim Peters
1830c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result == Py_NotImplemented)
1831c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(result);
1832c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
18332a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
18342a799bf77a83adef010ff4751e5195702f159f39Tim Peters
18352a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
18362a799bf77a83adef010ff4751e5195702f159f39Tim Peters * timedelta constructor.  sofar is the # of microseconds accounted for
18372a799bf77a83adef010ff4751e5195702f159f39Tim Peters * so far, and there are factor microseconds per current unit, the number
18382a799bf77a83adef010ff4751e5195702f159f39Tim Peters * of which is given by num.  num * factor is added to sofar in a
18392a799bf77a83adef010ff4751e5195702f159f39Tim Peters * numerically careful way, and that's the result.  Any fractional
18402a799bf77a83adef010ff4751e5195702f159f39Tim Peters * microseconds left over (this can happen if num is a float type) are
18412a799bf77a83adef010ff4751e5195702f159f39Tim Peters * added into *leftover.
18422a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Note that there are many ways this can give an error (NULL) return.
18432a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
18442a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
18452a799bf77a83adef010ff4751e5195702f159f39Tim Petersaccum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
18462a799bf77a83adef010ff4751e5195702f159f39Tim Peters      double *leftover)
18472a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1848c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *prod;
1849c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *sum;
1850c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1851c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(num != NULL);
1852c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1853c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyInt_Check(num) || PyLong_Check(num)) {
1854c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        prod = PyNumber_Multiply(num, factor);
1855c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (prod == NULL)
1856c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
1857c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        sum = PyNumber_Add(sofar, prod);
1858c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(prod);
1859c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return sum;
1860c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1861c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1862c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyFloat_Check(num)) {
1863c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        double dnum;
1864c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        double fracpart;
1865c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        double intpart;
1866c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *x;
1867c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *y;
1868c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1869c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* The Plan:  decompose num into an integer part and a
1870c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * fractional part, num = intpart + fracpart.
1871c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * Then num * factor ==
1872c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         *      intpart * factor + fracpart * factor
1873c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * and the LHS can be computed exactly in long arithmetic.
1874c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * The RHS is again broken into an int part and frac part.
1875c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * and the frac part is added into *leftover.
1876c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
1877c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        dnum = PyFloat_AsDouble(num);
1878c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (dnum == -1.0 && PyErr_Occurred())
1879c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
1880c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        fracpart = modf(dnum, &intpart);
1881c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        x = PyLong_FromDouble(intpart);
1882c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (x == NULL)
1883c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
1884c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1885c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        prod = PyNumber_Multiply(x, factor);
1886c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(x);
1887c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (prod == NULL)
1888c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
1889c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1890c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        sum = PyNumber_Add(sofar, prod);
1891c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(prod);
1892c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (sum == NULL)
1893c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
1894c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1895c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (fracpart == 0.0)
1896c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return sum;
1897c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* So far we've lost no information.  Dealing with the
1898c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * fractional part requires float arithmetic, and may
1899c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * lose a little info.
1900c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
1901c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(PyInt_Check(factor) || PyLong_Check(factor));
1902c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyInt_Check(factor))
1903c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            dnum = (double)PyInt_AsLong(factor);
1904c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else
1905c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            dnum = PyLong_AsDouble(factor);
1906c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1907c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        dnum *= fracpart;
1908c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        fracpart = modf(dnum, &intpart);
1909c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        x = PyLong_FromDouble(intpart);
1910c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (x == NULL) {
1911c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_DECREF(sum);
1912c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
1913c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
1914c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1915c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        y = PyNumber_Add(sum, x);
1916c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(sum);
1917c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(x);
1918c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        *leftover += fracpart;
1919c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return y;
1920c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1921c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1922c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_Format(PyExc_TypeError,
1923c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 "unsupported type for timedelta %s component: %s",
1924c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 tag, Py_TYPE(num)->tp_name);
1925c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return NULL;
19262a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
19272a799bf77a83adef010ff4751e5195702f159f39Tim Peters
19282a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
19292a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
19302a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
1931c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *self = NULL;
1932c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1933c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Argument objects. */
1934c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *day = NULL;
1935c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *second = NULL;
1936c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *us = NULL;
1937c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *ms = NULL;
1938c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *minute = NULL;
1939c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *hour = NULL;
1940c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *week = NULL;
1941c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1942c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *x = NULL;         /* running sum of microseconds */
1943c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *y = NULL;         /* temp sum of microseconds */
1944c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    double leftover_us = 0.0;
1945c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1946c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static char *keywords[] = {
1947c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        "days", "seconds", "microseconds", "milliseconds",
1948c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        "minutes", "hours", "weeks", NULL
1949c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    };
1950c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1951c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1952c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    keywords,
1953c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    &day, &second, &us,
1954c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    &ms, &minute, &hour, &week) == 0)
1955c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1956c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1957c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = PyInt_FromLong(0);
1958c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL)
1959c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done;
1960c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1961c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#define CLEANUP         \
1962c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);       \
1963c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = y;              \
1964c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL)      \
1965c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Done
1966c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
1967c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us) {
1968c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        y = accum("microseconds", x, us, us_per_us, &leftover_us);
1969c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        CLEANUP;
1970c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1971c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (ms) {
1972c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1973c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        CLEANUP;
1974c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1975c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (second) {
1976c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        y = accum("seconds", x, second, us_per_second, &leftover_us);
1977c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        CLEANUP;
1978c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1979c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (minute) {
1980c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1981c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        CLEANUP;
1982c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1983c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (hour) {
1984c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        y = accum("hours", x, hour, us_per_hour, &leftover_us);
1985c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        CLEANUP;
1986c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1987c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (day) {
1988c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        y = accum("days", x, day, us_per_day, &leftover_us);
1989c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        CLEANUP;
1990c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1991c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (week) {
1992c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        y = accum("weeks", x, week, us_per_week, &leftover_us);
1993c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        CLEANUP;
1994c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
1995c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (leftover_us) {
1996c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Round to nearest whole # of us, and add into x. */
1997c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1998c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (temp == NULL) {
1999c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_DECREF(x);
2000c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            goto Done;
2001c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
2002c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        y = PyNumber_Add(x, temp);
2003c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(temp);
2004c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        CLEANUP;
2005c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2006c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2007c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self = microseconds_to_delta_ex(x, type);
2008c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
20092a799bf77a83adef010ff4751e5195702f159f39Tim PetersDone:
2010c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self;
20112a799bf77a83adef010ff4751e5195702f159f39Tim Peters
20122a799bf77a83adef010ff4751e5195702f159f39Tim Peters#undef CLEANUP
20132a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
20142a799bf77a83adef010ff4751e5195702f159f39Tim Peters
20152a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
20162a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_nonzero(PyDateTime_Delta *self)
20172a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2018c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return (GET_TD_DAYS(self) != 0
2019c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        || GET_TD_SECONDS(self) != 0
2020c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        || GET_TD_MICROSECONDS(self) != 0);
20212a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
20222a799bf77a83adef010ff4751e5195702f159f39Tim Peters
20232a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
20242a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_repr(PyDateTime_Delta *self)
20252a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2026c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (GET_TD_MICROSECONDS(self) != 0)
2027c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return PyString_FromFormat("%s(%d, %d, %d)",
2028c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   Py_TYPE(self)->tp_name,
2029c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   GET_TD_DAYS(self),
2030c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   GET_TD_SECONDS(self),
2031c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   GET_TD_MICROSECONDS(self));
2032c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (GET_TD_SECONDS(self) != 0)
2033c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return PyString_FromFormat("%s(%d, %d)",
2034c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   Py_TYPE(self)->tp_name,
2035c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   GET_TD_DAYS(self),
2036c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   GET_TD_SECONDS(self));
20372a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2038c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyString_FromFormat("%s(%d)",
2039c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                               Py_TYPE(self)->tp_name,
2040c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                               GET_TD_DAYS(self));
20412a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
20422a799bf77a83adef010ff4751e5195702f159f39Tim Peters
20432a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
20442a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_str(PyDateTime_Delta *self)
20452a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2046c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int days = GET_TD_DAYS(self);
2047c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int seconds = GET_TD_SECONDS(self);
2048c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int us = GET_TD_MICROSECONDS(self);
2049c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int hours;
2050c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int minutes;
2051c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char buf[100];
2052c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char *pbuf = buf;
2053c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    size_t buflen = sizeof(buf);
2054c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int n;
2055c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2056c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    minutes = divmod(seconds, 60, &seconds);
2057c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    hours = divmod(minutes, 60, &minutes);
2058c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2059c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (days) {
2060c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2061c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                          (days == 1 || days == -1) ? "" : "s");
2062c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (n < 0 || (size_t)n >= buflen)
2063c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            goto Fail;
2064c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        pbuf += n;
2065c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        buflen -= (size_t)n;
2066c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2067c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2068c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2069c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      hours, minutes, seconds);
2070c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (n < 0 || (size_t)n >= buflen)
2071c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Fail;
2072c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    pbuf += n;
2073c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    buflen -= (size_t)n;
2074c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2075c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us) {
2076c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2077c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (n < 0 || (size_t)n >= buflen)
2078c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            goto Fail;
2079c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        pbuf += n;
2080c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2081c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2082c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyString_FromStringAndSize(buf, pbuf - buf);
2083ba873472d2a3f6cda91b13367360e1e05b7cdcbcTim Peters
2084ba873472d2a3f6cda91b13367360e1e05b7cdcbcTim Peters Fail:
2085c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2086c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return NULL;
20872a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
20882a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2089371935fc065e69c59c5382cbbf2cb098cf410f0eTim Peters/* Pickle support, a simple use of __reduce__. */
2090371935fc065e69c59c5382cbbf2cb098cf410f0eTim Peters
2091b57f8f02bafcb74cd6c47f59f67d1b6bdfb33aecTim Peters/* __getstate__ isn't exposed */
20922a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
20932a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_getstate(PyDateTime_Delta *self)
20942a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2095c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_BuildValue("iii", GET_TD_DAYS(self),
2096c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                GET_TD_SECONDS(self),
2097c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                GET_TD_MICROSECONDS(self));
20982a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
20992a799bf77a83adef010ff4751e5195702f159f39Tim Peters
21002a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
2101bcfaf8007d8d14e3a6e65d13ad693b4874688cabAntoine Pitroudelta_total_seconds(PyObject *self)
2102bcfaf8007d8d14e3a6e65d13ad693b4874688cabAntoine Pitrou{
2103c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *total_seconds;
2104c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *total_microseconds;
2105c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *one_million;
21067000e9e01bb784dfc23a70a9d736613ae83c8dadMark Dickinson
2107c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2108c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (total_microseconds == NULL)
2109c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
21107000e9e01bb784dfc23a70a9d736613ae83c8dadMark Dickinson
2111c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    one_million = PyLong_FromLong(1000000L);
2112c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (one_million == NULL) {
2113c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(total_microseconds);
2114c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2115c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
21167000e9e01bb784dfc23a70a9d736613ae83c8dadMark Dickinson
2117c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
21187000e9e01bb784dfc23a70a9d736613ae83c8dadMark Dickinson
2119c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(total_microseconds);
2120c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(one_million);
2121c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return total_seconds;
2122bcfaf8007d8d14e3a6e65d13ad693b4874688cabAntoine Pitrou}
2123bcfaf8007d8d14e3a6e65d13ad693b4874688cabAntoine Pitrou
2124bcfaf8007d8d14e3a6e65d13ad693b4874688cabAntoine Pitroustatic PyObject *
21252a799bf77a83adef010ff4751e5195702f159f39Tim Petersdelta_reduce(PyDateTime_Delta* self)
21262a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2127c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
21282a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
21292a799bf77a83adef010ff4751e5195702f159f39Tim Peters
21302a799bf77a83adef010ff4751e5195702f159f39Tim Peters#define OFFSET(field)  offsetof(PyDateTime_Delta, field)
21312a799bf77a83adef010ff4751e5195702f159f39Tim Peters
21322a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyMemberDef delta_members[] = {
2133177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
2134c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"days",         T_INT, OFFSET(days),         READONLY,
2135c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Number of days.")},
21362a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2137c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"seconds",      T_INT, OFFSET(seconds),      READONLY,
2138c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
21392a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2140c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2141c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2142c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL}
21432a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
21442a799bf77a83adef010ff4751e5195702f159f39Tim Peters
21452a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyMethodDef delta_methods[] = {
2146c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2147c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Total seconds in the duration.")},
2148bcfaf8007d8d14e3a6e65d13ad693b4874688cabAntoine Pitrou
2149c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2150c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("__reduce__() -> (cls, state)")},
2151177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
2152c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL,      NULL},
21532a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
21542a799bf77a83adef010ff4751e5195702f159f39Tim Peters
21552a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic char delta_doc[] =
21562a799bf77a83adef010ff4751e5195702f159f39Tim PetersPyDoc_STR("Difference between two datetime values.");
21572a799bf77a83adef010ff4751e5195702f159f39Tim Peters
21582a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyNumberMethods delta_as_number = {
2159c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta_add,                                  /* nb_add */
2160c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta_subtract,                             /* nb_subtract */
2161c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta_multiply,                             /* nb_multiply */
2162c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta_divide,                               /* nb_divide */
2163c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_remainder */
2164c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_divmod */
2165c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_power */
2166c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (unaryfunc)delta_negative,                  /* nb_negative */
2167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (unaryfunc)delta_positive,                  /* nb_positive */
2168c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (unaryfunc)delta_abs,                       /* nb_absolute */
2169c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (inquiry)delta_nonzero,                     /* nb_nonzero */
2170c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_invert*/
2171c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_lshift*/
2172c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_rshift*/
2173c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_and*/
2174c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_xor*/
2175c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_or*/
2176c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_coerce*/
2177c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_int*/
2178c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_long*/
2179c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_float*/
2180c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_oct*/
2181c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_hex*/
2182c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_add*/
2183c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_subtract*/
2184c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_multiply*/
2185c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_divide*/
2186c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_remainder*/
2187c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_power*/
2188c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_lshift*/
2189c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_rshift*/
2190c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_and*/
2191c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_xor*/
2192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /*nb_inplace_or*/
2193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta_divide,                               /* nb_floor_divide */
2194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_true_divide */
2195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_inplace_floor_divide */
2196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_inplace_true_divide */
21972a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
21982a799bf77a83adef010ff4751e5195702f159f39Tim Peters
21992a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyTypeObject PyDateTime_DeltaType = {
2200c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyVarObject_HEAD_INIT(NULL, 0)
2201c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    "datetime.timedelta",                               /* tp_name */
2202c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    sizeof(PyDateTime_Delta),                           /* tp_basicsize */
2203c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_itemsize */
2204c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_dealloc */
2205c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_print */
2206c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_getattr */
2207c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_setattr */
2208c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_compare */
2209c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (reprfunc)delta_repr,                               /* tp_repr */
2210c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &delta_as_number,                                   /* tp_as_number */
2211c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_as_sequence */
2212c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_as_mapping */
2213c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (hashfunc)delta_hash,                               /* tp_hash */
2214c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_call */
2215c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (reprfunc)delta_str,                                /* tp_str */
2216c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject_GenericGetAttr,                            /* tp_getattro */
2217c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_setattro */
2218c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_as_buffer */
2219c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2220c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_TPFLAGS_BASETYPE,                            /* tp_flags */
2221c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta_doc,                                          /* tp_doc */
2222c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_traverse */
2223c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_clear */
2224c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (richcmpfunc)delta_richcompare,                     /* tp_richcompare */
2225c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_weaklistoffset */
2226c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_iter */
2227c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_iternext */
2228c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta_methods,                                      /* tp_methods */
2229c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta_members,                                      /* tp_members */
2230c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_getset */
2231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_base */
2232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_dict */
2233c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_descr_get */
2234c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_descr_set */
2235c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_dictoffset */
2236c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_init */
2237c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_alloc */
2238c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta_new,                                          /* tp_new */
2239c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_free */
22402a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
22412a799bf77a83adef010ff4751e5195702f159f39Tim Peters
22422a799bf77a83adef010ff4751e5195702f159f39Tim Peters/*
22432a799bf77a83adef010ff4751e5195702f159f39Tim Peters * PyDateTime_Date implementation.
22442a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
22452a799bf77a83adef010ff4751e5195702f159f39Tim Peters
22462a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Accessor properties. */
22472a799bf77a83adef010ff4751e5195702f159f39Tim Peters
22482a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
22492a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_year(PyDateTime_Date *self, void *unused)
22502a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2251c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(GET_YEAR(self));
22522a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
22532a799bf77a83adef010ff4751e5195702f159f39Tim Peters
22542a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
22552a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_month(PyDateTime_Date *self, void *unused)
22562a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2257c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(GET_MONTH(self));
22582a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
22592a799bf77a83adef010ff4751e5195702f159f39Tim Peters
22602a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
22612a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_day(PyDateTime_Date *self, void *unused)
22622a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2263c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(GET_DAY(self));
22642a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
22652a799bf77a83adef010ff4751e5195702f159f39Tim Peters
22662a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyGetSetDef date_getset[] = {
2267c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"year",        (getter)date_year},
2268c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"month",       (getter)date_month},
2269c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"day",         (getter)date_day},
2270c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL}
22712a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
22722a799bf77a83adef010ff4751e5195702f159f39Tim Peters
22732a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Constructors. */
22742a799bf77a83adef010ff4751e5195702f159f39Tim Peters
227502cbf4ae4baff0dbe373351ebf182cbcfc05d6bdMartin v. Löwisstatic char *date_kws[] = {"year", "month", "day", NULL};
227612bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
22772a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
22782a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_new(PyTypeObject *type, PyObject *args, PyObject *kw)
22792a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2280c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *self = NULL;
2281c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *state;
2282c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int year;
2283c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int month;
2284c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int day;
2285c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2286c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Check for invocation from pickle with __getstate__ state */
2287c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyTuple_GET_SIZE(args) == 1 &&
2288c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2289c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2290c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
2291c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {
2292c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyDateTime_Date *me;
2293c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2294c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2295c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (me != NULL) {
2296c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            char *pdata = PyString_AS_STRING(state);
2297c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2298c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            me->hashcode = -1;
2299c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
2300c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return (PyObject *)me;
2301c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2302c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2303c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2304c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    &year, &month, &day)) {
2305c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (check_date_args(year, month, day) < 0)
2306c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
2307c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        self = new_date_ex(year, month, day, type);
2308c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2309c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self;
23102a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
23112a799bf77a83adef010ff4751e5195702f159f39Tim Peters
23122a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Return new date from localtime(t). */
23132a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
23141b6f7a9057874ecd2793059f210de87837fe1911Tim Petersdate_local_from_time_t(PyObject *cls, double ts)
23152a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2316c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    struct tm *tm;
2317c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time_t t;
2318c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
2319c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2320c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    t = _PyTime_DoubleToTimet(ts);
2321c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (t == (time_t)-1 && PyErr_Occurred())
2322c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2323c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tm = localtime(&t);
2324c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tm)
2325c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = PyObject_CallFunction(cls, "iii",
2326c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tm->tm_year + 1900,
2327c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tm->tm_mon + 1,
2328c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tm->tm_mday);
2329c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
2330c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
2331c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "timestamp out of range for "
2332c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "platform localtime() function");
2333c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
23342a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
23352a799bf77a83adef010ff4751e5195702f159f39Tim Peters
23362a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Return new date from current time.
23372a799bf77a83adef010ff4751e5195702f159f39Tim Peters * We say this is equivalent to fromtimestamp(time.time()), and the
23382a799bf77a83adef010ff4751e5195702f159f39Tim Peters * only way to be sure of that is to *call* time.time().  That's not
23392a799bf77a83adef010ff4751e5195702f159f39Tim Peters * generally the same as calling C's time.
23402a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
23412a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
23422a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_today(PyObject *cls, PyObject *dummy)
23432a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2344c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *time;
2345c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
23462a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2347c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time = time_time();
2348c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (time == NULL)
2349c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
23502a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2351c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Note well:  today() is a class method, so this may not call
2352c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * date.fromtimestamp.  For example, it may call
2353c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * datetime.fromtimestamp.  That's why we need all the accuracy
2354c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * time.time() delivers; if someone were gonzo about optimization,
2355c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * date.today() could get away with plain C time().
2356c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
2357c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2358c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(time);
2359c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
23602a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
23612a799bf77a83adef010ff4751e5195702f159f39Tim Peters
23622a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Return new date from given timestamp (Python timestamp -- a double). */
23632a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
23642a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_fromtimestamp(PyObject *cls, PyObject *args)
23652a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2366c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    double timestamp;
2367c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
23682a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2369c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2370c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = date_local_from_time_t(cls, timestamp);
2371c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
23722a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
23732a799bf77a83adef010ff4751e5195702f159f39Tim Peters
23742a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Return new date from proleptic Gregorian ordinal.  Raises ValueError if
23752a799bf77a83adef010ff4751e5195702f159f39Tim Peters * the ordinal is out of range.
23762a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
23772a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
23782a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_fromordinal(PyObject *cls, PyObject *args)
23792a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2380c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
2381c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int ordinal;
23822a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2383c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2384c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int year;
2385c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int month;
2386c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int day;
23872a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2388c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (ordinal < 1)
2389c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            PyErr_SetString(PyExc_ValueError, "ordinal must be "
2390c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                              ">= 1");
2391c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else {
2392c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ord_to_ymd(ordinal, &year, &month, &day);
2393c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = PyObject_CallFunction(cls, "iii",
2394c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                           year, month, day);
2395c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
2396c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2397c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
23982a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
23992a799bf77a83adef010ff4751e5195702f159f39Tim Peters
24002a799bf77a83adef010ff4751e5195702f159f39Tim Peters/*
24012a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Date arithmetic.
24022a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
24032a799bf77a83adef010ff4751e5195702f159f39Tim Peters
24042a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* date + timedelta -> date.  If arg negate is true, subtract the timedelta
24052a799bf77a83adef010ff4751e5195702f159f39Tim Peters * instead.
24062a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
24072a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
24082a799bf77a83adef010ff4751e5195702f159f39Tim Petersadd_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
24092a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2410c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
2411c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int year = GET_YEAR(date);
2412c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int month = GET_MONTH(date);
2413c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int deltadays = GET_TD_DAYS(delta);
2414c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* C-level overflow is impossible because |deltadays| < 1e9. */
2415c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
24162a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2417c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (normalize_date(&year, &month, &day) >= 0)
2418c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = new_date(year, month, day);
2419c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
24202a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
24212a799bf77a83adef010ff4751e5195702f159f39Tim Peters
24222a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
24232a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_add(PyObject *left, PyObject *right)
24242a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2425c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2426c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(Py_NotImplemented);
2427c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return Py_NotImplemented;
2428c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2429c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDate_Check(left)) {
2430c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* date + ??? */
2431c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyDelta_Check(right))
2432c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* date + delta */
2433c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return add_date_timedelta((PyDateTime_Date *) left,
2434c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      (PyDateTime_Delta *) right,
2435c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      0);
2436c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2437c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else {
2438c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* ??? + date
2439c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * 'right' must be one of us, or we wouldn't have been called
2440c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
2441c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyDelta_Check(left))
2442c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* delta + date */
2443c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return add_date_timedelta((PyDateTime_Date *) right,
2444c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      (PyDateTime_Delta *) left,
2445c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      0);
2446c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2447c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(Py_NotImplemented);
2448c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_NotImplemented;
24492a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
24502a799bf77a83adef010ff4751e5195702f159f39Tim Peters
24512a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
24522a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_subtract(PyObject *left, PyObject *right)
24532a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2454c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2455c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(Py_NotImplemented);
2456c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return Py_NotImplemented;
2457c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2458c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDate_Check(left)) {
2459c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyDate_Check(right)) {
2460c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* date - date */
2461c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int left_ord = ymd_to_ord(GET_YEAR(left),
2462c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      GET_MONTH(left),
2463c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      GET_DAY(left));
2464c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int right_ord = ymd_to_ord(GET_YEAR(right),
2465c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       GET_MONTH(right),
2466c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       GET_DAY(right));
2467c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return new_delta(left_ord - right_ord, 0, 0, 0);
2468c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
2469c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyDelta_Check(right)) {
2470c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* date - delta */
2471c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return add_date_timedelta((PyDateTime_Date *) left,
2472c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      (PyDateTime_Delta *) right,
2473c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      1);
2474c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
2475c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2476c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(Py_NotImplemented);
2477c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_NotImplemented;
24782a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
24792a799bf77a83adef010ff4751e5195702f159f39Tim Peters
24802a799bf77a83adef010ff4751e5195702f159f39Tim Peters
24812a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Various ways to turn a date into a string. */
24822a799bf77a83adef010ff4751e5195702f159f39Tim Peters
24832a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
24842a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_repr(PyDateTime_Date *self)
24852a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2486c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char buffer[1028];
2487c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    const char *type_name;
24882a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2489c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    type_name = Py_TYPE(self)->tp_name;
2490c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2491c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  type_name,
2492c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
24932a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2494c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyString_FromString(buffer);
24952a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
24962a799bf77a83adef010ff4751e5195702f159f39Tim Peters
24972a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
24982a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_isoformat(PyDateTime_Date *self)
24992a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2500c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char buffer[128];
25012a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2502c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    isoformat_date(self, buffer, sizeof(buffer));
2503c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyString_FromString(buffer);
25042a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
25052a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2506e2df5ffa539bc1d903684e8c5863645a8886bfe2Tim Peters/* str() calls the appropriate isoformat() method. */
25072a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
25082a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_str(PyDateTime_Date *self)
25092a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2510c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
25112a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
25122a799bf77a83adef010ff4751e5195702f159f39Tim Peters
25132a799bf77a83adef010ff4751e5195702f159f39Tim Peters
25142a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
25152a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_ctime(PyDateTime_Date *self)
25162a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2517c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return format_ctime(self, 0, 0, 0);
25182a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
25192a799bf77a83adef010ff4751e5195702f159f39Tim Peters
25202a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
25212a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
25222a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2523c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* This method can be inherited, and needs to call the
2524c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * timetuple() method appropriate to self's class.
2525c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
2526c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
2527c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tuple;
2528c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    const char *format;
2529c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_ssize_t format_len;
2530c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static char *keywords[] = {"format", NULL};
25312a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2532c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2533c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      &format, &format_len))
2534c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
25352a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2536c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2537c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tuple == NULL)
2538c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2539c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = wrap_strftime((PyObject *)self, format, format_len, tuple,
2540c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           (PyObject *)self);
2541c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(tuple);
2542c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
25432a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
25442a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2545a9f7d6248032c9572b4d2024a1be8bd2823af09fEric Smithstatic PyObject *
2546a9f7d6248032c9572b4d2024a1be8bd2823af09fEric Smithdate_format(PyDateTime_Date *self, PyObject *args)
2547a9f7d6248032c9572b4d2024a1be8bd2823af09fEric Smith{
2548c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *format;
2549c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2550c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (!PyArg_ParseTuple(args, "O:__format__", &format))
2551c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2552c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2553c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Check for str or unicode */
2554c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyString_Check(format)) {
2555c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* If format is zero length, return str(self) */
2556c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyString_GET_SIZE(format) == 0)
2557c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return PyObject_Str((PyObject *)self);
2558c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    } else if (PyUnicode_Check(format)) {
2559c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* If format is zero length, return str(self) */
2560c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyUnicode_GET_SIZE(format) == 0)
2561c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return PyObject_Unicode((PyObject *)self);
2562c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    } else {
2563c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_Format(PyExc_ValueError,
2564c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     "__format__ expects str or unicode, not %.200s",
2565c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                     Py_TYPE(format)->tp_name);
2566c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2567c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2568c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2569a9f7d6248032c9572b4d2024a1be8bd2823af09fEric Smith}
2570a9f7d6248032c9572b4d2024a1be8bd2823af09fEric Smith
25712a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ISO methods. */
25722a799bf77a83adef010ff4751e5195702f159f39Tim Peters
25732a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
25742a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_isoweekday(PyDateTime_Date *self)
25752a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2576c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
25772a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2578c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(dow + 1);
25792a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
25802a799bf77a83adef010ff4751e5195702f159f39Tim Peters
25812a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
25822a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_isocalendar(PyDateTime_Date *self)
25832a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2584c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int  year         = GET_YEAR(self);
2585c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int  week1_monday = iso_week1_monday(year);
2586c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int today         = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2587c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int  week;
2588c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int  day;
2589c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2590c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    week = divmod(today - week1_monday, 7, &day);
2591c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (week < 0) {
2592c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        --year;
2593c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        week1_monday = iso_week1_monday(year);
2594c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        week = divmod(today - week1_monday, 7, &day);
2595c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2596c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2597c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        ++year;
2598c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        week = 0;
2599c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2600c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_BuildValue("iii", year, week + 1, day + 1);
26012a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
26022a799bf77a83adef010ff4751e5195702f159f39Tim Peters
26032a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Miscellaneous methods. */
26042a799bf77a83adef010ff4751e5195702f159f39Tim Peters
26052a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* This is more natural as a tp_compare, but doesn't work then:  for whatever
26062a799bf77a83adef010ff4751e5195702f159f39Tim Peters * reason, Python's try_3way_compare ignores tp_compare unless
26072a799bf77a83adef010ff4751e5195702f159f39Tim Peters * PyInstance_Check returns true, but these aren't old-style classes.
26082a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
26092a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
26102a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_richcompare(PyDateTime_Date *self, PyObject *other, int op)
26112a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2612c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int diff = 42;      /* nonsense */
26132a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2614c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDate_Check(other))
2615c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2616c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      _PyDateTime_DATE_DATASIZE);
261707534a607bd3d2fd232323811a83279acda10885Tim Peters
2618c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (PyObject_HasAttrString(other, "timetuple")) {
2619c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* A hook for other kinds of date objects. */
2620c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(Py_NotImplemented);
2621c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return Py_NotImplemented;
2622c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2623c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (op == Py_EQ || op == Py_NE)
2624c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        diff = 1;               /* any non-zero value will do */
262507534a607bd3d2fd232323811a83279acda10885Tim Peters
2626c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else /* stop this from falling back to address comparison */
2627c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return cmperror((PyObject *)self, other);
262807534a607bd3d2fd232323811a83279acda10885Tim Peters
2629c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return diff_to_bool(diff, op);
26302a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
26312a799bf77a83adef010ff4751e5195702f159f39Tim Peters
26322a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
26332a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_timetuple(PyDateTime_Date *self)
26342a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2635c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return build_struct_time(GET_YEAR(self),
2636c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             GET_MONTH(self),
2637c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             GET_DAY(self),
2638c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             0, 0, 0, -1);
26392a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
26402a799bf77a83adef010ff4751e5195702f159f39Tim Peters
264112bf339aea9c787f7ce655d613b8898f7511c7dbTim Petersstatic PyObject *
264212bf339aea9c787f7ce655d613b8898f7511c7dbTim Petersdate_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
264312bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters{
2644c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *clone;
2645c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tuple;
2646c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int year = GET_YEAR(self);
2647c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int month = GET_MONTH(self);
2648c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int day = GET_DAY(self);
264912bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
2650c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2651c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      &year, &month, &day))
2652c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2653c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tuple = Py_BuildValue("iii", year, month, day);
2654c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tuple == NULL)
2655c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2656c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    clone = date_new(Py_TYPE(self), tuple, NULL);
2657c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(tuple);
2658c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return clone;
265912bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters}
266012bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
26612a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *date_getstate(PyDateTime_Date *self);
26622a799bf77a83adef010ff4751e5195702f159f39Tim Peters
26632a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic long
26642a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_hash(PyDateTime_Date *self)
26652a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2666c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self->hashcode == -1) {
2667c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *temp = date_getstate(self);
2668c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (temp != NULL) {
2669c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            self->hashcode = PyObject_Hash(temp);
2670c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_DECREF(temp);
2671c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
2672c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2673c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self->hashcode;
26742a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
26752a799bf77a83adef010ff4751e5195702f159f39Tim Peters
26762a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
26772a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_toordinal(PyDateTime_Date *self)
26782a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2679c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2680c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                     GET_DAY(self)));
26812a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
26822a799bf77a83adef010ff4751e5195702f159f39Tim Peters
26832a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
26842a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_weekday(PyDateTime_Date *self)
26852a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2686c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
26872a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2688c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(dow);
26892a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
26902a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2691371935fc065e69c59c5382cbbf2cb098cf410f0eTim Peters/* Pickle support, a simple use of __reduce__. */
26922a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2693b57f8f02bafcb74cd6c47f59f67d1b6bdfb33aecTim Peters/* __getstate__ isn't exposed */
26942a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
26952a799bf77a83adef010ff4751e5195702f159f39Tim Petersdate_getstate(PyDateTime_Date *self)
26962a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2697c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_BuildValue(
2698c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        "(N)",
2699c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyString_FromStringAndSize((char *)self->data,
2700c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   _PyDateTime_DATE_DATASIZE));
27012a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
27022a799bf77a83adef010ff4751e5195702f159f39Tim Peters
27032a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
2704177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossumdate_reduce(PyDateTime_Date *self, PyObject *arg)
27052a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2706c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
27072a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
27082a799bf77a83adef010ff4751e5195702f159f39Tim Peters
27092a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyMethodDef date_methods[] = {
2710177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
2711c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Class methods: */
2712177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
2713c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2714c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                                       METH_CLASS,
2715c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2716c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "time.time()).")},
27172a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2718c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"fromordinal", (PyCFunction)date_fromordinal,      METH_VARARGS |
2719c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                                    METH_CLASS,
2720c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2721c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "ordinal.")},
27222a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2723c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"today",         (PyCFunction)date_today,   METH_NOARGS | METH_CLASS,
2724c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Current date or datetime:  same as "
2725c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "self.__class__.fromtimestamp(time.time()).")},
27262a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2727c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Instance methods: */
27282a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2729c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"ctime",       (PyCFunction)date_ctime,        METH_NOARGS,
2730c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return ctime() style string.")},
27312a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2732c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"strftime",        (PyCFunction)date_strftime,     METH_VARARGS | METH_KEYWORDS,
2733c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("format -> strftime() style string.")},
27342a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2735c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"__format__",      (PyCFunction)date_format,       METH_VARARGS,
2736c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Formats self with strftime.")},
2737a9f7d6248032c9572b4d2024a1be8bd2823af09fEric Smith
2738c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"timetuple",   (PyCFunction)date_timetuple,    METH_NOARGS,
2739c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return time tuple, compatible with time.localtime().")},
27402a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2741c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"isocalendar", (PyCFunction)date_isocalendar,  METH_NOARGS,
2742c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2743c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "weekday.")},
27442a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2745c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"isoformat",   (PyCFunction)date_isoformat,        METH_NOARGS,
2746c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
27472a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2748c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"isoweekday",  (PyCFunction)date_isoweekday,   METH_NOARGS,
2749c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return the day of the week represented by the date.\n"
2750c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "Monday == 1 ... Sunday == 7")},
27512a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2752c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"toordinal",   (PyCFunction)date_toordinal,    METH_NOARGS,
2753c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return proleptic Gregorian ordinal.  January 1 of year "
2754c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "1 is day 1.")},
27552a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2756c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"weekday",     (PyCFunction)date_weekday,      METH_NOARGS,
2757c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return the day of the week represented by the date.\n"
2758c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "Monday == 0 ... Sunday == 6")},
27592a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2760c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"replace",     (PyCFunction)date_replace,      METH_VARARGS | METH_KEYWORDS,
2761c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return date with new specified fields.")},
276212bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
2763c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"__reduce__", (PyCFunction)date_reduce,        METH_NOARGS,
2764c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("__reduce__() -> (cls, state)")},
2765177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
2766c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL,      NULL}
27672a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
27682a799bf77a83adef010ff4751e5195702f159f39Tim Peters
27692a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic char date_doc[] =
27703a4231dd745e54ae533ce46371637f1fe8fa6a7bRaymond HettingerPyDoc_STR("date(year, month, day) --> date object");
27712a799bf77a83adef010ff4751e5195702f159f39Tim Peters
27722a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyNumberMethods date_as_number = {
2773c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    date_add,                                           /* nb_add */
2774c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    date_subtract,                                      /* nb_subtract */
2775c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* nb_multiply */
2776c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* nb_divide */
2777c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* nb_remainder */
2778c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* nb_divmod */
2779c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* nb_power */
2780c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* nb_negative */
2781c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* nb_positive */
2782c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* nb_absolute */
2783c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* nb_nonzero */
27842a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
27852a799bf77a83adef010ff4751e5195702f159f39Tim Peters
27862a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyTypeObject PyDateTime_DateType = {
2787c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyVarObject_HEAD_INIT(NULL, 0)
2788c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    "datetime.date",                                    /* tp_name */
2789c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    sizeof(PyDateTime_Date),                            /* tp_basicsize */
2790c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_itemsize */
2791c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_dealloc */
2792c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_print */
2793c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_getattr */
2794c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_setattr */
2795c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_compare */
2796c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (reprfunc)date_repr,                                /* tp_repr */
2797c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &date_as_number,                                    /* tp_as_number */
2798c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_as_sequence */
2799c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_as_mapping */
2800c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (hashfunc)date_hash,                                /* tp_hash */
2801c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_call */
2802c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (reprfunc)date_str,                                 /* tp_str */
2803c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject_GenericGetAttr,                            /* tp_getattro */
2804c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_setattro */
2805c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_as_buffer */
2806c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2807c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TPFLAGS_BASETYPE,                                /* tp_flags */
2808c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    date_doc,                                           /* tp_doc */
2809c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_traverse */
2810c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_clear */
2811c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (richcmpfunc)date_richcompare,                      /* tp_richcompare */
2812c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_weaklistoffset */
2813c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_iter */
2814c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_iternext */
2815c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    date_methods,                                       /* tp_methods */
2816c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_members */
2817c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    date_getset,                                        /* tp_getset */
2818c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_base */
2819c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_dict */
2820c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_descr_get */
2821c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_descr_set */
2822c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_dictoffset */
2823c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_init */
2824c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_alloc */
2825c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    date_new,                                           /* tp_new */
2826c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                                  /* tp_free */
28272a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
28282a799bf77a83adef010ff4751e5195702f159f39Tim Peters
28292a799bf77a83adef010ff4751e5195702f159f39Tim Peters/*
2830a9bc168f95408be86e79365a075d069465a06434Tim Peters * PyDateTime_TZInfo implementation.
28312a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
28322a799bf77a83adef010ff4751e5195702f159f39Tim Peters
2833a9bc168f95408be86e79365a075d069465a06434Tim Peters/* This is a pure abstract base class, so doesn't do anything beyond
2834a9bc168f95408be86e79365a075d069465a06434Tim Peters * raising NotImplemented exceptions.  Real tzinfo classes need
2835a9bc168f95408be86e79365a075d069465a06434Tim Peters * to derive from this.  This is mostly for clarity, and for efficiency in
2836a9bc168f95408be86e79365a075d069465a06434Tim Peters * datetime and time constructors (their tzinfo arguments need to
2837a9bc168f95408be86e79365a075d069465a06434Tim Peters * be subclasses of this tzinfo class, which is easy and quick to check).
2838a9bc168f95408be86e79365a075d069465a06434Tim Peters *
2839a9bc168f95408be86e79365a075d069465a06434Tim Peters * Note:  For reasons having to do with pickling of subclasses, we have
2840a9bc168f95408be86e79365a075d069465a06434Tim Peters * to allow tzinfo objects to be instantiated.  This wasn't an issue
2841a9bc168f95408be86e79365a075d069465a06434Tim Peters * in the Python implementation (__init__() could raise NotImplementedError
2842a9bc168f95408be86e79365a075d069465a06434Tim Peters * there without ill effect), but doing so in the C implementation hit a
2843a9bc168f95408be86e79365a075d069465a06434Tim Peters * brick wall.
2844a9bc168f95408be86e79365a075d069465a06434Tim Peters */
28452a799bf77a83adef010ff4751e5195702f159f39Tim Peters
28462a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
2847a9bc168f95408be86e79365a075d069465a06434Tim Peterstzinfo_nogo(const char* methodname)
28482a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
2849c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_Format(PyExc_NotImplementedError,
2850c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 "a tzinfo subclass must implement %s()",
2851c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                 methodname);
2852c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return NULL;
2853a9bc168f95408be86e79365a075d069465a06434Tim Peters}
2854a9bc168f95408be86e79365a075d069465a06434Tim Peters
2855a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Methods.  A subclass must implement these. */
2856a9bc168f95408be86e79365a075d069465a06434Tim Peters
285752dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Petersstatic PyObject *
2858a9bc168f95408be86e79365a075d069465a06434Tim Peterstzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2859a9bc168f95408be86e79365a075d069465a06434Tim Peters{
2860c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return tzinfo_nogo("tzname");
2861a9bc168f95408be86e79365a075d069465a06434Tim Peters}
2862a9bc168f95408be86e79365a075d069465a06434Tim Peters
286352dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Petersstatic PyObject *
2864a9bc168f95408be86e79365a075d069465a06434Tim Peterstzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2865a9bc168f95408be86e79365a075d069465a06434Tim Peters{
2866c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return tzinfo_nogo("utcoffset");
2867a9bc168f95408be86e79365a075d069465a06434Tim Peters}
2868a9bc168f95408be86e79365a075d069465a06434Tim Peters
286952dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Petersstatic PyObject *
2870a9bc168f95408be86e79365a075d069465a06434Tim Peterstzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2871a9bc168f95408be86e79365a075d069465a06434Tim Peters{
2872c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return tzinfo_nogo("dst");
2873a9bc168f95408be86e79365a075d069465a06434Tim Peters}
2874a9bc168f95408be86e79365a075d069465a06434Tim Peters
287552dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Petersstatic PyObject *
287652dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Peterstzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
287752dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Peters{
2878c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int y, m, d, hh, mm, ss, us;
2879c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2880c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
2881c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int off, dst;
2882c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int none;
2883c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int delta;
2884c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2885c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyDateTime_Check(dt)) {
2886c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
2887c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "fromutc: argument must be a datetime");
2888c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2889c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2890c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2891c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2892c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "is not self");
2893c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2894c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2895c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2896c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2897c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (off == -1 && PyErr_Occurred())
2898c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2899c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (none) {
2900c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2901c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "utcoffset() result required");
2902c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2903c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2904c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2905c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2906c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (dst == -1 && PyErr_Occurred())
2907c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2908c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (none) {
2909c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2910c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "dst() result required");
2911c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2912c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2913c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2914c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    y = GET_YEAR(dt);
2915c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    m = GET_MONTH(dt);
2916c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    d = GET_DAY(dt);
2917c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    hh = DATE_GET_HOUR(dt);
2918c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    mm = DATE_GET_MINUTE(dt);
2919c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    ss = DATE_GET_SECOND(dt);
2920c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us = DATE_GET_MICROSECOND(dt);
2921c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2922c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    delta = off - dst;
2923c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    mm += delta;
2924c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if ((mm < 0 || mm >= 60) &&
2925c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2926c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2927c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2928c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result == NULL)
2929c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return result;
2930c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2931c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    dst = call_dst(dt->tzinfo, result, &none);
2932c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (dst == -1 && PyErr_Occurred())
2933c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Fail;
2934c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (none)
2935c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Inconsistent;
2936c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (dst == 0)
2937c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return result;
2938c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2939c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    mm += dst;
2940c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if ((mm < 0 || mm >= 60) &&
2941c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2942c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto Fail;
2943c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(result);
2944c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2945c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
294652dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Peters
294752dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim PetersInconsistent:
2948c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2949c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    "inconsistent results; cannot convert");
295052dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Peters
2951c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* fall thru to failure */
295252dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim PetersFail:
2953c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(result);
2954c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return NULL;
295552dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Peters}
295652dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Peters
2957a9bc168f95408be86e79365a075d069465a06434Tim Peters/*
2958a9bc168f95408be86e79365a075d069465a06434Tim Peters * Pickle support.  This is solely so that tzinfo subclasses can use
2959177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum * pickling -- tzinfo itself is supposed to be uninstantiable.
2960a9bc168f95408be86e79365a075d069465a06434Tim Peters */
2961a9bc168f95408be86e79365a075d069465a06434Tim Peters
2962177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossumstatic PyObject *
2963177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossumtzinfo_reduce(PyObject *self)
2964177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum{
2965c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *args, *state, *tmp;
2966c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *getinitargs, *getstate;
2967c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2968c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tmp = PyTuple_New(0);
2969c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tmp == NULL)
2970c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
2971c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2972c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2973c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (getinitargs != NULL) {
2974c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        args = PyObject_CallObject(getinitargs, tmp);
2975c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(getinitargs);
2976c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (args == NULL) {
2977c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_DECREF(tmp);
2978c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
2979c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
2980c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2981c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else {
2982c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_Clear();
2983c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        args = tmp;
2984c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(args);
2985c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2986c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
2987c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    getstate = PyObject_GetAttrString(self, "__getstate__");
2988c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (getstate != NULL) {
2989c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        state = PyObject_CallObject(getstate, tmp);
2990c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(getstate);
2991c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (state == NULL) {
2992c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_DECREF(args);
2993c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_DECREF(tmp);
2994c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
2995c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
2996c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
2997c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else {
2998c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject **dictptr;
2999c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_Clear();
3000c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        state = Py_None;
3001c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        dictptr = _PyObject_GetDictPtr(self);
3002c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (dictptr && *dictptr && PyDict_Size(*dictptr))
3003c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            state = *dictptr;
3004c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(state);
3005c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3006c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3007c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(tmp);
3008c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3009c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (state == Py_None) {
3010c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(state);
3011c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return Py_BuildValue("(ON)", Py_TYPE(self), args);
3012c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3013c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
3014c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
3015177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum}
3016a9bc168f95408be86e79365a075d069465a06434Tim Peters
3017a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyMethodDef tzinfo_methods[] = {
3018177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
3019c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"tzname",          (PyCFunction)tzinfo_tzname,             METH_O,
3020c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("datetime -> string name of time zone.")},
3021a9bc168f95408be86e79365a075d069465a06434Tim Peters
3022c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"utcoffset",       (PyCFunction)tzinfo_utcoffset,          METH_O,
3023c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("datetime -> minutes east of UTC (negative for "
3024c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "west of UTC).")},
3025a9bc168f95408be86e79365a075d069465a06434Tim Peters
3026c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"dst",             (PyCFunction)tzinfo_dst,                METH_O,
3027c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3028a9bc168f95408be86e79365a075d069465a06434Tim Peters
3029c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"fromutc",         (PyCFunction)tzinfo_fromutc,            METH_O,
30301f6e2257dc552e8b5bb3485d2fa7f147288ca04dAlexander Belopolsky     PyDoc_STR("datetime in UTC -> datetime in local time.")},
303152dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Peters
3032c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"__reduce__",  (PyCFunction)tzinfo_reduce,             METH_NOARGS,
3033c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("-> (cls, state)")},
3034177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
3035c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL, NULL}
3036a9bc168f95408be86e79365a075d069465a06434Tim Peters};
3037a9bc168f95408be86e79365a075d069465a06434Tim Peters
3038a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic char tzinfo_doc[] =
3039a9bc168f95408be86e79365a075d069465a06434Tim PetersPyDoc_STR("Abstract base class for time zone info objects.");
3040a9bc168f95408be86e79365a075d069465a06434Tim Peters
3041ce3d34dde784e6e645703b6ce6aee53b8868298aNeal Norwitzstatichere PyTypeObject PyDateTime_TZInfoType = {
3042c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject_HEAD_INIT(NULL)
3043c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* ob_size */
3044c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    "datetime.tzinfo",                          /* tp_name */
3045c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    sizeof(PyDateTime_TZInfo),                  /* tp_basicsize */
3046c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_itemsize */
3047c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_dealloc */
3048c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_print */
3049c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_getattr */
3050c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_setattr */
3051c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_compare */
3052c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_repr */
3053c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_number */
3054c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_sequence */
3055c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_mapping */
3056c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_hash */
3057c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_call */
3058c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_str */
3059c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject_GenericGetAttr,                    /* tp_getattro */
3060c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_setattro */
3061c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_buffer */
3062c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3063c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TPFLAGS_BASETYPE,                        /* tp_flags */
3064c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tzinfo_doc,                                 /* tp_doc */
3065c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_traverse */
3066c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_clear */
3067c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_richcompare */
3068c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_weaklistoffset */
3069c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_iter */
3070c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_iternext */
3071c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tzinfo_methods,                             /* tp_methods */
3072c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_members */
3073c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_getset */
3074c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_base */
3075c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_dict */
3076c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_descr_get */
3077c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_descr_set */
3078c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_dictoffset */
3079c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_init */
3080c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_alloc */
3081c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyType_GenericNew,                          /* tp_new */
3082c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_free */
3083a9bc168f95408be86e79365a075d069465a06434Tim Peters};
3084a9bc168f95408be86e79365a075d069465a06434Tim Peters
3085a9bc168f95408be86e79365a075d069465a06434Tim Peters/*
3086a9bc168f95408be86e79365a075d069465a06434Tim Peters * PyDateTime_Time implementation.
3087a9bc168f95408be86e79365a075d069465a06434Tim Peters */
3088a9bc168f95408be86e79365a075d069465a06434Tim Peters
3089a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Accessor properties.
3090a9bc168f95408be86e79365a075d069465a06434Tim Peters */
3091a9bc168f95408be86e79365a075d069465a06434Tim Peters
3092a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3093a9bc168f95408be86e79365a075d069465a06434Tim Peterstime_hour(PyDateTime_Time *self, void *unused)
3094a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3095c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(TIME_GET_HOUR(self));
30962a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
30972a799bf77a83adef010ff4751e5195702f159f39Tim Peters
30982a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
3099a9bc168f95408be86e79365a075d069465a06434Tim Peterstime_minute(PyDateTime_Time *self, void *unused)
31002a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3101c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(TIME_GET_MINUTE(self));
31022a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
31032a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3104a9bc168f95408be86e79365a075d069465a06434Tim Peters/* The name time_second conflicted with some platform header file. */
31052a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
3106a9bc168f95408be86e79365a075d069465a06434Tim Peterspy_time_second(PyDateTime_Time *self, void *unused)
31072a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3108c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(TIME_GET_SECOND(self));
31092a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
31102a799bf77a83adef010ff4751e5195702f159f39Tim Peters
31112a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
3112a9bc168f95408be86e79365a075d069465a06434Tim Peterstime_microsecond(PyDateTime_Time *self, void *unused)
31132a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3114c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(TIME_GET_MICROSECOND(self));
31152a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
31162a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3117a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3118a9bc168f95408be86e79365a075d069465a06434Tim Peterstime_tzinfo(PyDateTime_Time *self, void *unused)
3119a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3120c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3121c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(result);
3122c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
3123a9bc168f95408be86e79365a075d069465a06434Tim Peters}
3124a9bc168f95408be86e79365a075d069465a06434Tim Peters
3125a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyGetSetDef time_getset[] = {
3126c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"hour",        (getter)time_hour},
3127c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"minute",      (getter)time_minute},
3128c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"second",      (getter)py_time_second},
3129c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"microsecond", (getter)time_microsecond},
3130c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"tzinfo",          (getter)time_tzinfo},
3131c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL}
31322a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
31332a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3134a9bc168f95408be86e79365a075d069465a06434Tim Peters/*
3135a9bc168f95408be86e79365a075d069465a06434Tim Peters * Constructors.
3136a9bc168f95408be86e79365a075d069465a06434Tim Peters */
313712bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
313802cbf4ae4baff0dbe373351ebf182cbcfc05d6bdMartin v. Löwisstatic char *time_kws[] = {"hour", "minute", "second", "microsecond",
3139c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           "tzinfo", NULL};
314012bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
31412a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
3142a9bc168f95408be86e79365a075d069465a06434Tim Peterstime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
31432a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3144c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *self = NULL;
3145c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *state;
3146c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int hour = 0;
3147c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int minute = 0;
3148c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int second = 0;
3149c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int usecond = 0;
3150c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tzinfo = Py_None;
3151c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3152c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Check for invocation from pickle with __getstate__ state */
3153c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyTuple_GET_SIZE(args) >= 1 &&
3154c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyTuple_GET_SIZE(args) <= 2 &&
3155c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3156c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3157c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
3158c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {
3159c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyDateTime_Time *me;
3160c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        char aware;
3161c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3162c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyTuple_GET_SIZE(args) == 2) {
3163c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            tzinfo = PyTuple_GET_ITEM(args, 1);
3164c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (check_tzinfo_subclass(tzinfo) < 0) {
3165c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyErr_SetString(PyExc_TypeError, "bad "
3166c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    "tzinfo state arg");
3167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                return NULL;
3168c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
3169c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
3170c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        aware = (char)(tzinfo != Py_None);
3171c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3172c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (me != NULL) {
3173c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            char *pdata = PyString_AS_STRING(state);
3174c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3175c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3176c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            me->hashcode = -1;
3177c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            me->hastzinfo = aware;
3178c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (aware) {
3179c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                Py_INCREF(tzinfo);
3180c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                me->tzinfo = tzinfo;
3181c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
3182c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
3183c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return (PyObject *)me;
3184c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3185c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3186c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3187c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    &hour, &minute, &second, &usecond,
3188c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    &tzinfo)) {
3189c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (check_time_args(hour, minute, second, usecond) < 0)
3190c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
3191c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (check_tzinfo_subclass(tzinfo) < 0)
3192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
3193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        self = new_time_ex(hour, minute, second, usecond, tzinfo,
3194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           type);
3195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self;
31972a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
31982a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3199a9bc168f95408be86e79365a075d069465a06434Tim Peters/*
3200a9bc168f95408be86e79365a075d069465a06434Tim Peters * Destructor.
3201a9bc168f95408be86e79365a075d069465a06434Tim Peters */
32022a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3203a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic void
3204a9bc168f95408be86e79365a075d069465a06434Tim Peterstime_dealloc(PyDateTime_Time *self)
3205a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3206c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (HASTZINFO(self)) {
3207c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_XDECREF(self->tzinfo);
3208c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3209c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TYPE(self)->tp_free((PyObject *)self);
3210a9bc168f95408be86e79365a075d069465a06434Tim Peters}
32112a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3212a9bc168f95408be86e79365a075d069465a06434Tim Peters/*
3213a9bc168f95408be86e79365a075d069465a06434Tim Peters * Indirect access to tzinfo methods.
32142a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
3215a9bc168f95408be86e79365a075d069465a06434Tim Peters
3216a9bc168f95408be86e79365a075d069465a06434Tim Peters/* These are all METH_NOARGS, so don't need to check the arglist. */
32172a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
3218a9bc168f95408be86e79365a075d069465a06434Tim Peterstime_utcoffset(PyDateTime_Time *self, PyObject *unused) {
3219c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3220c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                               "utcoffset", Py_None);
3221a9bc168f95408be86e79365a075d069465a06434Tim Peters}
322237f398282bf74b11e6167f7c7af75960e553dab9Tim Peters
322337f398282bf74b11e6167f7c7af75960e553dab9Tim Petersstatic PyObject *
322437f398282bf74b11e6167f7c7af75960e553dab9Tim Peterstime_dst(PyDateTime_Time *self, PyObject *unused) {
3225c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3226c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                               "dst", Py_None);
322737f398282bf74b11e6167f7c7af75960e553dab9Tim Peters}
322837f398282bf74b11e6167f7c7af75960e553dab9Tim Peters
322937f398282bf74b11e6167f7c7af75960e553dab9Tim Petersstatic PyObject *
323037f398282bf74b11e6167f7c7af75960e553dab9Tim Peterstime_tzname(PyDateTime_Time *self, PyObject *unused) {
3231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       Py_None);
323337f398282bf74b11e6167f7c7af75960e553dab9Tim Peters}
323437f398282bf74b11e6167f7c7af75960e553dab9Tim Peters
323537f398282bf74b11e6167f7c7af75960e553dab9Tim Peters/*
323637f398282bf74b11e6167f7c7af75960e553dab9Tim Peters * Various ways to turn a time into a string.
323737f398282bf74b11e6167f7c7af75960e553dab9Tim Peters */
32382a799bf77a83adef010ff4751e5195702f159f39Tim Peters
32392a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
32402a799bf77a83adef010ff4751e5195702f159f39Tim Peterstime_repr(PyDateTime_Time *self)
32412a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3242c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char buffer[100];
3243c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    const char *type_name = Py_TYPE(self)->tp_name;
3244c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int h = TIME_GET_HOUR(self);
3245c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int m = TIME_GET_MINUTE(self);
3246c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int s = TIME_GET_SECOND(self);
3247c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int us = TIME_GET_MICROSECOND(self);
3248c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
3249c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3250c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us)
3251c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyOS_snprintf(buffer, sizeof(buffer),
3252c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
3253c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (s)
3254c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyOS_snprintf(buffer, sizeof(buffer),
3255c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      "%s(%d, %d, %d)", type_name, h, m, s);
3256c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
3257c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyOS_snprintf(buffer, sizeof(buffer),
3258c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      "%s(%d, %d)", type_name, h, m);
3259c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = PyString_FromString(buffer);
3260c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result != NULL && HASTZINFO(self))
3261c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = append_keyword_tzinfo(result, self->tzinfo);
3262c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
32632a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
32642a799bf77a83adef010ff4751e5195702f159f39Tim Peters
32652a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
32662a799bf77a83adef010ff4751e5195702f159f39Tim Peterstime_str(PyDateTime_Time *self)
32672a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3268c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
32692a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
32702a799bf77a83adef010ff4751e5195702f159f39Tim Peters
32712a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
32724c11a926255ba5c798b52ce9529a37b9bae99132Martin v. Löwistime_isoformat(PyDateTime_Time *self, PyObject *unused)
32732a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3274c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char buf[100];
3275c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
3276c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Reuse the time format code from the datetime type. */
3277c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyDateTime_DateTime datetime;
3278c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyDateTime_DateTime *pdatetime = &datetime;
32792a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3280c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Copy over just the time bytes. */
3281c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3282c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           self->data,
3283c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           _PyDateTime_TIME_DATASIZE);
32842a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3285c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    isoformat_time(pdatetime, buf, sizeof(buf));
3286c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = PyString_FromString(buf);
3287c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3288c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return result;
328937f398282bf74b11e6167f7c7af75960e553dab9Tim Peters
3290c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* We need to append the UTC offset. */
3291c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3292c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         Py_None) < 0) {
3293c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(result);
3294c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3295c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3296c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyString_ConcatAndDel(&result, PyString_FromString(buf));
3297c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
32982a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
32992a799bf77a83adef010ff4751e5195702f159f39Tim Peters
33002a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
33012a799bf77a83adef010ff4751e5195702f159f39Tim Peterstime_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
33022a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3303c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
3304c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tuple;
3305c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    const char *format;
3306c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_ssize_t format_len;
3307c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static char *keywords[] = {"format", NULL};
3308c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3309c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3310c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      &format, &format_len))
3311c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3312c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3313c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Python's strftime does insane things with the year part of the
3314c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * timetuple.  The year is forced to (the otherwise nonsensical)
3315c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * 1900 to worm around that.
3316c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
3317c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tuple = Py_BuildValue("iiiiiiiii",
3318c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                          1900, 1, 1, /* year, month, day */
3319c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  TIME_GET_HOUR(self),
3320c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  TIME_GET_MINUTE(self),
3321c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  TIME_GET_SECOND(self),
3322c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  0, 1, -1); /* weekday, daynum, dst */
3323c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tuple == NULL)
3324c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3325c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(PyTuple_Size(tuple) == 9);
3326c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3327c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           Py_None);
3328c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(tuple);
3329c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
33302a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
33312a799bf77a83adef010ff4751e5195702f159f39Tim Peters
333237f398282bf74b11e6167f7c7af75960e553dab9Tim Peters/*
333337f398282bf74b11e6167f7c7af75960e553dab9Tim Peters * Miscellaneous methods.
333437f398282bf74b11e6167f7c7af75960e553dab9Tim Peters */
33352a799bf77a83adef010ff4751e5195702f159f39Tim Peters
33362a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* This is more natural as a tp_compare, but doesn't work then:  for whatever
33372a799bf77a83adef010ff4751e5195702f159f39Tim Peters * reason, Python's try_3way_compare ignores tp_compare unless
33382a799bf77a83adef010ff4751e5195702f159f39Tim Peters * PyInstance_Check returns true, but these aren't old-style classes.
33392a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
33402a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
33412a799bf77a83adef010ff4751e5195702f159f39Tim Peterstime_richcompare(PyDateTime_Time *self, PyObject *other, int op)
33422a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3343c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int diff;
3344c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    naivety n1, n2;
3345c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int offset1, offset2;
3346c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3347c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyTime_Check(other)) {
3348c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (op == Py_EQ || op == Py_NE) {
3349c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            PyObject *result = op == Py_EQ ? Py_False : Py_True;
3350c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_INCREF(result);
3351c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return result;
3352c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
3353c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Stop this from falling back to address comparison. */
3354c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return cmperror((PyObject *)self, other);
3355c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3356c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3357c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                 other, &offset2, &n2, Py_None) < 0)
3358c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3359c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3360c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* If they're both naive, or both aware and have the same offsets,
3361c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * we get off cheap.  Note that if they're both naive, offset1 ==
3362c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * offset2 == 0 at this point.
3363c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
3364c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (n1 == n2 && offset1 == offset2) {
3365c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3366c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      _PyDateTime_TIME_DATASIZE);
3367c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return diff_to_bool(diff, op);
3368c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3369c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3370c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3371c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(offset1 != offset2);             /* else last "if" handled it */
3372c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Convert everything except microseconds to seconds.  These
3373c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * can't overflow (no more than the # of seconds in 2 days).
3374c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
3375c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        offset1 = TIME_GET_HOUR(self) * 3600 +
3376c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  (TIME_GET_MINUTE(self) - offset1) * 60 +
3377c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  TIME_GET_SECOND(self);
3378c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        offset2 = TIME_GET_HOUR(other) * 3600 +
3379c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  (TIME_GET_MINUTE(other) - offset2) * 60 +
3380c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                  TIME_GET_SECOND(other);
3381c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        diff = offset1 - offset2;
3382c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (diff == 0)
3383c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            diff = TIME_GET_MICROSECOND(self) -
3384c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   TIME_GET_MICROSECOND(other);
3385c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return diff_to_bool(diff, op);
3386c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3387c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3388c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(n1 != n2);
3389c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_SetString(PyExc_TypeError,
3390c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    "can't compare offset-naive and "
3391c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    "offset-aware times");
3392c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return NULL;
33932a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
33942a799bf77a83adef010ff4751e5195702f159f39Tim Peters
33952a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic long
33962a799bf77a83adef010ff4751e5195702f159f39Tim Peterstime_hash(PyDateTime_Time *self)
33972a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3398c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self->hashcode == -1) {
3399c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        naivety n;
3400c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int offset;
3401c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *temp;
3402c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3403c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3404c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(n != OFFSET_UNKNOWN);
3405c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (n == OFFSET_ERROR)
3406c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return -1;
3407c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3408c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Reduce this to a hash of another object. */
3409c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (offset == 0)
3410c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            temp = PyString_FromStringAndSize((char *)self->data,
3411c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    _PyDateTime_TIME_DATASIZE);
3412c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else {
3413c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int hour;
3414c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int minute;
3415c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3416c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(n == OFFSET_AWARE);
3417c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(HASTZINFO(self));
3418c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            hour = divmod(TIME_GET_HOUR(self) * 60 +
3419c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            TIME_GET_MINUTE(self) - offset,
3420c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                          60,
3421c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                          &minute);
3422c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (0 <= hour && hour < 24)
3423c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                temp = new_time(hour, minute,
3424c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                TIME_GET_SECOND(self),
3425c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                TIME_GET_MICROSECOND(self),
3426c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                Py_None);
3427c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            else
3428c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                temp = Py_BuildValue("iiii",
3429c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           hour, minute,
3430c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           TIME_GET_SECOND(self),
3431c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           TIME_GET_MICROSECOND(self));
3432c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
3433c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (temp != NULL) {
3434c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            self->hashcode = PyObject_Hash(temp);
3435c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_DECREF(temp);
3436c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
3437c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3438c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self->hashcode;
34392a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
34402a799bf77a83adef010ff4751e5195702f159f39Tim Peters
344112bf339aea9c787f7ce655d613b8898f7511c7dbTim Petersstatic PyObject *
344212bf339aea9c787f7ce655d613b8898f7511c7dbTim Peterstime_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
344312bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters{
3444c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *clone;
3445c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tuple;
3446c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int hh = TIME_GET_HOUR(self);
3447c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int mm = TIME_GET_MINUTE(self);
3448c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int ss = TIME_GET_SECOND(self);
3449c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int us = TIME_GET_MICROSECOND(self);
3450c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
3451c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3452c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3453c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      time_kws,
3454c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      &hh, &mm, &ss, &us, &tzinfo))
3455c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3456c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3457c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tuple == NULL)
3458c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3459c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    clone = time_new(Py_TYPE(self), tuple, NULL);
3460c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(tuple);
3461c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return clone;
346212bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters}
346312bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
34642a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic int
34652a799bf77a83adef010ff4751e5195702f159f39Tim Peterstime_nonzero(PyDateTime_Time *self)
34662a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3467c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int offset;
3468c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int none;
3469c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3470c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3471c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Since utcoffset is in whole minutes, nothing can
3472c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * alter the conclusion that this is nonzero.
3473c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
3474c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return 1;
3475c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3476c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    offset = 0;
3477c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (HASTZINFO(self) && self->tzinfo != Py_None) {
3478c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        offset = call_utcoffset(self->tzinfo, Py_None, &none);
3479c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (offset == -1 && PyErr_Occurred())
3480c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return -1;
3481c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3482c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
34832a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
34842a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3485371935fc065e69c59c5382cbbf2cb098cf410f0eTim Peters/* Pickle support, a simple use of __reduce__. */
34862a799bf77a83adef010ff4751e5195702f159f39Tim Peters
348737f398282bf74b11e6167f7c7af75960e553dab9Tim Peters/* Let basestate be the non-tzinfo data string.
348837f398282bf74b11e6167f7c7af75960e553dab9Tim Peters * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
348937f398282bf74b11e6167f7c7af75960e553dab9Tim Peters * So it's a tuple in any (non-error) case.
3490b57f8f02bafcb74cd6c47f59f67d1b6bdfb33aecTim Peters * __getstate__ isn't exposed.
349137f398282bf74b11e6167f7c7af75960e553dab9Tim Peters */
349237f398282bf74b11e6167f7c7af75960e553dab9Tim Petersstatic PyObject *
349337f398282bf74b11e6167f7c7af75960e553dab9Tim Peterstime_getstate(PyDateTime_Time *self)
349437f398282bf74b11e6167f7c7af75960e553dab9Tim Peters{
3495c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *basestate;
3496c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
34972a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3498c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    basestate =  PyString_FromStringAndSize((char *)self->data,
3499c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                            _PyDateTime_TIME_DATASIZE);
3500c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (basestate != NULL) {
3501c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (! HASTZINFO(self) || self->tzinfo == Py_None)
3502c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = PyTuple_Pack(1, basestate);
3503c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else
3504c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = PyTuple_Pack(2, basestate, self->tzinfo);
3505c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(basestate);
3506c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3507c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
350837f398282bf74b11e6167f7c7af75960e553dab9Tim Peters}
35092a799bf77a83adef010ff4751e5195702f159f39Tim Peters
351037f398282bf74b11e6167f7c7af75960e553dab9Tim Petersstatic PyObject *
3511177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossumtime_reduce(PyDateTime_Time *self, PyObject *arg)
35122a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3513c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
35142a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
35152a799bf77a83adef010ff4751e5195702f159f39Tim Peters
351637f398282bf74b11e6167f7c7af75960e553dab9Tim Petersstatic PyMethodDef time_methods[] = {
3517177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
3518c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"isoformat",   (PyCFunction)time_isoformat,        METH_NOARGS,
3519c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3520c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "[+HH:MM].")},
35212a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3522c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"strftime",        (PyCFunction)time_strftime,     METH_VARARGS | METH_KEYWORDS,
3523c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("format -> strftime() style string.")},
352437f398282bf74b11e6167f7c7af75960e553dab9Tim Peters
3525c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"__format__",      (PyCFunction)date_format,       METH_VARARGS,
3526c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Formats self with strftime.")},
3527a9f7d6248032c9572b4d2024a1be8bd2823af09fEric Smith
3528c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"utcoffset",       (PyCFunction)time_utcoffset,    METH_NOARGS,
3529c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
35302a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3531c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"tzname",          (PyCFunction)time_tzname,       METH_NOARGS,
3532c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return self.tzinfo.tzname(self).")},
35332a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3534c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"dst",             (PyCFunction)time_dst,          METH_NOARGS,
3535c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return self.tzinfo.dst(self).")},
35362a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3537c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"replace",     (PyCFunction)time_replace,          METH_VARARGS | METH_KEYWORDS,
3538c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return time with new specified fields.")},
353912bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
3540c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"__reduce__", (PyCFunction)time_reduce,        METH_NOARGS,
3541c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("__reduce__() -> (cls, state)")},
3542177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
3543c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL,      NULL}
35442a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
35452a799bf77a83adef010ff4751e5195702f159f39Tim Peters
354637f398282bf74b11e6167f7c7af75960e553dab9Tim Petersstatic char time_doc[] =
35473a4231dd745e54ae533ce46371637f1fe8fa6a7bRaymond HettingerPyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
35483a4231dd745e54ae533ce46371637f1fe8fa6a7bRaymond Hettinger\n\
35493a4231dd745e54ae533ce46371637f1fe8fa6a7bRaymond HettingerAll arguments are optional. tzinfo may be None, or an instance of\n\
35503a4231dd745e54ae533ce46371637f1fe8fa6a7bRaymond Hettingera tzinfo subclass. The remaining arguments may be ints or longs.\n");
35512a799bf77a83adef010ff4751e5195702f159f39Tim Peters
355237f398282bf74b11e6167f7c7af75960e553dab9Tim Petersstatic PyNumberMethods time_as_number = {
3553c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_add */
3554c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_subtract */
3555c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_multiply */
3556c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_divide */
3557c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_remainder */
3558c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_divmod */
3559c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_power */
3560c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_negative */
3561c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_positive */
3562c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_absolute */
3563c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (inquiry)time_nonzero,                      /* nb_nonzero */
35642a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
35652a799bf77a83adef010ff4751e5195702f159f39Tim Peters
356637f398282bf74b11e6167f7c7af75960e553dab9Tim Petersstatichere PyTypeObject PyDateTime_TimeType = {
3567c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject_HEAD_INIT(NULL)
3568c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* ob_size */
3569c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    "datetime.time",                            /* tp_name */
3570c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    sizeof(PyDateTime_Time),                    /* tp_basicsize */
3571c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_itemsize */
3572c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (destructor)time_dealloc,                   /* tp_dealloc */
3573c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_print */
3574c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_getattr */
3575c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_setattr */
3576c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_compare */
3577c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (reprfunc)time_repr,                        /* tp_repr */
3578c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &time_as_number,                            /* tp_as_number */
3579c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_sequence */
3580c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_mapping */
3581c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (hashfunc)time_hash,                        /* tp_hash */
3582c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_call */
3583c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (reprfunc)time_str,                         /* tp_str */
3584c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject_GenericGetAttr,                    /* tp_getattro */
3585c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_setattro */
3586c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_buffer */
3587c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3588c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TPFLAGS_BASETYPE,                        /* tp_flags */
3589c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time_doc,                                   /* tp_doc */
3590c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_traverse */
3591c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_clear */
3592c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (richcmpfunc)time_richcompare,              /* tp_richcompare */
3593c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_weaklistoffset */
3594c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_iter */
3595c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_iternext */
3596c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time_methods,                               /* tp_methods */
3597c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_members */
3598c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time_getset,                                /* tp_getset */
3599c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_base */
3600c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_dict */
3601c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_descr_get */
3602c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_descr_set */
3603c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_dictoffset */
3604c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_init */
3605c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time_alloc,                                 /* tp_alloc */
3606c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time_new,                                   /* tp_new */
3607c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_free */
36082a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
36092a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3610a9bc168f95408be86e79365a075d069465a06434Tim Peters/*
3611a9bc168f95408be86e79365a075d069465a06434Tim Peters * PyDateTime_DateTime implementation.
3612a9bc168f95408be86e79365a075d069465a06434Tim Peters */
3613a9bc168f95408be86e79365a075d069465a06434Tim Peters
3614a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Accessor properties.  Properties for day, month, and year are inherited
3615a9bc168f95408be86e79365a075d069465a06434Tim Peters * from date.
3616a9bc168f95408be86e79365a075d069465a06434Tim Peters */
3617a9bc168f95408be86e79365a075d069465a06434Tim Peters
3618a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3619a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_hour(PyDateTime_DateTime *self, void *unused)
3620a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3621c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(DATE_GET_HOUR(self));
3622a9bc168f95408be86e79365a075d069465a06434Tim Peters}
3623a9bc168f95408be86e79365a075d069465a06434Tim Peters
3624a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3625a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_minute(PyDateTime_DateTime *self, void *unused)
3626a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3627c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(DATE_GET_MINUTE(self));
3628a9bc168f95408be86e79365a075d069465a06434Tim Peters}
36292a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3630a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3631a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_second(PyDateTime_DateTime *self, void *unused)
3632a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3633c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(DATE_GET_SECOND(self));
3634a9bc168f95408be86e79365a075d069465a06434Tim Peters}
3635a9bc168f95408be86e79365a075d069465a06434Tim Peters
3636a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3637a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_microsecond(PyDateTime_DateTime *self, void *unused)
3638a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3639c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3640a9bc168f95408be86e79365a075d069465a06434Tim Peters}
36412a799bf77a83adef010ff4751e5195702f159f39Tim Peters
36422a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
3643a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_tzinfo(PyDateTime_DateTime *self, void *unused)
36442a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3645c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3646c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(result);
3647c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
36482a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
36492a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3650a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyGetSetDef datetime_getset[] = {
3651c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"hour",        (getter)datetime_hour},
3652c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"minute",      (getter)datetime_minute},
3653c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"second",      (getter)datetime_second},
3654c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"microsecond", (getter)datetime_microsecond},
3655c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"tzinfo",          (getter)datetime_tzinfo},
3656c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL}
36572a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
36582a799bf77a83adef010ff4751e5195702f159f39Tim Peters
36592a799bf77a83adef010ff4751e5195702f159f39Tim Peters/*
36602a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Constructors.
36612a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
36622a799bf77a83adef010ff4751e5195702f159f39Tim Peters
366302cbf4ae4baff0dbe373351ebf182cbcfc05d6bdMartin v. Löwisstatic char *datetime_kws[] = {
3664c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    "year", "month", "day", "hour", "minute", "second",
3665c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    "microsecond", "tzinfo", NULL
366612bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters};
366712bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
36682a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
3669a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
36702a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3671c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *self = NULL;
3672c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *state;
3673c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int year;
3674c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int month;
3675c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int day;
3676c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int hour = 0;
3677c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int minute = 0;
3678c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int second = 0;
3679c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int usecond = 0;
3680c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tzinfo = Py_None;
3681c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3682c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Check for invocation from pickle with __getstate__ state */
3683c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyTuple_GET_SIZE(args) >= 1 &&
3684c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyTuple_GET_SIZE(args) <= 2 &&
3685c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3686c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3687c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
3688c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {
3689c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyDateTime_DateTime *me;
3690c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        char aware;
3691c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3692c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyTuple_GET_SIZE(args) == 2) {
3693c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            tzinfo = PyTuple_GET_ITEM(args, 1);
3694c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (check_tzinfo_subclass(tzinfo) < 0) {
3695c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyErr_SetString(PyExc_TypeError, "bad "
3696c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    "tzinfo state arg");
3697c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                return NULL;
3698c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
3699c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
3700c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        aware = (char)(tzinfo != Py_None);
3701c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3702c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (me != NULL) {
3703c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            char *pdata = PyString_AS_STRING(state);
3704c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3705c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3706c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            me->hashcode = -1;
3707c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            me->hastzinfo = aware;
3708c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (aware) {
3709c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                Py_INCREF(tzinfo);
3710c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                me->tzinfo = tzinfo;
3711c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
3712c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
3713c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return (PyObject *)me;
3714c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3715c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3716c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3717c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    &year, &month, &day, &hour, &minute,
3718c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    &second, &usecond, &tzinfo)) {
3719c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (check_date_args(year, month, day) < 0)
3720c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
3721c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (check_time_args(hour, minute, second, usecond) < 0)
3722c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
3723c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (check_tzinfo_subclass(tzinfo) < 0)
3724c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
3725c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        self = new_datetime_ex(year, month, day,
3726c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                hour, minute, second, usecond,
3727c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                tzinfo, type);
3728c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3729c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self;
37302a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
37312a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3732a9bc168f95408be86e79365a075d069465a06434Tim Peters/* TM_FUNC is the shared type of localtime() and gmtime(). */
3733a9bc168f95408be86e79365a075d069465a06434Tim Peterstypedef struct tm *(*TM_FUNC)(const time_t *timer);
3734a9bc168f95408be86e79365a075d069465a06434Tim Peters
3735a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Internal helper.
3736a9bc168f95408be86e79365a075d069465a06434Tim Peters * Build datetime from a time_t and a distinct count of microseconds.
3737a9bc168f95408be86e79365a075d069465a06434Tim Peters * Pass localtime or gmtime for f, to control the interpretation of timet.
3738a9bc168f95408be86e79365a075d069465a06434Tim Peters */
3739a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3740a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3741c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           PyObject *tzinfo)
3742c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{
3743c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    struct tm *tm;
3744c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
3745c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3746c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tm = f(&timet);
3747c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tm) {
3748c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* The platform localtime/gmtime may insert leap seconds,
3749c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * indicated by tm->tm_sec > 59.  We don't care about them,
3750c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * except to the extent that passing them on to the datetime
3751c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * constructor would raise ValueError for a reason that
3752c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * made no sense to the user.
3753c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
3754c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (tm->tm_sec > 59)
3755c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            tm->tm_sec = 59;
3756c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = PyObject_CallFunction(cls, "iiiiiiiO",
3757c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tm->tm_year + 1900,
3758c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tm->tm_mon + 1,
3759c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tm->tm_mday,
3760c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tm->tm_hour,
3761c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tm->tm_min,
3762c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tm->tm_sec,
3763c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       us,
3764c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                       tzinfo);
3765c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3766c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
3767c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
3768c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "timestamp out of range for "
3769c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        "platform localtime()/gmtime() function");
3770c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
3771a9bc168f95408be86e79365a075d069465a06434Tim Peters}
3772a9bc168f95408be86e79365a075d069465a06434Tim Peters
3773a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Internal helper.
3774a9bc168f95408be86e79365a075d069465a06434Tim Peters * Build datetime from a Python timestamp.  Pass localtime or gmtime for f,
3775a9bc168f95408be86e79365a075d069465a06434Tim Peters * to control the interpretation of the timestamp.  Since a double doesn't
3776a9bc168f95408be86e79365a075d069465a06434Tim Peters * have enough bits to cover a datetime's full range of precision, it's
3777a9bc168f95408be86e79365a075d069465a06434Tim Peters * better to call datetime_from_timet_and_us provided you have a way
3778a9bc168f95408be86e79365a075d069465a06434Tim Peters * to get that much precision (e.g., C time() isn't good enough).
3779a9bc168f95408be86e79365a075d069465a06434Tim Peters */
3780a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3781a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3782c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        PyObject *tzinfo)
3783c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{
3784c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time_t timet;
3785c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    double fraction;
3786c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int us;
3787c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3788c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    timet = _PyTime_DoubleToTimet(timestamp);
3789c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (timet == (time_t)-1 && PyErr_Occurred())
3790c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3791c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    fraction = timestamp - (double)timet;
3792c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us = (int)round_to_long(fraction * 1e6);
3793c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us < 0) {
3794c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Truncation towards zero is not what we wanted
3795c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou           for negative numbers (Python's mod semantics) */
3796c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        timet -= 1;
3797c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        us += 1000000;
3798c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3799c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* If timestamp is less than one microsecond smaller than a
3800c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * full second, round up. Otherwise, ValueErrors are raised
3801c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * for some floats. */
3802c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us == 1000000) {
3803c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        timet += 1;
3804c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        us = 0;
3805c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3806c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3807a9bc168f95408be86e79365a075d069465a06434Tim Peters}
3808a9bc168f95408be86e79365a075d069465a06434Tim Peters
3809a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Internal helper.
3810a9bc168f95408be86e79365a075d069465a06434Tim Peters * Build most accurate possible datetime for current time.  Pass localtime or
3811a9bc168f95408be86e79365a075d069465a06434Tim Peters * gmtime for f as appropriate.
3812a9bc168f95408be86e79365a075d069465a06434Tim Peters */
3813a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3814a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3815a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3816a9bc168f95408be86e79365a075d069465a06434Tim Peters#ifdef HAVE_GETTIMEOFDAY
3817c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    struct timeval t;
3818a9bc168f95408be86e79365a075d069465a06434Tim Peters
3819a9bc168f95408be86e79365a075d069465a06434Tim Peters#ifdef GETTIMEOFDAY_NO_TZ
3820c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    gettimeofday(&t);
3821a9bc168f95408be86e79365a075d069465a06434Tim Peters#else
3822c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    gettimeofday(&t, (struct timezone *)NULL);
3823a9bc168f95408be86e79365a075d069465a06434Tim Peters#endif
3824c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3825c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      tzinfo);
3826c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3827c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#else   /* ! HAVE_GETTIMEOFDAY */
3828c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* No flavor of gettimeofday exists on this platform.  Python's
3829c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * time.time() does a lot of other platform tricks to get the
3830c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * best time it can on the platform, and we're not going to do
3831c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * better than that (if we could, the better code would belong
3832c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * in time.time()!)  We're limited by the precision of a double,
3833c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * though.
3834c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
3835c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *time;
3836c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    double dtime;
3837c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3838c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    time = time_time();
3839c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (time == NULL)
3840c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3841c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    dtime = PyFloat_AsDouble(time);
3842c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(time);
3843c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (dtime == -1.0 && PyErr_Occurred())
3844c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3845c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return datetime_from_timestamp(cls, f, dtime, tzinfo);
3846c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou#endif  /* ! HAVE_GETTIMEOFDAY */
3847a9bc168f95408be86e79365a075d069465a06434Tim Peters}
3848a9bc168f95408be86e79365a075d069465a06434Tim Peters
38492a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Return best possible local time -- this isn't constrained by the
38502a799bf77a83adef010ff4751e5195702f159f39Tim Peters * precision of a timestamp.
38512a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
38522a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
3853a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_now(PyObject *cls, PyObject *args, PyObject *kw)
38542a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3855c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *self;
3856c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tzinfo = Py_None;
3857c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static char *keywords[] = {"tz", NULL};
38582a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3859c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3860c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      &tzinfo))
3861c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3862c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (check_tzinfo_subclass(tzinfo) < 0)
3863c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
386410cadce41ec7b94aafc11b4f2c9cfb7587f5b81dTim Peters
3865c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self = datetime_best_possible(cls,
3866c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                  tzinfo == Py_None ? localtime : gmtime,
3867c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                  tzinfo);
3868c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self != NULL && tzinfo != Py_None) {
3869c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Convert UTC to tzinfo's zone. */
3870c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *temp = self;
3871c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3872c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(temp);
3873c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3874c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self;
38752a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
38762a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3877a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Return best possible UTC time -- this isn't constrained by the
3878a9bc168f95408be86e79365a075d069465a06434Tim Peters * precision of a timestamp.
3879a9bc168f95408be86e79365a075d069465a06434Tim Peters */
3880a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3881a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_utcnow(PyObject *cls, PyObject *dummy)
3882a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3883c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return datetime_best_possible(cls, gmtime, Py_None);
3884a9bc168f95408be86e79365a075d069465a06434Tim Peters}
3885a9bc168f95408be86e79365a075d069465a06434Tim Peters
38862a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* Return new local datetime from timestamp (Python timestamp -- a double). */
38872a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
3888a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
38892a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
3890c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *self;
3891c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    double timestamp;
3892c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tzinfo = Py_None;
3893c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static char *keywords[] = {"timestamp", "tz", NULL};
3894c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3895c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3896c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      keywords, &timestamp, &tzinfo))
3897c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3898c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (check_tzinfo_subclass(tzinfo) < 0)
3899c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3900c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3901c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    self = datetime_from_timestamp(cls,
3902c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   tzinfo == Py_None ? localtime : gmtime,
3903c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   timestamp,
3904c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                   tzinfo);
3905c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self != NULL && tzinfo != Py_None) {
3906c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Convert UTC to tzinfo's zone. */
3907c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *temp = self;
3908c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3909c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(temp);
3910c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3911c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self;
39122a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
39132a799bf77a83adef010ff4751e5195702f159f39Tim Peters
3914a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3915a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3916a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3917a9bc168f95408be86e79365a075d069465a06434Tim Peters{
3918c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    double timestamp;
3919c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
3920a9bc168f95408be86e79365a075d069465a06434Tim Peters
3921c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3922c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = datetime_from_timestamp(cls, gmtime, timestamp,
3923c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                         Py_None);
3924c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
3925a9bc168f95408be86e79365a075d069465a06434Tim Peters}
3926a9bc168f95408be86e79365a075d069465a06434Tim Peters
39270af3ade6aa597a8871dbb62c312a8ab62e3cd309Skip Montanaro/* Return new datetime from time.strptime(). */
39280af3ade6aa597a8871dbb62c312a8ab62e3cd309Skip Montanarostatic PyObject *
39290af3ade6aa597a8871dbb62c312a8ab62e3cd309Skip Montanarodatetime_strptime(PyObject *cls, PyObject *args)
39300af3ade6aa597a8871dbb62c312a8ab62e3cd309Skip Montanaro{
3931c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static PyObject *module = NULL;
3932c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3933c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    const char *string, *format;
3934c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3935c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3936c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3937c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3938c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (module == NULL &&
3939c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3940c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
3941c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
3942c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* _strptime._strptime returns a two-element tuple.  The first
3943c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou       element is a time.struct_time object.  The second is the
3944c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou       microseconds (which are not defined for time.struct_time). */
3945c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
3946c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (obj != NULL) {
3947c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int i, good_timetuple = 1;
3948c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        long int ia[7];
3949c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3950c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            st = PySequence_GetItem(obj, 0);
3951c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            frac = PySequence_GetItem(obj, 1);
3952c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (st == NULL || frac == NULL)
3953c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                good_timetuple = 0;
3954c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* copy y/m/d/h/m/s values out of the
3955c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               time.struct_time */
3956c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (good_timetuple &&
3957c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PySequence_Check(st) &&
3958c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PySequence_Size(st) >= 6) {
3959c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                for (i=0; i < 6; i++) {
3960c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    PyObject *p = PySequence_GetItem(st, i);
3961c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    if (p == NULL) {
3962c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        good_timetuple = 0;
3963c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        break;
3964c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    }
3965c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    if (PyInt_Check(p))
3966c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        ia[i] = PyInt_AsLong(p);
3967c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    else
3968c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        good_timetuple = 0;
3969c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    Py_DECREF(p);
3970c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                }
3971c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
3972c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            else
3973c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                good_timetuple = 0;
3974c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* follow that up with a little dose of microseconds */
3975c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (good_timetuple && PyInt_Check(frac))
3976c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                ia[6] = PyInt_AsLong(frac);
3977c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            else
3978c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                good_timetuple = 0;
3979c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
3980c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else
3981c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            good_timetuple = 0;
3982c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (good_timetuple)
3983c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = PyObject_CallFunction(cls, "iiiiiii",
3984c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                           ia[0], ia[1], ia[2],
3985c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                           ia[3], ia[4], ia[5],
3986c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                           ia[6]);
3987c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else
3988c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            PyErr_SetString(PyExc_ValueError,
3989c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                "unexpected value from _strptime._strptime");
3990c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
3991c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(obj);
3992c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(st);
3993c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_XDECREF(frac);
3994c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
39950af3ade6aa597a8871dbb62c312a8ab62e3cd309Skip Montanaro}
39960af3ade6aa597a8871dbb62c312a8ab62e3cd309Skip Montanaro
3997a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Return new datetime from date/datetime and time arguments. */
3998a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
3999a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4000a9bc168f95408be86e79365a075d069465a06434Tim Peters{
4001c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static char *keywords[] = {"date", "time", NULL};
4002c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *date;
4003c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *time;
4004c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
4005c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4006c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4007c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    &PyDateTime_DateType, &date,
4008c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                    &PyDateTime_TimeType, &time)) {
4009c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *tzinfo = Py_None;
4010c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4011c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (HASTZINFO(time))
4012c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4013c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = PyObject_CallFunction(cls, "iiiiiiiO",
4014c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        GET_YEAR(date),
4015c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        GET_MONTH(date),
4016c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        GET_DAY(date),
4017c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        TIME_GET_HOUR(time),
4018c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        TIME_GET_MINUTE(time),
4019c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        TIME_GET_SECOND(time),
4020c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        TIME_GET_MICROSECOND(time),
4021c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        tzinfo);
4022c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4023c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
4024a9bc168f95408be86e79365a075d069465a06434Tim Peters}
40252a799bf77a83adef010ff4751e5195702f159f39Tim Peters
40262a799bf77a83adef010ff4751e5195702f159f39Tim Peters/*
40272a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Destructor.
40282a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
40292a799bf77a83adef010ff4751e5195702f159f39Tim Peters
40302a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic void
4031a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_dealloc(PyDateTime_DateTime *self)
40322a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4033c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (HASTZINFO(self)) {
4034c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_XDECREF(self->tzinfo);
4035c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4036c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TYPE(self)->tp_free((PyObject *)self);
40372a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
40382a799bf77a83adef010ff4751e5195702f159f39Tim Peters
40392a799bf77a83adef010ff4751e5195702f159f39Tim Peters/*
40402a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Indirect access to tzinfo methods.
40412a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
40422a799bf77a83adef010ff4751e5195702f159f39Tim Peters
40432a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* These are all METH_NOARGS, so don't need to check the arglist. */
40442a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4045a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
4046c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4047c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                               "utcoffset", (PyObject *)self);
40482a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
40492a799bf77a83adef010ff4751e5195702f159f39Tim Peters
40502a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4051a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
4052c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4053c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                               "dst", (PyObject *)self);
40542a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
40552a799bf77a83adef010ff4751e5195702f159f39Tim Peters
40562a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4057a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
4058c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4059c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       (PyObject *)self);
40602a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
40612a799bf77a83adef010ff4751e5195702f159f39Tim Peters
40622a799bf77a83adef010ff4751e5195702f159f39Tim Peters/*
4063a9bc168f95408be86e79365a075d069465a06434Tim Peters * datetime arithmetic.
40642a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
40652a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4066a9bc168f95408be86e79365a075d069465a06434Tim Peters/* factor must be 1 (to add) or -1 (to subtract).  The result inherits
4067a9bc168f95408be86e79365a075d069465a06434Tim Peters * the tzinfo state of date.
40682a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
40692a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4070a9bc168f95408be86e79365a075d069465a06434Tim Petersadd_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4071c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       int factor)
4072c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou{
4073c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Note that the C-level additions can't overflow, because of
4074c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * invariant bounds on the member values.
4075c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
4076c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int year = GET_YEAR(date);
4077c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int month = GET_MONTH(date);
4078c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4079c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int hour = DATE_GET_HOUR(date);
4080c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int minute = DATE_GET_MINUTE(date);
4081c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4082c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int microsecond = DATE_GET_MICROSECOND(date) +
4083c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      GET_TD_MICROSECONDS(delta) * factor;
4084c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4085c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(factor == 1 || factor == -1);
4086c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (normalize_datetime(&year, &month, &day,
4087c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                           &hour, &minute, &second, &microsecond) < 0)
4088c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
4089c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else
4090c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return new_datetime(year, month, day,
4091c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            hour, minute, second, microsecond,
4092c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            HASTZINFO(date) ? date->tzinfo : Py_None);
40932a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
40942a799bf77a83adef010ff4751e5195702f159f39Tim Peters
40952a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4096a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_add(PyObject *left, PyObject *right)
40972a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4098c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDateTime_Check(left)) {
4099c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* datetime + ??? */
4100c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyDelta_Check(right))
4101c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* datetime + delta */
4102c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return add_datetime_timedelta(
4103c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            (PyDateTime_DateTime *)left,
4104c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            (PyDateTime_Delta *)right,
4105c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            1);
4106c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4107c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (PyDelta_Check(left)) {
4108c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* delta + datetime */
4109c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return add_datetime_timedelta((PyDateTime_DateTime *) right,
4110c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      (PyDateTime_Delta *) left,
4111c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      1);
4112c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4113c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(Py_NotImplemented);
4114c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_NotImplemented;
41152a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
41162a799bf77a83adef010ff4751e5195702f159f39Tim Peters
41172a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4118a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_subtract(PyObject *left, PyObject *right)
41192a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4120c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = Py_NotImplemented;
4121c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4122c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyDateTime_Check(left)) {
4123c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* datetime - ??? */
4124c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyDateTime_Check(right)) {
4125c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* datetime - datetime */
4126c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            naivety n1, n2;
4127c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int offset1, offset2;
4128c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int delta_d, delta_s, delta_us;
4129c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4130c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (classify_two_utcoffsets(left, &offset1, &n1, left,
4131c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        right, &offset2, &n2,
4132c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                        right) < 0)
4133c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                return NULL;
4134c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4135c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (n1 != n2) {
4136c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyErr_SetString(PyExc_TypeError,
4137c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    "can't subtract offset-naive and "
4138c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    "offset-aware datetimes");
4139c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                return NULL;
4140c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            }
4141c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            delta_d = ymd_to_ord(GET_YEAR(left),
4142c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                 GET_MONTH(left),
4143c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                 GET_DAY(left)) -
4144c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      ymd_to_ord(GET_YEAR(right),
4145c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                 GET_MONTH(right),
4146c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                 GET_DAY(right));
4147c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* These can't overflow, since the values are
4148c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             * normalized.  At most this gives the number of
4149c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             * seconds in one day.
4150c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             */
4151c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            delta_s = (DATE_GET_HOUR(left) -
4152c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       DATE_GET_HOUR(right)) * 3600 +
4153c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      (DATE_GET_MINUTE(left) -
4154c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       DATE_GET_MINUTE(right)) * 60 +
4155c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      (DATE_GET_SECOND(left) -
4156c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       DATE_GET_SECOND(right));
4157c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            delta_us = DATE_GET_MICROSECOND(left) -
4158c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       DATE_GET_MICROSECOND(right);
4159c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* (left - offset1) - (right - offset2) =
4160c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             * (left - right) + (offset2 - offset1)
4161c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             */
4162c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            delta_s += (offset2 - offset1) * 60;
4163c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = new_delta(delta_d, delta_s, delta_us, 1);
4164c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
4165c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else if (PyDelta_Check(right)) {
4166c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* datetime - delta */
4167c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = add_datetime_timedelta(
4168c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            (PyDateTime_DateTime *)left,
4169c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            (PyDateTime_Delta *)right,
4170c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            -1);
4171c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
4172c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4173c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4174c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result == Py_NotImplemented)
4175c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(result);
4176c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
4177a9bc168f95408be86e79365a075d069465a06434Tim Peters}
4178a9bc168f95408be86e79365a075d069465a06434Tim Peters
4179a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Various ways to turn a datetime into a string. */
4180a9bc168f95408be86e79365a075d069465a06434Tim Peters
4181a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
4182a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_repr(PyDateTime_DateTime *self)
4183a9bc168f95408be86e79365a075d069465a06434Tim Peters{
4184c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char buffer[1000];
4185c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    const char *type_name = Py_TYPE(self)->tp_name;
4186c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *baserepr;
4187c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4188c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (DATE_GET_MICROSECOND(self)) {
4189c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyOS_snprintf(buffer, sizeof(buffer),
4190c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      "%s(%d, %d, %d, %d, %d, %d, %d)",
4191c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      type_name,
4192c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4193c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4194c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_SECOND(self),
4195c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_MICROSECOND(self));
4196c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4197c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else if (DATE_GET_SECOND(self)) {
4198c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyOS_snprintf(buffer, sizeof(buffer),
4199c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      "%s(%d, %d, %d, %d, %d, %d)",
4200c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      type_name,
4201c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4202c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4203c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_SECOND(self));
4204c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4205c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    else {
4206c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyOS_snprintf(buffer, sizeof(buffer),
4207c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      "%s(%d, %d, %d, %d, %d)",
4208c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      type_name,
4209c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4210c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4211c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4212c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    baserepr = PyString_FromString(buffer);
4213c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (baserepr == NULL || ! HASTZINFO(self))
4214c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return baserepr;
4215c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return append_keyword_tzinfo(baserepr, self->tzinfo);
4216a9bc168f95408be86e79365a075d069465a06434Tim Peters}
4217a9bc168f95408be86e79365a075d069465a06434Tim Peters
4218a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
4219a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_str(PyDateTime_DateTime *self)
4220a9bc168f95408be86e79365a075d069465a06434Tim Peters{
4221c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4222a9bc168f95408be86e79365a075d069465a06434Tim Peters}
4223a9bc168f95408be86e79365a075d069465a06434Tim Peters
4224a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
4225a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4226a9bc168f95408be86e79365a075d069465a06434Tim Peters{
4227c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char sep = 'T';
4228c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static char *keywords[] = {"sep", NULL};
4229c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char buffer[100];
4230c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    char *cp;
4231c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
4232c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4233c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4234c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                     &sep))
4235c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
4236c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4237c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(cp != NULL);
4238c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    *cp++ = sep;
4239c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4240c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = PyString_FromStringAndSize(buffer, cp - buffer);
4241c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result == NULL || ! HASTZINFO(self))
4242c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return result;
4243c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4244c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* We need to append the UTC offset. */
4245c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4246c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                         (PyObject *)self) < 0) {
4247c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(result);
4248c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
4249c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4250c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyString_ConcatAndDel(&result, PyString_FromString(buffer));
4251c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
42522a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
42532a799bf77a83adef010ff4751e5195702f159f39Tim Peters
42542a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4255a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_ctime(PyDateTime_DateTime *self)
42562a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4257c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return format_ctime((PyDateTime_Date *)self,
4258c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        DATE_GET_HOUR(self),
4259c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        DATE_GET_MINUTE(self),
4260c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                        DATE_GET_SECOND(self));
42612a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
42622a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4263a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Miscellaneous methods. */
42642a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4265a9bc168f95408be86e79365a075d069465a06434Tim Peters/* This is more natural as a tp_compare, but doesn't work then:  for whatever
4266a9bc168f95408be86e79365a075d069465a06434Tim Peters * reason, Python's try_3way_compare ignores tp_compare unless
4267a9bc168f95408be86e79365a075d069465a06434Tim Peters * PyInstance_Check returns true, but these aren't old-style classes.
4268a9bc168f95408be86e79365a075d069465a06434Tim Peters */
42692a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4270a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
42712a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4272c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int diff;
4273c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    naivety n1, n2;
4274c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int offset1, offset2;
4275c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4276c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyDateTime_Check(other)) {
4277c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* If other has a "timetuple" attr, that's an advertised
4278c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * hook for other classes to ask to get comparison control.
4279c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * However, date instances have a timetuple attr, and we
4280c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * don't want to allow that comparison.  Because datetime
4281c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * is a subclass of date, when mixing date and datetime
4282c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * in a comparison, Python gives datetime the first shot
4283c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * (it's the more specific subtype).  So we can stop that
4284c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         * combination here reliably.
4285c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou         */
4286c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (PyObject_HasAttrString(other, "timetuple") &&
4287c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            ! PyDate_Check(other)) {
4288c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* A hook for other kinds of datetime objects. */
4289c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_INCREF(Py_NotImplemented);
4290c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return Py_NotImplemented;
4291c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
4292c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (op == Py_EQ || op == Py_NE) {
4293c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            PyObject *result = op == Py_EQ ? Py_False : Py_True;
4294c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_INCREF(result);
4295c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return result;
4296c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
4297c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Stop this from falling back to address comparison. */
4298c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return cmperror((PyObject *)self, other);
4299c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4300c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4301c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4302c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                (PyObject *)self,
4303c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                 other, &offset2, &n2,
4304c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                 other) < 0)
4305c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
4306c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4307c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* If they're both naive, or both aware and have the same offsets,
4308c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * we get off cheap.  Note that if they're both naive, offset1 ==
4309c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * offset2 == 0 at this point.
4310c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
4311c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (n1 == n2 && offset1 == offset2) {
4312c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4313c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      _PyDateTime_DATETIME_DATASIZE);
4314c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return diff_to_bool(diff, op);
4315c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4316c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4317c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4318c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyDateTime_Delta *delta;
4319c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4320c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(offset1 != offset2);             /* else last "if" handled it */
4321c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4322c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                                       other);
4323c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (delta == NULL)
4324c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
4325c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        diff = GET_TD_DAYS(delta);
4326c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (diff == 0)
4327c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            diff = GET_TD_SECONDS(delta) |
4328c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                   GET_TD_MICROSECONDS(delta);
4329c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(delta);
4330c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return diff_to_bool(diff, op);
4331c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4332c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4333c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(n1 != n2);
4334c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_SetString(PyExc_TypeError,
4335c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    "can't compare offset-naive and "
4336c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    "offset-aware datetimes");
4337c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return NULL;
43382a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
43392a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4340a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic long
4341a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_hash(PyDateTime_DateTime *self)
4342a9bc168f95408be86e79365a075d069465a06434Tim Peters{
4343c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self->hashcode == -1) {
4344c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        naivety n;
4345c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int offset;
4346c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *temp;
4347c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4348c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4349c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                               &offset);
4350c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        assert(n != OFFSET_UNKNOWN);
4351c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (n == OFFSET_ERROR)
4352c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return -1;
4353c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4354c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Reduce this to a hash of another object. */
4355c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (n == OFFSET_NAIVE)
4356c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            temp = PyString_FromStringAndSize(
4357c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            (char *)self->data,
4358c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                            _PyDateTime_DATETIME_DATASIZE);
4359c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else {
4360c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int days;
4361c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            int seconds;
4362c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4363c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(n == OFFSET_AWARE);
4364c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            assert(HASTZINFO(self));
4365c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            days = ymd_to_ord(GET_YEAR(self),
4366c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                              GET_MONTH(self),
4367c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                              GET_DAY(self));
4368c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            seconds = DATE_GET_HOUR(self) * 3600 +
4369c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      (DATE_GET_MINUTE(self) - offset) * 60 +
4370c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                      DATE_GET_SECOND(self);
4371c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            temp = new_delta(days,
4372c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             seconds,
4373c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             DATE_GET_MICROSECOND(self),
4374c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             1);
4375c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
4376c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (temp != NULL) {
4377c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            self->hashcode = PyObject_Hash(temp);
4378c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            Py_DECREF(temp);
4379c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
4380c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4381c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return self->hashcode;
4382a9bc168f95408be86e79365a075d069465a06434Tim Peters}
43832a799bf77a83adef010ff4751e5195702f159f39Tim Peters
43842a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4385a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
438612bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters{
4387c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *clone;
4388c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tuple;
4389c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int y = GET_YEAR(self);
4390c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int m = GET_MONTH(self);
4391c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int d = GET_DAY(self);
4392c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int hh = DATE_GET_HOUR(self);
4393c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int mm = DATE_GET_MINUTE(self);
4394c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int ss = DATE_GET_SECOND(self);
4395c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int us = DATE_GET_MICROSECOND(self);
4396c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
4397c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4398c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4399c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      datetime_kws,
4400c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      &y, &m, &d, &hh, &mm, &ss, &us,
4401c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      &tzinfo))
4402c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
4403c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4404c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (tuple == NULL)
4405c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
4406c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    clone = datetime_new(Py_TYPE(self), tuple, NULL);
4407c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(tuple);
4408c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return clone;
440912bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters}
441012bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
441112bf339aea9c787f7ce655d613b8898f7511c7dbTim Petersstatic PyObject *
4412a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
441380475bb4d21d1e5ddbb9eb0042adb1113052b38aTim Peters{
4414c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int y, m, d, hh, mm, ss, us;
4415c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result;
4416c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int offset, none;
4417c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4418c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *tzinfo;
4419c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    static char *keywords[] = {"tz", NULL};
4420c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4421c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4422c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      &PyDateTime_TZInfoType, &tzinfo))
4423c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
4424c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4425c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (!HASTZINFO(self) || self->tzinfo == Py_None)
4426c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto NeedAware;
4427c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4428c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Conversion to self's own time zone is a NOP. */
4429c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (self->tzinfo == tzinfo) {
4430c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_INCREF(self);
4431c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return (PyObject *)self;
4432c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4433c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4434c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Convert self to UTC. */
4435c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4436c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (offset == -1 && PyErr_Occurred())
4437c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
4438c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (none)
4439c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        goto NeedAware;
4440c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4441c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    y = GET_YEAR(self);
4442c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    m = GET_MONTH(self);
4443c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    d = GET_DAY(self);
4444c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    hh = DATE_GET_HOUR(self);
4445c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    mm = DATE_GET_MINUTE(self);
4446c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    ss = DATE_GET_SECOND(self);
4447c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us = DATE_GET_MICROSECOND(self);
4448c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4449c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    mm -= offset;
4450c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if ((mm < 0 || mm >= 60) &&
4451c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4452c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return NULL;
4453c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4454c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Attach new tzinfo and let fromutc() do the rest. */
4455c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4456c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (result != NULL) {
4457c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        PyObject *temp = result;
4458c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4459c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4460c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(temp);
4461c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4462c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
446352dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim Peters
446452dcce24e232a9e4f57e5f828f0fd1e40f1fecdbTim PetersNeedAware:
4465c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4466c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      "a naive datetime");
4467c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return NULL;
446880475bb4d21d1e5ddbb9eb0042adb1113052b38aTim Peters}
446980475bb4d21d1e5ddbb9eb0042adb1113052b38aTim Peters
447080475bb4d21d1e5ddbb9eb0042adb1113052b38aTim Petersstatic PyObject *
4471a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_timetuple(PyDateTime_DateTime *self)
44722a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4473c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int dstflag = -1;
44742a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4475c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (HASTZINFO(self) && self->tzinfo != Py_None) {
4476c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int none;
44772a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4478c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4479c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (dstflag == -1 && PyErr_Occurred())
4480c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
44812a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4482c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (none)
4483c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            dstflag = -1;
4484c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else if (dstflag != 0)
4485c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            dstflag = 1;
44862a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4487c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4488c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return build_struct_time(GET_YEAR(self),
4489c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             GET_MONTH(self),
4490c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             GET_DAY(self),
4491c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             DATE_GET_HOUR(self),
4492c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             DATE_GET_MINUTE(self),
4493c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             DATE_GET_SECOND(self),
4494c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                             dstflag);
44952a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
44962a799bf77a83adef010ff4751e5195702f159f39Tim Peters
44972a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4498a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_getdate(PyDateTime_DateTime *self)
4499a9bc168f95408be86e79365a075d069465a06434Tim Peters{
4500c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return new_date(GET_YEAR(self),
4501c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    GET_MONTH(self),
4502c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    GET_DAY(self));
4503a9bc168f95408be86e79365a075d069465a06434Tim Peters}
4504a9bc168f95408be86e79365a075d069465a06434Tim Peters
4505a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
4506a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_gettime(PyDateTime_DateTime *self)
4507a9bc168f95408be86e79365a075d069465a06434Tim Peters{
4508c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return new_time(DATE_GET_HOUR(self),
4509c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    DATE_GET_MINUTE(self),
4510c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    DATE_GET_SECOND(self),
4511c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    DATE_GET_MICROSECOND(self),
4512c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    Py_None);
4513a9bc168f95408be86e79365a075d069465a06434Tim Peters}
4514a9bc168f95408be86e79365a075d069465a06434Tim Peters
4515a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
4516a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_gettimetz(PyDateTime_DateTime *self)
4517a9bc168f95408be86e79365a075d069465a06434Tim Peters{
4518c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return new_time(DATE_GET_HOUR(self),
4519c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    DATE_GET_MINUTE(self),
4520c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    DATE_GET_SECOND(self),
4521c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    DATE_GET_MICROSECOND(self),
4522c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                    HASTZINFO(self) ? self->tzinfo : Py_None);
4523a9bc168f95408be86e79365a075d069465a06434Tim Peters}
4524a9bc168f95408be86e79365a075d069465a06434Tim Peters
4525a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyObject *
4526a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_utctimetuple(PyDateTime_DateTime *self)
45272a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4528c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int y = GET_YEAR(self);
4529c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int m = GET_MONTH(self);
4530c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int d = GET_DAY(self);
4531c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int hh = DATE_GET_HOUR(self);
4532c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int mm = DATE_GET_MINUTE(self);
4533c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int ss = DATE_GET_SECOND(self);
4534c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int us = 0;         /* microseconds are ignored in a timetuple */
4535c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    int offset = 0;
4536c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4537c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (HASTZINFO(self) && self->tzinfo != Py_None) {
4538c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int none;
4539c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4540c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4541c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (offset == -1 && PyErr_Occurred())
4542c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            return NULL;
4543c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4544c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4545c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * 0 in a UTC timetuple regardless of what dst() says.
4546c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
4547c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (offset) {
4548c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        /* Subtract offset minutes & normalize. */
4549c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        int stat;
4550c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4551c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        mm -= offset;
4552c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4553c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (stat < 0) {
4554c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            /* At the edges, it's possible we overflowed
4555c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             * beyond MINYEAR or MAXYEAR.
4556c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou             */
4557c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            if (PyErr_ExceptionMatches(PyExc_OverflowError))
4558c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                PyErr_Clear();
4559c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            else
4560c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                return NULL;
4561c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        }
4562c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4563c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return build_struct_time(y, m, d, hh, mm, ss, 0);
45642a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
45652a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4566371935fc065e69c59c5382cbbf2cb098cf410f0eTim Peters/* Pickle support, a simple use of __reduce__. */
456733e0f383d488ed3f199f2efcb080e2b6b4dc6161Tim Peters
4568a9bc168f95408be86e79365a075d069465a06434Tim Peters/* Let basestate be the non-tzinfo data string.
45692a799bf77a83adef010ff4751e5195702f159f39Tim Peters * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
45702a799bf77a83adef010ff4751e5195702f159f39Tim Peters * So it's a tuple in any (non-error) case.
4571b57f8f02bafcb74cd6c47f59f67d1b6bdfb33aecTim Peters * __getstate__ isn't exposed.
45722a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
45732a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4574a9bc168f95408be86e79365a075d069465a06434Tim Petersdatetime_getstate(PyDateTime_DateTime *self)
45752a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4576c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *basestate;
4577c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *result = NULL;
45782a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4579c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    basestate = PyString_FromStringAndSize((char *)self->data,
4580c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                                      _PyDateTime_DATETIME_DATASIZE);
4581c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (basestate != NULL) {
4582c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        if (! HASTZINFO(self) || self->tzinfo == Py_None)
4583c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = PyTuple_Pack(1, basestate);
4584c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        else
4585c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou            result = PyTuple_Pack(2, basestate, self->tzinfo);
4586c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        Py_DECREF(basestate);
4587c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    }
4588c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return result;
45892a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
45902a799bf77a83adef010ff4751e5195702f159f39Tim Peters
45912a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyObject *
4592177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossumdatetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
45932a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4594c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
45952a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
45962a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4597a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyMethodDef datetime_methods[] = {
4598177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
4599c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Class methods: */
46002a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4601c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"now",         (PyCFunction)datetime_now,
4602c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4603c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4604a9bc168f95408be86e79365a075d069465a06434Tim Peters
4605c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"utcnow",         (PyCFunction)datetime_utcnow,
4606c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     METH_NOARGS | METH_CLASS,
4607c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return a new datetime representing UTC day and time.")},
46082a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4609c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4610c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4611c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
46122a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4613c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4614c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     METH_VARARGS | METH_CLASS,
4615c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4616c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "(like time.time()).")},
4617a9bc168f95408be86e79365a075d069465a06434Tim Peters
4618c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"strptime", (PyCFunction)datetime_strptime,
4619c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     METH_VARARGS | METH_CLASS,
4620c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("string, format -> new datetime parsed from a string "
4621c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "(like time.strptime()).")},
46220af3ade6aa597a8871dbb62c312a8ab62e3cd309Skip Montanaro
4623c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"combine", (PyCFunction)datetime_combine,
4624c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4625c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("date, time -> datetime with same date and time fields")},
4626a9bc168f95408be86e79365a075d069465a06434Tim Peters
4627c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Instance methods: */
4628177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
4629c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"date",   (PyCFunction)datetime_getdate, METH_NOARGS,
4630c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return date object with same year, month and day.")},
4631a9bc168f95408be86e79365a075d069465a06434Tim Peters
4632c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"time",   (PyCFunction)datetime_gettime, METH_NOARGS,
4633c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4634a9bc168f95408be86e79365a075d069465a06434Tim Peters
4635c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"timetz",   (PyCFunction)datetime_gettimetz, METH_NOARGS,
4636c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return time object with same time and tzinfo.")},
4637a9bc168f95408be86e79365a075d069465a06434Tim Peters
4638c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"ctime",       (PyCFunction)datetime_ctime,        METH_NOARGS,
4639c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return ctime() style string.")},
4640a9bc168f95408be86e79365a075d069465a06434Tim Peters
4641c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"timetuple",   (PyCFunction)datetime_timetuple, METH_NOARGS,
4642c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return time tuple, compatible with time.localtime().")},
46432a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4644c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"utctimetuple",   (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4645c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
46462a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4647c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"isoformat",   (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4648c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("[sep] -> string in ISO 8601 format, "
4649c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4650c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "sep is used to separate the year from the time, and "
4651c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou               "defaults to 'T'.")},
46522a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4653c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"utcoffset",       (PyCFunction)datetime_utcoffset, METH_NOARGS,
4654c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
46552a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4656c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"tzname",          (PyCFunction)datetime_tzname,   METH_NOARGS,
4657c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return self.tzinfo.tzname(self).")},
46582a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4659c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"dst",             (PyCFunction)datetime_dst, METH_NOARGS,
4660c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return self.tzinfo.dst(self).")},
46612a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4662c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"replace",     (PyCFunction)datetime_replace,      METH_VARARGS | METH_KEYWORDS,
4663c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("Return datetime with new specified fields.")},
466412bf339aea9c787f7ce655d613b8898f7511c7dbTim Peters
4665c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"astimezone",  (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4666c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
466780475bb4d21d1e5ddbb9eb0042adb1113052b38aTim Peters
4668c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {"__reduce__", (PyCFunction)datetime_reduce,     METH_NOARGS,
4669c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     PyDoc_STR("__reduce__() -> (cls, state)")},
4670177e41a1178e501887d24610c0c3feba2cf7f70cGuido van Rossum
4671c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL,      NULL}
46722a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
46732a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4674a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic char datetime_doc[] =
46753a4231dd745e54ae533ce46371637f1fe8fa6a7bRaymond HettingerPyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
46763a4231dd745e54ae533ce46371637f1fe8fa6a7bRaymond Hettinger\n\
46773a4231dd745e54ae533ce46371637f1fe8fa6a7bRaymond HettingerThe year, month and day arguments are required. tzinfo may be None, or an\n\
46783a4231dd745e54ae533ce46371637f1fe8fa6a7bRaymond Hettingerinstance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
46792a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4680a9bc168f95408be86e79365a075d069465a06434Tim Petersstatic PyNumberMethods datetime_as_number = {
4681c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    datetime_add,                               /* nb_add */
4682c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    datetime_subtract,                          /* nb_subtract */
4683c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_multiply */
4684c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_divide */
4685c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_remainder */
4686c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_divmod */
4687c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_power */
4688c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_negative */
4689c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_positive */
4690c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_absolute */
4691c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* nb_nonzero */
46922a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
46932a799bf77a83adef010ff4751e5195702f159f39Tim Peters
4694a9bc168f95408be86e79365a075d069465a06434Tim Petersstatichere PyTypeObject PyDateTime_DateTimeType = {
4695c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject_HEAD_INIT(NULL)
4696c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* ob_size */
4697c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    "datetime.datetime",                        /* tp_name */
4698c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    sizeof(PyDateTime_DateTime),                /* tp_basicsize */
4699c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_itemsize */
4700c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (destructor)datetime_dealloc,               /* tp_dealloc */
4701c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_print */
4702c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_getattr */
4703c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_setattr */
4704c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_compare */
4705c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (reprfunc)datetime_repr,                    /* tp_repr */
4706c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &datetime_as_number,                        /* tp_as_number */
4707c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_sequence */
4708c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_mapping */
4709c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (hashfunc)datetime_hash,                    /* tp_hash */
4710c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_call */
4711c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (reprfunc)datetime_str,                     /* tp_str */
4712c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject_GenericGetAttr,                    /* tp_getattro */
4713c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_setattro */
4714c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_as_buffer */
4715c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4716c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_TPFLAGS_BASETYPE,                        /* tp_flags */
4717c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    datetime_doc,                               /* tp_doc */
4718c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_traverse */
4719c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_clear */
4720c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    (richcmpfunc)datetime_richcompare,          /* tp_richcompare */
4721c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_weaklistoffset */
4722c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_iter */
4723c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_iternext */
4724c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    datetime_methods,                           /* tp_methods */
4725c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_members */
4726c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    datetime_getset,                            /* tp_getset */
4727c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &PyDateTime_DateType,                       /* tp_base */
4728c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_dict */
4729c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_descr_get */
4730c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_descr_set */
4731c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_dictoffset */
4732c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_init */
4733c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    datetime_alloc,                             /* tp_alloc */
4734c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    datetime_new,                               /* tp_new */
4735c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    0,                                          /* tp_free */
47362a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
47372a799bf77a83adef010ff4751e5195702f159f39Tim Peters
47382a799bf77a83adef010ff4751e5195702f159f39Tim Peters/* ---------------------------------------------------------------------------
47392a799bf77a83adef010ff4751e5195702f159f39Tim Peters * Module methods and initialization.
47402a799bf77a83adef010ff4751e5195702f159f39Tim Peters */
47412a799bf77a83adef010ff4751e5195702f159f39Tim Peters
47422a799bf77a83adef010ff4751e5195702f159f39Tim Petersstatic PyMethodDef module_methods[] = {
4743c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    {NULL, NULL}
47442a799bf77a83adef010ff4751e5195702f159f39Tim Peters};
47452a799bf77a83adef010ff4751e5195702f159f39Tim Peters
47469ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters/* C API.  Clients get at this via PyDateTime_IMPORT, defined in
47479ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters * datetime.h.
47489ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters */
47499ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Petersstatic PyDateTime_CAPI CAPI = {
4750c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &PyDateTime_DateType,
4751c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &PyDateTime_DateTimeType,
4752c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &PyDateTime_TimeType,
4753c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &PyDateTime_DeltaType,
4754c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    &PyDateTime_TZInfoType,
4755c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    new_date_ex,
4756c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    new_datetime_ex,
4757c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    new_time_ex,
4758c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    new_delta_ex,
4759c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    datetime_fromtimestamp,
4760c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    date_fromtimestamp
47619ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters};
47629ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters
47639ddf40b4e1f8875a807c026ef04e79f51debbe26Tim Peters
47642a799bf77a83adef010ff4751e5195702f159f39Tim PetersPyMODINIT_FUNC
47652a799bf77a83adef010ff4751e5195702f159f39Tim Petersinitdatetime(void)
47662a799bf77a83adef010ff4751e5195702f159f39Tim Peters{
4767c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *m;        /* a module object */
4768c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *d;        /* its dict */
4769c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyObject *x;
4770c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4771c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    m = Py_InitModule3("datetime", module_methods,
4772c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       "Fast implementation of the datetime type.");
4773c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (m == NULL)
4774c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4775c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4776c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyType_Ready(&PyDateTime_DateType) < 0)
4777c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4778c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4779c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4780c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4781c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4782c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyType_Ready(&PyDateTime_TimeType) < 0)
4783c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4784c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4785c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4786c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4787c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* timedelta values */
4788c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    d = PyDateTime_DeltaType.tp_dict;
4789c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4790c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_delta(0, 0, 1, 0);
4791c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4792c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4793c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4794c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4795c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4796c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4797c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4798c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4799c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4800c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4801c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4802c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4803c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4804c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4805c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* date values */
4806c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    d = PyDateTime_DateType.tp_dict;
4807c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4808c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_date(1, 1, 1);
4809c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4810c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4811c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4812c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4813c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_date(MAXYEAR, 12, 31);
4814c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4815c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4816c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4817c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4818c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_delta(1, 0, 0, 0);
4819c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4820c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4821c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4822c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4823c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* time values */
4824c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    d = PyDateTime_TimeType.tp_dict;
4825c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4826c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_time(0, 0, 0, 0, Py_None);
4827c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4828c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4829c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4830c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4831c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_time(23, 59, 59, 999999, Py_None);
4832c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4833c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4834c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4835c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4836c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_delta(0, 0, 1, 0);
4837c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4838c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4839c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4840c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4841c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* datetime values */
4842c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    d = PyDateTime_DateTimeType.tp_dict;
4843c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4844c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4845c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4846c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4847c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4848c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4849c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4850c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4851c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4852c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4853c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4854c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = new_delta(0, 0, 1, 0);
4855c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4856c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4857c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_DECREF(x);
4858c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4859c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* module initialization */
4860c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4861c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4862c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4863c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(&PyDateTime_DateType);
4864c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4865c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4866c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(&PyDateTime_DateTimeType);
4867c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyModule_AddObject(m, "datetime",
4868c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou                       (PyObject *)&PyDateTime_DateTimeType);
4869c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4870c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(&PyDateTime_TimeType);
4871c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4872c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4873c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(&PyDateTime_DeltaType);
4874c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4875c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4876c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    Py_INCREF(&PyDateTime_TZInfoType);
4877c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4878c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4879c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
4880c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (x == NULL)
4881c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4882c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    PyModule_AddObject(m, "datetime_CAPI", x);
4883c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4884c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* A 4-year cycle has an extra leap day over what we'd get from
4885c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * pasting together 4 single years.
4886c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
4887c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(DI4Y == 4 * 365 + 1);
4888c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(DI4Y == days_before_year(4+1));
4889c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4890c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* Similarly, a 400-year cycle has an extra leap day over what we'd
4891c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * get from pasting together 4 100-year cycles.
4892c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
4893c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(DI400Y == 4 * DI100Y + 1);
4894c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(DI400Y == days_before_year(400+1));
4895c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4896c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4897c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * pasting together 25 4-year cycles.
4898c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
4899c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(DI100Y == 25 * DI4Y - 1);
4900c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    assert(DI100Y == days_before_year(100+1));
4901c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4902c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us_per_us = PyInt_FromLong(1);
4903c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us_per_ms = PyInt_FromLong(1000);
4904c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us_per_second = PyInt_FromLong(1000000);
4905c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us_per_minute = PyInt_FromLong(60000000);
4906c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    seconds_per_day = PyInt_FromLong(24 * 3600);
4907c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4908c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        us_per_minute == NULL || seconds_per_day == NULL)
4909c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
4910c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou
4911c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    /* The rest are too big for 32-bit ints, but even
4912c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     * us_per_week fits in 40 bits, so doubles should be exact.
4913c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou     */
4914c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us_per_hour = PyLong_FromDouble(3600000000.0);
4915c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us_per_day = PyLong_FromDouble(86400000000.0);
4916c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    us_per_week = PyLong_FromDouble(604800000000.0);
4917c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou    if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4918c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        return;
49192a799bf77a83adef010ff4751e5195702f159f39Tim Peters}
4920f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4921f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters/* ---------------------------------------------------------------------------
4922a9bc168f95408be86e79365a075d069465a06434Tim PetersSome time zone algebra.  For a datetime x, let
4923f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters    x.n = x stripped of its timezone -- its naive time.
4924f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters    x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4925c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou      return None
4926f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters    x.d = x.dst(), and assuming that doesn't raise an exception or
4927c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou      return None
4928f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters    x.s = x's standard offset, x.o - x.d
4929f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4930f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim PetersNow some derived rules, where k is a duration (timedelta).
4931f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4932f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters1. x.o = x.s + x.d
4933f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters   This follows from the definition of x.s.
4934f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4935c5dc4da125ee686f5544430b97545a17ad77a6cbTim Peters2. If x and y have the same tzinfo member, x.s = y.s.
4936f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters   This is actually a requirement, an assumption we need to make about
4937f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters   sane tzinfo classes.
4938f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4939f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters3. The naive UTC time corresponding to x is x.n - x.o.
4940f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters   This is again a requirement for a sane tzinfo class.
4941f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4942f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters4. (x+k).s = x.s
49438bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
4944f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4945c5dc4da125ee686f5544430b97545a17ad77a6cbTim Peters5. (x+k).n = x.n + k
4946f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters   Again follows from how arithmetic is defined.
4947f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
49488bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersNow we can explain tz.fromutc(x).  Let's assume it's an interesting case
4949f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters(meaning that the various tzinfo methods exist, and don't blow up or return
4950f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim PetersNone when called).
4951f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4952a9bc168f95408be86e79365a075d069465a06434Tim PetersThe function wants to return a datetime y with timezone tz, equivalent to x.
49538bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersx is already in UTC.
4954f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4955f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim PetersBy #3, we want
4956f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
49578bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    y.n - y.o = x.n                             [1]
4958f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4959f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim PetersThe algorithm starts by attaching tz to x.n, and calling that y.  So
4960f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Petersx.n = y.n at the start.  Then it wants to add a duration k to y, so that [1]
4961f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Petersbecomes true; in effect, we want to solve [2] for k:
4962f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
49638bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   (y+k).n - (y+k).o = x.n                      [2]
4964f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4965f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim PetersBy #1, this is the same as
4966f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
49678bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   (y+k).n - ((y+k).s + (y+k).d) = x.n          [3]
4968f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4969f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim PetersBy #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4970f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim PetersSubstituting that into [3],
4971f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
49728bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
49738bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   k - (y+k).s - (y+k).d = 0; rearranging,
49748bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
49758bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   k = y.s - (y+k).d
4976f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
49778bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersOn the RHS, (y+k).d can't be computed directly, but y.s can be, and we
49788bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersapproximate k by ignoring the (y+k).d term at first.  Note that k can't be
49798bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersvery large, since all offset-returning methods return a duration of magnitude
49808bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersless than 24 hours.  For that reason, if y is firmly in std time, (y+k).d must
49818bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersbe 0, so ignoring it has no consequence then.
4982f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
4983f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim PetersIn any case, the new value is
4984f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
49858bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    z = y + y.s                                 [4]
4986f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
49878bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersIt's helpful to step back at look at [4] from a higher level:  it's simply
49888bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersmapping from UTC to tz's standard time.
4989c5dc4da125ee686f5544430b97545a17ad77a6cbTim Peters
4990c5dc4da125ee686f5544430b97545a17ad77a6cbTim PetersAt this point, if
4991c5dc4da125ee686f5544430b97545a17ad77a6cbTim Peters
49928bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    z.n - z.o = x.n                             [5]
4993c5dc4da125ee686f5544430b97545a17ad77a6cbTim Peters
4994c5dc4da125ee686f5544430b97545a17ad77a6cbTim Peterswe have an equivalent time, and are almost done.  The insecurity here is
4995f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Petersat the start of daylight time.  Picture US Eastern for concreteness.  The wall
4996f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peterstime jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
49978bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterssense then.  The docs ask that an Eastern tzinfo class consider such a time to
49988bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersbe EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
49998bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterson the day DST starts.  We want to return the 1:MM EST spelling because that's
5000f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Petersthe only spelling that makes sense on the local wall clock.
5001f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters
5002c5dc4da125ee686f5544430b97545a17ad77a6cbTim PetersIn fact, if [5] holds at this point, we do have the standard-time spelling,
5003c5dc4da125ee686f5544430b97545a17ad77a6cbTim Petersbut that takes a bit of proof.  We first prove a stronger result.  What's the
5004c5dc4da125ee686f5544430b97545a17ad77a6cbTim Petersdifference between the LHS and RHS of [5]?  Let
5005c3bb26a099249ae267905a200451011c229ba00bTim Peters
50068bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    diff = x.n - (z.n - z.o)                    [6]
5007c3bb26a099249ae267905a200451011c229ba00bTim Peters
5008c5dc4da125ee686f5544430b97545a17ad77a6cbTim PetersNow
5009c5dc4da125ee686f5544430b97545a17ad77a6cbTim Peters    z.n =                       by [4]
50108bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    (y + y.s).n =               by #5
50118bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    y.n + y.s =                 since y.n = x.n
50128bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    x.n + y.s =                 since z and y are have the same tzinfo member,
50138bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters                                    y.s = z.s by #2
50148bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    x.n + z.s
5015c3bb26a099249ae267905a200451011c229ba00bTim Peters
5016c5dc4da125ee686f5544430b97545a17ad77a6cbTim PetersPlugging that back into [6] gives
5017c3bb26a099249ae267905a200451011c229ba00bTim Peters
5018c5dc4da125ee686f5544430b97545a17ad77a6cbTim Peters    diff =
50198bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    x.n - ((x.n + z.s) - z.o) =     expanding
50208bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    x.n - x.n - z.s + z.o =         cancelling
50218bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    - z.s + z.o =                   by #2
5022c5dc4da125ee686f5544430b97545a17ad77a6cbTim Peters    z.d
5023c3bb26a099249ae267905a200451011c229ba00bTim Peters
5024c5dc4da125ee686f5544430b97545a17ad77a6cbTim PetersSo diff = z.d.
5025c3bb26a099249ae267905a200451011c229ba00bTim Peters
5026c5dc4da125ee686f5544430b97545a17ad77a6cbTim PetersIf [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
50278bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersspelling we wanted in the endcase described above.  We're done.  Contrarily,
50288bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersif z.d = 0, then we have a UTC equivalent, and are also done.
5029c3bb26a099249ae267905a200451011c229ba00bTim Peters
5030c5dc4da125ee686f5544430b97545a17ad77a6cbTim PetersIf [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5031c5dc4da125ee686f5544430b97545a17ad77a6cbTim Petersadd to z (in effect, z is in tz's standard time, and we need to shift the
50328bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterslocal clock into tz's daylight time).
5033c3bb26a099249ae267905a200451011c229ba00bTim Peters
5034c5dc4da125ee686f5544430b97545a17ad77a6cbTim PetersLet
5035c3bb26a099249ae267905a200451011c229ba00bTim Peters
50364fede1a36bf4130bceddb786ccee1a259f203f45Tim Peters    z' = z + z.d = z + diff                     [7]
5037c3bb26a099249ae267905a200451011c229ba00bTim Peters
50384fede1a36bf4130bceddb786ccee1a259f203f45Tim Petersand we can again ask whether
5039c3bb26a099249ae267905a200451011c229ba00bTim Peters
50408bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    z'.n - z'.o = x.n                           [8]
5041c3bb26a099249ae267905a200451011c229ba00bTim Peters
50428bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersIf so, we're done.  If not, the tzinfo class is insane, according to the
50438bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersassumptions we've made.  This also requires a bit of proof.  As before, let's
50448bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterscompute the difference between the LHS and RHS of [8] (and skipping some of
50458bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersthe justifications for the kinds of substitutions we've done several times
50468bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersalready):
50474fede1a36bf4130bceddb786ccee1a259f203f45Tim Peters
50488bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters    diff' = x.n - (z'.n - z'.o) =           replacing z'.n via [7]
5049c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        x.n  - (z.n + diff - z'.o) =    replacing diff via [6]
5050c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5051c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        x.n - z.n - x.n + z.n - z.o + z'.o =    cancel x.n
5052c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        - z.n + z.n - z.o + z'.o =              cancel z.n
5053c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        - z.o + z'.o =                      #1 twice
5054c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        -z.s - z.d + z'.s + z'.d =          z and z' have same tzinfo
5055c83ea137d7e717f764e2f31fc2544f522de7d857Antoine Pitrou        z'.d - z.d
50564fede1a36bf4130bceddb786ccee1a259f203f45Tim Peters
50574fede1a36bf4130bceddb786ccee1a259f203f45Tim PetersSo z' is UTC-equivalent to x iff z'.d = z.d at this point.  If they are equal,
50588bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterswe've found the UTC-equivalent so are done.  In fact, we stop with [7] and
50598bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersreturn z', not bothering to compute z'.d.
50608bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters
50618bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersHow could z.d and z'd differ?  z' = z + z.d [7], so merely moving z' by
50628bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersa dst() offset, and starting *from* a time already in DST (we know z.d != 0),
50638bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterswould have to change the result dst() returns:  we start in DST, and moving
50648bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersa little further into it takes us out of DST.
50658bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters
50668bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersThere isn't a sane case where this can happen.  The closest it gets is at
50678bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersthe end of DST, where there's an hour in UTC with no spelling in a hybrid
50688bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterstzinfo class.  In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT.  During
50698bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersthat hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
50708bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersUTC) because the docs insist on that, but 0:MM is taken as being in daylight
50718bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterstime (4:MM UTC).  There is no local time mapping to 5:MM UTC.  The local
50728bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersclock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
50738bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersstandard time.  Since that's what the local clock *does*, we want to map both
50748bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersUTC hours 5:MM and 6:MM to 1:MM Eastern.  The result is ambiguous
50754fede1a36bf4130bceddb786ccee1a259f203f45Tim Petersin local time, but so it goes -- it's the way the local clock works.
50764fede1a36bf4130bceddb786ccee1a259f203f45Tim Peters
50778bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersWhen x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
50788bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersso z=0:MM.  z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
50798bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersz' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
50804fede1a36bf4130bceddb786ccee1a259f203f45Tim Peters(correctly) concludes that z' is not UTC-equivalent to x.
50814fede1a36bf4130bceddb786ccee1a259f203f45Tim Peters
50824fede1a36bf4130bceddb786ccee1a259f203f45Tim PetersBecause we know z.d said z was in daylight time (else [5] would have held and
50834fede1a36bf4130bceddb786ccee1a259f203f45Tim Peterswe would have stopped then), and we know z.d != z'.d (else [8] would have held
5084f0dfc7ac5c2f76baaae0c3b45bc339281cfa2adcWalter Dörwaldand we would have stopped then), and there are only 2 possible values dst() can
50854fede1a36bf4130bceddb786ccee1a259f203f45Tim Petersreturn in Eastern, it follows that z'.d must be 0 (which it is in the example,
50864fede1a36bf4130bceddb786ccee1a259f203f45Tim Petersbut the reasoning doesn't depend on the example -- it depends on there being
50874fede1a36bf4130bceddb786ccee1a259f203f45Tim Peterstwo possible dst() outcomes, one zero and the other non-zero).  Therefore
50888bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersz' must be in standard time, and is the spelling we want in this case.
50898bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters
50908bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersNote again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
50918bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersconcerned (because it takes z' as being in standard time rather than the
50928bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersdaylight time we intend here), but returning it gives the real-life "local
50938bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersclock repeats an hour" behavior when mapping the "unspellable" UTC hour into
50948bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterstz.
50958bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters
50968bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersWhen the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
50978bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersthe 1:MM standard time spelling we want.
50988bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters
50998bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersSo how can this break?  One of the assumptions must be violated.  Two
51008bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterspossibilities:
51018bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters
51028bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters1) [2] effectively says that y.s is invariant across all y belong to a given
51038bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   time zone.  This isn't true if, for political reasons or continental drift,
51048bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   a region decides to change its base offset from UTC.
51058bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters
51068bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters2) There may be versions of "double daylight" time where the tail end of
51078bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   the analysis gives up a step too early.  I haven't thought about that
51088bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters   enough to say.
51098bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters
51108bb5ad2e566102e7319f6d5b8eac3347c64261cfTim PetersIn any case, it's clear that the default fromutc() is strong enough to handle
51118bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peters"almost all" time zones:  so long as the standard offset is invariant, it
51128bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersdoesn't matter if daylight time transition points change from year to year, or
51138bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersif daylight time is skipped in some years; it doesn't matter how large or
51148bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterssmall dst() may get within its bounds; and it doesn't even matter if some
51158bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Petersperverse time zone returns a negative dst()).  So a breaking case must be
51168bb5ad2e566102e7319f6d5b8eac3347c64261cfTim Peterspretty bizarre, and a tzinfo subclass can override fromutc() if it is.
5117f36151556f834deaa1cb0be3f1d6f3fdf73231ebTim Peters--------------------------------------------------------------------------- */
5118