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, µseconds); 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", ×tamp)) 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, ×tamp, &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", ×tamp)) 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, µsecond) < 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