blob: 4c8f3f6fa2941fff287730755236aeac2e0c30e0 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
Tim Peters2a799bf2002-12-16 20:18:38 +00006#include "structmember.h"
7
8#include <time.h>
9
Victor Stinner09e5cf22015-03-30 00:09:18 +020010#ifdef MS_WINDOWS
11# include <winsock2.h> /* struct timeval */
12#endif
13
Tim Peters9ddf40b2004-06-20 22:41:32 +000014/* Differentiate between building the core module and building extension
15 * modules.
16 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000017#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000018#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000019#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000020#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000021#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000022
Larry Hastings61272b72014-01-07 12:41:53 -080023/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080024module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080025class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Larry Hastings61272b72014-01-07 12:41:53 -080026[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -080027/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080028
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030029#include "clinic/_datetimemodule.c.h"
30
Tim Peters2a799bf2002-12-16 20:18:38 +000031/* We require that C int be at least 32 bits, and use int virtually
32 * everywhere. In just a few cases we use a temp long, where a Python
33 * API returns a C long. In such cases, we have to ensure that the
34 * final result fits in a C int (this can be an issue on 64-bit boxes).
35 */
36#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000037# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000038#endif
39
40#define MINYEAR 1
41#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000042#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000043
44/* Nine decimal digits is easy to communicate, and leaves enough room
45 * so that two delta days can be added w/o fear of overflowing a signed
46 * 32-bit int, and with plenty of room left over to absorb any possible
47 * carries from adding seconds.
48 */
49#define MAX_DELTA_DAYS 999999999
50
51/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define GET_YEAR PyDateTime_GET_YEAR
53#define GET_MONTH PyDateTime_GET_MONTH
54#define GET_DAY PyDateTime_GET_DAY
55#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
56#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
57#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
58#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000059
60/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
62 ((o)->data[1] = ((v) & 0x00ff)))
63#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
64#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000065
66/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
68#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
69#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
70#define DATE_SET_MICROSECOND(o, v) \
71 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
72 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
73 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000074
75/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
77#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
78#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
79#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
80#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
81#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
82#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
83#define TIME_SET_MICROSECOND(o, v) \
84 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
85 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
86 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000087
88/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
90#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
91#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093#define SET_TD_DAYS(o, v) ((o)->days = (v))
94#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000095#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
96
Tim Petersa032d2e2003-01-11 00:15:54 +000097/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
98 * p->hastzinfo.
99 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000100#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
101#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
102 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
103#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
104 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000105/* M is a char or int claiming to be a valid month. The macro is equivalent
106 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000108 */
109#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
110
Tim Peters2a799bf2002-12-16 20:18:38 +0000111/* Forward declarations. */
112static PyTypeObject PyDateTime_DateType;
113static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000114static PyTypeObject PyDateTime_DeltaType;
115static PyTypeObject PyDateTime_TimeType;
116static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000117static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000118
Martin v. Löwise75fc142013-11-07 18:46:53 +0100119_Py_IDENTIFIER(as_integer_ratio);
120_Py_IDENTIFIER(fromutc);
121_Py_IDENTIFIER(isoformat);
122_Py_IDENTIFIER(strftime);
123
Tim Peters2a799bf2002-12-16 20:18:38 +0000124/* ---------------------------------------------------------------------------
125 * Math utilities.
126 */
127
128/* k = i+j overflows iff k differs in sign from both inputs,
129 * iff k^i has sign bit set and k^j has sign bit set,
130 * iff (k^i)&(k^j) has sign bit set.
131 */
132#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000134
135/* Compute Python divmod(x, y), returning the quotient and storing the
136 * remainder into *r. The quotient is the floor of x/y, and that's
137 * the real point of this. C will probably truncate instead (C99
138 * requires truncation; C89 left it implementation-defined).
139 * Simplification: we *require* that y > 0 here. That's appropriate
140 * for all the uses made of it. This simplifies the code and makes
141 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
142 * overflow case).
143 */
144static int
145divmod(int x, int y, int *r)
146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 assert(y > 0);
150 quo = x / y;
151 *r = x - quo * y;
152 if (*r < 0) {
153 --quo;
154 *r += y;
155 }
156 assert(0 <= *r && *r < y);
157 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000158}
159
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000160/* Nearest integer to m / n for integers m and n. Half-integer results
161 * are rounded to even.
162 */
163static PyObject *
164divide_nearest(PyObject *m, PyObject *n)
165{
166 PyObject *result;
167 PyObject *temp;
168
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000169 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000170 if (temp == NULL)
171 return NULL;
172 result = PyTuple_GET_ITEM(temp, 0);
173 Py_INCREF(result);
174 Py_DECREF(temp);
175
176 return result;
177}
178
Tim Peters2a799bf2002-12-16 20:18:38 +0000179/* ---------------------------------------------------------------------------
180 * General calendrical helper functions
181 */
182
183/* For each month ordinal in 1..12, the number of days in that month,
184 * and the number of days before that month in the same year. These
185 * are correct for non-leap years only.
186 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200187static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 0, /* unused; this vector uses 1-based indexing */
189 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000190};
191
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200192static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 0, /* unused; this vector uses 1-based indexing */
194 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000195};
196
197/* year -> 1 if leap year, else 0. */
198static int
199is_leap(int year)
200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 /* Cast year to unsigned. The result is the same either way, but
202 * C can generate faster code for unsigned mod than for signed
203 * mod (especially for % 4 -- a good compiler should just grab
204 * the last 2 bits when the LHS is unsigned).
205 */
206 const unsigned int ayear = (unsigned int)year;
207 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000208}
209
210/* year, month -> number of days in that month in that year */
211static int
212days_in_month(int year, int month)
213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 assert(month >= 1);
215 assert(month <= 12);
216 if (month == 2 && is_leap(year))
217 return 29;
218 else
219 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000220}
221
222/* year, month -> number of days in year preceeding first day of month */
223static int
224days_before_month(int year, int month)
225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 assert(month >= 1);
229 assert(month <= 12);
230 days = _days_before_month[month];
231 if (month > 2 && is_leap(year))
232 ++days;
233 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000234}
235
236/* year -> number of days before January 1st of year. Remember that we
237 * start with year 1, so days_before_year(1) == 0.
238 */
239static int
240days_before_year(int year)
241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 int y = year - 1;
243 /* This is incorrect if year <= 0; we really want the floor
244 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000245 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000247 assert (year >= 1);
248 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000249}
250
251/* Number of days in 4, 100, and 400 year cycles. That these have
252 * the correct values is asserted in the module init function.
253 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254#define DI4Y 1461 /* days_before_year(5); days in 4 years */
255#define DI100Y 36524 /* days_before_year(101); days in 100 years */
256#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000257
258/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
259static void
260ord_to_ymd(int ordinal, int *year, int *month, int *day)
261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
265 * leap years repeats exactly every 400 years. The basic strategy is
266 * to find the closest 400-year boundary at or before ordinal, then
267 * work with the offset from that boundary to ordinal. Life is much
268 * clearer if we subtract 1 from ordinal first -- then the values
269 * of ordinal at 400-year boundaries are exactly those divisible
270 * by DI400Y:
271 *
272 * D M Y n n-1
273 * -- --- ---- ---------- ----------------
274 * 31 Dec -400 -DI400Y -DI400Y -1
275 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
276 * ...
277 * 30 Dec 000 -1 -2
278 * 31 Dec 000 0 -1
279 * 1 Jan 001 1 0 400-year boundary
280 * 2 Jan 001 2 1
281 * 3 Jan 001 3 2
282 * ...
283 * 31 Dec 400 DI400Y DI400Y -1
284 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
285 */
286 assert(ordinal >= 1);
287 --ordinal;
288 n400 = ordinal / DI400Y;
289 n = ordinal % DI400Y;
290 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 /* Now n is the (non-negative) offset, in days, from January 1 of
293 * year, to the desired date. Now compute how many 100-year cycles
294 * precede n.
295 * Note that it's possible for n100 to equal 4! In that case 4 full
296 * 100-year cycles precede the desired day, which implies the
297 * desired day is December 31 at the end of a 400-year cycle.
298 */
299 n100 = n / DI100Y;
300 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 /* Now compute how many 4-year cycles precede it. */
303 n4 = n / DI4Y;
304 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 /* And now how many single years. Again n1 can be 4, and again
307 * meaning that the desired day is December 31 at the end of the
308 * 4-year cycle.
309 */
310 n1 = n / 365;
311 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 *year += n100 * 100 + n4 * 4 + n1;
314 if (n1 == 4 || n100 == 4) {
315 assert(n == 0);
316 *year -= 1;
317 *month = 12;
318 *day = 31;
319 return;
320 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 /* Now the year is correct, and n is the offset from January 1. We
323 * find the month via an estimate that's either exact or one too
324 * large.
325 */
326 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
327 assert(leapyear == is_leap(*year));
328 *month = (n + 50) >> 5;
329 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
330 if (preceding > n) {
331 /* estimate is too large */
332 *month -= 1;
333 preceding -= days_in_month(*year, *month);
334 }
335 n -= preceding;
336 assert(0 <= n);
337 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000340}
341
342/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
343static int
344ymd_to_ord(int year, int month, int day)
345{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000347}
348
349/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
350static int
351weekday(int year, int month, int day)
352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000354}
355
356/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
357 * first calendar week containing a Thursday.
358 */
359static int
360iso_week1_monday(int year)
361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
363 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
364 int first_weekday = (first_day + 6) % 7;
365 /* ordinal of closest Monday at or before 1/1 */
366 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
369 week1_monday += 7;
370 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000371}
372
373/* ---------------------------------------------------------------------------
374 * Range checkers.
375 */
376
377/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
378 * If not, raise OverflowError and return -1.
379 */
380static int
381check_delta_day_range(int days)
382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000383 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
384 return 0;
385 PyErr_Format(PyExc_OverflowError,
386 "days=%d; must have magnitude <= %d",
387 days, MAX_DELTA_DAYS);
388 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000389}
390
391/* Check that date arguments are in range. Return 0 if they are. If they
392 * aren't, raise ValueError and return -1.
393 */
394static int
395check_date_args(int year, int month, int day)
396{
397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 if (year < MINYEAR || year > MAXYEAR) {
399 PyErr_SetString(PyExc_ValueError,
400 "year is out of range");
401 return -1;
402 }
403 if (month < 1 || month > 12) {
404 PyErr_SetString(PyExc_ValueError,
405 "month must be in 1..12");
406 return -1;
407 }
408 if (day < 1 || day > days_in_month(year, month)) {
409 PyErr_SetString(PyExc_ValueError,
410 "day is out of range for month");
411 return -1;
412 }
413 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000414}
415
416/* Check that time arguments are in range. Return 0 if they are. If they
417 * aren't, raise ValueError and return -1.
418 */
419static int
420check_time_args(int h, int m, int s, int us)
421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 if (h < 0 || h > 23) {
423 PyErr_SetString(PyExc_ValueError,
424 "hour must be in 0..23");
425 return -1;
426 }
427 if (m < 0 || m > 59) {
428 PyErr_SetString(PyExc_ValueError,
429 "minute must be in 0..59");
430 return -1;
431 }
432 if (s < 0 || s > 59) {
433 PyErr_SetString(PyExc_ValueError,
434 "second must be in 0..59");
435 return -1;
436 }
437 if (us < 0 || us > 999999) {
438 PyErr_SetString(PyExc_ValueError,
439 "microsecond must be in 0..999999");
440 return -1;
441 }
442 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000443}
444
445/* ---------------------------------------------------------------------------
446 * Normalization utilities.
447 */
448
449/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
450 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
451 * at least factor, enough of *lo is converted into "hi" units so that
452 * 0 <= *lo < factor. The input values must be such that int overflow
453 * is impossible.
454 */
455static void
456normalize_pair(int *hi, int *lo, int factor)
457{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 assert(factor > 0);
459 assert(lo != hi);
460 if (*lo < 0 || *lo >= factor) {
461 const int num_hi = divmod(*lo, factor, lo);
462 const int new_hi = *hi + num_hi;
463 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
464 *hi = new_hi;
465 }
466 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000467}
468
469/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 * 0 <= *s < 24*3600
471 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000472 * The input values must be such that the internals don't overflow.
473 * The way this routine is used, we don't get close.
474 */
475static void
476normalize_d_s_us(int *d, int *s, int *us)
477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 if (*us < 0 || *us >= 1000000) {
479 normalize_pair(s, us, 1000000);
480 /* |s| can't be bigger than about
481 * |original s| + |original us|/1000000 now.
482 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 }
485 if (*s < 0 || *s >= 24*3600) {
486 normalize_pair(d, s, 24*3600);
487 /* |d| can't be bigger than about
488 * |original d| +
489 * (|original s| + |original us|/1000000) / (24*3600) now.
490 */
491 }
492 assert(0 <= *s && *s < 24*3600);
493 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000494}
495
496/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 * 1 <= *m <= 12
498 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000499 * The input values must be such that the internals don't overflow.
500 * The way this routine is used, we don't get close.
501 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000502static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000503normalize_y_m_d(int *y, int *m, int *d)
504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000506
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000507 /* In actual use, m is always the month component extracted from a
508 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 /* Now only day can be out of bounds (year may also be out of bounds
514 * for a datetime object, but we don't care about that here).
515 * If day is out of bounds, what to do is arguable, but at least the
516 * method here is principled and explainable.
517 */
518 dim = days_in_month(*y, *m);
519 if (*d < 1 || *d > dim) {
520 /* Move day-1 days from the first of the month. First try to
521 * get off cheap if we're only one day out of range
522 * (adjustments for timezone alone can't be worse than that).
523 */
524 if (*d == 0) {
525 --*m;
526 if (*m > 0)
527 *d = days_in_month(*y, *m);
528 else {
529 --*y;
530 *m = 12;
531 *d = 31;
532 }
533 }
534 else if (*d == dim + 1) {
535 /* move forward a day */
536 ++*m;
537 *d = 1;
538 if (*m > 12) {
539 *m = 1;
540 ++*y;
541 }
542 }
543 else {
544 int ordinal = ymd_to_ord(*y, *m, 1) +
545 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000546 if (ordinal < 1 || ordinal > MAXORDINAL) {
547 goto error;
548 } else {
549 ord_to_ymd(ordinal, y, m, d);
550 return 0;
551 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 }
553 }
554 assert(*m > 0);
555 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000556 if (MINYEAR <= *y && *y <= MAXYEAR)
557 return 0;
558 error:
559 PyErr_SetString(PyExc_OverflowError,
560 "date value out of range");
561 return -1;
562
Tim Peters2a799bf2002-12-16 20:18:38 +0000563}
564
565/* Fiddle out-of-bounds months and days so that the result makes some kind
566 * of sense. The parameters are both inputs and outputs. Returns < 0 on
567 * failure, where failure means the adjusted year is out of bounds.
568 */
569static int
570normalize_date(int *year, int *month, int *day)
571{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000572 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000573}
574
575/* Force all the datetime fields into range. The parameters are both
576 * inputs and outputs. Returns < 0 on error.
577 */
578static int
579normalize_datetime(int *year, int *month, int *day,
580 int *hour, int *minute, int *second,
581 int *microsecond)
582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 normalize_pair(second, microsecond, 1000000);
584 normalize_pair(minute, second, 60);
585 normalize_pair(hour, minute, 60);
586 normalize_pair(day, hour, 24);
587 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000588}
589
590/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000591 * Basic object allocation: tp_alloc implementations. These allocate
592 * Python objects of the right size and type, and do the Python object-
593 * initialization bit. If there's not enough memory, they return NULL after
594 * setting MemoryError. All data members remain uninitialized trash.
595 *
596 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000597 * member is needed. This is ugly, imprecise, and possibly insecure.
598 * tp_basicsize for the time and datetime types is set to the size of the
599 * struct that has room for the tzinfo member, so subclasses in Python will
600 * allocate enough space for a tzinfo member whether or not one is actually
601 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
602 * part is that PyType_GenericAlloc() (which subclasses in Python end up
603 * using) just happens today to effectively ignore the nitems argument
604 * when tp_itemsize is 0, which it is for these type objects. If that
605 * changes, perhaps the callers of tp_alloc slots in this file should
606 * be changed to force a 0 nitems argument unless the type being allocated
607 * is a base type implemented in this file (so that tp_alloc is time_alloc
608 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000609 */
610
611static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000612time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 self = (PyObject *)
617 PyObject_MALLOC(aware ?
618 sizeof(PyDateTime_Time) :
619 sizeof(_PyDateTime_BaseTime));
620 if (self == NULL)
621 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100622 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000624}
625
626static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000627datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 self = (PyObject *)
632 PyObject_MALLOC(aware ?
633 sizeof(PyDateTime_DateTime) :
634 sizeof(_PyDateTime_BaseDateTime));
635 if (self == NULL)
636 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100637 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000639}
640
641/* ---------------------------------------------------------------------------
642 * Helpers for setting object fields. These work on pointers to the
643 * appropriate base class.
644 */
645
646/* For date and datetime. */
647static void
648set_date_fields(PyDateTime_Date *self, int y, int m, int d)
649{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000650 self->hashcode = -1;
651 SET_YEAR(self, y);
652 SET_MONTH(self, m);
653 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000654}
655
656/* ---------------------------------------------------------------------------
657 * Create various objects, mostly without range checking.
658 */
659
660/* Create a date instance with no range checking. */
661static PyObject *
662new_date_ex(int year, int month, int day, PyTypeObject *type)
663{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
667 if (self != NULL)
668 set_date_fields(self, year, month, day);
669 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000670}
671
672#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000674
675/* Create a datetime instance with no range checking. */
676static PyObject *
677new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 PyDateTime_DateTime *self;
681 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
684 if (self != NULL) {
685 self->hastzinfo = aware;
686 set_date_fields((PyDateTime_Date *)self, year, month, day);
687 DATE_SET_HOUR(self, hour);
688 DATE_SET_MINUTE(self, minute);
689 DATE_SET_SECOND(self, second);
690 DATE_SET_MICROSECOND(self, usecond);
691 if (aware) {
692 Py_INCREF(tzinfo);
693 self->tzinfo = tzinfo;
694 }
695 }
696 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000697}
698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
700 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
701 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000702
703/* Create a time instance with no range checking. */
704static PyObject *
705new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 PyDateTime_Time *self;
709 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
712 if (self != NULL) {
713 self->hastzinfo = aware;
714 self->hashcode = -1;
715 TIME_SET_HOUR(self, hour);
716 TIME_SET_MINUTE(self, minute);
717 TIME_SET_SECOND(self, second);
718 TIME_SET_MICROSECOND(self, usecond);
719 if (aware) {
720 Py_INCREF(tzinfo);
721 self->tzinfo = tzinfo;
722 }
723 }
724 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000725}
726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727#define new_time(hh, mm, ss, us, tzinfo) \
728 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000729
730/* Create a timedelta instance. Normalize the members iff normalize is
731 * true. Passing false is a speed optimization, if you know for sure
732 * that seconds and microseconds are already in their proper ranges. In any
733 * case, raises OverflowError and returns NULL if the normalized days is out
734 * of range).
735 */
736static PyObject *
737new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 if (normalize)
743 normalize_d_s_us(&days, &seconds, &microseconds);
744 assert(0 <= seconds && seconds < 24*3600);
745 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000746
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 if (check_delta_day_range(days) < 0)
748 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
751 if (self != NULL) {
752 self->hashcode = -1;
753 SET_TD_DAYS(self, days);
754 SET_TD_SECONDS(self, seconds);
755 SET_TD_MICROSECONDS(self, microseconds);
756 }
757 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000758}
759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760#define new_delta(d, s, us, normalize) \
761 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000762
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000763
764typedef struct
765{
766 PyObject_HEAD
767 PyObject *offset;
768 PyObject *name;
769} PyDateTime_TimeZone;
770
Victor Stinner6ced7c42011-03-21 18:15:42 +0100771/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000772static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -0400773/* The interned Epoch datetime instance */
774static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000775
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000776/* Create new timezone instance checking offset range. This
777 function does not check the name argument. Caller must assure
778 that offset is a timedelta instance and name is either NULL
779 or a unicode object. */
780static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000781create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000782{
783 PyDateTime_TimeZone *self;
784 PyTypeObject *type = &PyDateTime_TimeZoneType;
785
786 assert(offset != NULL);
787 assert(PyDelta_Check(offset));
788 assert(name == NULL || PyUnicode_Check(name));
789
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000790 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
791 if (self == NULL) {
792 return NULL;
793 }
794 Py_INCREF(offset);
795 self->offset = offset;
796 Py_XINCREF(name);
797 self->name = name;
798 return (PyObject *)self;
799}
800
801static int delta_bool(PyDateTime_Delta *self);
802
803static PyObject *
804new_timezone(PyObject *offset, PyObject *name)
805{
806 assert(offset != NULL);
807 assert(PyDelta_Check(offset));
808 assert(name == NULL || PyUnicode_Check(name));
809
810 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
811 Py_INCREF(PyDateTime_TimeZone_UTC);
812 return PyDateTime_TimeZone_UTC;
813 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000814 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
815 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400816 " representing a whole number of minutes,"
817 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000818 return NULL;
819 }
820 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
821 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
822 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
823 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400824 " timedelta(hours=24),"
825 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000826 return NULL;
827 }
828
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000829 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000830}
831
Tim Petersb0c854d2003-05-17 15:57:00 +0000832/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000833 * tzinfo helpers.
834 */
835
Tim Peters855fe882002-12-22 03:43:39 +0000836/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
837 * raise TypeError and return -1.
838 */
839static int
840check_tzinfo_subclass(PyObject *p)
841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 if (p == Py_None || PyTZInfo_Check(p))
843 return 0;
844 PyErr_Format(PyExc_TypeError,
845 "tzinfo argument must be None or of a tzinfo subclass, "
846 "not type '%s'",
847 Py_TYPE(p)->tp_name);
848 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000849}
850
Tim Peters2a799bf2002-12-16 20:18:38 +0000851/* If self has a tzinfo member, return a BORROWED reference to it. Else
852 * return NULL, which is NOT AN ERROR. There are no error returns here,
853 * and the caller must not decref the result.
854 */
855static PyObject *
856get_tzinfo_member(PyObject *self)
857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 if (PyDateTime_Check(self) && HASTZINFO(self))
861 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
862 else if (PyTime_Check(self) && HASTZINFO(self))
863 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000866}
867
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000868/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
869 * be an instance of the tzinfo class. If the method returns None, this
870 * returns None. If the method doesn't return None or timedelta, TypeError is
871 * raised and this returns NULL. If it returns a timedelta and the value is
872 * out of range or isn't a whole number of minutes, ValueError is raised and
873 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000874 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000875static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200876call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000877{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000878 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000881 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000883
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000884 if (tzinfo == Py_None)
885 Py_RETURN_NONE;
886 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
887 if (offset == Py_None || offset == NULL)
888 return offset;
889 if (PyDelta_Check(offset)) {
890 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
891 Py_DECREF(offset);
892 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
893 " representing a whole number of minutes");
894 return NULL;
895 }
896 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
897 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
898 Py_DECREF(offset);
899 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
900 " strictly between -timedelta(hours=24) and"
901 " timedelta(hours=24).");
902 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 }
904 }
905 else {
906 PyErr_Format(PyExc_TypeError,
907 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000908 "timedelta, not '%.200s'",
909 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -0700910 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000911 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000913
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000914 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000915}
916
917/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
918 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
919 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000920 * doesn't return None or timedelta, TypeError is raised and this returns -1.
921 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
922 * # of minutes), ValueError is raised and this returns -1. Else *none is
923 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000924 */
Tim Peters855fe882002-12-22 03:43:39 +0000925static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000926call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
927{
928 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000929}
930
Tim Peters2a799bf2002-12-16 20:18:38 +0000931/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
932 * result. tzinfo must be an instance of the tzinfo class. If dst()
933 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000934 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000935 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000936 * ValueError is raised and this returns -1. Else *none is set to 0 and
937 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000938 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000939static PyObject *
940call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000941{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000942 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000943}
944
Tim Petersbad8ff02002-12-30 20:52:32 +0000945/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000946 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000947 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000948 * returns NULL. If the result is a string, we ensure it is a Unicode
949 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000950 */
951static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000952call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200955 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 assert(tzinfo != NULL);
958 assert(check_tzinfo_subclass(tzinfo) >= 0);
959 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000962 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000963
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200964 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000965
966 if (result == NULL || result == Py_None)
967 return result;
968
969 if (!PyUnicode_Check(result)) {
970 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
971 "return None or a string, not '%s'",
972 Py_TYPE(result)->tp_name);
973 Py_DECREF(result);
974 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000976
977 return result;
Tim Peters00237032002-12-27 02:21:51 +0000978}
979
Tim Peters2a799bf2002-12-16 20:18:38 +0000980/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
981 * stuff
982 * ", tzinfo=" + repr(tzinfo)
983 * before the closing ")".
984 */
985static PyObject *
986append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +0000989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 assert(PyUnicode_Check(repr));
991 assert(tzinfo);
992 if (tzinfo == Py_None)
993 return repr;
994 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200995 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
996 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 Py_DECREF(repr);
998 if (temp == NULL)
999 return NULL;
1000 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1001 Py_DECREF(temp);
1002 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001003}
1004
1005/* ---------------------------------------------------------------------------
1006 * String format helpers.
1007 */
1008
1009static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001010format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001011{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001012 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1014 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001015 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1017 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1018 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1023 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1024 GET_DAY(date), hours, minutes, seconds,
1025 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001026}
1027
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001028static PyObject *delta_negative(PyDateTime_Delta *self);
1029
Tim Peters2a799bf2002-12-16 20:18:38 +00001030/* Add an hours & minutes UTC offset string to buf. buf has no more than
1031 * buflen bytes remaining. The UTC offset is gotten by calling
1032 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1033 * *buf, and that's all. Else the returned value is checked for sanity (an
1034 * integer in range), and if that's OK it's converted to an hours & minutes
1035 * string of the form
1036 * sign HH sep MM
1037 * Returns 0 if everything is OK. If the return value from utcoffset() is
1038 * bogus, an appropriate exception is set and -1 is returned.
1039 */
1040static int
Tim Peters328fff72002-12-20 01:31:27 +00001041format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001043{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001044 PyObject *offset;
1045 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001049
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001050 offset = call_utcoffset(tzinfo, tzinfoarg);
1051 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001053 if (offset == Py_None) {
1054 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 *buf = '\0';
1056 return 0;
1057 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001058 /* Offset is normalized, so it is negative if days < 0 */
1059 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 sign = '-';
Serhiy Storchaka576f1322016-01-05 21:27:54 +02001061 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001062 if (offset == NULL)
1063 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001065 else {
1066 sign = '+';
1067 }
1068 /* Offset is not negative here. */
1069 seconds = GET_TD_SECONDS(offset);
1070 Py_DECREF(offset);
1071 minutes = divmod(seconds, 60, &seconds);
1072 hours = divmod(minutes, 60, &minutes);
1073 assert(seconds == 0);
1074 /* XXX ignore sub-minute data, curently not allowed. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001078}
1079
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001080static PyObject *
1081make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 PyObject *temp;
1084 PyObject *tzinfo = get_tzinfo_member(object);
1085 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001086 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 if (Zreplacement == NULL)
1089 return NULL;
1090 if (tzinfo == Py_None || tzinfo == NULL)
1091 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 assert(tzinfoarg != NULL);
1094 temp = call_tzname(tzinfo, tzinfoarg);
1095 if (temp == NULL)
1096 goto Error;
1097 if (temp == Py_None) {
1098 Py_DECREF(temp);
1099 return Zreplacement;
1100 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 assert(PyUnicode_Check(temp));
1103 /* Since the tzname is getting stuffed into the
1104 * format, we have to double any % signs so that
1105 * strftime doesn't treat them as format codes.
1106 */
1107 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001108 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 Py_DECREF(temp);
1110 if (Zreplacement == NULL)
1111 return NULL;
1112 if (!PyUnicode_Check(Zreplacement)) {
1113 PyErr_SetString(PyExc_TypeError,
1114 "tzname.replace() did not return a string");
1115 goto Error;
1116 }
1117 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001118
1119 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 Py_DECREF(Zreplacement);
1121 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001122}
1123
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001124static PyObject *
1125make_freplacement(PyObject *object)
1126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 char freplacement[64];
1128 if (PyTime_Check(object))
1129 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1130 else if (PyDateTime_Check(object))
1131 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1132 else
1133 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001136}
1137
Tim Peters2a799bf2002-12-16 20:18:38 +00001138/* I sure don't want to reproduce the strftime code from the time module,
1139 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001140 * giving special meanings to the %z, %Z and %f format codes via a
1141 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001142 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1143 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001144 */
1145static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001146wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1152 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1153 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 const char *pin; /* pointer to next char in input format */
1156 Py_ssize_t flen; /* length of input format */
1157 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 PyObject *newfmt = NULL; /* py string, the output format */
1160 char *pnew; /* pointer to available byte in output format */
1161 size_t totalnew; /* number bytes total in output format buffer,
1162 exclusive of trailing \0 */
1163 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 const char *ptoappend; /* ptr to string to append to output buffer */
1166 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 assert(object && format && timetuple);
1169 assert(PyUnicode_Check(format));
1170 /* Convert the input format to a C string and size */
1171 pin = _PyUnicode_AsStringAndSize(format, &flen);
1172 if (!pin)
1173 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 /* Scan the input format, looking for %z/%Z/%f escapes, building
1176 * a new format. Since computing the replacements for those codes
1177 * is expensive, don't unless they're actually used.
1178 */
1179 if (flen > INT_MAX - 1) {
1180 PyErr_NoMemory();
1181 goto Done;
1182 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 totalnew = flen + 1; /* realistic if no %z/%Z */
1185 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1186 if (newfmt == NULL) goto Done;
1187 pnew = PyBytes_AsString(newfmt);
1188 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 while ((ch = *pin++) != '\0') {
1191 if (ch != '%') {
1192 ptoappend = pin - 1;
1193 ntoappend = 1;
1194 }
1195 else if ((ch = *pin++) == '\0') {
1196 /* There's a lone trailing %; doesn't make sense. */
1197 PyErr_SetString(PyExc_ValueError, "strftime format "
1198 "ends with raw %");
1199 goto Done;
1200 }
1201 /* A % has been seen and ch is the character after it. */
1202 else if (ch == 'z') {
1203 if (zreplacement == NULL) {
1204 /* format utcoffset */
1205 char buf[100];
1206 PyObject *tzinfo = get_tzinfo_member(object);
1207 zreplacement = PyBytes_FromStringAndSize("", 0);
1208 if (zreplacement == NULL) goto Done;
1209 if (tzinfo != Py_None && tzinfo != NULL) {
1210 assert(tzinfoarg != NULL);
1211 if (format_utcoffset(buf,
1212 sizeof(buf),
1213 "",
1214 tzinfo,
1215 tzinfoarg) < 0)
1216 goto Done;
1217 Py_DECREF(zreplacement);
1218 zreplacement =
1219 PyBytes_FromStringAndSize(buf,
1220 strlen(buf));
1221 if (zreplacement == NULL)
1222 goto Done;
1223 }
1224 }
1225 assert(zreplacement != NULL);
1226 ptoappend = PyBytes_AS_STRING(zreplacement);
1227 ntoappend = PyBytes_GET_SIZE(zreplacement);
1228 }
1229 else if (ch == 'Z') {
1230 /* format tzname */
1231 if (Zreplacement == NULL) {
1232 Zreplacement = make_Zreplacement(object,
1233 tzinfoarg);
1234 if (Zreplacement == NULL)
1235 goto Done;
1236 }
1237 assert(Zreplacement != NULL);
1238 assert(PyUnicode_Check(Zreplacement));
1239 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1240 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001241 if (ptoappend == NULL)
1242 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 }
1244 else if (ch == 'f') {
1245 /* format microseconds */
1246 if (freplacement == NULL) {
1247 freplacement = make_freplacement(object);
1248 if (freplacement == NULL)
1249 goto Done;
1250 }
1251 assert(freplacement != NULL);
1252 assert(PyBytes_Check(freplacement));
1253 ptoappend = PyBytes_AS_STRING(freplacement);
1254 ntoappend = PyBytes_GET_SIZE(freplacement);
1255 }
1256 else {
1257 /* percent followed by neither z nor Z */
1258 ptoappend = pin - 2;
1259 ntoappend = 2;
1260 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 /* Append the ntoappend chars starting at ptoappend to
1263 * the new format.
1264 */
1265 if (ntoappend == 0)
1266 continue;
1267 assert(ptoappend != NULL);
1268 assert(ntoappend > 0);
1269 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001270 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 PyErr_NoMemory();
1272 goto Done;
1273 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001274 totalnew <<= 1;
1275 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 pnew = PyBytes_AsString(newfmt) + usednew;
1278 }
1279 memcpy(pnew, ptoappend, ntoappend);
1280 pnew += ntoappend;
1281 usednew += ntoappend;
1282 assert(usednew <= totalnew);
1283 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1286 goto Done;
1287 {
1288 PyObject *format;
1289 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 if (time == NULL)
1292 goto Done;
1293 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1294 if (format != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001295 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1296 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 Py_DECREF(format);
1298 }
1299 Py_DECREF(time);
1300 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001301 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 Py_XDECREF(freplacement);
1303 Py_XDECREF(zreplacement);
1304 Py_XDECREF(Zreplacement);
1305 Py_XDECREF(newfmt);
1306 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001307}
1308
Tim Peters2a799bf2002-12-16 20:18:38 +00001309/* ---------------------------------------------------------------------------
1310 * Wrap functions from the time module. These aren't directly available
1311 * from C. Perhaps they should be.
1312 */
1313
1314/* Call time.time() and return its result (a Python float). */
1315static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001316time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 PyObject *result = NULL;
1319 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001322 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001323
1324 result = _PyObject_CallMethodId(time, &PyId_time, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 Py_DECREF(time);
1326 }
1327 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001328}
1329
1330/* Build a time.struct_time. The weekday and day number are automatically
1331 * computed from the y,m,d args.
1332 */
1333static PyObject *
1334build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 PyObject *time;
1337 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 time = PyImport_ImportModuleNoBlock("time");
1340 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001341 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001342
1343 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1344 "((iiiiiiiii))",
1345 y, m, d,
1346 hh, mm, ss,
1347 weekday(y, m, d),
1348 days_before_month(y, m) + d,
1349 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 Py_DECREF(time);
1351 }
1352 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001353}
1354
1355/* ---------------------------------------------------------------------------
1356 * Miscellaneous helpers.
1357 */
1358
Mark Dickinsone94c6792009-02-02 20:36:42 +00001359/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001360 * The comparisons here all most naturally compute a cmp()-like result.
1361 * This little helper turns that into a bool result for rich comparisons.
1362 */
1363static PyObject *
1364diff_to_bool(int diff, int op)
1365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 PyObject *result;
1367 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 switch (op) {
1370 case Py_EQ: istrue = diff == 0; break;
1371 case Py_NE: istrue = diff != 0; break;
1372 case Py_LE: istrue = diff <= 0; break;
1373 case Py_GE: istrue = diff >= 0; break;
1374 case Py_LT: istrue = diff < 0; break;
1375 case Py_GT: istrue = diff > 0; break;
1376 default:
1377 assert(! "op unknown");
1378 istrue = 0; /* To shut up compiler */
1379 }
1380 result = istrue ? Py_True : Py_False;
1381 Py_INCREF(result);
1382 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001383}
1384
Tim Peters07534a62003-02-07 22:50:28 +00001385/* Raises a "can't compare" TypeError and returns NULL. */
1386static PyObject *
1387cmperror(PyObject *a, PyObject *b)
1388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 PyErr_Format(PyExc_TypeError,
1390 "can't compare %s to %s",
1391 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1392 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001393}
1394
Tim Peters2a799bf2002-12-16 20:18:38 +00001395/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001396 * Cached Python objects; these are set by the module init function.
1397 */
1398
1399/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001400static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401static PyObject *us_per_ms = NULL; /* 1000 */
1402static PyObject *us_per_second = NULL; /* 1000000 */
1403static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001404static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1405static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1406static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001407static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1408
Tim Peters2a799bf2002-12-16 20:18:38 +00001409/* ---------------------------------------------------------------------------
1410 * Class implementations.
1411 */
1412
1413/*
1414 * PyDateTime_Delta implementation.
1415 */
1416
1417/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001419 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001420 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1421 * due to ubiquitous overflow possibilities.
1422 */
1423static PyObject *
1424delta_to_microseconds(PyDateTime_Delta *self)
1425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 PyObject *x1 = NULL;
1427 PyObject *x2 = NULL;
1428 PyObject *x3 = NULL;
1429 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1432 if (x1 == NULL)
1433 goto Done;
1434 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1435 if (x2 == NULL)
1436 goto Done;
1437 Py_DECREF(x1);
1438 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 /* x2 has days in seconds */
1441 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1442 if (x1 == NULL)
1443 goto Done;
1444 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1445 if (x3 == NULL)
1446 goto Done;
1447 Py_DECREF(x1);
1448 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001449 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 /* x3 has days+seconds in seconds */
1452 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1453 if (x1 == NULL)
1454 goto Done;
1455 Py_DECREF(x3);
1456 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 /* x1 has days+seconds in us */
1459 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1460 if (x2 == NULL)
1461 goto Done;
1462 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001463
1464Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 Py_XDECREF(x1);
1466 Py_XDECREF(x2);
1467 Py_XDECREF(x3);
1468 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001469}
1470
Serhiy Storchaka95949422013-08-27 19:40:23 +03001471/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001472 */
1473static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001474microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 int us;
1477 int s;
1478 int d;
1479 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 PyObject *tuple = NULL;
1482 PyObject *num = NULL;
1483 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 tuple = PyNumber_Divmod(pyus, us_per_second);
1486 if (tuple == NULL)
1487 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 num = PyTuple_GetItem(tuple, 1); /* us */
1490 if (num == NULL)
1491 goto Done;
1492 temp = PyLong_AsLong(num);
1493 num = NULL;
1494 if (temp == -1 && PyErr_Occurred())
1495 goto Done;
1496 assert(0 <= temp && temp < 1000000);
1497 us = (int)temp;
1498 if (us < 0) {
1499 /* The divisor was positive, so this must be an error. */
1500 assert(PyErr_Occurred());
1501 goto Done;
1502 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1505 if (num == NULL)
1506 goto Done;
1507 Py_INCREF(num);
1508 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 tuple = PyNumber_Divmod(num, seconds_per_day);
1511 if (tuple == NULL)
1512 goto Done;
1513 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 num = PyTuple_GetItem(tuple, 1); /* seconds */
1516 if (num == NULL)
1517 goto Done;
1518 temp = PyLong_AsLong(num);
1519 num = NULL;
1520 if (temp == -1 && PyErr_Occurred())
1521 goto Done;
1522 assert(0 <= temp && temp < 24*3600);
1523 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 if (s < 0) {
1526 /* The divisor was positive, so this must be an error. */
1527 assert(PyErr_Occurred());
1528 goto Done;
1529 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1532 if (num == NULL)
1533 goto Done;
1534 Py_INCREF(num);
1535 temp = PyLong_AsLong(num);
1536 if (temp == -1 && PyErr_Occurred())
1537 goto Done;
1538 d = (int)temp;
1539 if ((long)d != temp) {
1540 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1541 "large to fit in a C int");
1542 goto Done;
1543 }
1544 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001545
1546Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 Py_XDECREF(tuple);
1548 Py_XDECREF(num);
1549 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001550}
1551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552#define microseconds_to_delta(pymicros) \
1553 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001554
Tim Peters2a799bf2002-12-16 20:18:38 +00001555static PyObject *
1556multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 PyObject *pyus_in;
1559 PyObject *pyus_out;
1560 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 pyus_in = delta_to_microseconds(delta);
1563 if (pyus_in == NULL)
1564 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1567 Py_DECREF(pyus_in);
1568 if (pyus_out == NULL)
1569 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 result = microseconds_to_delta(pyus_out);
1572 Py_DECREF(pyus_out);
1573 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001574}
1575
1576static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001577multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1578{
1579 PyObject *result = NULL;
1580 PyObject *pyus_in = NULL, *temp, *pyus_out;
1581 PyObject *ratio = NULL;
1582
1583 pyus_in = delta_to_microseconds(delta);
1584 if (pyus_in == NULL)
1585 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001586 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001587 if (ratio == NULL)
1588 goto error;
1589 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1590 Py_DECREF(pyus_in);
1591 pyus_in = NULL;
1592 if (temp == NULL)
1593 goto error;
1594 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1595 Py_DECREF(temp);
1596 if (pyus_out == NULL)
1597 goto error;
1598 result = microseconds_to_delta(pyus_out);
1599 Py_DECREF(pyus_out);
1600 error:
1601 Py_XDECREF(pyus_in);
1602 Py_XDECREF(ratio);
1603
1604 return result;
1605}
1606
1607static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001608divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 PyObject *pyus_in;
1611 PyObject *pyus_out;
1612 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 pyus_in = delta_to_microseconds(delta);
1615 if (pyus_in == NULL)
1616 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1619 Py_DECREF(pyus_in);
1620 if (pyus_out == NULL)
1621 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 result = microseconds_to_delta(pyus_out);
1624 Py_DECREF(pyus_out);
1625 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001626}
1627
1628static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001629divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 PyObject *pyus_left;
1632 PyObject *pyus_right;
1633 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 pyus_left = delta_to_microseconds(left);
1636 if (pyus_left == NULL)
1637 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 pyus_right = delta_to_microseconds(right);
1640 if (pyus_right == NULL) {
1641 Py_DECREF(pyus_left);
1642 return NULL;
1643 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1646 Py_DECREF(pyus_left);
1647 Py_DECREF(pyus_right);
1648 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001649}
1650
1651static PyObject *
1652truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 PyObject *pyus_left;
1655 PyObject *pyus_right;
1656 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 pyus_left = delta_to_microseconds(left);
1659 if (pyus_left == NULL)
1660 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 pyus_right = delta_to_microseconds(right);
1663 if (pyus_right == NULL) {
1664 Py_DECREF(pyus_left);
1665 return NULL;
1666 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1669 Py_DECREF(pyus_left);
1670 Py_DECREF(pyus_right);
1671 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001672}
1673
1674static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001675truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1676{
1677 PyObject *result = NULL;
1678 PyObject *pyus_in = NULL, *temp, *pyus_out;
1679 PyObject *ratio = NULL;
1680
1681 pyus_in = delta_to_microseconds(delta);
1682 if (pyus_in == NULL)
1683 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001684 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001685 if (ratio == NULL)
1686 goto error;
1687 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1688 Py_DECREF(pyus_in);
1689 pyus_in = NULL;
1690 if (temp == NULL)
1691 goto error;
1692 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1693 Py_DECREF(temp);
1694 if (pyus_out == NULL)
1695 goto error;
1696 result = microseconds_to_delta(pyus_out);
1697 Py_DECREF(pyus_out);
1698 error:
1699 Py_XDECREF(pyus_in);
1700 Py_XDECREF(ratio);
1701
1702 return result;
1703}
1704
1705static PyObject *
1706truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1707{
1708 PyObject *result;
1709 PyObject *pyus_in, *pyus_out;
1710 pyus_in = delta_to_microseconds(delta);
1711 if (pyus_in == NULL)
1712 return NULL;
1713 pyus_out = divide_nearest(pyus_in, i);
1714 Py_DECREF(pyus_in);
1715 if (pyus_out == NULL)
1716 return NULL;
1717 result = microseconds_to_delta(pyus_out);
1718 Py_DECREF(pyus_out);
1719
1720 return result;
1721}
1722
1723static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001724delta_add(PyObject *left, PyObject *right)
1725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1729 /* delta + delta */
1730 /* The C-level additions can't overflow because of the
1731 * invariant bounds.
1732 */
1733 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1734 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1735 int microseconds = GET_TD_MICROSECONDS(left) +
1736 GET_TD_MICROSECONDS(right);
1737 result = new_delta(days, seconds, microseconds, 1);
1738 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 if (result == Py_NotImplemented)
1741 Py_INCREF(result);
1742 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001743}
1744
1745static PyObject *
1746delta_negative(PyDateTime_Delta *self)
1747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 return new_delta(-GET_TD_DAYS(self),
1749 -GET_TD_SECONDS(self),
1750 -GET_TD_MICROSECONDS(self),
1751 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001752}
1753
1754static PyObject *
1755delta_positive(PyDateTime_Delta *self)
1756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 /* Could optimize this (by returning self) if this isn't a
1758 * subclass -- but who uses unary + ? Approximately nobody.
1759 */
1760 return new_delta(GET_TD_DAYS(self),
1761 GET_TD_SECONDS(self),
1762 GET_TD_MICROSECONDS(self),
1763 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001764}
1765
1766static PyObject *
1767delta_abs(PyDateTime_Delta *self)
1768{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 assert(GET_TD_MICROSECONDS(self) >= 0);
1772 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 if (GET_TD_DAYS(self) < 0)
1775 result = delta_negative(self);
1776 else
1777 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001780}
1781
1782static PyObject *
1783delta_subtract(PyObject *left, PyObject *right)
1784{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1788 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001789 /* The C-level additions can't overflow because of the
1790 * invariant bounds.
1791 */
1792 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1793 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1794 int microseconds = GET_TD_MICROSECONDS(left) -
1795 GET_TD_MICROSECONDS(right);
1796 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 if (result == Py_NotImplemented)
1800 Py_INCREF(result);
1801 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001802}
1803
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001804static int
1805delta_cmp(PyObject *self, PyObject *other)
1806{
1807 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1808 if (diff == 0) {
1809 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1810 if (diff == 0)
1811 diff = GET_TD_MICROSECONDS(self) -
1812 GET_TD_MICROSECONDS(other);
1813 }
1814 return diff;
1815}
1816
Tim Peters2a799bf2002-12-16 20:18:38 +00001817static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001818delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001821 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 return diff_to_bool(diff, op);
1823 }
1824 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001825 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001827}
1828
1829static PyObject *delta_getstate(PyDateTime_Delta *self);
1830
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001831static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001832delta_hash(PyDateTime_Delta *self)
1833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 if (self->hashcode == -1) {
1835 PyObject *temp = delta_getstate(self);
1836 if (temp != NULL) {
1837 self->hashcode = PyObject_Hash(temp);
1838 Py_DECREF(temp);
1839 }
1840 }
1841 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001842}
1843
1844static PyObject *
1845delta_multiply(PyObject *left, PyObject *right)
1846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 if (PyDelta_Check(left)) {
1850 /* delta * ??? */
1851 if (PyLong_Check(right))
1852 result = multiply_int_timedelta(right,
1853 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001854 else if (PyFloat_Check(right))
1855 result = multiply_float_timedelta(right,
1856 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001857 }
1858 else if (PyLong_Check(left))
1859 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001860 (PyDateTime_Delta *) right);
1861 else if (PyFloat_Check(left))
1862 result = multiply_float_timedelta(left,
1863 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 if (result == Py_NotImplemented)
1866 Py_INCREF(result);
1867 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001868}
1869
1870static PyObject *
1871delta_divide(PyObject *left, PyObject *right)
1872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 if (PyDelta_Check(left)) {
1876 /* delta * ??? */
1877 if (PyLong_Check(right))
1878 result = divide_timedelta_int(
1879 (PyDateTime_Delta *)left,
1880 right);
1881 else if (PyDelta_Check(right))
1882 result = divide_timedelta_timedelta(
1883 (PyDateTime_Delta *)left,
1884 (PyDateTime_Delta *)right);
1885 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 if (result == Py_NotImplemented)
1888 Py_INCREF(result);
1889 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001890}
1891
Mark Dickinson7c186e22010-04-20 22:32:49 +00001892static PyObject *
1893delta_truedivide(PyObject *left, PyObject *right)
1894{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 if (PyDelta_Check(left)) {
1898 if (PyDelta_Check(right))
1899 result = truedivide_timedelta_timedelta(
1900 (PyDateTime_Delta *)left,
1901 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001902 else if (PyFloat_Check(right))
1903 result = truedivide_timedelta_float(
1904 (PyDateTime_Delta *)left, right);
1905 else if (PyLong_Check(right))
1906 result = truedivide_timedelta_int(
1907 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 if (result == Py_NotImplemented)
1911 Py_INCREF(result);
1912 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001913}
1914
1915static PyObject *
1916delta_remainder(PyObject *left, PyObject *right)
1917{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 PyObject *pyus_left;
1919 PyObject *pyus_right;
1920 PyObject *pyus_remainder;
1921 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001922
Brian Curtindfc80e32011-08-10 20:28:54 -05001923 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1924 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1927 if (pyus_left == NULL)
1928 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1931 if (pyus_right == NULL) {
1932 Py_DECREF(pyus_left);
1933 return NULL;
1934 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1937 Py_DECREF(pyus_left);
1938 Py_DECREF(pyus_right);
1939 if (pyus_remainder == NULL)
1940 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 remainder = microseconds_to_delta(pyus_remainder);
1943 Py_DECREF(pyus_remainder);
1944 if (remainder == NULL)
1945 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001948}
1949
1950static PyObject *
1951delta_divmod(PyObject *left, PyObject *right)
1952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 PyObject *pyus_left;
1954 PyObject *pyus_right;
1955 PyObject *divmod;
1956 PyObject *delta;
1957 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001958
Brian Curtindfc80e32011-08-10 20:28:54 -05001959 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1960 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1963 if (pyus_left == NULL)
1964 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1967 if (pyus_right == NULL) {
1968 Py_DECREF(pyus_left);
1969 return NULL;
1970 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 divmod = PyNumber_Divmod(pyus_left, pyus_right);
1973 Py_DECREF(pyus_left);
1974 Py_DECREF(pyus_right);
1975 if (divmod == NULL)
1976 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 assert(PyTuple_Size(divmod) == 2);
1979 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
1980 if (delta == NULL) {
1981 Py_DECREF(divmod);
1982 return NULL;
1983 }
1984 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
1985 Py_DECREF(delta);
1986 Py_DECREF(divmod);
1987 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001988}
1989
Tim Peters2a799bf2002-12-16 20:18:38 +00001990/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1991 * timedelta constructor. sofar is the # of microseconds accounted for
1992 * so far, and there are factor microseconds per current unit, the number
1993 * of which is given by num. num * factor is added to sofar in a
1994 * numerically careful way, and that's the result. Any fractional
1995 * microseconds left over (this can happen if num is a float type) are
1996 * added into *leftover.
1997 * Note that there are many ways this can give an error (NULL) return.
1998 */
1999static PyObject *
2000accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2001 double *leftover)
2002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 PyObject *prod;
2004 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 if (PyLong_Check(num)) {
2009 prod = PyNumber_Multiply(num, factor);
2010 if (prod == NULL)
2011 return NULL;
2012 sum = PyNumber_Add(sofar, prod);
2013 Py_DECREF(prod);
2014 return sum;
2015 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 if (PyFloat_Check(num)) {
2018 double dnum;
2019 double fracpart;
2020 double intpart;
2021 PyObject *x;
2022 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 /* The Plan: decompose num into an integer part and a
2025 * fractional part, num = intpart + fracpart.
2026 * Then num * factor ==
2027 * intpart * factor + fracpart * factor
2028 * and the LHS can be computed exactly in long arithmetic.
2029 * The RHS is again broken into an int part and frac part.
2030 * and the frac part is added into *leftover.
2031 */
2032 dnum = PyFloat_AsDouble(num);
2033 if (dnum == -1.0 && PyErr_Occurred())
2034 return NULL;
2035 fracpart = modf(dnum, &intpart);
2036 x = PyLong_FromDouble(intpart);
2037 if (x == NULL)
2038 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 prod = PyNumber_Multiply(x, factor);
2041 Py_DECREF(x);
2042 if (prod == NULL)
2043 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 sum = PyNumber_Add(sofar, prod);
2046 Py_DECREF(prod);
2047 if (sum == NULL)
2048 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 if (fracpart == 0.0)
2051 return sum;
2052 /* So far we've lost no information. Dealing with the
2053 * fractional part requires float arithmetic, and may
2054 * lose a little info.
2055 */
2056 assert(PyLong_Check(factor));
2057 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 dnum *= fracpart;
2060 fracpart = modf(dnum, &intpart);
2061 x = PyLong_FromDouble(intpart);
2062 if (x == NULL) {
2063 Py_DECREF(sum);
2064 return NULL;
2065 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 y = PyNumber_Add(sum, x);
2068 Py_DECREF(sum);
2069 Py_DECREF(x);
2070 *leftover += fracpart;
2071 return y;
2072 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 PyErr_Format(PyExc_TypeError,
2075 "unsupported type for timedelta %s component: %s",
2076 tag, Py_TYPE(num)->tp_name);
2077 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002078}
2079
2080static PyObject *
2081delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 /* Argument objects. */
2086 PyObject *day = NULL;
2087 PyObject *second = NULL;
2088 PyObject *us = NULL;
2089 PyObject *ms = NULL;
2090 PyObject *minute = NULL;
2091 PyObject *hour = NULL;
2092 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 PyObject *x = NULL; /* running sum of microseconds */
2095 PyObject *y = NULL; /* temp sum of microseconds */
2096 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 static char *keywords[] = {
2099 "days", "seconds", "microseconds", "milliseconds",
2100 "minutes", "hours", "weeks", NULL
2101 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2104 keywords,
2105 &day, &second, &us,
2106 &ms, &minute, &hour, &week) == 0)
2107 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 x = PyLong_FromLong(0);
2110 if (x == NULL)
2111 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002112
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113#define CLEANUP \
2114 Py_DECREF(x); \
2115 x = y; \
2116 if (x == NULL) \
2117 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002120 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 CLEANUP;
2122 }
2123 if (ms) {
2124 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2125 CLEANUP;
2126 }
2127 if (second) {
2128 y = accum("seconds", x, second, us_per_second, &leftover_us);
2129 CLEANUP;
2130 }
2131 if (minute) {
2132 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2133 CLEANUP;
2134 }
2135 if (hour) {
2136 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2137 CLEANUP;
2138 }
2139 if (day) {
2140 y = accum("days", x, day, us_per_day, &leftover_us);
2141 CLEANUP;
2142 }
2143 if (week) {
2144 y = accum("weeks", x, week, us_per_week, &leftover_us);
2145 CLEANUP;
2146 }
2147 if (leftover_us) {
2148 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002149 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002150 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002151 PyObject *temp;
2152
Victor Stinner69cc4872015-09-08 23:58:54 +02002153 whole_us = round(leftover_us);
2154 if (fabs(whole_us - leftover_us) == 0.5) {
2155 /* We're exactly halfway between two integers. In order
2156 * to do round-half-to-even, we must determine whether x
2157 * is odd. Note that x is odd when it's last bit is 1. The
2158 * code below uses bitwise and operation to check the last
2159 * bit. */
2160 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2161 if (temp == NULL) {
2162 Py_DECREF(x);
2163 goto Done;
2164 }
2165 x_is_odd = PyObject_IsTrue(temp);
2166 Py_DECREF(temp);
2167 if (x_is_odd == -1) {
2168 Py_DECREF(x);
2169 goto Done;
2170 }
2171 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2172 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002173
Victor Stinner36a5a062013-08-28 01:53:39 +02002174 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 if (temp == NULL) {
2177 Py_DECREF(x);
2178 goto Done;
2179 }
2180 y = PyNumber_Add(x, temp);
2181 Py_DECREF(temp);
2182 CLEANUP;
2183 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 self = microseconds_to_delta_ex(x, type);
2186 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002187Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002189
2190#undef CLEANUP
2191}
2192
2193static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002194delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 return (GET_TD_DAYS(self) != 0
2197 || GET_TD_SECONDS(self) != 0
2198 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002199}
2200
2201static PyObject *
2202delta_repr(PyDateTime_Delta *self)
2203{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 if (GET_TD_MICROSECONDS(self) != 0)
2205 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2206 Py_TYPE(self)->tp_name,
2207 GET_TD_DAYS(self),
2208 GET_TD_SECONDS(self),
2209 GET_TD_MICROSECONDS(self));
2210 if (GET_TD_SECONDS(self) != 0)
2211 return PyUnicode_FromFormat("%s(%d, %d)",
2212 Py_TYPE(self)->tp_name,
2213 GET_TD_DAYS(self),
2214 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002216 return PyUnicode_FromFormat("%s(%d)",
2217 Py_TYPE(self)->tp_name,
2218 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002219}
2220
2221static PyObject *
2222delta_str(PyDateTime_Delta *self)
2223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 int us = GET_TD_MICROSECONDS(self);
2225 int seconds = GET_TD_SECONDS(self);
2226 int minutes = divmod(seconds, 60, &seconds);
2227 int hours = divmod(minutes, 60, &minutes);
2228 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002230 if (days) {
2231 if (us)
2232 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2233 days, (days == 1 || days == -1) ? "" : "s",
2234 hours, minutes, seconds, us);
2235 else
2236 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2237 days, (days == 1 || days == -1) ? "" : "s",
2238 hours, minutes, seconds);
2239 } else {
2240 if (us)
2241 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2242 hours, minutes, seconds, us);
2243 else
2244 return PyUnicode_FromFormat("%d:%02d:%02d",
2245 hours, minutes, seconds);
2246 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002247
Tim Peters2a799bf2002-12-16 20:18:38 +00002248}
2249
Tim Peters371935f2003-02-01 01:52:50 +00002250/* Pickle support, a simple use of __reduce__. */
2251
Tim Petersb57f8f02003-02-01 02:54:15 +00002252/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002253static PyObject *
2254delta_getstate(PyDateTime_Delta *self)
2255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 return Py_BuildValue("iii", GET_TD_DAYS(self),
2257 GET_TD_SECONDS(self),
2258 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002259}
2260
Tim Peters2a799bf2002-12-16 20:18:38 +00002261static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002262delta_total_seconds(PyObject *self)
2263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002264 PyObject *total_seconds;
2265 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2268 if (total_microseconds == NULL)
2269 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002270
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002271 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002275}
2276
2277static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002278delta_reduce(PyDateTime_Delta* self)
2279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002280 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002281}
2282
2283#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2284
2285static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 {"days", T_INT, OFFSET(days), READONLY,
2288 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 {"seconds", T_INT, OFFSET(seconds), READONLY,
2291 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2294 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2295 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002296};
2297
2298static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2300 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2303 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002306};
2307
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002308static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002309PyDoc_STR("Difference between two datetime values.");
2310
2311static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 delta_add, /* nb_add */
2313 delta_subtract, /* nb_subtract */
2314 delta_multiply, /* nb_multiply */
2315 delta_remainder, /* nb_remainder */
2316 delta_divmod, /* nb_divmod */
2317 0, /* nb_power */
2318 (unaryfunc)delta_negative, /* nb_negative */
2319 (unaryfunc)delta_positive, /* nb_positive */
2320 (unaryfunc)delta_abs, /* nb_absolute */
2321 (inquiry)delta_bool, /* nb_bool */
2322 0, /*nb_invert*/
2323 0, /*nb_lshift*/
2324 0, /*nb_rshift*/
2325 0, /*nb_and*/
2326 0, /*nb_xor*/
2327 0, /*nb_or*/
2328 0, /*nb_int*/
2329 0, /*nb_reserved*/
2330 0, /*nb_float*/
2331 0, /*nb_inplace_add*/
2332 0, /*nb_inplace_subtract*/
2333 0, /*nb_inplace_multiply*/
2334 0, /*nb_inplace_remainder*/
2335 0, /*nb_inplace_power*/
2336 0, /*nb_inplace_lshift*/
2337 0, /*nb_inplace_rshift*/
2338 0, /*nb_inplace_and*/
2339 0, /*nb_inplace_xor*/
2340 0, /*nb_inplace_or*/
2341 delta_divide, /* nb_floor_divide */
2342 delta_truedivide, /* nb_true_divide */
2343 0, /* nb_inplace_floor_divide */
2344 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002345};
2346
2347static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 PyVarObject_HEAD_INIT(NULL, 0)
2349 "datetime.timedelta", /* tp_name */
2350 sizeof(PyDateTime_Delta), /* tp_basicsize */
2351 0, /* tp_itemsize */
2352 0, /* tp_dealloc */
2353 0, /* tp_print */
2354 0, /* tp_getattr */
2355 0, /* tp_setattr */
2356 0, /* tp_reserved */
2357 (reprfunc)delta_repr, /* tp_repr */
2358 &delta_as_number, /* tp_as_number */
2359 0, /* tp_as_sequence */
2360 0, /* tp_as_mapping */
2361 (hashfunc)delta_hash, /* tp_hash */
2362 0, /* tp_call */
2363 (reprfunc)delta_str, /* tp_str */
2364 PyObject_GenericGetAttr, /* tp_getattro */
2365 0, /* tp_setattro */
2366 0, /* tp_as_buffer */
2367 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2368 delta_doc, /* tp_doc */
2369 0, /* tp_traverse */
2370 0, /* tp_clear */
2371 delta_richcompare, /* tp_richcompare */
2372 0, /* tp_weaklistoffset */
2373 0, /* tp_iter */
2374 0, /* tp_iternext */
2375 delta_methods, /* tp_methods */
2376 delta_members, /* tp_members */
2377 0, /* tp_getset */
2378 0, /* tp_base */
2379 0, /* tp_dict */
2380 0, /* tp_descr_get */
2381 0, /* tp_descr_set */
2382 0, /* tp_dictoffset */
2383 0, /* tp_init */
2384 0, /* tp_alloc */
2385 delta_new, /* tp_new */
2386 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002387};
2388
2389/*
2390 * PyDateTime_Date implementation.
2391 */
2392
2393/* Accessor properties. */
2394
2395static PyObject *
2396date_year(PyDateTime_Date *self, void *unused)
2397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002399}
2400
2401static PyObject *
2402date_month(PyDateTime_Date *self, void *unused)
2403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002405}
2406
2407static PyObject *
2408date_day(PyDateTime_Date *self, void *unused)
2409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002411}
2412
2413static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 {"year", (getter)date_year},
2415 {"month", (getter)date_month},
2416 {"day", (getter)date_day},
2417 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002418};
2419
2420/* Constructors. */
2421
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002422static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002423
Tim Peters2a799bf2002-12-16 20:18:38 +00002424static PyObject *
2425date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 PyObject *self = NULL;
2428 PyObject *state;
2429 int year;
2430 int month;
2431 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 /* Check for invocation from pickle with __getstate__ state */
2434 if (PyTuple_GET_SIZE(args) == 1 &&
2435 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2436 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2437 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2438 {
2439 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002441 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2442 if (me != NULL) {
2443 char *pdata = PyBytes_AS_STRING(state);
2444 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2445 me->hashcode = -1;
2446 }
2447 return (PyObject *)me;
2448 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2451 &year, &month, &day)) {
2452 if (check_date_args(year, month, day) < 0)
2453 return NULL;
2454 self = new_date_ex(year, month, day, type);
2455 }
2456 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002457}
2458
2459/* Return new date from localtime(t). */
2460static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002461date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 struct tm *tm;
2464 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002465
Victor Stinnere4a994d2015-03-30 01:10:14 +02002466 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 tm = localtime(&t);
Victor Stinner21f58932012-03-14 00:15:40 +01002470 if (tm == NULL) {
2471 /* unconvertible time */
2472#ifdef EINVAL
2473 if (errno == 0)
2474 errno = EINVAL;
2475#endif
2476 PyErr_SetFromErrno(PyExc_OSError);
2477 return NULL;
2478 }
2479
2480 return PyObject_CallFunction(cls, "iii",
2481 tm->tm_year + 1900,
2482 tm->tm_mon + 1,
2483 tm->tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002484}
2485
2486/* Return new date from current time.
2487 * We say this is equivalent to fromtimestamp(time.time()), and the
2488 * only way to be sure of that is to *call* time.time(). That's not
2489 * generally the same as calling C's time.
2490 */
2491static PyObject *
2492date_today(PyObject *cls, PyObject *dummy)
2493{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002494 PyObject *time;
2495 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002496 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 time = time_time();
2499 if (time == NULL)
2500 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 /* Note well: today() is a class method, so this may not call
2503 * date.fromtimestamp. For example, it may call
2504 * datetime.fromtimestamp. That's why we need all the accuracy
2505 * time.time() delivers; if someone were gonzo about optimization,
2506 * date.today() could get away with plain C time().
2507 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002508 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 Py_DECREF(time);
2510 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002511}
2512
2513/* Return new date from given timestamp (Python timestamp -- a double). */
2514static PyObject *
2515date_fromtimestamp(PyObject *cls, PyObject *args)
2516{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002517 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002518 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002519
Victor Stinner5d272cc2012-03-13 13:35:55 +01002520 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2521 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002523}
2524
2525/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2526 * the ordinal is out of range.
2527 */
2528static PyObject *
2529date_fromordinal(PyObject *cls, PyObject *args)
2530{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002531 PyObject *result = NULL;
2532 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002534 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2535 int year;
2536 int month;
2537 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002539 if (ordinal < 1)
2540 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2541 ">= 1");
2542 else {
2543 ord_to_ymd(ordinal, &year, &month, &day);
2544 result = PyObject_CallFunction(cls, "iii",
2545 year, month, day);
2546 }
2547 }
2548 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002549}
2550
2551/*
2552 * Date arithmetic.
2553 */
2554
2555/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2556 * instead.
2557 */
2558static PyObject *
2559add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2560{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 PyObject *result = NULL;
2562 int year = GET_YEAR(date);
2563 int month = GET_MONTH(date);
2564 int deltadays = GET_TD_DAYS(delta);
2565 /* C-level overflow is impossible because |deltadays| < 1e9. */
2566 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002568 if (normalize_date(&year, &month, &day) >= 0)
2569 result = new_date(year, month, day);
2570 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002571}
2572
2573static PyObject *
2574date_add(PyObject *left, PyObject *right)
2575{
Brian Curtindfc80e32011-08-10 20:28:54 -05002576 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2577 Py_RETURN_NOTIMPLEMENTED;
2578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002579 if (PyDate_Check(left)) {
2580 /* date + ??? */
2581 if (PyDelta_Check(right))
2582 /* date + delta */
2583 return add_date_timedelta((PyDateTime_Date *) left,
2584 (PyDateTime_Delta *) right,
2585 0);
2586 }
2587 else {
2588 /* ??? + date
2589 * 'right' must be one of us, or we wouldn't have been called
2590 */
2591 if (PyDelta_Check(left))
2592 /* delta + date */
2593 return add_date_timedelta((PyDateTime_Date *) right,
2594 (PyDateTime_Delta *) left,
2595 0);
2596 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002597 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002598}
2599
2600static PyObject *
2601date_subtract(PyObject *left, PyObject *right)
2602{
Brian Curtindfc80e32011-08-10 20:28:54 -05002603 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2604 Py_RETURN_NOTIMPLEMENTED;
2605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002606 if (PyDate_Check(left)) {
2607 if (PyDate_Check(right)) {
2608 /* date - date */
2609 int left_ord = ymd_to_ord(GET_YEAR(left),
2610 GET_MONTH(left),
2611 GET_DAY(left));
2612 int right_ord = ymd_to_ord(GET_YEAR(right),
2613 GET_MONTH(right),
2614 GET_DAY(right));
2615 return new_delta(left_ord - right_ord, 0, 0, 0);
2616 }
2617 if (PyDelta_Check(right)) {
2618 /* date - delta */
2619 return add_date_timedelta((PyDateTime_Date *) left,
2620 (PyDateTime_Delta *) right,
2621 1);
2622 }
2623 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002624 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002625}
2626
2627
2628/* Various ways to turn a date into a string. */
2629
2630static PyObject *
2631date_repr(PyDateTime_Date *self)
2632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002633 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2634 Py_TYPE(self)->tp_name,
2635 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002636}
2637
2638static PyObject *
2639date_isoformat(PyDateTime_Date *self)
2640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002641 return PyUnicode_FromFormat("%04d-%02d-%02d",
2642 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002643}
2644
Tim Peterse2df5ff2003-05-02 18:39:55 +00002645/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002646static PyObject *
2647date_str(PyDateTime_Date *self)
2648{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002649 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002650}
2651
2652
2653static PyObject *
2654date_ctime(PyDateTime_Date *self)
2655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002656 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002657}
2658
2659static PyObject *
2660date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 /* This method can be inherited, and needs to call the
2663 * timetuple() method appropriate to self's class.
2664 */
2665 PyObject *result;
2666 PyObject *tuple;
2667 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002668 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002669 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2672 &format))
2673 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002674
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002675 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002676 if (tuple == NULL)
2677 return NULL;
2678 result = wrap_strftime((PyObject *)self, format, tuple,
2679 (PyObject *)self);
2680 Py_DECREF(tuple);
2681 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002682}
2683
Eric Smith1ba31142007-09-11 18:06:02 +00002684static PyObject *
2685date_format(PyDateTime_Date *self, PyObject *args)
2686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002687 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002689 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2690 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002692 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002693 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002694 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002695
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002696 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002697}
2698
Tim Peters2a799bf2002-12-16 20:18:38 +00002699/* ISO methods. */
2700
2701static PyObject *
2702date_isoweekday(PyDateTime_Date *self)
2703{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002704 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002706 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002707}
2708
2709static PyObject *
2710date_isocalendar(PyDateTime_Date *self)
2711{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002712 int year = GET_YEAR(self);
2713 int week1_monday = iso_week1_monday(year);
2714 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2715 int week;
2716 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 week = divmod(today - week1_monday, 7, &day);
2719 if (week < 0) {
2720 --year;
2721 week1_monday = iso_week1_monday(year);
2722 week = divmod(today - week1_monday, 7, &day);
2723 }
2724 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2725 ++year;
2726 week = 0;
2727 }
2728 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002729}
2730
2731/* Miscellaneous methods. */
2732
Tim Peters2a799bf2002-12-16 20:18:38 +00002733static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002734date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002736 if (PyDate_Check(other)) {
2737 int diff = memcmp(((PyDateTime_Date *)self)->data,
2738 ((PyDateTime_Date *)other)->data,
2739 _PyDateTime_DATE_DATASIZE);
2740 return diff_to_bool(diff, op);
2741 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002742 else
2743 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002744}
2745
2746static PyObject *
2747date_timetuple(PyDateTime_Date *self)
2748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002749 return build_struct_time(GET_YEAR(self),
2750 GET_MONTH(self),
2751 GET_DAY(self),
2752 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002753}
2754
Tim Peters12bf3392002-12-24 05:41:27 +00002755static PyObject *
2756date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002758 PyObject *clone;
2759 PyObject *tuple;
2760 int year = GET_YEAR(self);
2761 int month = GET_MONTH(self);
2762 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002764 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2765 &year, &month, &day))
2766 return NULL;
2767 tuple = Py_BuildValue("iii", year, month, day);
2768 if (tuple == NULL)
2769 return NULL;
2770 clone = date_new(Py_TYPE(self), tuple, NULL);
2771 Py_DECREF(tuple);
2772 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002773}
2774
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002775static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002776generic_hash(unsigned char *data, int len)
2777{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002778 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002779}
2780
2781
2782static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002783
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002784static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002785date_hash(PyDateTime_Date *self)
2786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002787 if (self->hashcode == -1)
2788 self->hashcode = generic_hash(
2789 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002791 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002792}
2793
2794static PyObject *
2795date_toordinal(PyDateTime_Date *self)
2796{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002797 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2798 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002799}
2800
2801static PyObject *
2802date_weekday(PyDateTime_Date *self)
2803{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002804 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002806 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002807}
2808
Tim Peters371935f2003-02-01 01:52:50 +00002809/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002810
Tim Petersb57f8f02003-02-01 02:54:15 +00002811/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002812static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002813date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 PyObject* field;
2816 field = PyBytes_FromStringAndSize((char*)self->data,
2817 _PyDateTime_DATE_DATASIZE);
2818 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002819}
2820
2821static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002822date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002824 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002825}
2826
2827static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002829 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2832 METH_CLASS,
2833 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2834 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2837 METH_CLASS,
2838 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2839 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002841 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2842 PyDoc_STR("Current date or datetime: same as "
2843 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002847 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2848 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2851 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2854 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2857 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002859 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2860 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2861 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002863 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2864 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002866 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2867 PyDoc_STR("Return the day of the week represented by the date.\n"
2868 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002870 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2871 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2872 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002874 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2875 PyDoc_STR("Return the day of the week represented by the date.\n"
2876 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2879 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002881 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2882 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002885};
2886
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002887static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002888PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002889
2890static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002891 date_add, /* nb_add */
2892 date_subtract, /* nb_subtract */
2893 0, /* nb_multiply */
2894 0, /* nb_remainder */
2895 0, /* nb_divmod */
2896 0, /* nb_power */
2897 0, /* nb_negative */
2898 0, /* nb_positive */
2899 0, /* nb_absolute */
2900 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002901};
2902
2903static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002904 PyVarObject_HEAD_INIT(NULL, 0)
2905 "datetime.date", /* tp_name */
2906 sizeof(PyDateTime_Date), /* tp_basicsize */
2907 0, /* tp_itemsize */
2908 0, /* tp_dealloc */
2909 0, /* tp_print */
2910 0, /* tp_getattr */
2911 0, /* tp_setattr */
2912 0, /* tp_reserved */
2913 (reprfunc)date_repr, /* tp_repr */
2914 &date_as_number, /* tp_as_number */
2915 0, /* tp_as_sequence */
2916 0, /* tp_as_mapping */
2917 (hashfunc)date_hash, /* tp_hash */
2918 0, /* tp_call */
2919 (reprfunc)date_str, /* tp_str */
2920 PyObject_GenericGetAttr, /* tp_getattro */
2921 0, /* tp_setattro */
2922 0, /* tp_as_buffer */
2923 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2924 date_doc, /* tp_doc */
2925 0, /* tp_traverse */
2926 0, /* tp_clear */
2927 date_richcompare, /* tp_richcompare */
2928 0, /* tp_weaklistoffset */
2929 0, /* tp_iter */
2930 0, /* tp_iternext */
2931 date_methods, /* tp_methods */
2932 0, /* tp_members */
2933 date_getset, /* tp_getset */
2934 0, /* tp_base */
2935 0, /* tp_dict */
2936 0, /* tp_descr_get */
2937 0, /* tp_descr_set */
2938 0, /* tp_dictoffset */
2939 0, /* tp_init */
2940 0, /* tp_alloc */
2941 date_new, /* tp_new */
2942 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002943};
2944
2945/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002946 * PyDateTime_TZInfo implementation.
2947 */
2948
2949/* This is a pure abstract base class, so doesn't do anything beyond
2950 * raising NotImplemented exceptions. Real tzinfo classes need
2951 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002952 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002953 * be subclasses of this tzinfo class, which is easy and quick to check).
2954 *
2955 * Note: For reasons having to do with pickling of subclasses, we have
2956 * to allow tzinfo objects to be instantiated. This wasn't an issue
2957 * in the Python implementation (__init__() could raise NotImplementedError
2958 * there without ill effect), but doing so in the C implementation hit a
2959 * brick wall.
2960 */
2961
2962static PyObject *
2963tzinfo_nogo(const char* methodname)
2964{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002965 PyErr_Format(PyExc_NotImplementedError,
2966 "a tzinfo subclass must implement %s()",
2967 methodname);
2968 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002969}
2970
2971/* Methods. A subclass must implement these. */
2972
Tim Peters52dcce22003-01-23 16:36:11 +00002973static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002974tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002976 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002977}
2978
Tim Peters52dcce22003-01-23 16:36:11 +00002979static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002980tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002982 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002983}
2984
Tim Peters52dcce22003-01-23 16:36:11 +00002985static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002986tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2987{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002988 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002989}
2990
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002991
2992static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
2993 PyDateTime_Delta *delta,
2994 int factor);
2995static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
2996static PyObject *datetime_dst(PyObject *self, PyObject *);
2997
Tim Peters52dcce22003-01-23 16:36:11 +00002998static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00002999tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003000{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003001 PyObject *result = NULL;
3002 PyObject *off = NULL, *dst = NULL;
3003 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003004
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003005 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003006 PyErr_SetString(PyExc_TypeError,
3007 "fromutc: argument must be a datetime");
3008 return NULL;
3009 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003010 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003011 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3012 "is not self");
3013 return NULL;
3014 }
Tim Peters52dcce22003-01-23 16:36:11 +00003015
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003016 off = datetime_utcoffset(dt, NULL);
3017 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003018 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003019 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003020 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3021 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003022 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003023 }
Tim Peters52dcce22003-01-23 16:36:11 +00003024
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003025 dst = datetime_dst(dt, NULL);
3026 if (dst == NULL)
3027 goto Fail;
3028 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003029 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3030 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003031 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003032 }
Tim Peters52dcce22003-01-23 16:36:11 +00003033
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003034 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3035 if (delta == NULL)
3036 goto Fail;
3037 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003039 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003040
3041 Py_DECREF(dst);
3042 dst = call_dst(GET_DT_TZINFO(dt), result);
3043 if (dst == NULL)
3044 goto Fail;
3045 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003046 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003047 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003048 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
3049 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003050 if (result == NULL)
3051 goto Fail;
3052 }
3053 Py_DECREF(delta);
3054 Py_DECREF(dst);
3055 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003056 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003057
3058Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003059 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3060 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003063Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003064 Py_XDECREF(off);
3065 Py_XDECREF(dst);
3066 Py_XDECREF(delta);
3067 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003068 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003069}
3070
Tim Peters2a799bf2002-12-16 20:18:38 +00003071/*
3072 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003073 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003074 */
3075
Guido van Rossum177e41a2003-01-30 22:06:23 +00003076static PyObject *
3077tzinfo_reduce(PyObject *self)
3078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003079 PyObject *args, *state, *tmp;
3080 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003081 _Py_IDENTIFIER(__getinitargs__);
3082 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003084 tmp = PyTuple_New(0);
3085 if (tmp == NULL)
3086 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003087
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003088 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003089 if (getinitargs != NULL) {
3090 args = PyObject_CallObject(getinitargs, tmp);
3091 Py_DECREF(getinitargs);
3092 if (args == NULL) {
3093 Py_DECREF(tmp);
3094 return NULL;
3095 }
3096 }
3097 else {
3098 PyErr_Clear();
3099 args = tmp;
3100 Py_INCREF(args);
3101 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003102
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003103 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003104 if (getstate != NULL) {
3105 state = PyObject_CallObject(getstate, tmp);
3106 Py_DECREF(getstate);
3107 if (state == NULL) {
3108 Py_DECREF(args);
3109 Py_DECREF(tmp);
3110 return NULL;
3111 }
3112 }
3113 else {
3114 PyObject **dictptr;
3115 PyErr_Clear();
3116 state = Py_None;
3117 dictptr = _PyObject_GetDictPtr(self);
3118 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3119 state = *dictptr;
3120 Py_INCREF(state);
3121 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003123 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 if (state == Py_None) {
3126 Py_DECREF(state);
3127 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3128 }
3129 else
3130 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003131}
Tim Peters2a799bf2002-12-16 20:18:38 +00003132
3133static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003135 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3136 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003138 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003139 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3140 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003142 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3143 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003145 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003146 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003148 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3149 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003151 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003152};
3153
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003154static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003155PyDoc_STR("Abstract base class for time zone info objects.");
3156
Neal Norwitz227b5332006-03-22 09:28:35 +00003157static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003158 PyVarObject_HEAD_INIT(NULL, 0)
3159 "datetime.tzinfo", /* tp_name */
3160 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3161 0, /* tp_itemsize */
3162 0, /* tp_dealloc */
3163 0, /* tp_print */
3164 0, /* tp_getattr */
3165 0, /* tp_setattr */
3166 0, /* tp_reserved */
3167 0, /* tp_repr */
3168 0, /* tp_as_number */
3169 0, /* tp_as_sequence */
3170 0, /* tp_as_mapping */
3171 0, /* tp_hash */
3172 0, /* tp_call */
3173 0, /* tp_str */
3174 PyObject_GenericGetAttr, /* tp_getattro */
3175 0, /* tp_setattro */
3176 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003177 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003178 tzinfo_doc, /* tp_doc */
3179 0, /* tp_traverse */
3180 0, /* tp_clear */
3181 0, /* tp_richcompare */
3182 0, /* tp_weaklistoffset */
3183 0, /* tp_iter */
3184 0, /* tp_iternext */
3185 tzinfo_methods, /* tp_methods */
3186 0, /* tp_members */
3187 0, /* tp_getset */
3188 0, /* tp_base */
3189 0, /* tp_dict */
3190 0, /* tp_descr_get */
3191 0, /* tp_descr_set */
3192 0, /* tp_dictoffset */
3193 0, /* tp_init */
3194 0, /* tp_alloc */
3195 PyType_GenericNew, /* tp_new */
3196 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003197};
3198
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003199static char *timezone_kws[] = {"offset", "name", NULL};
3200
3201static PyObject *
3202timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3203{
3204 PyObject *offset;
3205 PyObject *name = NULL;
3206 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3207 &PyDateTime_DeltaType, &offset,
3208 &PyUnicode_Type, &name))
3209 return new_timezone(offset, name);
3210
3211 return NULL;
3212}
3213
3214static void
3215timezone_dealloc(PyDateTime_TimeZone *self)
3216{
3217 Py_CLEAR(self->offset);
3218 Py_CLEAR(self->name);
3219 Py_TYPE(self)->tp_free((PyObject *)self);
3220}
3221
3222static PyObject *
3223timezone_richcompare(PyDateTime_TimeZone *self,
3224 PyDateTime_TimeZone *other, int op)
3225{
Brian Curtindfc80e32011-08-10 20:28:54 -05003226 if (op != Py_EQ && op != Py_NE)
3227 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003228 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003229 if (op == Py_EQ)
3230 Py_RETURN_FALSE;
3231 else
3232 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003233 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003234 return delta_richcompare(self->offset, other->offset, op);
3235}
3236
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003237static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003238timezone_hash(PyDateTime_TimeZone *self)
3239{
3240 return delta_hash((PyDateTime_Delta *)self->offset);
3241}
3242
3243/* Check argument type passed to tzname, utcoffset, or dst methods.
3244 Returns 0 for good argument. Returns -1 and sets exception info
3245 otherwise.
3246 */
3247static int
3248_timezone_check_argument(PyObject *dt, const char *meth)
3249{
3250 if (dt == Py_None || PyDateTime_Check(dt))
3251 return 0;
3252 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3253 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3254 return -1;
3255}
3256
3257static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003258timezone_repr(PyDateTime_TimeZone *self)
3259{
3260 /* Note that although timezone is not subclassable, it is convenient
3261 to use Py_TYPE(self)->tp_name here. */
3262 const char *type_name = Py_TYPE(self)->tp_name;
3263
3264 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3265 return PyUnicode_FromFormat("%s.utc", type_name);
3266
3267 if (self->name == NULL)
3268 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3269
3270 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3271 self->name);
3272}
3273
3274
3275static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003276timezone_str(PyDateTime_TimeZone *self)
3277{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003278 int hours, minutes, seconds;
3279 PyObject *offset;
3280 char sign;
3281
3282 if (self->name != NULL) {
3283 Py_INCREF(self->name);
3284 return self->name;
3285 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003286 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003287 (GET_TD_DAYS(self->offset) == 0 &&
3288 GET_TD_SECONDS(self->offset) == 0 &&
3289 GET_TD_MICROSECONDS(self->offset) == 0))
3290 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003291 /* Offset is normalized, so it is negative if days < 0 */
3292 if (GET_TD_DAYS(self->offset) < 0) {
3293 sign = '-';
3294 offset = delta_negative((PyDateTime_Delta *)self->offset);
3295 if (offset == NULL)
3296 return NULL;
3297 }
3298 else {
3299 sign = '+';
3300 offset = self->offset;
3301 Py_INCREF(offset);
3302 }
3303 /* Offset is not negative here. */
3304 seconds = GET_TD_SECONDS(offset);
3305 Py_DECREF(offset);
3306 minutes = divmod(seconds, 60, &seconds);
3307 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003308 /* XXX ignore sub-minute data, curently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003309 assert(seconds == 0);
3310 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003311}
3312
3313static PyObject *
3314timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3315{
3316 if (_timezone_check_argument(dt, "tzname") == -1)
3317 return NULL;
3318
3319 return timezone_str(self);
3320}
3321
3322static PyObject *
3323timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3324{
3325 if (_timezone_check_argument(dt, "utcoffset") == -1)
3326 return NULL;
3327
3328 Py_INCREF(self->offset);
3329 return self->offset;
3330}
3331
3332static PyObject *
3333timezone_dst(PyObject *self, PyObject *dt)
3334{
3335 if (_timezone_check_argument(dt, "dst") == -1)
3336 return NULL;
3337
3338 Py_RETURN_NONE;
3339}
3340
3341static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003342timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3343{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003344 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003345 PyErr_SetString(PyExc_TypeError,
3346 "fromutc: argument must be a datetime");
3347 return NULL;
3348 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003349 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003350 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3351 "is not self");
3352 return NULL;
3353 }
3354
3355 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3356}
3357
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003358static PyObject *
3359timezone_getinitargs(PyDateTime_TimeZone *self)
3360{
3361 if (self->name == NULL)
3362 return Py_BuildValue("(O)", self->offset);
3363 return Py_BuildValue("(OO)", self->offset, self->name);
3364}
3365
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003366static PyMethodDef timezone_methods[] = {
3367 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3368 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003369 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003370
3371 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003372 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003373
3374 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003375 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003376
3377 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3378 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3379
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003380 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3381 PyDoc_STR("pickle support")},
3382
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003383 {NULL, NULL}
3384};
3385
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003386static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003387PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3388
3389static PyTypeObject PyDateTime_TimeZoneType = {
3390 PyVarObject_HEAD_INIT(NULL, 0)
3391 "datetime.timezone", /* tp_name */
3392 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3393 0, /* tp_itemsize */
3394 (destructor)timezone_dealloc, /* tp_dealloc */
3395 0, /* tp_print */
3396 0, /* tp_getattr */
3397 0, /* tp_setattr */
3398 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003399 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003400 0, /* tp_as_number */
3401 0, /* tp_as_sequence */
3402 0, /* tp_as_mapping */
3403 (hashfunc)timezone_hash, /* tp_hash */
3404 0, /* tp_call */
3405 (reprfunc)timezone_str, /* tp_str */
3406 0, /* tp_getattro */
3407 0, /* tp_setattro */
3408 0, /* tp_as_buffer */
3409 Py_TPFLAGS_DEFAULT, /* tp_flags */
3410 timezone_doc, /* tp_doc */
3411 0, /* tp_traverse */
3412 0, /* tp_clear */
3413 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3414 0, /* tp_weaklistoffset */
3415 0, /* tp_iter */
3416 0, /* tp_iternext */
3417 timezone_methods, /* tp_methods */
3418 0, /* tp_members */
3419 0, /* tp_getset */
3420 &PyDateTime_TZInfoType, /* tp_base */
3421 0, /* tp_dict */
3422 0, /* tp_descr_get */
3423 0, /* tp_descr_set */
3424 0, /* tp_dictoffset */
3425 0, /* tp_init */
3426 0, /* tp_alloc */
3427 timezone_new, /* tp_new */
3428};
3429
Tim Peters2a799bf2002-12-16 20:18:38 +00003430/*
Tim Peters37f39822003-01-10 03:49:02 +00003431 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003432 */
3433
Tim Peters37f39822003-01-10 03:49:02 +00003434/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003435 */
3436
3437static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003438time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003440 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003441}
3442
Tim Peters37f39822003-01-10 03:49:02 +00003443static PyObject *
3444time_minute(PyDateTime_Time *self, void *unused)
3445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003446 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003447}
3448
3449/* The name time_second conflicted with some platform header file. */
3450static PyObject *
3451py_time_second(PyDateTime_Time *self, void *unused)
3452{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003453 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003454}
3455
3456static PyObject *
3457time_microsecond(PyDateTime_Time *self, void *unused)
3458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003459 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003460}
3461
3462static PyObject *
3463time_tzinfo(PyDateTime_Time *self, void *unused)
3464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003465 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3466 Py_INCREF(result);
3467 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003468}
3469
3470static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003471 {"hour", (getter)time_hour},
3472 {"minute", (getter)time_minute},
3473 {"second", (getter)py_time_second},
3474 {"microsecond", (getter)time_microsecond},
3475 {"tzinfo", (getter)time_tzinfo},
3476 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003477};
3478
3479/*
3480 * Constructors.
3481 */
3482
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003483static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003484 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003485
Tim Peters2a799bf2002-12-16 20:18:38 +00003486static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003487time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 PyObject *self = NULL;
3490 PyObject *state;
3491 int hour = 0;
3492 int minute = 0;
3493 int second = 0;
3494 int usecond = 0;
3495 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003497 /* Check for invocation from pickle with __getstate__ state */
3498 if (PyTuple_GET_SIZE(args) >= 1 &&
3499 PyTuple_GET_SIZE(args) <= 2 &&
3500 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3501 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3502 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3503 {
3504 PyDateTime_Time *me;
3505 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003507 if (PyTuple_GET_SIZE(args) == 2) {
3508 tzinfo = PyTuple_GET_ITEM(args, 1);
3509 if (check_tzinfo_subclass(tzinfo) < 0) {
3510 PyErr_SetString(PyExc_TypeError, "bad "
3511 "tzinfo state arg");
3512 return NULL;
3513 }
3514 }
3515 aware = (char)(tzinfo != Py_None);
3516 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3517 if (me != NULL) {
3518 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003520 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3521 me->hashcode = -1;
3522 me->hastzinfo = aware;
3523 if (aware) {
3524 Py_INCREF(tzinfo);
3525 me->tzinfo = tzinfo;
3526 }
3527 }
3528 return (PyObject *)me;
3529 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003531 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3532 &hour, &minute, &second, &usecond,
3533 &tzinfo)) {
3534 if (check_time_args(hour, minute, second, usecond) < 0)
3535 return NULL;
3536 if (check_tzinfo_subclass(tzinfo) < 0)
3537 return NULL;
3538 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3539 type);
3540 }
3541 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003542}
3543
3544/*
3545 * Destructor.
3546 */
3547
3548static void
Tim Peters37f39822003-01-10 03:49:02 +00003549time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003550{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003551 if (HASTZINFO(self)) {
3552 Py_XDECREF(self->tzinfo);
3553 }
3554 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003555}
3556
3557/*
Tim Peters855fe882002-12-22 03:43:39 +00003558 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003559 */
3560
Tim Peters2a799bf2002-12-16 20:18:38 +00003561/* These are all METH_NOARGS, so don't need to check the arglist. */
3562static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003563time_utcoffset(PyObject *self, PyObject *unused) {
3564 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003565}
3566
3567static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003568time_dst(PyObject *self, PyObject *unused) {
3569 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003570}
3571
3572static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003573time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003574 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003575}
3576
3577/*
Tim Peters37f39822003-01-10 03:49:02 +00003578 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003579 */
3580
3581static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003582time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003583{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003584 const char *type_name = Py_TYPE(self)->tp_name;
3585 int h = TIME_GET_HOUR(self);
3586 int m = TIME_GET_MINUTE(self);
3587 int s = TIME_GET_SECOND(self);
3588 int us = TIME_GET_MICROSECOND(self);
3589 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003591 if (us)
3592 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3593 type_name, h, m, s, us);
3594 else if (s)
3595 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3596 type_name, h, m, s);
3597 else
3598 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3599 if (result != NULL && HASTZINFO(self))
3600 result = append_keyword_tzinfo(result, self->tzinfo);
3601 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003602}
3603
Tim Peters37f39822003-01-10 03:49:02 +00003604static PyObject *
3605time_str(PyDateTime_Time *self)
3606{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003607 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003608}
Tim Peters2a799bf2002-12-16 20:18:38 +00003609
3610static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003611time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003613 char buf[100];
3614 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003615 int us = TIME_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003617 if (us)
3618 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3619 TIME_GET_HOUR(self),
3620 TIME_GET_MINUTE(self),
3621 TIME_GET_SECOND(self),
3622 us);
3623 else
3624 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3625 TIME_GET_HOUR(self),
3626 TIME_GET_MINUTE(self),
3627 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003628
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003629 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003630 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003632 /* We need to append the UTC offset. */
3633 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3634 Py_None) < 0) {
3635 Py_DECREF(result);
3636 return NULL;
3637 }
3638 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3639 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003640}
3641
Tim Peters37f39822003-01-10 03:49:02 +00003642static PyObject *
3643time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003645 PyObject *result;
3646 PyObject *tuple;
3647 PyObject *format;
3648 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003650 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3651 &format))
3652 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003654 /* Python's strftime does insane things with the year part of the
3655 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003656 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003657 */
3658 tuple = Py_BuildValue("iiiiiiiii",
3659 1900, 1, 1, /* year, month, day */
3660 TIME_GET_HOUR(self),
3661 TIME_GET_MINUTE(self),
3662 TIME_GET_SECOND(self),
3663 0, 1, -1); /* weekday, daynum, dst */
3664 if (tuple == NULL)
3665 return NULL;
3666 assert(PyTuple_Size(tuple) == 9);
3667 result = wrap_strftime((PyObject *)self, format, tuple,
3668 Py_None);
3669 Py_DECREF(tuple);
3670 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003671}
Tim Peters2a799bf2002-12-16 20:18:38 +00003672
3673/*
3674 * Miscellaneous methods.
3675 */
3676
Tim Peters37f39822003-01-10 03:49:02 +00003677static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003678time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003679{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003680 PyObject *result = NULL;
3681 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003682 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003683
Brian Curtindfc80e32011-08-10 20:28:54 -05003684 if (! PyTime_Check(other))
3685 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003686
3687 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003688 diff = memcmp(((PyDateTime_Time *)self)->data,
3689 ((PyDateTime_Time *)other)->data,
3690 _PyDateTime_TIME_DATASIZE);
3691 return diff_to_bool(diff, op);
3692 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003693 offset1 = time_utcoffset(self, NULL);
3694 if (offset1 == NULL)
3695 return NULL;
3696 offset2 = time_utcoffset(other, NULL);
3697 if (offset2 == NULL)
3698 goto done;
3699 /* If they're both naive, or both aware and have the same offsets,
3700 * we get off cheap. Note that if they're both naive, offset1 ==
3701 * offset2 == Py_None at this point.
3702 */
3703 if ((offset1 == offset2) ||
3704 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3705 delta_cmp(offset1, offset2) == 0)) {
3706 diff = memcmp(((PyDateTime_Time *)self)->data,
3707 ((PyDateTime_Time *)other)->data,
3708 _PyDateTime_TIME_DATASIZE);
3709 result = diff_to_bool(diff, op);
3710 }
3711 /* The hard case: both aware with different UTC offsets */
3712 else if (offset1 != Py_None && offset2 != Py_None) {
3713 int offsecs1, offsecs2;
3714 assert(offset1 != offset2); /* else last "if" handled it */
3715 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3716 TIME_GET_MINUTE(self) * 60 +
3717 TIME_GET_SECOND(self) -
3718 GET_TD_DAYS(offset1) * 86400 -
3719 GET_TD_SECONDS(offset1);
3720 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3721 TIME_GET_MINUTE(other) * 60 +
3722 TIME_GET_SECOND(other) -
3723 GET_TD_DAYS(offset2) * 86400 -
3724 GET_TD_SECONDS(offset2);
3725 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003726 if (diff == 0)
3727 diff = TIME_GET_MICROSECOND(self) -
3728 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003729 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003730 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003731 else if (op == Py_EQ) {
3732 result = Py_False;
3733 Py_INCREF(result);
3734 }
3735 else if (op == Py_NE) {
3736 result = Py_True;
3737 Py_INCREF(result);
3738 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003739 else {
3740 PyErr_SetString(PyExc_TypeError,
3741 "can't compare offset-naive and "
3742 "offset-aware times");
3743 }
3744 done:
3745 Py_DECREF(offset1);
3746 Py_XDECREF(offset2);
3747 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003748}
3749
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003750static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003751time_hash(PyDateTime_Time *self)
3752{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003753 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003754 PyObject *offset;
Tim Peters37f39822003-01-10 03:49:02 +00003755
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003756 offset = time_utcoffset((PyObject *)self, NULL);
3757
3758 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003759 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003761 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003762 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003763 self->hashcode = generic_hash(
3764 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003765 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003766 PyObject *temp1, *temp2;
3767 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003768 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003769 seconds = TIME_GET_HOUR(self) * 3600 +
3770 TIME_GET_MINUTE(self) * 60 +
3771 TIME_GET_SECOND(self);
3772 microseconds = TIME_GET_MICROSECOND(self);
3773 temp1 = new_delta(0, seconds, microseconds, 1);
3774 if (temp1 == NULL) {
3775 Py_DECREF(offset);
3776 return -1;
3777 }
3778 temp2 = delta_subtract(temp1, offset);
3779 Py_DECREF(temp1);
3780 if (temp2 == NULL) {
3781 Py_DECREF(offset);
3782 return -1;
3783 }
3784 self->hashcode = PyObject_Hash(temp2);
3785 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003786 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003787 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003788 }
3789 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003790}
Tim Peters2a799bf2002-12-16 20:18:38 +00003791
Tim Peters12bf3392002-12-24 05:41:27 +00003792static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003793time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003794{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003795 PyObject *clone;
3796 PyObject *tuple;
3797 int hh = TIME_GET_HOUR(self);
3798 int mm = TIME_GET_MINUTE(self);
3799 int ss = TIME_GET_SECOND(self);
3800 int us = TIME_GET_MICROSECOND(self);
3801 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003803 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3804 time_kws,
3805 &hh, &mm, &ss, &us, &tzinfo))
3806 return NULL;
3807 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3808 if (tuple == NULL)
3809 return NULL;
3810 clone = time_new(Py_TYPE(self), tuple, NULL);
3811 Py_DECREF(tuple);
3812 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003813}
3814
Tim Peters371935f2003-02-01 01:52:50 +00003815/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003816
Tim Peters33e0f382003-01-10 02:05:14 +00003817/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003818 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3819 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003820 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003821 */
3822static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003823time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003825 PyObject *basestate;
3826 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003828 basestate = PyBytes_FromStringAndSize((char *)self->data,
3829 _PyDateTime_TIME_DATASIZE);
3830 if (basestate != NULL) {
3831 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3832 result = PyTuple_Pack(1, basestate);
3833 else
3834 result = PyTuple_Pack(2, basestate, self->tzinfo);
3835 Py_DECREF(basestate);
3836 }
3837 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003838}
3839
3840static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003841time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003842{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003843 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003844}
3845
Tim Peters37f39822003-01-10 03:49:02 +00003846static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003848 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3849 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3850 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003852 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3853 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003855 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3856 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3859 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003861 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3862 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003864 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3865 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003867 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3868 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003870 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3871 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003873 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003874};
3875
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003876static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003877PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3878\n\
3879All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03003880a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003881
Neal Norwitz227b5332006-03-22 09:28:35 +00003882static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 PyVarObject_HEAD_INIT(NULL, 0)
3884 "datetime.time", /* tp_name */
3885 sizeof(PyDateTime_Time), /* tp_basicsize */
3886 0, /* tp_itemsize */
3887 (destructor)time_dealloc, /* tp_dealloc */
3888 0, /* tp_print */
3889 0, /* tp_getattr */
3890 0, /* tp_setattr */
3891 0, /* tp_reserved */
3892 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05003893 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003894 0, /* tp_as_sequence */
3895 0, /* tp_as_mapping */
3896 (hashfunc)time_hash, /* tp_hash */
3897 0, /* tp_call */
3898 (reprfunc)time_str, /* tp_str */
3899 PyObject_GenericGetAttr, /* tp_getattro */
3900 0, /* tp_setattro */
3901 0, /* tp_as_buffer */
3902 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3903 time_doc, /* tp_doc */
3904 0, /* tp_traverse */
3905 0, /* tp_clear */
3906 time_richcompare, /* tp_richcompare */
3907 0, /* tp_weaklistoffset */
3908 0, /* tp_iter */
3909 0, /* tp_iternext */
3910 time_methods, /* tp_methods */
3911 0, /* tp_members */
3912 time_getset, /* tp_getset */
3913 0, /* tp_base */
3914 0, /* tp_dict */
3915 0, /* tp_descr_get */
3916 0, /* tp_descr_set */
3917 0, /* tp_dictoffset */
3918 0, /* tp_init */
3919 time_alloc, /* tp_alloc */
3920 time_new, /* tp_new */
3921 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003922};
3923
3924/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003925 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003926 */
3927
Tim Petersa9bc1682003-01-11 03:39:11 +00003928/* Accessor properties. Properties for day, month, and year are inherited
3929 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003930 */
3931
3932static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003933datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003935 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003936}
3937
Tim Petersa9bc1682003-01-11 03:39:11 +00003938static PyObject *
3939datetime_minute(PyDateTime_DateTime *self, void *unused)
3940{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003941 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003942}
3943
3944static PyObject *
3945datetime_second(PyDateTime_DateTime *self, void *unused)
3946{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003947 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003948}
3949
3950static PyObject *
3951datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3952{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003953 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003954}
3955
3956static PyObject *
3957datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003959 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3960 Py_INCREF(result);
3961 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003962}
3963
3964static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003965 {"hour", (getter)datetime_hour},
3966 {"minute", (getter)datetime_minute},
3967 {"second", (getter)datetime_second},
3968 {"microsecond", (getter)datetime_microsecond},
3969 {"tzinfo", (getter)datetime_tzinfo},
3970 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003971};
3972
3973/*
3974 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003975 */
3976
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003977static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 "year", "month", "day", "hour", "minute", "second",
3979 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003980};
3981
Tim Peters2a799bf2002-12-16 20:18:38 +00003982static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003983datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003984{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003985 PyObject *self = NULL;
3986 PyObject *state;
3987 int year;
3988 int month;
3989 int day;
3990 int hour = 0;
3991 int minute = 0;
3992 int second = 0;
3993 int usecond = 0;
3994 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003996 /* Check for invocation from pickle with __getstate__ state */
3997 if (PyTuple_GET_SIZE(args) >= 1 &&
3998 PyTuple_GET_SIZE(args) <= 2 &&
3999 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4000 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4001 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4002 {
4003 PyDateTime_DateTime *me;
4004 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004006 if (PyTuple_GET_SIZE(args) == 2) {
4007 tzinfo = PyTuple_GET_ITEM(args, 1);
4008 if (check_tzinfo_subclass(tzinfo) < 0) {
4009 PyErr_SetString(PyExc_TypeError, "bad "
4010 "tzinfo state arg");
4011 return NULL;
4012 }
4013 }
4014 aware = (char)(tzinfo != Py_None);
4015 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4016 if (me != NULL) {
4017 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004019 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4020 me->hashcode = -1;
4021 me->hastzinfo = aware;
4022 if (aware) {
4023 Py_INCREF(tzinfo);
4024 me->tzinfo = tzinfo;
4025 }
4026 }
4027 return (PyObject *)me;
4028 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004030 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4031 &year, &month, &day, &hour, &minute,
4032 &second, &usecond, &tzinfo)) {
4033 if (check_date_args(year, month, day) < 0)
4034 return NULL;
4035 if (check_time_args(hour, minute, second, usecond) < 0)
4036 return NULL;
4037 if (check_tzinfo_subclass(tzinfo) < 0)
4038 return NULL;
4039 self = new_datetime_ex(year, month, day,
4040 hour, minute, second, usecond,
4041 tzinfo, type);
4042 }
4043 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004044}
4045
Tim Petersa9bc1682003-01-11 03:39:11 +00004046/* TM_FUNC is the shared type of localtime() and gmtime(). */
4047typedef struct tm *(*TM_FUNC)(const time_t *timer);
4048
4049/* Internal helper.
4050 * Build datetime from a time_t and a distinct count of microseconds.
4051 * Pass localtime or gmtime for f, to control the interpretation of timet.
4052 */
4053static PyObject *
4054datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004055 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004056{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004057 struct tm *tm;
Tim Petersa9bc1682003-01-11 03:39:11 +00004058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004059 tm = f(&timet);
Victor Stinner21f58932012-03-14 00:15:40 +01004060 if (tm == NULL) {
4061#ifdef EINVAL
4062 if (errno == 0)
4063 errno = EINVAL;
4064#endif
4065 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004066 }
Victor Stinner21f58932012-03-14 00:15:40 +01004067
4068 /* The platform localtime/gmtime may insert leap seconds,
4069 * indicated by tm->tm_sec > 59. We don't care about them,
4070 * except to the extent that passing them on to the datetime
4071 * constructor would raise ValueError for a reason that
4072 * made no sense to the user.
4073 */
4074 if (tm->tm_sec > 59)
4075 tm->tm_sec = 59;
4076 return PyObject_CallFunction(cls, "iiiiiiiO",
4077 tm->tm_year + 1900,
4078 tm->tm_mon + 1,
4079 tm->tm_mday,
4080 tm->tm_hour,
4081 tm->tm_min,
4082 tm->tm_sec,
4083 us,
4084 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004085}
4086
4087/* Internal helper.
4088 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4089 * to control the interpretation of the timestamp. Since a double doesn't
4090 * have enough bits to cover a datetime's full range of precision, it's
4091 * better to call datetime_from_timet_and_us provided you have a way
4092 * to get that much precision (e.g., C time() isn't good enough).
4093 */
4094static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004095datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004096 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004098 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004099 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004100
Victor Stinnere4a994d2015-03-30 01:10:14 +02004101 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004102 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004103 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004104
Victor Stinner21f58932012-03-14 00:15:40 +01004105 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004106}
4107
4108/* Internal helper.
4109 * Build most accurate possible datetime for current time. Pass localtime or
4110 * gmtime for f as appropriate.
4111 */
4112static PyObject *
4113datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4114{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004115 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004116 time_t secs;
4117 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004118
Victor Stinner1e2b6882015-09-18 13:23:02 +02004119 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004120 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004121 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004122
Victor Stinner1e2b6882015-09-18 13:23:02 +02004123 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004124}
4125
Larry Hastings61272b72014-01-07 12:41:53 -08004126/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004127
4128@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004129datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004130
4131 tz: object = None
4132 Timezone object.
4133
4134Returns new datetime object representing current time local to tz.
4135
4136If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004137[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004138
Larry Hastings31826802013-10-19 00:09:25 -07004139static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004140datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004141/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004143 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004144
Larry Hastings31826802013-10-19 00:09:25 -07004145 /* Return best possible local time -- this isn't constrained by the
4146 * precision of a timestamp.
4147 */
4148 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004149 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004150
Larry Hastings5c661892014-01-24 06:17:25 -08004151 self = datetime_best_possible((PyObject *)type,
Larry Hastings31826802013-10-19 00:09:25 -07004152 tz == Py_None ? localtime : gmtime,
4153 tz);
4154 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004155 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004156 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004157 }
4158 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004159}
4160
Tim Petersa9bc1682003-01-11 03:39:11 +00004161/* Return best possible UTC time -- this isn't constrained by the
4162 * precision of a timestamp.
4163 */
4164static PyObject *
4165datetime_utcnow(PyObject *cls, PyObject *dummy)
4166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004167 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004168}
4169
Tim Peters2a799bf2002-12-16 20:18:38 +00004170/* Return new local datetime from timestamp (Python timestamp -- a double). */
4171static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004172datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004174 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004175 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004176 PyObject *tzinfo = Py_None;
4177 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004178
Victor Stinner5d272cc2012-03-13 13:35:55 +01004179 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004180 keywords, &timestamp, &tzinfo))
4181 return NULL;
4182 if (check_tzinfo_subclass(tzinfo) < 0)
4183 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004185 self = datetime_from_timestamp(cls,
4186 tzinfo == Py_None ? localtime : gmtime,
4187 timestamp,
4188 tzinfo);
4189 if (self != NULL && tzinfo != Py_None) {
4190 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004191 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004192 }
4193 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004194}
4195
Tim Petersa9bc1682003-01-11 03:39:11 +00004196/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4197static PyObject *
4198datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4199{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004200 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004201 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004202
Victor Stinner5d272cc2012-03-13 13:35:55 +01004203 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004204 result = datetime_from_timestamp(cls, gmtime, timestamp,
4205 Py_None);
4206 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004207}
4208
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004209/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004210static PyObject *
4211datetime_strptime(PyObject *cls, PyObject *args)
4212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004213 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004214 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004215 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004216
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004217 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004218 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004219
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004220 if (module == NULL) {
4221 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004222 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004223 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004224 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004225 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4226 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004227}
4228
Tim Petersa9bc1682003-01-11 03:39:11 +00004229/* Return new datetime from date/datetime and time arguments. */
4230static PyObject *
4231datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004233 static char *keywords[] = {"date", "time", NULL};
4234 PyObject *date;
4235 PyObject *time;
4236 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004238 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4239 &PyDateTime_DateType, &date,
4240 &PyDateTime_TimeType, &time)) {
4241 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004243 if (HASTZINFO(time))
4244 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4245 result = PyObject_CallFunction(cls, "iiiiiiiO",
4246 GET_YEAR(date),
4247 GET_MONTH(date),
4248 GET_DAY(date),
4249 TIME_GET_HOUR(time),
4250 TIME_GET_MINUTE(time),
4251 TIME_GET_SECOND(time),
4252 TIME_GET_MICROSECOND(time),
4253 tzinfo);
4254 }
4255 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004256}
Tim Peters2a799bf2002-12-16 20:18:38 +00004257
4258/*
4259 * Destructor.
4260 */
4261
4262static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004263datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004265 if (HASTZINFO(self)) {
4266 Py_XDECREF(self->tzinfo);
4267 }
4268 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004269}
4270
4271/*
4272 * Indirect access to tzinfo methods.
4273 */
4274
Tim Peters2a799bf2002-12-16 20:18:38 +00004275/* These are all METH_NOARGS, so don't need to check the arglist. */
4276static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004277datetime_utcoffset(PyObject *self, PyObject *unused) {
4278 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004279}
4280
4281static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004282datetime_dst(PyObject *self, PyObject *unused) {
4283 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004284}
4285
4286static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004287datetime_tzname(PyObject *self, PyObject *unused) {
4288 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004289}
4290
4291/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004292 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004293 */
4294
Tim Petersa9bc1682003-01-11 03:39:11 +00004295/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4296 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004297 */
4298static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004299add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004300 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004302 /* Note that the C-level additions can't overflow, because of
4303 * invariant bounds on the member values.
4304 */
4305 int year = GET_YEAR(date);
4306 int month = GET_MONTH(date);
4307 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4308 int hour = DATE_GET_HOUR(date);
4309 int minute = DATE_GET_MINUTE(date);
4310 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4311 int microsecond = DATE_GET_MICROSECOND(date) +
4312 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004314 assert(factor == 1 || factor == -1);
4315 if (normalize_datetime(&year, &month, &day,
4316 &hour, &minute, &second, &microsecond) < 0)
4317 return NULL;
4318 else
4319 return new_datetime(year, month, day,
4320 hour, minute, second, microsecond,
4321 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004322}
4323
4324static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004325datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004327 if (PyDateTime_Check(left)) {
4328 /* datetime + ??? */
4329 if (PyDelta_Check(right))
4330 /* datetime + delta */
4331 return add_datetime_timedelta(
4332 (PyDateTime_DateTime *)left,
4333 (PyDateTime_Delta *)right,
4334 1);
4335 }
4336 else if (PyDelta_Check(left)) {
4337 /* delta + datetime */
4338 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4339 (PyDateTime_Delta *) left,
4340 1);
4341 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004342 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004343}
4344
4345static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004346datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004348 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004350 if (PyDateTime_Check(left)) {
4351 /* datetime - ??? */
4352 if (PyDateTime_Check(right)) {
4353 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004354 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004355 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004356
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004357 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4358 offset2 = offset1 = Py_None;
4359 Py_INCREF(offset1);
4360 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004361 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004362 else {
4363 offset1 = datetime_utcoffset(left, NULL);
4364 if (offset1 == NULL)
4365 return NULL;
4366 offset2 = datetime_utcoffset(right, NULL);
4367 if (offset2 == NULL) {
4368 Py_DECREF(offset1);
4369 return NULL;
4370 }
4371 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4372 PyErr_SetString(PyExc_TypeError,
4373 "can't subtract offset-naive and "
4374 "offset-aware datetimes");
4375 Py_DECREF(offset1);
4376 Py_DECREF(offset2);
4377 return NULL;
4378 }
4379 }
4380 if ((offset1 != offset2) &&
4381 delta_cmp(offset1, offset2) != 0) {
4382 offdiff = delta_subtract(offset1, offset2);
4383 if (offdiff == NULL) {
4384 Py_DECREF(offset1);
4385 Py_DECREF(offset2);
4386 return NULL;
4387 }
4388 }
4389 Py_DECREF(offset1);
4390 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004391 delta_d = ymd_to_ord(GET_YEAR(left),
4392 GET_MONTH(left),
4393 GET_DAY(left)) -
4394 ymd_to_ord(GET_YEAR(right),
4395 GET_MONTH(right),
4396 GET_DAY(right));
4397 /* These can't overflow, since the values are
4398 * normalized. At most this gives the number of
4399 * seconds in one day.
4400 */
4401 delta_s = (DATE_GET_HOUR(left) -
4402 DATE_GET_HOUR(right)) * 3600 +
4403 (DATE_GET_MINUTE(left) -
4404 DATE_GET_MINUTE(right)) * 60 +
4405 (DATE_GET_SECOND(left) -
4406 DATE_GET_SECOND(right));
4407 delta_us = DATE_GET_MICROSECOND(left) -
4408 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004409 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004410 if (result == NULL)
4411 return NULL;
4412
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004413 if (offdiff != NULL) {
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004414 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004415 Py_DECREF(offdiff);
4416 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004417 }
4418 else if (PyDelta_Check(right)) {
4419 /* datetime - delta */
4420 result = add_datetime_timedelta(
4421 (PyDateTime_DateTime *)left,
4422 (PyDateTime_Delta *)right,
4423 -1);
4424 }
4425 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004427 if (result == Py_NotImplemented)
4428 Py_INCREF(result);
4429 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004430}
4431
4432/* Various ways to turn a datetime into a string. */
4433
4434static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004435datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004437 const char *type_name = Py_TYPE(self)->tp_name;
4438 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004440 if (DATE_GET_MICROSECOND(self)) {
4441 baserepr = PyUnicode_FromFormat(
4442 "%s(%d, %d, %d, %d, %d, %d, %d)",
4443 type_name,
4444 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4445 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4446 DATE_GET_SECOND(self),
4447 DATE_GET_MICROSECOND(self));
4448 }
4449 else if (DATE_GET_SECOND(self)) {
4450 baserepr = PyUnicode_FromFormat(
4451 "%s(%d, %d, %d, %d, %d, %d)",
4452 type_name,
4453 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4454 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4455 DATE_GET_SECOND(self));
4456 }
4457 else {
4458 baserepr = PyUnicode_FromFormat(
4459 "%s(%d, %d, %d, %d, %d)",
4460 type_name,
4461 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4462 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4463 }
4464 if (baserepr == NULL || ! HASTZINFO(self))
4465 return baserepr;
4466 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004467}
4468
Tim Petersa9bc1682003-01-11 03:39:11 +00004469static PyObject *
4470datetime_str(PyDateTime_DateTime *self)
4471{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004472 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004473}
Tim Peters2a799bf2002-12-16 20:18:38 +00004474
4475static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004476datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004478 int sep = 'T';
4479 static char *keywords[] = {"sep", NULL};
4480 char buffer[100];
4481 PyObject *result;
4482 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004484 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4485 return NULL;
4486 if (us)
4487 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4488 GET_YEAR(self), GET_MONTH(self),
4489 GET_DAY(self), (int)sep,
4490 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4491 DATE_GET_SECOND(self), us);
4492 else
4493 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4494 GET_YEAR(self), GET_MONTH(self),
4495 GET_DAY(self), (int)sep,
4496 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4497 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004499 if (!result || !HASTZINFO(self))
4500 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004502 /* We need to append the UTC offset. */
4503 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4504 (PyObject *)self) < 0) {
4505 Py_DECREF(result);
4506 return NULL;
4507 }
4508 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4509 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004510}
4511
Tim Petersa9bc1682003-01-11 03:39:11 +00004512static PyObject *
4513datetime_ctime(PyDateTime_DateTime *self)
4514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004515 return format_ctime((PyDateTime_Date *)self,
4516 DATE_GET_HOUR(self),
4517 DATE_GET_MINUTE(self),
4518 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004519}
4520
Tim Peters2a799bf2002-12-16 20:18:38 +00004521/* Miscellaneous methods. */
4522
Tim Petersa9bc1682003-01-11 03:39:11 +00004523static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004524datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004525{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004526 PyObject *result = NULL;
4527 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004528 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004530 if (! PyDateTime_Check(other)) {
4531 if (PyDate_Check(other)) {
4532 /* Prevent invocation of date_richcompare. We want to
4533 return NotImplemented here to give the other object
4534 a chance. But since DateTime is a subclass of
4535 Date, if the other object is a Date, it would
4536 compute an ordering based on the date part alone,
4537 and we don't want that. So force unequal or
4538 uncomparable here in that case. */
4539 if (op == Py_EQ)
4540 Py_RETURN_FALSE;
4541 if (op == Py_NE)
4542 Py_RETURN_TRUE;
4543 return cmperror(self, other);
4544 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004545 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004546 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004547
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004548 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004549 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4550 ((PyDateTime_DateTime *)other)->data,
4551 _PyDateTime_DATETIME_DATASIZE);
4552 return diff_to_bool(diff, op);
4553 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004554 offset1 = datetime_utcoffset(self, NULL);
4555 if (offset1 == NULL)
4556 return NULL;
4557 offset2 = datetime_utcoffset(other, NULL);
4558 if (offset2 == NULL)
4559 goto done;
4560 /* If they're both naive, or both aware and have the same offsets,
4561 * we get off cheap. Note that if they're both naive, offset1 ==
4562 * offset2 == Py_None at this point.
4563 */
4564 if ((offset1 == offset2) ||
4565 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4566 delta_cmp(offset1, offset2) == 0)) {
4567 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4568 ((PyDateTime_DateTime *)other)->data,
4569 _PyDateTime_DATETIME_DATASIZE);
4570 result = diff_to_bool(diff, op);
4571 }
4572 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004574
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004575 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004576 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4577 other);
4578 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004579 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004580 diff = GET_TD_DAYS(delta);
4581 if (diff == 0)
4582 diff = GET_TD_SECONDS(delta) |
4583 GET_TD_MICROSECONDS(delta);
4584 Py_DECREF(delta);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004585 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004586 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004587 else if (op == Py_EQ) {
4588 result = Py_False;
4589 Py_INCREF(result);
4590 }
4591 else if (op == Py_NE) {
4592 result = Py_True;
4593 Py_INCREF(result);
4594 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004595 else {
4596 PyErr_SetString(PyExc_TypeError,
4597 "can't compare offset-naive and "
4598 "offset-aware datetimes");
4599 }
4600 done:
4601 Py_DECREF(offset1);
4602 Py_XDECREF(offset2);
4603 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004604}
4605
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004606static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004607datetime_hash(PyDateTime_DateTime *self)
4608{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004609 if (self->hashcode == -1) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004610 PyObject *offset;
Tim Petersa9bc1682003-01-11 03:39:11 +00004611
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004612 offset = datetime_utcoffset((PyObject *)self, NULL);
4613
4614 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004615 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004617 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004618 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004619 self->hashcode = generic_hash(
4620 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004621 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004622 PyObject *temp1, *temp2;
4623 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004625 assert(HASTZINFO(self));
4626 days = ymd_to_ord(GET_YEAR(self),
4627 GET_MONTH(self),
4628 GET_DAY(self));
4629 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004630 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004632 temp1 = new_delta(days, seconds,
4633 DATE_GET_MICROSECOND(self),
4634 1);
4635 if (temp1 == NULL) {
4636 Py_DECREF(offset);
4637 return -1;
4638 }
4639 temp2 = delta_subtract(temp1, offset);
4640 Py_DECREF(temp1);
4641 if (temp2 == NULL) {
4642 Py_DECREF(offset);
4643 return -1;
4644 }
4645 self->hashcode = PyObject_Hash(temp2);
4646 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004647 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004648 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004649 }
4650 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004651}
Tim Peters2a799bf2002-12-16 20:18:38 +00004652
4653static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004654datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004656 PyObject *clone;
4657 PyObject *tuple;
4658 int y = GET_YEAR(self);
4659 int m = GET_MONTH(self);
4660 int d = GET_DAY(self);
4661 int hh = DATE_GET_HOUR(self);
4662 int mm = DATE_GET_MINUTE(self);
4663 int ss = DATE_GET_SECOND(self);
4664 int us = DATE_GET_MICROSECOND(self);
4665 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004667 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4668 datetime_kws,
4669 &y, &m, &d, &hh, &mm, &ss, &us,
4670 &tzinfo))
4671 return NULL;
4672 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4673 if (tuple == NULL)
4674 return NULL;
4675 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4676 Py_DECREF(tuple);
4677 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004678}
4679
4680static PyObject *
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004681local_timezone(PyDateTime_DateTime *utc_time)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004682{
4683 PyObject *result = NULL;
4684 struct tm *timep;
4685 time_t timestamp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004686 PyObject *delta;
4687 PyObject *one_second;
4688 PyObject *seconds;
4689 PyObject *nameo = NULL;
4690 const char *zone = NULL;
4691
4692 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
4693 if (delta == NULL)
4694 return NULL;
4695 one_second = new_delta(0, 1, 0, 0);
4696 if (one_second == NULL)
4697 goto error;
4698 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
4699 (PyDateTime_Delta *)one_second);
4700 Py_DECREF(one_second);
4701 if (seconds == NULL)
4702 goto error;
4703 Py_DECREF(delta);
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03004704 timestamp = _PyLong_AsTime_t(seconds);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004705 Py_DECREF(seconds);
4706 if (timestamp == -1 && PyErr_Occurred())
4707 return NULL;
4708 timep = localtime(&timestamp);
4709#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004710 zone = timep->tm_zone;
4711 delta = new_delta(0, timep->tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004712#else /* HAVE_STRUCT_TM_TM_ZONE */
4713 {
4714 PyObject *local_time;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004715 local_time = new_datetime(timep->tm_year + 1900, timep->tm_mon + 1,
4716 timep->tm_mday, timep->tm_hour, timep->tm_min,
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004717 timep->tm_sec, DATE_GET_MICROSECOND(utc_time),
4718 utc_time->tzinfo);
4719 if (local_time == NULL)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004720 goto error;
Alexander Belopolsky93c9cd02012-06-22 16:04:19 -04004721 delta = datetime_subtract(local_time, (PyObject*)utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004722 /* XXX: before relying on tzname, we should compare delta
4723 to the offset implied by timezone/altzone */
4724 if (daylight && timep->tm_isdst >= 0)
4725 zone = tzname[timep->tm_isdst % 2];
4726 else
4727 zone = tzname[0];
4728 Py_DECREF(local_time);
4729 }
4730#endif /* HAVE_STRUCT_TM_TM_ZONE */
4731 if (zone != NULL) {
4732 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
4733 if (nameo == NULL)
4734 goto error;
4735 }
4736 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02004737 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004738 error:
4739 Py_DECREF(delta);
4740 return result;
4741}
4742
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004743static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00004744datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004745{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004746 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004747 PyObject *offset;
4748 PyObject *temp;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004749 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004750 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004751
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004752 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07004753 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004754 return NULL;
4755
4756 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004757 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004759 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4760 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004762 /* Conversion to self's own time zone is a NOP. */
4763 if (self->tzinfo == tzinfo) {
4764 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004765 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004766 }
Tim Peters521fc152002-12-31 17:36:56 +00004767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004768 /* Convert self to UTC. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004769 offset = datetime_utcoffset((PyObject *)self, NULL);
4770 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004771 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004772 if (offset == Py_None) {
4773 Py_DECREF(offset);
4774 NeedAware:
4775 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4776 "a naive datetime");
4777 return NULL;
4778 }
Tim Petersf3615152003-01-01 21:51:37 +00004779
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004780 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004781 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4782 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004783 Py_DECREF(offset);
4784 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004785 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004787 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004788 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04004789 if (tzinfo == Py_None) {
4790 tzinfo = local_timezone(result);
4791 if (tzinfo == NULL) {
4792 Py_DECREF(result);
4793 return NULL;
4794 }
4795 }
4796 else
4797 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004798 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004799 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00004800
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04004801 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004802 result = (PyDateTime_DateTime *)
4803 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004804 Py_DECREF(temp);
4805
Alexander Belopolsky878054e2012-06-22 14:11:58 -04004806 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00004807}
4808
4809static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004810datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004811{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004812 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004814 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004815 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00004816
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004817 dst = call_dst(self->tzinfo, (PyObject *)self);
4818 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004819 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004820
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004821 if (dst != Py_None)
4822 dstflag = delta_bool((PyDateTime_Delta *)dst);
4823 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004824 }
4825 return build_struct_time(GET_YEAR(self),
4826 GET_MONTH(self),
4827 GET_DAY(self),
4828 DATE_GET_HOUR(self),
4829 DATE_GET_MINUTE(self),
4830 DATE_GET_SECOND(self),
4831 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004832}
4833
4834static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04004835datetime_timestamp(PyDateTime_DateTime *self)
4836{
4837 PyObject *result;
4838
4839 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4840 PyObject *delta;
4841 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
4842 if (delta == NULL)
4843 return NULL;
4844 result = delta_total_seconds(delta);
4845 Py_DECREF(delta);
4846 }
4847 else {
4848 struct tm time;
4849 time_t timestamp;
4850 memset((void *) &time, '\0', sizeof(struct tm));
4851 time.tm_year = GET_YEAR(self) - 1900;
4852 time.tm_mon = GET_MONTH(self) - 1;
4853 time.tm_mday = GET_DAY(self);
4854 time.tm_hour = DATE_GET_HOUR(self);
4855 time.tm_min = DATE_GET_MINUTE(self);
4856 time.tm_sec = DATE_GET_SECOND(self);
4857 time.tm_wday = -1;
4858 time.tm_isdst = -1;
4859 timestamp = mktime(&time);
Victor Stinner93037492013-06-25 22:54:35 +02004860 if (timestamp == (time_t)(-1)
4861#ifndef _AIX
4862 /* Return value of -1 does not necessarily mean an error,
4863 * but tm_wday cannot remain set to -1 if mktime succeeded. */
4864 && time.tm_wday == -1
4865#else
4866 /* on AIX, tm_wday is always sets, even on error */
4867#endif
4868 )
4869 {
Alexander Belopolskya4415142012-06-08 12:33:09 -04004870 PyErr_SetString(PyExc_OverflowError,
4871 "timestamp out of range");
4872 return NULL;
4873 }
4874 result = PyFloat_FromDouble(timestamp + DATE_GET_MICROSECOND(self) / 1e6);
4875 }
4876 return result;
4877}
4878
4879static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004880datetime_getdate(PyDateTime_DateTime *self)
4881{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 return new_date(GET_YEAR(self),
4883 GET_MONTH(self),
4884 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004885}
4886
4887static PyObject *
4888datetime_gettime(PyDateTime_DateTime *self)
4889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 return new_time(DATE_GET_HOUR(self),
4891 DATE_GET_MINUTE(self),
4892 DATE_GET_SECOND(self),
4893 DATE_GET_MICROSECOND(self),
4894 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004895}
4896
4897static PyObject *
4898datetime_gettimetz(PyDateTime_DateTime *self)
4899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004900 return new_time(DATE_GET_HOUR(self),
4901 DATE_GET_MINUTE(self),
4902 DATE_GET_SECOND(self),
4903 DATE_GET_MICROSECOND(self),
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004904 GET_DT_TZINFO(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004905}
4906
4907static PyObject *
4908datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004909{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004910 int y, m, d, hh, mm, ss;
4911 PyObject *tzinfo;
4912 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00004913
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004914 tzinfo = GET_DT_TZINFO(self);
4915 if (tzinfo == Py_None) {
4916 utcself = self;
4917 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004918 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004919 else {
4920 PyObject *offset;
4921 offset = call_utcoffset(tzinfo, (PyObject *)self);
4922 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004923 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004924 if (offset == Py_None) {
4925 Py_DECREF(offset);
4926 utcself = self;
4927 Py_INCREF(utcself);
4928 }
4929 else {
4930 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
4931 (PyDateTime_Delta *)offset, -1);
4932 Py_DECREF(offset);
4933 if (utcself == NULL)
4934 return NULL;
4935 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004936 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004937 y = GET_YEAR(utcself);
4938 m = GET_MONTH(utcself);
4939 d = GET_DAY(utcself);
4940 hh = DATE_GET_HOUR(utcself);
4941 mm = DATE_GET_MINUTE(utcself);
4942 ss = DATE_GET_SECOND(utcself);
4943
4944 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004945 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004946}
4947
Tim Peters371935f2003-02-01 01:52:50 +00004948/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004949
Tim Petersa9bc1682003-01-11 03:39:11 +00004950/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004951 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4952 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004953 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004954 */
4955static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004956datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004958 PyObject *basestate;
4959 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004961 basestate = PyBytes_FromStringAndSize((char *)self->data,
4962 _PyDateTime_DATETIME_DATASIZE);
4963 if (basestate != NULL) {
4964 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4965 result = PyTuple_Pack(1, basestate);
4966 else
4967 result = PyTuple_Pack(2, basestate, self->tzinfo);
4968 Py_DECREF(basestate);
4969 }
4970 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004971}
4972
4973static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004974datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004976 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004977}
4978
Tim Petersa9bc1682003-01-11 03:39:11 +00004979static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004981 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004982
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004983 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00004984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004985 {"utcnow", (PyCFunction)datetime_utcnow,
4986 METH_NOARGS | METH_CLASS,
4987 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004989 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4990 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4991 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004993 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4994 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05004995 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004997 {"strptime", (PyCFunction)datetime_strptime,
4998 METH_VARARGS | METH_CLASS,
4999 PyDoc_STR("string, format -> new datetime parsed from a string "
5000 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005002 {"combine", (PyCFunction)datetime_combine,
5003 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5004 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005006 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005008 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5009 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005011 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5012 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005014 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5015 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005017 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5018 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005020 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5021 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005022
Alexander Belopolskya4415142012-06-08 12:33:09 -04005023 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5024 PyDoc_STR("Return POSIX timestamp as float.")},
5025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005026 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5027 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005029 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5030 PyDoc_STR("[sep] -> string in ISO 8601 format, "
5031 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
5032 "sep is used to separate the year from the time, and "
5033 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5036 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005038 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5039 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005041 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5042 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005044 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5045 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005047 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5048 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005050 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5051 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005053 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005054};
5055
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005056static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005057PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5058\n\
5059The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005060instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005061
Tim Petersa9bc1682003-01-11 03:39:11 +00005062static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005063 datetime_add, /* nb_add */
5064 datetime_subtract, /* nb_subtract */
5065 0, /* nb_multiply */
5066 0, /* nb_remainder */
5067 0, /* nb_divmod */
5068 0, /* nb_power */
5069 0, /* nb_negative */
5070 0, /* nb_positive */
5071 0, /* nb_absolute */
5072 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005073};
5074
Neal Norwitz227b5332006-03-22 09:28:35 +00005075static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005076 PyVarObject_HEAD_INIT(NULL, 0)
5077 "datetime.datetime", /* tp_name */
5078 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5079 0, /* tp_itemsize */
5080 (destructor)datetime_dealloc, /* tp_dealloc */
5081 0, /* tp_print */
5082 0, /* tp_getattr */
5083 0, /* tp_setattr */
5084 0, /* tp_reserved */
5085 (reprfunc)datetime_repr, /* tp_repr */
5086 &datetime_as_number, /* tp_as_number */
5087 0, /* tp_as_sequence */
5088 0, /* tp_as_mapping */
5089 (hashfunc)datetime_hash, /* tp_hash */
5090 0, /* tp_call */
5091 (reprfunc)datetime_str, /* tp_str */
5092 PyObject_GenericGetAttr, /* tp_getattro */
5093 0, /* tp_setattro */
5094 0, /* tp_as_buffer */
5095 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5096 datetime_doc, /* tp_doc */
5097 0, /* tp_traverse */
5098 0, /* tp_clear */
5099 datetime_richcompare, /* tp_richcompare */
5100 0, /* tp_weaklistoffset */
5101 0, /* tp_iter */
5102 0, /* tp_iternext */
5103 datetime_methods, /* tp_methods */
5104 0, /* tp_members */
5105 datetime_getset, /* tp_getset */
5106 &PyDateTime_DateType, /* tp_base */
5107 0, /* tp_dict */
5108 0, /* tp_descr_get */
5109 0, /* tp_descr_set */
5110 0, /* tp_dictoffset */
5111 0, /* tp_init */
5112 datetime_alloc, /* tp_alloc */
5113 datetime_new, /* tp_new */
5114 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005115};
5116
5117/* ---------------------------------------------------------------------------
5118 * Module methods and initialization.
5119 */
5120
5121static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005122 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005123};
5124
Tim Peters9ddf40b2004-06-20 22:41:32 +00005125/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5126 * datetime.h.
5127 */
5128static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005129 &PyDateTime_DateType,
5130 &PyDateTime_DateTimeType,
5131 &PyDateTime_TimeType,
5132 &PyDateTime_DeltaType,
5133 &PyDateTime_TZInfoType,
5134 new_date_ex,
5135 new_datetime_ex,
5136 new_time_ex,
5137 new_delta_ex,
5138 datetime_fromtimestamp,
5139 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005140};
5141
5142
Martin v. Löwis1a214512008-06-11 05:26:20 +00005143
5144static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005145 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005146 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005147 "Fast implementation of the datetime type.",
5148 -1,
5149 module_methods,
5150 NULL,
5151 NULL,
5152 NULL,
5153 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005154};
5155
Tim Peters2a799bf2002-12-16 20:18:38 +00005156PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005157PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005159 PyObject *m; /* a module object */
5160 PyObject *d; /* its dict */
5161 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005162 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005164 m = PyModule_Create(&datetimemodule);
5165 if (m == NULL)
5166 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005168 if (PyType_Ready(&PyDateTime_DateType) < 0)
5169 return NULL;
5170 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5171 return NULL;
5172 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5173 return NULL;
5174 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5175 return NULL;
5176 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5177 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005178 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5179 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005181 /* timedelta values */
5182 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005184 x = new_delta(0, 0, 1, 0);
5185 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5186 return NULL;
5187 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005189 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5190 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5191 return NULL;
5192 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005194 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5195 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5196 return NULL;
5197 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005199 /* date values */
5200 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005202 x = new_date(1, 1, 1);
5203 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5204 return NULL;
5205 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005207 x = new_date(MAXYEAR, 12, 31);
5208 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5209 return NULL;
5210 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005212 x = new_delta(1, 0, 0, 0);
5213 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5214 return NULL;
5215 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005217 /* time values */
5218 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005220 x = new_time(0, 0, 0, 0, Py_None);
5221 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5222 return NULL;
5223 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005225 x = new_time(23, 59, 59, 999999, Py_None);
5226 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5227 return NULL;
5228 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005230 x = new_delta(0, 0, 1, 0);
5231 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5232 return NULL;
5233 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005235 /* datetime values */
5236 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005238 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5239 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5240 return NULL;
5241 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5244 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5245 return NULL;
5246 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005248 x = new_delta(0, 0, 1, 0);
5249 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5250 return NULL;
5251 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005252
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005253 /* timezone values */
5254 d = PyDateTime_TimeZoneType.tp_dict;
5255
5256 delta = new_delta(0, 0, 0, 0);
5257 if (delta == NULL)
5258 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005259 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005260 Py_DECREF(delta);
5261 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5262 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005263 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005264
5265 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5266 if (delta == NULL)
5267 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005268 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005269 Py_DECREF(delta);
5270 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5271 return NULL;
5272 Py_DECREF(x);
5273
5274 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5275 if (delta == NULL)
5276 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005277 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005278 Py_DECREF(delta);
5279 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5280 return NULL;
5281 Py_DECREF(x);
5282
Alexander Belopolskya4415142012-06-08 12:33:09 -04005283 /* Epoch */
5284 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
5285 PyDateTime_TimeZone_UTC);
5286 if (PyDateTime_Epoch == NULL)
5287 return NULL;
5288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005289 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005290 PyModule_AddIntMacro(m, MINYEAR);
5291 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005293 Py_INCREF(&PyDateTime_DateType);
5294 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005296 Py_INCREF(&PyDateTime_DateTimeType);
5297 PyModule_AddObject(m, "datetime",
5298 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005300 Py_INCREF(&PyDateTime_TimeType);
5301 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005303 Py_INCREF(&PyDateTime_DeltaType);
5304 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005306 Py_INCREF(&PyDateTime_TZInfoType);
5307 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005308
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005309 Py_INCREF(&PyDateTime_TimeZoneType);
5310 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005312 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5313 if (x == NULL)
5314 return NULL;
5315 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005317 /* A 4-year cycle has an extra leap day over what we'd get from
5318 * pasting together 4 single years.
5319 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005320 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005321 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005323 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5324 * get from pasting together 4 100-year cycles.
5325 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005326 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005327 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005329 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5330 * pasting together 25 4-year cycles.
5331 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005332 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005333 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005334
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005335 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005336 us_per_ms = PyLong_FromLong(1000);
5337 us_per_second = PyLong_FromLong(1000000);
5338 us_per_minute = PyLong_FromLong(60000000);
5339 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005340 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005341 us_per_minute == NULL || seconds_per_day == NULL)
5342 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005344 /* The rest are too big for 32-bit ints, but even
5345 * us_per_week fits in 40 bits, so doubles should be exact.
5346 */
5347 us_per_hour = PyLong_FromDouble(3600000000.0);
5348 us_per_day = PyLong_FromDouble(86400000000.0);
5349 us_per_week = PyLong_FromDouble(604800000000.0);
5350 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5351 return NULL;
5352 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005353}
Tim Petersf3615152003-01-01 21:51:37 +00005354
5355/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005356Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005357 x.n = x stripped of its timezone -- its naive time.
5358 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005359 return None
Tim Petersf3615152003-01-01 21:51:37 +00005360 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005361 return None
Tim Petersf3615152003-01-01 21:51:37 +00005362 x.s = x's standard offset, x.o - x.d
5363
5364Now some derived rules, where k is a duration (timedelta).
5365
53661. x.o = x.s + x.d
5367 This follows from the definition of x.s.
5368
Tim Petersc5dc4da2003-01-02 17:55:03 +000053692. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005370 This is actually a requirement, an assumption we need to make about
5371 sane tzinfo classes.
5372
53733. The naive UTC time corresponding to x is x.n - x.o.
5374 This is again a requirement for a sane tzinfo class.
5375
53764. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005377 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005378
Tim Petersc5dc4da2003-01-02 17:55:03 +000053795. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005380 Again follows from how arithmetic is defined.
5381
Tim Peters8bb5ad22003-01-24 02:44:45 +00005382Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005383(meaning that the various tzinfo methods exist, and don't blow up or return
5384None when called).
5385
Tim Petersa9bc1682003-01-11 03:39:11 +00005386The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005387x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005388
5389By #3, we want
5390
Tim Peters8bb5ad22003-01-24 02:44:45 +00005391 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005392
5393The algorithm starts by attaching tz to x.n, and calling that y. So
5394x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5395becomes true; in effect, we want to solve [2] for k:
5396
Tim Peters8bb5ad22003-01-24 02:44:45 +00005397 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005398
5399By #1, this is the same as
5400
Tim Peters8bb5ad22003-01-24 02:44:45 +00005401 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005402
5403By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5404Substituting that into [3],
5405
Tim Peters8bb5ad22003-01-24 02:44:45 +00005406 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5407 k - (y+k).s - (y+k).d = 0; rearranging,
5408 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5409 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005410
Tim Peters8bb5ad22003-01-24 02:44:45 +00005411On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5412approximate k by ignoring the (y+k).d term at first. Note that k can't be
5413very large, since all offset-returning methods return a duration of magnitude
5414less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5415be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005416
5417In any case, the new value is
5418
Tim Peters8bb5ad22003-01-24 02:44:45 +00005419 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005420
Tim Peters8bb5ad22003-01-24 02:44:45 +00005421It's helpful to step back at look at [4] from a higher level: it's simply
5422mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005423
5424At this point, if
5425
Tim Peters8bb5ad22003-01-24 02:44:45 +00005426 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005427
5428we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005429at the start of daylight time. Picture US Eastern for concreteness. The wall
5430time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
Tim Peters8bb5ad22003-01-24 02:44:45 +00005431sense then. The docs ask that an Eastern tzinfo class consider such a time to
5432be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5433on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005434the only spelling that makes sense on the local wall clock.
5435
Tim Petersc5dc4da2003-01-02 17:55:03 +00005436In fact, if [5] holds at this point, we do have the standard-time spelling,
5437but that takes a bit of proof. We first prove a stronger result. What's the
5438difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005439
Tim Peters8bb5ad22003-01-24 02:44:45 +00005440 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005441
Tim Petersc5dc4da2003-01-02 17:55:03 +00005442Now
5443 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005444 (y + y.s).n = by #5
5445 y.n + y.s = since y.n = x.n
5446 x.n + y.s = since z and y are have the same tzinfo member,
5447 y.s = z.s by #2
5448 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005449
Tim Petersc5dc4da2003-01-02 17:55:03 +00005450Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005451
Tim Petersc5dc4da2003-01-02 17:55:03 +00005452 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005453 x.n - ((x.n + z.s) - z.o) = expanding
5454 x.n - x.n - z.s + z.o = cancelling
5455 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005456 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005457
Tim Petersc5dc4da2003-01-02 17:55:03 +00005458So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005459
Tim Petersc5dc4da2003-01-02 17:55:03 +00005460If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005461spelling we wanted in the endcase described above. We're done. Contrarily,
5462if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005463
Tim Petersc5dc4da2003-01-02 17:55:03 +00005464If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5465add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005466local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005467
Tim Petersc5dc4da2003-01-02 17:55:03 +00005468Let
Tim Petersf3615152003-01-01 21:51:37 +00005469
Tim Peters4fede1a2003-01-04 00:26:59 +00005470 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005471
Tim Peters4fede1a2003-01-04 00:26:59 +00005472and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005473
Tim Peters8bb5ad22003-01-24 02:44:45 +00005474 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005475
Tim Peters8bb5ad22003-01-24 02:44:45 +00005476If so, we're done. If not, the tzinfo class is insane, according to the
5477assumptions we've made. This also requires a bit of proof. As before, let's
5478compute the difference between the LHS and RHS of [8] (and skipping some of
5479the justifications for the kinds of substitutions we've done several times
5480already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005481
Tim Peters8bb5ad22003-01-24 02:44:45 +00005482 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005483 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5484 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5485 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5486 - z.n + z.n - z.o + z'.o = cancel z.n
5487 - z.o + z'.o = #1 twice
5488 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5489 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005490
5491So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
Tim Peters8bb5ad22003-01-24 02:44:45 +00005492we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5493return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005494
Tim Peters8bb5ad22003-01-24 02:44:45 +00005495How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5496a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5497would have to change the result dst() returns: we start in DST, and moving
5498a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005499
Tim Peters8bb5ad22003-01-24 02:44:45 +00005500There isn't a sane case where this can happen. The closest it gets is at
5501the end of DST, where there's an hour in UTC with no spelling in a hybrid
5502tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5503that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5504UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5505time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5506clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5507standard time. Since that's what the local clock *does*, we want to map both
5508UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005509in local time, but so it goes -- it's the way the local clock works.
5510
Tim Peters8bb5ad22003-01-24 02:44:45 +00005511When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5512so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5513z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
Tim Peters4fede1a2003-01-04 00:26:59 +00005514(correctly) concludes that z' is not UTC-equivalent to x.
5515
5516Because we know z.d said z was in daylight time (else [5] would have held and
5517we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005518and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005519return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5520but the reasoning doesn't depend on the example -- it depends on there being
5521two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005522z' must be in standard time, and is the spelling we want in this case.
5523
5524Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5525concerned (because it takes z' as being in standard time rather than the
5526daylight time we intend here), but returning it gives the real-life "local
5527clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5528tz.
5529
5530When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5531the 1:MM standard time spelling we want.
5532
5533So how can this break? One of the assumptions must be violated. Two
5534possibilities:
5535
55361) [2] effectively says that y.s is invariant across all y belong to a given
5537 time zone. This isn't true if, for political reasons or continental drift,
5538 a region decides to change its base offset from UTC.
5539
55402) There may be versions of "double daylight" time where the tail end of
5541 the analysis gives up a step too early. I haven't thought about that
5542 enough to say.
5543
5544In any case, it's clear that the default fromutc() is strong enough to handle
5545"almost all" time zones: so long as the standard offset is invariant, it
5546doesn't matter if daylight time transition points change from year to year, or
5547if daylight time is skipped in some years; it doesn't matter how large or
5548small dst() may get within its bounds; and it doesn't even matter if some
5549perverse time zone returns a negative dst()). So a breaking case must be
5550pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005551--------------------------------------------------------------------------- */