blob: 1157859ae3f77156532308fe42418cb78091a7bd [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 */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040012static struct tm *localtime_r(const time_t *timep, struct tm *result)
13{
14 if (localtime_s(result, timep) == 0)
15 return result;
16 return NULL;
17}
Victor Stinner09e5cf22015-03-30 00:09:18 +020018#endif
19
Tim Peters9ddf40b2004-06-20 22:41:32 +000020/* Differentiate between building the core module and building extension
21 * modules.
22 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000023#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000024#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000025#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000026#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000027#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000028
Larry Hastings61272b72014-01-07 12:41:53 -080029/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080030module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080031class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Larry Hastings61272b72014-01-07 12:41:53 -080032[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -080033/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080034
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030035#include "clinic/_datetimemodule.c.h"
36
Tim Peters2a799bf2002-12-16 20:18:38 +000037/* We require that C int be at least 32 bits, and use int virtually
38 * everywhere. In just a few cases we use a temp long, where a Python
39 * API returns a C long. In such cases, we have to ensure that the
40 * final result fits in a C int (this can be an issue on 64-bit boxes).
41 */
42#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000043# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000044#endif
45
46#define MINYEAR 1
47#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000048#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000049
50/* Nine decimal digits is easy to communicate, and leaves enough room
51 * so that two delta days can be added w/o fear of overflowing a signed
52 * 32-bit int, and with plenty of room left over to absorb any possible
53 * carries from adding seconds.
54 */
55#define MAX_DELTA_DAYS 999999999
56
57/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058#define GET_YEAR PyDateTime_GET_YEAR
59#define GET_MONTH PyDateTime_GET_MONTH
60#define GET_DAY PyDateTime_GET_DAY
61#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
62#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
63#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
64#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040065#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000066
67/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
69 ((o)->data[1] = ((v) & 0x00ff)))
70#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
71#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000072
73/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
75#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
76#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
77#define DATE_SET_MICROSECOND(o, v) \
78 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
79 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
80 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040081#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000082
83/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
85#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
86#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
87#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040088#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
90#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
91#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
92#define TIME_SET_MICROSECOND(o, v) \
93 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
94 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
95 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040096#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000097
98/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
100#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
101#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103#define SET_TD_DAYS(o, v) ((o)->days = (v))
104#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +0000105#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
106
Tim Petersa032d2e2003-01-11 00:15:54 +0000107/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
108 * p->hastzinfo.
109 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000110#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
111#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
112 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
113#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
114 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000115/* M is a char or int claiming to be a valid month. The macro is equivalent
116 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000118 */
119#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
120
Tim Peters2a799bf2002-12-16 20:18:38 +0000121/* Forward declarations. */
122static PyTypeObject PyDateTime_DateType;
123static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000124static PyTypeObject PyDateTime_DeltaType;
125static PyTypeObject PyDateTime_TimeType;
126static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000127static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000128
Martin v. Löwise75fc142013-11-07 18:46:53 +0100129_Py_IDENTIFIER(as_integer_ratio);
130_Py_IDENTIFIER(fromutc);
131_Py_IDENTIFIER(isoformat);
132_Py_IDENTIFIER(strftime);
133
Tim Peters2a799bf2002-12-16 20:18:38 +0000134/* ---------------------------------------------------------------------------
135 * Math utilities.
136 */
137
138/* k = i+j overflows iff k differs in sign from both inputs,
139 * iff k^i has sign bit set and k^j has sign bit set,
140 * iff (k^i)&(k^j) has sign bit set.
141 */
142#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000144
145/* Compute Python divmod(x, y), returning the quotient and storing the
146 * remainder into *r. The quotient is the floor of x/y, and that's
147 * the real point of this. C will probably truncate instead (C99
148 * requires truncation; C89 left it implementation-defined).
149 * Simplification: we *require* that y > 0 here. That's appropriate
150 * for all the uses made of it. This simplifies the code and makes
151 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
152 * overflow case).
153 */
154static int
155divmod(int x, int y, int *r)
156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 assert(y > 0);
160 quo = x / y;
161 *r = x - quo * y;
162 if (*r < 0) {
163 --quo;
164 *r += y;
165 }
166 assert(0 <= *r && *r < y);
167 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000168}
169
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000170/* Nearest integer to m / n for integers m and n. Half-integer results
171 * are rounded to even.
172 */
173static PyObject *
174divide_nearest(PyObject *m, PyObject *n)
175{
176 PyObject *result;
177 PyObject *temp;
178
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000179 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000180 if (temp == NULL)
181 return NULL;
182 result = PyTuple_GET_ITEM(temp, 0);
183 Py_INCREF(result);
184 Py_DECREF(temp);
185
186 return result;
187}
188
Tim Peters2a799bf2002-12-16 20:18:38 +0000189/* ---------------------------------------------------------------------------
190 * General calendrical helper functions
191 */
192
193/* For each month ordinal in 1..12, the number of days in that month,
194 * and the number of days before that month in the same year. These
195 * are correct for non-leap years only.
196 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200197static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 0, /* unused; this vector uses 1-based indexing */
199 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000200};
201
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200202static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 0, /* unused; this vector uses 1-based indexing */
204 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000205};
206
207/* year -> 1 if leap year, else 0. */
208static int
209is_leap(int year)
210{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 /* Cast year to unsigned. The result is the same either way, but
212 * C can generate faster code for unsigned mod than for signed
213 * mod (especially for % 4 -- a good compiler should just grab
214 * the last 2 bits when the LHS is unsigned).
215 */
216 const unsigned int ayear = (unsigned int)year;
217 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000218}
219
220/* year, month -> number of days in that month in that year */
221static int
222days_in_month(int year, int month)
223{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 assert(month >= 1);
225 assert(month <= 12);
226 if (month == 2 && is_leap(year))
227 return 29;
228 else
229 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000230}
231
Martin Panter46f50722016-05-26 05:35:26 +0000232/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000233static int
234days_before_month(int year, int month)
235{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 assert(month >= 1);
239 assert(month <= 12);
240 days = _days_before_month[month];
241 if (month > 2 && is_leap(year))
242 ++days;
243 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000244}
245
246/* year -> number of days before January 1st of year. Remember that we
247 * start with year 1, so days_before_year(1) == 0.
248 */
249static int
250days_before_year(int year)
251{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 int y = year - 1;
253 /* This is incorrect if year <= 0; we really want the floor
254 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000255 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000257 assert (year >= 1);
258 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000259}
260
261/* Number of days in 4, 100, and 400 year cycles. That these have
262 * the correct values is asserted in the module init function.
263 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264#define DI4Y 1461 /* days_before_year(5); days in 4 years */
265#define DI100Y 36524 /* days_before_year(101); days in 100 years */
266#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000267
268/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
269static void
270ord_to_ymd(int ordinal, int *year, int *month, int *day)
271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
275 * leap years repeats exactly every 400 years. The basic strategy is
276 * to find the closest 400-year boundary at or before ordinal, then
277 * work with the offset from that boundary to ordinal. Life is much
278 * clearer if we subtract 1 from ordinal first -- then the values
279 * of ordinal at 400-year boundaries are exactly those divisible
280 * by DI400Y:
281 *
282 * D M Y n n-1
283 * -- --- ---- ---------- ----------------
284 * 31 Dec -400 -DI400Y -DI400Y -1
285 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
286 * ...
287 * 30 Dec 000 -1 -2
288 * 31 Dec 000 0 -1
289 * 1 Jan 001 1 0 400-year boundary
290 * 2 Jan 001 2 1
291 * 3 Jan 001 3 2
292 * ...
293 * 31 Dec 400 DI400Y DI400Y -1
294 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
295 */
296 assert(ordinal >= 1);
297 --ordinal;
298 n400 = ordinal / DI400Y;
299 n = ordinal % DI400Y;
300 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 /* Now n is the (non-negative) offset, in days, from January 1 of
303 * year, to the desired date. Now compute how many 100-year cycles
304 * precede n.
305 * Note that it's possible for n100 to equal 4! In that case 4 full
306 * 100-year cycles precede the desired day, which implies the
307 * desired day is December 31 at the end of a 400-year cycle.
308 */
309 n100 = n / DI100Y;
310 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 /* Now compute how many 4-year cycles precede it. */
313 n4 = n / DI4Y;
314 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 /* And now how many single years. Again n1 can be 4, and again
317 * meaning that the desired day is December 31 at the end of the
318 * 4-year cycle.
319 */
320 n1 = n / 365;
321 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 *year += n100 * 100 + n4 * 4 + n1;
324 if (n1 == 4 || n100 == 4) {
325 assert(n == 0);
326 *year -= 1;
327 *month = 12;
328 *day = 31;
329 return;
330 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 /* Now the year is correct, and n is the offset from January 1. We
333 * find the month via an estimate that's either exact or one too
334 * large.
335 */
336 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
337 assert(leapyear == is_leap(*year));
338 *month = (n + 50) >> 5;
339 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
340 if (preceding > n) {
341 /* estimate is too large */
342 *month -= 1;
343 preceding -= days_in_month(*year, *month);
344 }
345 n -= preceding;
346 assert(0 <= n);
347 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000350}
351
352/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
353static int
354ymd_to_ord(int year, int month, int day)
355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000357}
358
359/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
360static int
361weekday(int year, int month, int day)
362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000364}
365
366/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
367 * first calendar week containing a Thursday.
368 */
369static int
370iso_week1_monday(int year)
371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
373 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
374 int first_weekday = (first_day + 6) % 7;
375 /* ordinal of closest Monday at or before 1/1 */
376 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
379 week1_monday += 7;
380 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000381}
382
383/* ---------------------------------------------------------------------------
384 * Range checkers.
385 */
386
387/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
388 * If not, raise OverflowError and return -1.
389 */
390static int
391check_delta_day_range(int days)
392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
394 return 0;
395 PyErr_Format(PyExc_OverflowError,
396 "days=%d; must have magnitude <= %d",
397 days, MAX_DELTA_DAYS);
398 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000399}
400
401/* Check that date arguments are in range. Return 0 if they are. If they
402 * aren't, raise ValueError and return -1.
403 */
404static int
405check_date_args(int year, int month, int day)
406{
407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 if (year < MINYEAR || year > MAXYEAR) {
409 PyErr_SetString(PyExc_ValueError,
410 "year is out of range");
411 return -1;
412 }
413 if (month < 1 || month > 12) {
414 PyErr_SetString(PyExc_ValueError,
415 "month must be in 1..12");
416 return -1;
417 }
418 if (day < 1 || day > days_in_month(year, month)) {
419 PyErr_SetString(PyExc_ValueError,
420 "day is out of range for month");
421 return -1;
422 }
423 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000424}
425
426/* Check that time arguments are in range. Return 0 if they are. If they
427 * aren't, raise ValueError and return -1.
428 */
429static int
430check_time_args(int h, int m, int s, int us)
431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 if (h < 0 || h > 23) {
433 PyErr_SetString(PyExc_ValueError,
434 "hour must be in 0..23");
435 return -1;
436 }
437 if (m < 0 || m > 59) {
438 PyErr_SetString(PyExc_ValueError,
439 "minute must be in 0..59");
440 return -1;
441 }
442 if (s < 0 || s > 59) {
443 PyErr_SetString(PyExc_ValueError,
444 "second must be in 0..59");
445 return -1;
446 }
447 if (us < 0 || us > 999999) {
448 PyErr_SetString(PyExc_ValueError,
449 "microsecond must be in 0..999999");
450 return -1;
451 }
452 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000453}
454
455/* ---------------------------------------------------------------------------
456 * Normalization utilities.
457 */
458
459/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
460 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
461 * at least factor, enough of *lo is converted into "hi" units so that
462 * 0 <= *lo < factor. The input values must be such that int overflow
463 * is impossible.
464 */
465static void
466normalize_pair(int *hi, int *lo, int factor)
467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 assert(factor > 0);
469 assert(lo != hi);
470 if (*lo < 0 || *lo >= factor) {
471 const int num_hi = divmod(*lo, factor, lo);
472 const int new_hi = *hi + num_hi;
473 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
474 *hi = new_hi;
475 }
476 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000477}
478
479/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 * 0 <= *s < 24*3600
481 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000482 * The input values must be such that the internals don't overflow.
483 * The way this routine is used, we don't get close.
484 */
485static void
486normalize_d_s_us(int *d, int *s, int *us)
487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 if (*us < 0 || *us >= 1000000) {
489 normalize_pair(s, us, 1000000);
490 /* |s| can't be bigger than about
491 * |original s| + |original us|/1000000 now.
492 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 }
495 if (*s < 0 || *s >= 24*3600) {
496 normalize_pair(d, s, 24*3600);
497 /* |d| can't be bigger than about
498 * |original d| +
499 * (|original s| + |original us|/1000000) / (24*3600) now.
500 */
501 }
502 assert(0 <= *s && *s < 24*3600);
503 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000504}
505
506/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 * 1 <= *m <= 12
508 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000509 * The input values must be such that the internals don't overflow.
510 * The way this routine is used, we don't get close.
511 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000512static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000513normalize_y_m_d(int *y, int *m, int *d)
514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000516
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000517 /* In actual use, m is always the month component extracted from a
518 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 /* Now only day can be out of bounds (year may also be out of bounds
524 * for a datetime object, but we don't care about that here).
525 * If day is out of bounds, what to do is arguable, but at least the
526 * method here is principled and explainable.
527 */
528 dim = days_in_month(*y, *m);
529 if (*d < 1 || *d > dim) {
530 /* Move day-1 days from the first of the month. First try to
531 * get off cheap if we're only one day out of range
532 * (adjustments for timezone alone can't be worse than that).
533 */
534 if (*d == 0) {
535 --*m;
536 if (*m > 0)
537 *d = days_in_month(*y, *m);
538 else {
539 --*y;
540 *m = 12;
541 *d = 31;
542 }
543 }
544 else if (*d == dim + 1) {
545 /* move forward a day */
546 ++*m;
547 *d = 1;
548 if (*m > 12) {
549 *m = 1;
550 ++*y;
551 }
552 }
553 else {
554 int ordinal = ymd_to_ord(*y, *m, 1) +
555 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000556 if (ordinal < 1 || ordinal > MAXORDINAL) {
557 goto error;
558 } else {
559 ord_to_ymd(ordinal, y, m, d);
560 return 0;
561 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 }
563 }
564 assert(*m > 0);
565 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000566 if (MINYEAR <= *y && *y <= MAXYEAR)
567 return 0;
568 error:
569 PyErr_SetString(PyExc_OverflowError,
570 "date value out of range");
571 return -1;
572
Tim Peters2a799bf2002-12-16 20:18:38 +0000573}
574
575/* Fiddle out-of-bounds months and days so that the result makes some kind
576 * of sense. The parameters are both inputs and outputs. Returns < 0 on
577 * failure, where failure means the adjusted year is out of bounds.
578 */
579static int
580normalize_date(int *year, int *month, int *day)
581{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000582 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000583}
584
585/* Force all the datetime fields into range. The parameters are both
586 * inputs and outputs. Returns < 0 on error.
587 */
588static int
589normalize_datetime(int *year, int *month, int *day,
590 int *hour, int *minute, int *second,
591 int *microsecond)
592{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 normalize_pair(second, microsecond, 1000000);
594 normalize_pair(minute, second, 60);
595 normalize_pair(hour, minute, 60);
596 normalize_pair(day, hour, 24);
597 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000598}
599
600/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000601 * Basic object allocation: tp_alloc implementations. These allocate
602 * Python objects of the right size and type, and do the Python object-
603 * initialization bit. If there's not enough memory, they return NULL after
604 * setting MemoryError. All data members remain uninitialized trash.
605 *
606 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000607 * member is needed. This is ugly, imprecise, and possibly insecure.
608 * tp_basicsize for the time and datetime types is set to the size of the
609 * struct that has room for the tzinfo member, so subclasses in Python will
610 * allocate enough space for a tzinfo member whether or not one is actually
611 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
612 * part is that PyType_GenericAlloc() (which subclasses in Python end up
613 * using) just happens today to effectively ignore the nitems argument
614 * when tp_itemsize is 0, which it is for these type objects. If that
615 * changes, perhaps the callers of tp_alloc slots in this file should
616 * be changed to force a 0 nitems argument unless the type being allocated
617 * is a base type implemented in this file (so that tp_alloc is time_alloc
618 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000619 */
620
621static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000622time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 self = (PyObject *)
627 PyObject_MALLOC(aware ?
628 sizeof(PyDateTime_Time) :
629 sizeof(_PyDateTime_BaseTime));
630 if (self == NULL)
631 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100632 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000634}
635
636static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000637datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 self = (PyObject *)
642 PyObject_MALLOC(aware ?
643 sizeof(PyDateTime_DateTime) :
644 sizeof(_PyDateTime_BaseDateTime));
645 if (self == NULL)
646 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100647 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000649}
650
651/* ---------------------------------------------------------------------------
652 * Helpers for setting object fields. These work on pointers to the
653 * appropriate base class.
654 */
655
656/* For date and datetime. */
657static void
658set_date_fields(PyDateTime_Date *self, int y, int m, int d)
659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 self->hashcode = -1;
661 SET_YEAR(self, y);
662 SET_MONTH(self, m);
663 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000664}
665
666/* ---------------------------------------------------------------------------
667 * Create various objects, mostly without range checking.
668 */
669
670/* Create a date instance with no range checking. */
671static PyObject *
672new_date_ex(int year, int month, int day, PyTypeObject *type)
673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
677 if (self != NULL)
678 set_date_fields(self, year, month, day);
679 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000680}
681
682#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000684
685/* Create a datetime instance with no range checking. */
686static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400687new_datetime_ex2(int year, int month, int day, int hour, int minute,
688 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000689{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 PyDateTime_DateTime *self;
691 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
694 if (self != NULL) {
695 self->hastzinfo = aware;
696 set_date_fields((PyDateTime_Date *)self, year, month, day);
697 DATE_SET_HOUR(self, hour);
698 DATE_SET_MINUTE(self, minute);
699 DATE_SET_SECOND(self, second);
700 DATE_SET_MICROSECOND(self, usecond);
701 if (aware) {
702 Py_INCREF(tzinfo);
703 self->tzinfo = tzinfo;
704 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400705 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 }
707 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000708}
709
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400710static PyObject *
711new_datetime_ex(int year, int month, int day, int hour, int minute,
712 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
713{
714 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
715 tzinfo, 0, type);
716}
717
718#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
719 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000721
722/* Create a time instance with no range checking. */
723static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400724new_time_ex2(int hour, int minute, int second, int usecond,
725 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000726{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 PyDateTime_Time *self;
728 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
731 if (self != NULL) {
732 self->hastzinfo = aware;
733 self->hashcode = -1;
734 TIME_SET_HOUR(self, hour);
735 TIME_SET_MINUTE(self, minute);
736 TIME_SET_SECOND(self, second);
737 TIME_SET_MICROSECOND(self, usecond);
738 if (aware) {
739 Py_INCREF(tzinfo);
740 self->tzinfo = tzinfo;
741 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400742 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 }
744 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000745}
746
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400747static PyObject *
748new_time_ex(int hour, int minute, int second, int usecond,
749 PyObject *tzinfo, PyTypeObject *type)
750{
751 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
752}
753
754#define new_time(hh, mm, ss, us, tzinfo, fold) \
755 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000756
757/* Create a timedelta instance. Normalize the members iff normalize is
758 * true. Passing false is a speed optimization, if you know for sure
759 * that seconds and microseconds are already in their proper ranges. In any
760 * case, raises OverflowError and returns NULL if the normalized days is out
761 * of range).
762 */
763static PyObject *
764new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000767 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 if (normalize)
770 normalize_d_s_us(&days, &seconds, &microseconds);
771 assert(0 <= seconds && seconds < 24*3600);
772 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000774 if (check_delta_day_range(days) < 0)
775 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
778 if (self != NULL) {
779 self->hashcode = -1;
780 SET_TD_DAYS(self, days);
781 SET_TD_SECONDS(self, seconds);
782 SET_TD_MICROSECONDS(self, microseconds);
783 }
784 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000785}
786
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787#define new_delta(d, s, us, normalize) \
788 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000789
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000790
791typedef struct
792{
793 PyObject_HEAD
794 PyObject *offset;
795 PyObject *name;
796} PyDateTime_TimeZone;
797
Victor Stinner6ced7c42011-03-21 18:15:42 +0100798/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000799static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -0400800/* The interned Epoch datetime instance */
801static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000802
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000803/* Create new timezone instance checking offset range. This
804 function does not check the name argument. Caller must assure
805 that offset is a timedelta instance and name is either NULL
806 or a unicode object. */
807static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000808create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000809{
810 PyDateTime_TimeZone *self;
811 PyTypeObject *type = &PyDateTime_TimeZoneType;
812
813 assert(offset != NULL);
814 assert(PyDelta_Check(offset));
815 assert(name == NULL || PyUnicode_Check(name));
816
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000817 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
818 if (self == NULL) {
819 return NULL;
820 }
821 Py_INCREF(offset);
822 self->offset = offset;
823 Py_XINCREF(name);
824 self->name = name;
825 return (PyObject *)self;
826}
827
828static int delta_bool(PyDateTime_Delta *self);
829
830static PyObject *
831new_timezone(PyObject *offset, PyObject *name)
832{
833 assert(offset != NULL);
834 assert(PyDelta_Check(offset));
835 assert(name == NULL || PyUnicode_Check(name));
836
837 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
838 Py_INCREF(PyDateTime_TimeZone_UTC);
839 return PyDateTime_TimeZone_UTC;
840 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000841 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
842 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400843 " representing a whole number of minutes,"
844 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000845 return NULL;
846 }
847 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
848 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
849 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
850 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400851 " timedelta(hours=24),"
852 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000853 return NULL;
854 }
855
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000856 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000857}
858
Tim Petersb0c854d2003-05-17 15:57:00 +0000859/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000860 * tzinfo helpers.
861 */
862
Tim Peters855fe882002-12-22 03:43:39 +0000863/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
864 * raise TypeError and return -1.
865 */
866static int
867check_tzinfo_subclass(PyObject *p)
868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 if (p == Py_None || PyTZInfo_Check(p))
870 return 0;
871 PyErr_Format(PyExc_TypeError,
872 "tzinfo argument must be None or of a tzinfo subclass, "
873 "not type '%s'",
874 Py_TYPE(p)->tp_name);
875 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000876}
877
Tim Peters2a799bf2002-12-16 20:18:38 +0000878/* If self has a tzinfo member, return a BORROWED reference to it. Else
879 * return NULL, which is NOT AN ERROR. There are no error returns here,
880 * and the caller must not decref the result.
881 */
882static PyObject *
883get_tzinfo_member(PyObject *self)
884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000885 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000887 if (PyDateTime_Check(self) && HASTZINFO(self))
888 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
889 else if (PyTime_Check(self) && HASTZINFO(self))
890 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000891
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000893}
894
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000895/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
896 * be an instance of the tzinfo class. If the method returns None, this
897 * returns None. If the method doesn't return None or timedelta, TypeError is
898 * raised and this returns NULL. If it returns a timedelta and the value is
899 * out of range or isn't a whole number of minutes, ValueError is raised and
900 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000901 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000902static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200903call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000904{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000905 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000908 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000909 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000910
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000911 if (tzinfo == Py_None)
912 Py_RETURN_NONE;
913 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
914 if (offset == Py_None || offset == NULL)
915 return offset;
916 if (PyDelta_Check(offset)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400917 if (GET_TD_MICROSECONDS(offset) != 0) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000918 Py_DECREF(offset);
919 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400920 " representing a whole number of seconds");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000921 return NULL;
922 }
923 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
924 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
925 Py_DECREF(offset);
926 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
927 " strictly between -timedelta(hours=24) and"
928 " timedelta(hours=24).");
929 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 }
931 }
932 else {
933 PyErr_Format(PyExc_TypeError,
934 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000935 "timedelta, not '%.200s'",
936 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -0700937 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000938 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000940
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000941 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000942}
943
944/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
945 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
946 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000947 * doesn't return None or timedelta, TypeError is raised and this returns -1.
948 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
949 * # of minutes), ValueError is raised and this returns -1. Else *none is
950 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000951 */
Tim Peters855fe882002-12-22 03:43:39 +0000952static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000953call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
954{
955 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000956}
957
Tim Peters2a799bf2002-12-16 20:18:38 +0000958/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
959 * result. tzinfo must be an instance of the tzinfo class. If dst()
960 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000961 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000962 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000963 * ValueError is raised and this returns -1. Else *none is set to 0 and
964 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000965 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000966static PyObject *
967call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000968{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000969 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000970}
971
Tim Petersbad8ff02002-12-30 20:52:32 +0000972/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000973 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000974 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000975 * returns NULL. If the result is a string, we ensure it is a Unicode
976 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000977 */
978static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000979call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200982 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 assert(tzinfo != NULL);
985 assert(check_tzinfo_subclass(tzinfo) >= 0);
986 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000989 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000990
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200991 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000992
993 if (result == NULL || result == Py_None)
994 return result;
995
996 if (!PyUnicode_Check(result)) {
997 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
998 "return None or a string, not '%s'",
999 Py_TYPE(result)->tp_name);
1000 Py_DECREF(result);
1001 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001003
1004 return result;
Tim Peters00237032002-12-27 02:21:51 +00001005}
1006
Tim Peters2a799bf2002-12-16 20:18:38 +00001007/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1008 * stuff
1009 * ", tzinfo=" + repr(tzinfo)
1010 * before the closing ")".
1011 */
1012static PyObject *
1013append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1014{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 assert(PyUnicode_Check(repr));
1018 assert(tzinfo);
1019 if (tzinfo == Py_None)
1020 return repr;
1021 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001022 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1023 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 Py_DECREF(repr);
1025 if (temp == NULL)
1026 return NULL;
1027 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1028 Py_DECREF(temp);
1029 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001030}
1031
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001032/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1033 * stuff
1034 * ", fold=" + repr(tzinfo)
1035 * before the closing ")".
1036 */
1037static PyObject *
1038append_keyword_fold(PyObject *repr, int fold)
1039{
1040 PyObject *temp;
1041
1042 assert(PyUnicode_Check(repr));
1043 if (fold == 0)
1044 return repr;
1045 /* Get rid of the trailing ')'. */
1046 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1047 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1048 Py_DECREF(repr);
1049 if (temp == NULL)
1050 return NULL;
1051 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1052 Py_DECREF(temp);
1053 return repr;
1054}
1055
Tim Peters2a799bf2002-12-16 20:18:38 +00001056/* ---------------------------------------------------------------------------
1057 * String format helpers.
1058 */
1059
1060static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001061format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001062{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001063 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1065 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001066 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1068 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1069 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1074 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1075 GET_DAY(date), hours, minutes, seconds,
1076 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001077}
1078
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001079static PyObject *delta_negative(PyDateTime_Delta *self);
1080
Tim Peters2a799bf2002-12-16 20:18:38 +00001081/* Add an hours & minutes UTC offset string to buf. buf has no more than
1082 * buflen bytes remaining. The UTC offset is gotten by calling
1083 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1084 * *buf, and that's all. Else the returned value is checked for sanity (an
1085 * integer in range), and if that's OK it's converted to an hours & minutes
1086 * string of the form
1087 * sign HH sep MM
1088 * Returns 0 if everything is OK. If the return value from utcoffset() is
1089 * bogus, an appropriate exception is set and -1 is returned.
1090 */
1091static int
Tim Peters328fff72002-12-20 01:31:27 +00001092format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001094{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001095 PyObject *offset;
1096 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001100
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001101 offset = call_utcoffset(tzinfo, tzinfoarg);
1102 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001104 if (offset == Py_None) {
1105 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 *buf = '\0';
1107 return 0;
1108 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001109 /* Offset is normalized, so it is negative if days < 0 */
1110 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001112 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001113 if (offset == NULL)
1114 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001116 else {
1117 sign = '+';
1118 }
1119 /* Offset is not negative here. */
1120 seconds = GET_TD_SECONDS(offset);
1121 Py_DECREF(offset);
1122 minutes = divmod(seconds, 60, &seconds);
1123 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001124 if (seconds == 0)
1125 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1126 else
1127 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1128 sep, minutes, sep, seconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001130}
1131
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001132static PyObject *
1133make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 PyObject *temp;
1136 PyObject *tzinfo = get_tzinfo_member(object);
1137 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001138 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 if (Zreplacement == NULL)
1141 return NULL;
1142 if (tzinfo == Py_None || tzinfo == NULL)
1143 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 assert(tzinfoarg != NULL);
1146 temp = call_tzname(tzinfo, tzinfoarg);
1147 if (temp == NULL)
1148 goto Error;
1149 if (temp == Py_None) {
1150 Py_DECREF(temp);
1151 return Zreplacement;
1152 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 assert(PyUnicode_Check(temp));
1155 /* Since the tzname is getting stuffed into the
1156 * format, we have to double any % signs so that
1157 * strftime doesn't treat them as format codes.
1158 */
1159 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001160 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 Py_DECREF(temp);
1162 if (Zreplacement == NULL)
1163 return NULL;
1164 if (!PyUnicode_Check(Zreplacement)) {
1165 PyErr_SetString(PyExc_TypeError,
1166 "tzname.replace() did not return a string");
1167 goto Error;
1168 }
1169 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001170
1171 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 Py_DECREF(Zreplacement);
1173 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001174}
1175
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001176static PyObject *
1177make_freplacement(PyObject *object)
1178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 char freplacement[64];
1180 if (PyTime_Check(object))
1181 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1182 else if (PyDateTime_Check(object))
1183 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1184 else
1185 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001188}
1189
Tim Peters2a799bf2002-12-16 20:18:38 +00001190/* I sure don't want to reproduce the strftime code from the time module,
1191 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001192 * giving special meanings to the %z, %Z and %f format codes via a
1193 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001194 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1195 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001196 */
1197static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001198wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1204 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1205 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 const char *pin; /* pointer to next char in input format */
1208 Py_ssize_t flen; /* length of input format */
1209 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 PyObject *newfmt = NULL; /* py string, the output format */
1212 char *pnew; /* pointer to available byte in output format */
1213 size_t totalnew; /* number bytes total in output format buffer,
1214 exclusive of trailing \0 */
1215 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 const char *ptoappend; /* ptr to string to append to output buffer */
1218 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 assert(object && format && timetuple);
1221 assert(PyUnicode_Check(format));
1222 /* Convert the input format to a C string and size */
1223 pin = _PyUnicode_AsStringAndSize(format, &flen);
1224 if (!pin)
1225 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 /* Scan the input format, looking for %z/%Z/%f escapes, building
1228 * a new format. Since computing the replacements for those codes
1229 * is expensive, don't unless they're actually used.
1230 */
1231 if (flen > INT_MAX - 1) {
1232 PyErr_NoMemory();
1233 goto Done;
1234 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 totalnew = flen + 1; /* realistic if no %z/%Z */
1237 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1238 if (newfmt == NULL) goto Done;
1239 pnew = PyBytes_AsString(newfmt);
1240 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 while ((ch = *pin++) != '\0') {
1243 if (ch != '%') {
1244 ptoappend = pin - 1;
1245 ntoappend = 1;
1246 }
1247 else if ((ch = *pin++) == '\0') {
1248 /* There's a lone trailing %; doesn't make sense. */
1249 PyErr_SetString(PyExc_ValueError, "strftime format "
1250 "ends with raw %");
1251 goto Done;
1252 }
1253 /* A % has been seen and ch is the character after it. */
1254 else if (ch == 'z') {
1255 if (zreplacement == NULL) {
1256 /* format utcoffset */
1257 char buf[100];
1258 PyObject *tzinfo = get_tzinfo_member(object);
1259 zreplacement = PyBytes_FromStringAndSize("", 0);
1260 if (zreplacement == NULL) goto Done;
1261 if (tzinfo != Py_None && tzinfo != NULL) {
1262 assert(tzinfoarg != NULL);
1263 if (format_utcoffset(buf,
1264 sizeof(buf),
1265 "",
1266 tzinfo,
1267 tzinfoarg) < 0)
1268 goto Done;
1269 Py_DECREF(zreplacement);
1270 zreplacement =
1271 PyBytes_FromStringAndSize(buf,
1272 strlen(buf));
1273 if (zreplacement == NULL)
1274 goto Done;
1275 }
1276 }
1277 assert(zreplacement != NULL);
1278 ptoappend = PyBytes_AS_STRING(zreplacement);
1279 ntoappend = PyBytes_GET_SIZE(zreplacement);
1280 }
1281 else if (ch == 'Z') {
1282 /* format tzname */
1283 if (Zreplacement == NULL) {
1284 Zreplacement = make_Zreplacement(object,
1285 tzinfoarg);
1286 if (Zreplacement == NULL)
1287 goto Done;
1288 }
1289 assert(Zreplacement != NULL);
1290 assert(PyUnicode_Check(Zreplacement));
1291 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1292 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001293 if (ptoappend == NULL)
1294 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 }
1296 else if (ch == 'f') {
1297 /* format microseconds */
1298 if (freplacement == NULL) {
1299 freplacement = make_freplacement(object);
1300 if (freplacement == NULL)
1301 goto Done;
1302 }
1303 assert(freplacement != NULL);
1304 assert(PyBytes_Check(freplacement));
1305 ptoappend = PyBytes_AS_STRING(freplacement);
1306 ntoappend = PyBytes_GET_SIZE(freplacement);
1307 }
1308 else {
1309 /* percent followed by neither z nor Z */
1310 ptoappend = pin - 2;
1311 ntoappend = 2;
1312 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 /* Append the ntoappend chars starting at ptoappend to
1315 * the new format.
1316 */
1317 if (ntoappend == 0)
1318 continue;
1319 assert(ptoappend != NULL);
1320 assert(ntoappend > 0);
1321 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001322 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 PyErr_NoMemory();
1324 goto Done;
1325 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001326 totalnew <<= 1;
1327 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 pnew = PyBytes_AsString(newfmt) + usednew;
1330 }
1331 memcpy(pnew, ptoappend, ntoappend);
1332 pnew += ntoappend;
1333 usednew += ntoappend;
1334 assert(usednew <= totalnew);
1335 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1338 goto Done;
1339 {
1340 PyObject *format;
1341 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 if (time == NULL)
1344 goto Done;
1345 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1346 if (format != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001347 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1348 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 Py_DECREF(format);
1350 }
1351 Py_DECREF(time);
1352 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001353 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 Py_XDECREF(freplacement);
1355 Py_XDECREF(zreplacement);
1356 Py_XDECREF(Zreplacement);
1357 Py_XDECREF(newfmt);
1358 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001359}
1360
Tim Peters2a799bf2002-12-16 20:18:38 +00001361/* ---------------------------------------------------------------------------
1362 * Wrap functions from the time module. These aren't directly available
1363 * from C. Perhaps they should be.
1364 */
1365
1366/* Call time.time() and return its result (a Python float). */
1367static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001368time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 PyObject *result = NULL;
1371 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001374 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001375
1376 result = _PyObject_CallMethodId(time, &PyId_time, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 Py_DECREF(time);
1378 }
1379 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001380}
1381
1382/* Build a time.struct_time. The weekday and day number are automatically
1383 * computed from the y,m,d args.
1384 */
1385static PyObject *
1386build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 PyObject *time;
1389 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 time = PyImport_ImportModuleNoBlock("time");
1392 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001393 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001394
1395 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1396 "((iiiiiiiii))",
1397 y, m, d,
1398 hh, mm, ss,
1399 weekday(y, m, d),
1400 days_before_month(y, m) + d,
1401 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 Py_DECREF(time);
1403 }
1404 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001405}
1406
1407/* ---------------------------------------------------------------------------
1408 * Miscellaneous helpers.
1409 */
1410
Mark Dickinsone94c6792009-02-02 20:36:42 +00001411/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001412 * The comparisons here all most naturally compute a cmp()-like result.
1413 * This little helper turns that into a bool result for rich comparisons.
1414 */
1415static PyObject *
1416diff_to_bool(int diff, int op)
1417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 PyObject *result;
1419 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 switch (op) {
1422 case Py_EQ: istrue = diff == 0; break;
1423 case Py_NE: istrue = diff != 0; break;
1424 case Py_LE: istrue = diff <= 0; break;
1425 case Py_GE: istrue = diff >= 0; break;
1426 case Py_LT: istrue = diff < 0; break;
1427 case Py_GT: istrue = diff > 0; break;
1428 default:
1429 assert(! "op unknown");
1430 istrue = 0; /* To shut up compiler */
1431 }
1432 result = istrue ? Py_True : Py_False;
1433 Py_INCREF(result);
1434 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001435}
1436
Tim Peters07534a62003-02-07 22:50:28 +00001437/* Raises a "can't compare" TypeError and returns NULL. */
1438static PyObject *
1439cmperror(PyObject *a, PyObject *b)
1440{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 PyErr_Format(PyExc_TypeError,
1442 "can't compare %s to %s",
1443 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1444 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001445}
1446
Tim Peters2a799bf2002-12-16 20:18:38 +00001447/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001448 * Cached Python objects; these are set by the module init function.
1449 */
1450
1451/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001452static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453static PyObject *us_per_ms = NULL; /* 1000 */
1454static PyObject *us_per_second = NULL; /* 1000000 */
1455static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001456static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1457static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1458static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001459static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1460
Tim Peters2a799bf2002-12-16 20:18:38 +00001461/* ---------------------------------------------------------------------------
1462 * Class implementations.
1463 */
1464
1465/*
1466 * PyDateTime_Delta implementation.
1467 */
1468
1469/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001471 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001472 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1473 * due to ubiquitous overflow possibilities.
1474 */
1475static PyObject *
1476delta_to_microseconds(PyDateTime_Delta *self)
1477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 PyObject *x1 = NULL;
1479 PyObject *x2 = NULL;
1480 PyObject *x3 = NULL;
1481 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1484 if (x1 == NULL)
1485 goto Done;
1486 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1487 if (x2 == NULL)
1488 goto Done;
1489 Py_DECREF(x1);
1490 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 /* x2 has days in seconds */
1493 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1494 if (x1 == NULL)
1495 goto Done;
1496 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1497 if (x3 == NULL)
1498 goto Done;
1499 Py_DECREF(x1);
1500 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001501 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 /* x3 has days+seconds in seconds */
1504 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1505 if (x1 == NULL)
1506 goto Done;
1507 Py_DECREF(x3);
1508 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 /* x1 has days+seconds in us */
1511 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1512 if (x2 == NULL)
1513 goto Done;
1514 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001515
1516Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 Py_XDECREF(x1);
1518 Py_XDECREF(x2);
1519 Py_XDECREF(x3);
1520 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001521}
1522
Serhiy Storchaka95949422013-08-27 19:40:23 +03001523/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001524 */
1525static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001526microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 int us;
1529 int s;
1530 int d;
1531 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 PyObject *tuple = NULL;
1534 PyObject *num = NULL;
1535 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 tuple = PyNumber_Divmod(pyus, us_per_second);
1538 if (tuple == NULL)
1539 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 num = PyTuple_GetItem(tuple, 1); /* us */
1542 if (num == NULL)
1543 goto Done;
1544 temp = PyLong_AsLong(num);
1545 num = NULL;
1546 if (temp == -1 && PyErr_Occurred())
1547 goto Done;
1548 assert(0 <= temp && temp < 1000000);
1549 us = (int)temp;
1550 if (us < 0) {
1551 /* The divisor was positive, so this must be an error. */
1552 assert(PyErr_Occurred());
1553 goto Done;
1554 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1557 if (num == NULL)
1558 goto Done;
1559 Py_INCREF(num);
1560 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 tuple = PyNumber_Divmod(num, seconds_per_day);
1563 if (tuple == NULL)
1564 goto Done;
1565 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 num = PyTuple_GetItem(tuple, 1); /* seconds */
1568 if (num == NULL)
1569 goto Done;
1570 temp = PyLong_AsLong(num);
1571 num = NULL;
1572 if (temp == -1 && PyErr_Occurred())
1573 goto Done;
1574 assert(0 <= temp && temp < 24*3600);
1575 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 if (s < 0) {
1578 /* The divisor was positive, so this must be an error. */
1579 assert(PyErr_Occurred());
1580 goto Done;
1581 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1584 if (num == NULL)
1585 goto Done;
1586 Py_INCREF(num);
1587 temp = PyLong_AsLong(num);
1588 if (temp == -1 && PyErr_Occurred())
1589 goto Done;
1590 d = (int)temp;
1591 if ((long)d != temp) {
1592 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1593 "large to fit in a C int");
1594 goto Done;
1595 }
1596 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001597
1598Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 Py_XDECREF(tuple);
1600 Py_XDECREF(num);
1601 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001602}
1603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604#define microseconds_to_delta(pymicros) \
1605 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001606
Tim Peters2a799bf2002-12-16 20:18:38 +00001607static PyObject *
1608multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
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_Multiply(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 *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001629multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1630{
1631 PyObject *result = NULL;
1632 PyObject *pyus_in = NULL, *temp, *pyus_out;
1633 PyObject *ratio = NULL;
1634
1635 pyus_in = delta_to_microseconds(delta);
1636 if (pyus_in == NULL)
1637 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001638 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001639 if (ratio == NULL)
1640 goto error;
1641 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1642 Py_DECREF(pyus_in);
1643 pyus_in = NULL;
1644 if (temp == NULL)
1645 goto error;
1646 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1647 Py_DECREF(temp);
1648 if (pyus_out == NULL)
1649 goto error;
1650 result = microseconds_to_delta(pyus_out);
1651 Py_DECREF(pyus_out);
1652 error:
1653 Py_XDECREF(pyus_in);
1654 Py_XDECREF(ratio);
1655
1656 return result;
1657}
1658
1659static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001660divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 PyObject *pyus_in;
1663 PyObject *pyus_out;
1664 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 pyus_in = delta_to_microseconds(delta);
1667 if (pyus_in == NULL)
1668 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1671 Py_DECREF(pyus_in);
1672 if (pyus_out == NULL)
1673 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 result = microseconds_to_delta(pyus_out);
1676 Py_DECREF(pyus_out);
1677 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001678}
1679
1680static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001681divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1682{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 PyObject *pyus_left;
1684 PyObject *pyus_right;
1685 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 pyus_left = delta_to_microseconds(left);
1688 if (pyus_left == NULL)
1689 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 pyus_right = delta_to_microseconds(right);
1692 if (pyus_right == NULL) {
1693 Py_DECREF(pyus_left);
1694 return NULL;
1695 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1698 Py_DECREF(pyus_left);
1699 Py_DECREF(pyus_right);
1700 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001701}
1702
1703static PyObject *
1704truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1705{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 PyObject *pyus_left;
1707 PyObject *pyus_right;
1708 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001710 pyus_left = delta_to_microseconds(left);
1711 if (pyus_left == NULL)
1712 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 pyus_right = delta_to_microseconds(right);
1715 if (pyus_right == NULL) {
1716 Py_DECREF(pyus_left);
1717 return NULL;
1718 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1721 Py_DECREF(pyus_left);
1722 Py_DECREF(pyus_right);
1723 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001724}
1725
1726static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001727truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1728{
1729 PyObject *result = NULL;
1730 PyObject *pyus_in = NULL, *temp, *pyus_out;
1731 PyObject *ratio = NULL;
1732
1733 pyus_in = delta_to_microseconds(delta);
1734 if (pyus_in == NULL)
1735 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001736 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001737 if (ratio == NULL)
1738 goto error;
1739 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1740 Py_DECREF(pyus_in);
1741 pyus_in = NULL;
1742 if (temp == NULL)
1743 goto error;
1744 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1745 Py_DECREF(temp);
1746 if (pyus_out == NULL)
1747 goto error;
1748 result = microseconds_to_delta(pyus_out);
1749 Py_DECREF(pyus_out);
1750 error:
1751 Py_XDECREF(pyus_in);
1752 Py_XDECREF(ratio);
1753
1754 return result;
1755}
1756
1757static PyObject *
1758truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1759{
1760 PyObject *result;
1761 PyObject *pyus_in, *pyus_out;
1762 pyus_in = delta_to_microseconds(delta);
1763 if (pyus_in == NULL)
1764 return NULL;
1765 pyus_out = divide_nearest(pyus_in, i);
1766 Py_DECREF(pyus_in);
1767 if (pyus_out == NULL)
1768 return NULL;
1769 result = microseconds_to_delta(pyus_out);
1770 Py_DECREF(pyus_out);
1771
1772 return result;
1773}
1774
1775static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001776delta_add(PyObject *left, PyObject *right)
1777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1781 /* delta + delta */
1782 /* The C-level additions can't overflow because of the
1783 * invariant bounds.
1784 */
1785 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1786 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1787 int microseconds = GET_TD_MICROSECONDS(left) +
1788 GET_TD_MICROSECONDS(right);
1789 result = new_delta(days, seconds, microseconds, 1);
1790 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 if (result == Py_NotImplemented)
1793 Py_INCREF(result);
1794 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001795}
1796
1797static PyObject *
1798delta_negative(PyDateTime_Delta *self)
1799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 return new_delta(-GET_TD_DAYS(self),
1801 -GET_TD_SECONDS(self),
1802 -GET_TD_MICROSECONDS(self),
1803 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001804}
1805
1806static PyObject *
1807delta_positive(PyDateTime_Delta *self)
1808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 /* Could optimize this (by returning self) if this isn't a
1810 * subclass -- but who uses unary + ? Approximately nobody.
1811 */
1812 return new_delta(GET_TD_DAYS(self),
1813 GET_TD_SECONDS(self),
1814 GET_TD_MICROSECONDS(self),
1815 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001816}
1817
1818static PyObject *
1819delta_abs(PyDateTime_Delta *self)
1820{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001822
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 assert(GET_TD_MICROSECONDS(self) >= 0);
1824 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001826 if (GET_TD_DAYS(self) < 0)
1827 result = delta_negative(self);
1828 else
1829 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001832}
1833
1834static PyObject *
1835delta_subtract(PyObject *left, PyObject *right)
1836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1840 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001841 /* The C-level additions can't overflow because of the
1842 * invariant bounds.
1843 */
1844 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1845 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1846 int microseconds = GET_TD_MICROSECONDS(left) -
1847 GET_TD_MICROSECONDS(right);
1848 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 if (result == Py_NotImplemented)
1852 Py_INCREF(result);
1853 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001854}
1855
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001856static int
1857delta_cmp(PyObject *self, PyObject *other)
1858{
1859 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1860 if (diff == 0) {
1861 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1862 if (diff == 0)
1863 diff = GET_TD_MICROSECONDS(self) -
1864 GET_TD_MICROSECONDS(other);
1865 }
1866 return diff;
1867}
1868
Tim Peters2a799bf2002-12-16 20:18:38 +00001869static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001870delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001871{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001873 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 return diff_to_bool(diff, op);
1875 }
1876 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001877 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001879}
1880
1881static PyObject *delta_getstate(PyDateTime_Delta *self);
1882
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001883static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001884delta_hash(PyDateTime_Delta *self)
1885{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (self->hashcode == -1) {
1887 PyObject *temp = delta_getstate(self);
1888 if (temp != NULL) {
1889 self->hashcode = PyObject_Hash(temp);
1890 Py_DECREF(temp);
1891 }
1892 }
1893 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001894}
1895
1896static PyObject *
1897delta_multiply(PyObject *left, PyObject *right)
1898{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 if (PyDelta_Check(left)) {
1902 /* delta * ??? */
1903 if (PyLong_Check(right))
1904 result = multiply_int_timedelta(right,
1905 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001906 else if (PyFloat_Check(right))
1907 result = multiply_float_timedelta(right,
1908 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 }
1910 else if (PyLong_Check(left))
1911 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001912 (PyDateTime_Delta *) right);
1913 else if (PyFloat_Check(left))
1914 result = multiply_float_timedelta(left,
1915 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 if (result == Py_NotImplemented)
1918 Py_INCREF(result);
1919 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001920}
1921
1922static PyObject *
1923delta_divide(PyObject *left, PyObject *right)
1924{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 if (PyDelta_Check(left)) {
1928 /* delta * ??? */
1929 if (PyLong_Check(right))
1930 result = divide_timedelta_int(
1931 (PyDateTime_Delta *)left,
1932 right);
1933 else if (PyDelta_Check(right))
1934 result = divide_timedelta_timedelta(
1935 (PyDateTime_Delta *)left,
1936 (PyDateTime_Delta *)right);
1937 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 if (result == Py_NotImplemented)
1940 Py_INCREF(result);
1941 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001942}
1943
Mark Dickinson7c186e22010-04-20 22:32:49 +00001944static PyObject *
1945delta_truedivide(PyObject *left, PyObject *right)
1946{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 if (PyDelta_Check(left)) {
1950 if (PyDelta_Check(right))
1951 result = truedivide_timedelta_timedelta(
1952 (PyDateTime_Delta *)left,
1953 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001954 else if (PyFloat_Check(right))
1955 result = truedivide_timedelta_float(
1956 (PyDateTime_Delta *)left, right);
1957 else if (PyLong_Check(right))
1958 result = truedivide_timedelta_int(
1959 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 if (result == Py_NotImplemented)
1963 Py_INCREF(result);
1964 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001965}
1966
1967static PyObject *
1968delta_remainder(PyObject *left, PyObject *right)
1969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 PyObject *pyus_left;
1971 PyObject *pyus_right;
1972 PyObject *pyus_remainder;
1973 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001974
Brian Curtindfc80e32011-08-10 20:28:54 -05001975 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1976 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1979 if (pyus_left == NULL)
1980 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1983 if (pyus_right == NULL) {
1984 Py_DECREF(pyus_left);
1985 return NULL;
1986 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1989 Py_DECREF(pyus_left);
1990 Py_DECREF(pyus_right);
1991 if (pyus_remainder == NULL)
1992 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 remainder = microseconds_to_delta(pyus_remainder);
1995 Py_DECREF(pyus_remainder);
1996 if (remainder == NULL)
1997 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002000}
2001
2002static PyObject *
2003delta_divmod(PyObject *left, PyObject *right)
2004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 PyObject *pyus_left;
2006 PyObject *pyus_right;
2007 PyObject *divmod;
2008 PyObject *delta;
2009 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002010
Brian Curtindfc80e32011-08-10 20:28:54 -05002011 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2012 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2015 if (pyus_left == NULL)
2016 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2019 if (pyus_right == NULL) {
2020 Py_DECREF(pyus_left);
2021 return NULL;
2022 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2025 Py_DECREF(pyus_left);
2026 Py_DECREF(pyus_right);
2027 if (divmod == NULL)
2028 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 assert(PyTuple_Size(divmod) == 2);
2031 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2032 if (delta == NULL) {
2033 Py_DECREF(divmod);
2034 return NULL;
2035 }
2036 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2037 Py_DECREF(delta);
2038 Py_DECREF(divmod);
2039 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002040}
2041
Tim Peters2a799bf2002-12-16 20:18:38 +00002042/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2043 * timedelta constructor. sofar is the # of microseconds accounted for
2044 * so far, and there are factor microseconds per current unit, the number
2045 * of which is given by num. num * factor is added to sofar in a
2046 * numerically careful way, and that's the result. Any fractional
2047 * microseconds left over (this can happen if num is a float type) are
2048 * added into *leftover.
2049 * Note that there are many ways this can give an error (NULL) return.
2050 */
2051static PyObject *
2052accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2053 double *leftover)
2054{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002055 PyObject *prod;
2056 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002060 if (PyLong_Check(num)) {
2061 prod = PyNumber_Multiply(num, factor);
2062 if (prod == NULL)
2063 return NULL;
2064 sum = PyNumber_Add(sofar, prod);
2065 Py_DECREF(prod);
2066 return sum;
2067 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 if (PyFloat_Check(num)) {
2070 double dnum;
2071 double fracpart;
2072 double intpart;
2073 PyObject *x;
2074 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 /* The Plan: decompose num into an integer part and a
2077 * fractional part, num = intpart + fracpart.
2078 * Then num * factor ==
2079 * intpart * factor + fracpart * factor
2080 * and the LHS can be computed exactly in long arithmetic.
2081 * The RHS is again broken into an int part and frac part.
2082 * and the frac part is added into *leftover.
2083 */
2084 dnum = PyFloat_AsDouble(num);
2085 if (dnum == -1.0 && PyErr_Occurred())
2086 return NULL;
2087 fracpart = modf(dnum, &intpart);
2088 x = PyLong_FromDouble(intpart);
2089 if (x == NULL)
2090 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002092 prod = PyNumber_Multiply(x, factor);
2093 Py_DECREF(x);
2094 if (prod == NULL)
2095 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 sum = PyNumber_Add(sofar, prod);
2098 Py_DECREF(prod);
2099 if (sum == NULL)
2100 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 if (fracpart == 0.0)
2103 return sum;
2104 /* So far we've lost no information. Dealing with the
2105 * fractional part requires float arithmetic, and may
2106 * lose a little info.
2107 */
2108 assert(PyLong_Check(factor));
2109 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 dnum *= fracpart;
2112 fracpart = modf(dnum, &intpart);
2113 x = PyLong_FromDouble(intpart);
2114 if (x == NULL) {
2115 Py_DECREF(sum);
2116 return NULL;
2117 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 y = PyNumber_Add(sum, x);
2120 Py_DECREF(sum);
2121 Py_DECREF(x);
2122 *leftover += fracpart;
2123 return y;
2124 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002126 PyErr_Format(PyExc_TypeError,
2127 "unsupported type for timedelta %s component: %s",
2128 tag, Py_TYPE(num)->tp_name);
2129 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002130}
2131
2132static PyObject *
2133delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 /* Argument objects. */
2138 PyObject *day = NULL;
2139 PyObject *second = NULL;
2140 PyObject *us = NULL;
2141 PyObject *ms = NULL;
2142 PyObject *minute = NULL;
2143 PyObject *hour = NULL;
2144 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 PyObject *x = NULL; /* running sum of microseconds */
2147 PyObject *y = NULL; /* temp sum of microseconds */
2148 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002150 static char *keywords[] = {
2151 "days", "seconds", "microseconds", "milliseconds",
2152 "minutes", "hours", "weeks", NULL
2153 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2156 keywords,
2157 &day, &second, &us,
2158 &ms, &minute, &hour, &week) == 0)
2159 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 x = PyLong_FromLong(0);
2162 if (x == NULL)
2163 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165#define CLEANUP \
2166 Py_DECREF(x); \
2167 x = y; \
2168 if (x == NULL) \
2169 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002172 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002173 CLEANUP;
2174 }
2175 if (ms) {
2176 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2177 CLEANUP;
2178 }
2179 if (second) {
2180 y = accum("seconds", x, second, us_per_second, &leftover_us);
2181 CLEANUP;
2182 }
2183 if (minute) {
2184 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2185 CLEANUP;
2186 }
2187 if (hour) {
2188 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2189 CLEANUP;
2190 }
2191 if (day) {
2192 y = accum("days", x, day, us_per_day, &leftover_us);
2193 CLEANUP;
2194 }
2195 if (week) {
2196 y = accum("weeks", x, week, us_per_week, &leftover_us);
2197 CLEANUP;
2198 }
2199 if (leftover_us) {
2200 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002201 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002202 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002203 PyObject *temp;
2204
Victor Stinner69cc4872015-09-08 23:58:54 +02002205 whole_us = round(leftover_us);
2206 if (fabs(whole_us - leftover_us) == 0.5) {
2207 /* We're exactly halfway between two integers. In order
2208 * to do round-half-to-even, we must determine whether x
2209 * is odd. Note that x is odd when it's last bit is 1. The
2210 * code below uses bitwise and operation to check the last
2211 * bit. */
2212 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2213 if (temp == NULL) {
2214 Py_DECREF(x);
2215 goto Done;
2216 }
2217 x_is_odd = PyObject_IsTrue(temp);
2218 Py_DECREF(temp);
2219 if (x_is_odd == -1) {
2220 Py_DECREF(x);
2221 goto Done;
2222 }
2223 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2224 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002225
Victor Stinner36a5a062013-08-28 01:53:39 +02002226 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 if (temp == NULL) {
2229 Py_DECREF(x);
2230 goto Done;
2231 }
2232 y = PyNumber_Add(x, temp);
2233 Py_DECREF(temp);
2234 CLEANUP;
2235 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 self = microseconds_to_delta_ex(x, type);
2238 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002239Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002241
2242#undef CLEANUP
2243}
2244
2245static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002246delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 return (GET_TD_DAYS(self) != 0
2249 || GET_TD_SECONDS(self) != 0
2250 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002251}
2252
2253static PyObject *
2254delta_repr(PyDateTime_Delta *self)
2255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 if (GET_TD_MICROSECONDS(self) != 0)
2257 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2258 Py_TYPE(self)->tp_name,
2259 GET_TD_DAYS(self),
2260 GET_TD_SECONDS(self),
2261 GET_TD_MICROSECONDS(self));
2262 if (GET_TD_SECONDS(self) != 0)
2263 return PyUnicode_FromFormat("%s(%d, %d)",
2264 Py_TYPE(self)->tp_name,
2265 GET_TD_DAYS(self),
2266 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 return PyUnicode_FromFormat("%s(%d)",
2269 Py_TYPE(self)->tp_name,
2270 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002271}
2272
2273static PyObject *
2274delta_str(PyDateTime_Delta *self)
2275{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 int us = GET_TD_MICROSECONDS(self);
2277 int seconds = GET_TD_SECONDS(self);
2278 int minutes = divmod(seconds, 60, &seconds);
2279 int hours = divmod(minutes, 60, &minutes);
2280 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 if (days) {
2283 if (us)
2284 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2285 days, (days == 1 || days == -1) ? "" : "s",
2286 hours, minutes, seconds, us);
2287 else
2288 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2289 days, (days == 1 || days == -1) ? "" : "s",
2290 hours, minutes, seconds);
2291 } else {
2292 if (us)
2293 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2294 hours, minutes, seconds, us);
2295 else
2296 return PyUnicode_FromFormat("%d:%02d:%02d",
2297 hours, minutes, seconds);
2298 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002299
Tim Peters2a799bf2002-12-16 20:18:38 +00002300}
2301
Tim Peters371935f2003-02-01 01:52:50 +00002302/* Pickle support, a simple use of __reduce__. */
2303
Tim Petersb57f8f02003-02-01 02:54:15 +00002304/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002305static PyObject *
2306delta_getstate(PyDateTime_Delta *self)
2307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 return Py_BuildValue("iii", GET_TD_DAYS(self),
2309 GET_TD_SECONDS(self),
2310 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002311}
2312
Tim Peters2a799bf2002-12-16 20:18:38 +00002313static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002314delta_total_seconds(PyObject *self)
2315{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002316 PyObject *total_seconds;
2317 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002319 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2320 if (total_microseconds == NULL)
2321 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002322
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002323 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002326 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002327}
2328
2329static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002330delta_reduce(PyDateTime_Delta* self)
2331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002332 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002333}
2334
2335#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2336
2337static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339 {"days", T_INT, OFFSET(days), READONLY,
2340 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002342 {"seconds", T_INT, OFFSET(seconds), READONLY,
2343 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2346 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2347 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002348};
2349
2350static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2352 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002354 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2355 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002357 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002358};
2359
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002360static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002361PyDoc_STR("Difference between two datetime values.");
2362
2363static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 delta_add, /* nb_add */
2365 delta_subtract, /* nb_subtract */
2366 delta_multiply, /* nb_multiply */
2367 delta_remainder, /* nb_remainder */
2368 delta_divmod, /* nb_divmod */
2369 0, /* nb_power */
2370 (unaryfunc)delta_negative, /* nb_negative */
2371 (unaryfunc)delta_positive, /* nb_positive */
2372 (unaryfunc)delta_abs, /* nb_absolute */
2373 (inquiry)delta_bool, /* nb_bool */
2374 0, /*nb_invert*/
2375 0, /*nb_lshift*/
2376 0, /*nb_rshift*/
2377 0, /*nb_and*/
2378 0, /*nb_xor*/
2379 0, /*nb_or*/
2380 0, /*nb_int*/
2381 0, /*nb_reserved*/
2382 0, /*nb_float*/
2383 0, /*nb_inplace_add*/
2384 0, /*nb_inplace_subtract*/
2385 0, /*nb_inplace_multiply*/
2386 0, /*nb_inplace_remainder*/
2387 0, /*nb_inplace_power*/
2388 0, /*nb_inplace_lshift*/
2389 0, /*nb_inplace_rshift*/
2390 0, /*nb_inplace_and*/
2391 0, /*nb_inplace_xor*/
2392 0, /*nb_inplace_or*/
2393 delta_divide, /* nb_floor_divide */
2394 delta_truedivide, /* nb_true_divide */
2395 0, /* nb_inplace_floor_divide */
2396 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002397};
2398
2399static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 PyVarObject_HEAD_INIT(NULL, 0)
2401 "datetime.timedelta", /* tp_name */
2402 sizeof(PyDateTime_Delta), /* tp_basicsize */
2403 0, /* tp_itemsize */
2404 0, /* tp_dealloc */
2405 0, /* tp_print */
2406 0, /* tp_getattr */
2407 0, /* tp_setattr */
2408 0, /* tp_reserved */
2409 (reprfunc)delta_repr, /* tp_repr */
2410 &delta_as_number, /* tp_as_number */
2411 0, /* tp_as_sequence */
2412 0, /* tp_as_mapping */
2413 (hashfunc)delta_hash, /* tp_hash */
2414 0, /* tp_call */
2415 (reprfunc)delta_str, /* tp_str */
2416 PyObject_GenericGetAttr, /* tp_getattro */
2417 0, /* tp_setattro */
2418 0, /* tp_as_buffer */
2419 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2420 delta_doc, /* tp_doc */
2421 0, /* tp_traverse */
2422 0, /* tp_clear */
2423 delta_richcompare, /* tp_richcompare */
2424 0, /* tp_weaklistoffset */
2425 0, /* tp_iter */
2426 0, /* tp_iternext */
2427 delta_methods, /* tp_methods */
2428 delta_members, /* tp_members */
2429 0, /* tp_getset */
2430 0, /* tp_base */
2431 0, /* tp_dict */
2432 0, /* tp_descr_get */
2433 0, /* tp_descr_set */
2434 0, /* tp_dictoffset */
2435 0, /* tp_init */
2436 0, /* tp_alloc */
2437 delta_new, /* tp_new */
2438 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002439};
2440
2441/*
2442 * PyDateTime_Date implementation.
2443 */
2444
2445/* Accessor properties. */
2446
2447static PyObject *
2448date_year(PyDateTime_Date *self, void *unused)
2449{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002450 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002451}
2452
2453static PyObject *
2454date_month(PyDateTime_Date *self, void *unused)
2455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002456 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002457}
2458
2459static PyObject *
2460date_day(PyDateTime_Date *self, void *unused)
2461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002463}
2464
2465static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 {"year", (getter)date_year},
2467 {"month", (getter)date_month},
2468 {"day", (getter)date_day},
2469 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002470};
2471
2472/* Constructors. */
2473
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002474static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002475
Tim Peters2a799bf2002-12-16 20:18:38 +00002476static PyObject *
2477date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2478{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002479 PyObject *self = NULL;
2480 PyObject *state;
2481 int year;
2482 int month;
2483 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 /* Check for invocation from pickle with __getstate__ state */
2486 if (PyTuple_GET_SIZE(args) == 1 &&
2487 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2488 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2489 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2490 {
2491 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2494 if (me != NULL) {
2495 char *pdata = PyBytes_AS_STRING(state);
2496 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2497 me->hashcode = -1;
2498 }
2499 return (PyObject *)me;
2500 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2503 &year, &month, &day)) {
2504 if (check_date_args(year, month, day) < 0)
2505 return NULL;
2506 self = new_date_ex(year, month, day, type);
2507 }
2508 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002509}
2510
2511/* Return new date from localtime(t). */
2512static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002513date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002515 struct tm *tm;
2516 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002517
Victor Stinnere4a994d2015-03-30 01:10:14 +02002518 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002521 tm = localtime(&t);
Victor Stinner21f58932012-03-14 00:15:40 +01002522 if (tm == NULL) {
2523 /* unconvertible time */
2524#ifdef EINVAL
2525 if (errno == 0)
2526 errno = EINVAL;
2527#endif
2528 PyErr_SetFromErrno(PyExc_OSError);
2529 return NULL;
2530 }
2531
2532 return PyObject_CallFunction(cls, "iii",
2533 tm->tm_year + 1900,
2534 tm->tm_mon + 1,
2535 tm->tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002536}
2537
2538/* Return new date from current time.
2539 * We say this is equivalent to fromtimestamp(time.time()), and the
2540 * only way to be sure of that is to *call* time.time(). That's not
2541 * generally the same as calling C's time.
2542 */
2543static PyObject *
2544date_today(PyObject *cls, PyObject *dummy)
2545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002546 PyObject *time;
2547 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002548 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002550 time = time_time();
2551 if (time == NULL)
2552 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002554 /* Note well: today() is a class method, so this may not call
2555 * date.fromtimestamp. For example, it may call
2556 * datetime.fromtimestamp. That's why we need all the accuracy
2557 * time.time() delivers; if someone were gonzo about optimization,
2558 * date.today() could get away with plain C time().
2559 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002560 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 Py_DECREF(time);
2562 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002563}
2564
2565/* Return new date from given timestamp (Python timestamp -- a double). */
2566static PyObject *
2567date_fromtimestamp(PyObject *cls, PyObject *args)
2568{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002569 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002570 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002571
Victor Stinner5d272cc2012-03-13 13:35:55 +01002572 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2573 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002574 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002575}
2576
2577/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2578 * the ordinal is out of range.
2579 */
2580static PyObject *
2581date_fromordinal(PyObject *cls, PyObject *args)
2582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002583 PyObject *result = NULL;
2584 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2587 int year;
2588 int month;
2589 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002591 if (ordinal < 1)
2592 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2593 ">= 1");
2594 else {
2595 ord_to_ymd(ordinal, &year, &month, &day);
2596 result = PyObject_CallFunction(cls, "iii",
2597 year, month, day);
2598 }
2599 }
2600 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002601}
2602
2603/*
2604 * Date arithmetic.
2605 */
2606
2607/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2608 * instead.
2609 */
2610static PyObject *
2611add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 PyObject *result = NULL;
2614 int year = GET_YEAR(date);
2615 int month = GET_MONTH(date);
2616 int deltadays = GET_TD_DAYS(delta);
2617 /* C-level overflow is impossible because |deltadays| < 1e9. */
2618 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002620 if (normalize_date(&year, &month, &day) >= 0)
2621 result = new_date(year, month, day);
2622 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002623}
2624
2625static PyObject *
2626date_add(PyObject *left, PyObject *right)
2627{
Brian Curtindfc80e32011-08-10 20:28:54 -05002628 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2629 Py_RETURN_NOTIMPLEMENTED;
2630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002631 if (PyDate_Check(left)) {
2632 /* date + ??? */
2633 if (PyDelta_Check(right))
2634 /* date + delta */
2635 return add_date_timedelta((PyDateTime_Date *) left,
2636 (PyDateTime_Delta *) right,
2637 0);
2638 }
2639 else {
2640 /* ??? + date
2641 * 'right' must be one of us, or we wouldn't have been called
2642 */
2643 if (PyDelta_Check(left))
2644 /* delta + date */
2645 return add_date_timedelta((PyDateTime_Date *) right,
2646 (PyDateTime_Delta *) left,
2647 0);
2648 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002649 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002650}
2651
2652static PyObject *
2653date_subtract(PyObject *left, PyObject *right)
2654{
Brian Curtindfc80e32011-08-10 20:28:54 -05002655 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2656 Py_RETURN_NOTIMPLEMENTED;
2657
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 if (PyDate_Check(left)) {
2659 if (PyDate_Check(right)) {
2660 /* date - date */
2661 int left_ord = ymd_to_ord(GET_YEAR(left),
2662 GET_MONTH(left),
2663 GET_DAY(left));
2664 int right_ord = ymd_to_ord(GET_YEAR(right),
2665 GET_MONTH(right),
2666 GET_DAY(right));
2667 return new_delta(left_ord - right_ord, 0, 0, 0);
2668 }
2669 if (PyDelta_Check(right)) {
2670 /* date - delta */
2671 return add_date_timedelta((PyDateTime_Date *) left,
2672 (PyDateTime_Delta *) right,
2673 1);
2674 }
2675 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002676 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002677}
2678
2679
2680/* Various ways to turn a date into a string. */
2681
2682static PyObject *
2683date_repr(PyDateTime_Date *self)
2684{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002685 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2686 Py_TYPE(self)->tp_name,
2687 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002688}
2689
2690static PyObject *
2691date_isoformat(PyDateTime_Date *self)
2692{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002693 return PyUnicode_FromFormat("%04d-%02d-%02d",
2694 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002695}
2696
Tim Peterse2df5ff2003-05-02 18:39:55 +00002697/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002698static PyObject *
2699date_str(PyDateTime_Date *self)
2700{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002701 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002702}
2703
2704
2705static PyObject *
2706date_ctime(PyDateTime_Date *self)
2707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002708 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002709}
2710
2711static PyObject *
2712date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002714 /* This method can be inherited, and needs to call the
2715 * timetuple() method appropriate to self's class.
2716 */
2717 PyObject *result;
2718 PyObject *tuple;
2719 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002720 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002721 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002723 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2724 &format))
2725 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002726
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002727 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002728 if (tuple == NULL)
2729 return NULL;
2730 result = wrap_strftime((PyObject *)self, format, tuple,
2731 (PyObject *)self);
2732 Py_DECREF(tuple);
2733 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002734}
2735
Eric Smith1ba31142007-09-11 18:06:02 +00002736static PyObject *
2737date_format(PyDateTime_Date *self, PyObject *args)
2738{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002739 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002741 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2742 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002743
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002744 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002745 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002746 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002747
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002748 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002749}
2750
Tim Peters2a799bf2002-12-16 20:18:38 +00002751/* ISO methods. */
2752
2753static PyObject *
2754date_isoweekday(PyDateTime_Date *self)
2755{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002756 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002758 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002759}
2760
2761static PyObject *
2762date_isocalendar(PyDateTime_Date *self)
2763{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002764 int year = GET_YEAR(self);
2765 int week1_monday = iso_week1_monday(year);
2766 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2767 int week;
2768 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002770 week = divmod(today - week1_monday, 7, &day);
2771 if (week < 0) {
2772 --year;
2773 week1_monday = iso_week1_monday(year);
2774 week = divmod(today - week1_monday, 7, &day);
2775 }
2776 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2777 ++year;
2778 week = 0;
2779 }
2780 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002781}
2782
2783/* Miscellaneous methods. */
2784
Tim Peters2a799bf2002-12-16 20:18:38 +00002785static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002786date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002788 if (PyDate_Check(other)) {
2789 int diff = memcmp(((PyDateTime_Date *)self)->data,
2790 ((PyDateTime_Date *)other)->data,
2791 _PyDateTime_DATE_DATASIZE);
2792 return diff_to_bool(diff, op);
2793 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002794 else
2795 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002796}
2797
2798static PyObject *
2799date_timetuple(PyDateTime_Date *self)
2800{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002801 return build_struct_time(GET_YEAR(self),
2802 GET_MONTH(self),
2803 GET_DAY(self),
2804 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002805}
2806
Tim Peters12bf3392002-12-24 05:41:27 +00002807static PyObject *
2808date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 PyObject *clone;
2811 PyObject *tuple;
2812 int year = GET_YEAR(self);
2813 int month = GET_MONTH(self);
2814 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002816 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2817 &year, &month, &day))
2818 return NULL;
2819 tuple = Py_BuildValue("iii", year, month, day);
2820 if (tuple == NULL)
2821 return NULL;
2822 clone = date_new(Py_TYPE(self), tuple, NULL);
2823 Py_DECREF(tuple);
2824 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002825}
2826
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002827static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002828generic_hash(unsigned char *data, int len)
2829{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002830 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002831}
2832
2833
2834static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002835
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002836static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002837date_hash(PyDateTime_Date *self)
2838{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002839 if (self->hashcode == -1)
2840 self->hashcode = generic_hash(
2841 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002843 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002844}
2845
2846static PyObject *
2847date_toordinal(PyDateTime_Date *self)
2848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2850 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002851}
2852
2853static PyObject *
2854date_weekday(PyDateTime_Date *self)
2855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002858 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002859}
2860
Tim Peters371935f2003-02-01 01:52:50 +00002861/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002862
Tim Petersb57f8f02003-02-01 02:54:15 +00002863/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002864static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002865date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002866{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002867 PyObject* field;
2868 field = PyBytes_FromStringAndSize((char*)self->data,
2869 _PyDateTime_DATE_DATASIZE);
2870 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002871}
2872
2873static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002874date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002876 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002877}
2878
2879static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002881 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002883 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2884 METH_CLASS,
2885 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2886 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002888 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2889 METH_CLASS,
2890 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2891 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2894 PyDoc_STR("Current date or datetime: same as "
2895 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002897 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002899 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2900 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002902 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2903 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002905 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2906 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002908 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2909 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002911 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2912 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2913 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002915 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2916 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002918 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2919 PyDoc_STR("Return the day of the week represented by the date.\n"
2920 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002922 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2923 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2924 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002926 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2927 PyDoc_STR("Return the day of the week represented by the date.\n"
2928 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002930 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2931 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002933 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2934 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002936 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002937};
2938
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002939static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002940PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002941
2942static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002943 date_add, /* nb_add */
2944 date_subtract, /* nb_subtract */
2945 0, /* nb_multiply */
2946 0, /* nb_remainder */
2947 0, /* nb_divmod */
2948 0, /* nb_power */
2949 0, /* nb_negative */
2950 0, /* nb_positive */
2951 0, /* nb_absolute */
2952 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002953};
2954
2955static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002956 PyVarObject_HEAD_INIT(NULL, 0)
2957 "datetime.date", /* tp_name */
2958 sizeof(PyDateTime_Date), /* tp_basicsize */
2959 0, /* tp_itemsize */
2960 0, /* tp_dealloc */
2961 0, /* tp_print */
2962 0, /* tp_getattr */
2963 0, /* tp_setattr */
2964 0, /* tp_reserved */
2965 (reprfunc)date_repr, /* tp_repr */
2966 &date_as_number, /* tp_as_number */
2967 0, /* tp_as_sequence */
2968 0, /* tp_as_mapping */
2969 (hashfunc)date_hash, /* tp_hash */
2970 0, /* tp_call */
2971 (reprfunc)date_str, /* tp_str */
2972 PyObject_GenericGetAttr, /* tp_getattro */
2973 0, /* tp_setattro */
2974 0, /* tp_as_buffer */
2975 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2976 date_doc, /* tp_doc */
2977 0, /* tp_traverse */
2978 0, /* tp_clear */
2979 date_richcompare, /* tp_richcompare */
2980 0, /* tp_weaklistoffset */
2981 0, /* tp_iter */
2982 0, /* tp_iternext */
2983 date_methods, /* tp_methods */
2984 0, /* tp_members */
2985 date_getset, /* tp_getset */
2986 0, /* tp_base */
2987 0, /* tp_dict */
2988 0, /* tp_descr_get */
2989 0, /* tp_descr_set */
2990 0, /* tp_dictoffset */
2991 0, /* tp_init */
2992 0, /* tp_alloc */
2993 date_new, /* tp_new */
2994 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002995};
2996
2997/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002998 * PyDateTime_TZInfo implementation.
2999 */
3000
3001/* This is a pure abstract base class, so doesn't do anything beyond
3002 * raising NotImplemented exceptions. Real tzinfo classes need
3003 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003004 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003005 * be subclasses of this tzinfo class, which is easy and quick to check).
3006 *
3007 * Note: For reasons having to do with pickling of subclasses, we have
3008 * to allow tzinfo objects to be instantiated. This wasn't an issue
3009 * in the Python implementation (__init__() could raise NotImplementedError
3010 * there without ill effect), but doing so in the C implementation hit a
3011 * brick wall.
3012 */
3013
3014static PyObject *
3015tzinfo_nogo(const char* methodname)
3016{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003017 PyErr_Format(PyExc_NotImplementedError,
3018 "a tzinfo subclass must implement %s()",
3019 methodname);
3020 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003021}
3022
3023/* Methods. A subclass must implement these. */
3024
Tim Peters52dcce22003-01-23 16:36:11 +00003025static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003026tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003028 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003029}
3030
Tim Peters52dcce22003-01-23 16:36:11 +00003031static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003032tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003034 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003035}
3036
Tim Peters52dcce22003-01-23 16:36:11 +00003037static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003038tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3039{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003040 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003041}
3042
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003043
3044static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3045 PyDateTime_Delta *delta,
3046 int factor);
3047static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3048static PyObject *datetime_dst(PyObject *self, PyObject *);
3049
Tim Peters52dcce22003-01-23 16:36:11 +00003050static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003051tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003052{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003053 PyObject *result = NULL;
3054 PyObject *off = NULL, *dst = NULL;
3055 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003056
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003057 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003058 PyErr_SetString(PyExc_TypeError,
3059 "fromutc: argument must be a datetime");
3060 return NULL;
3061 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003062 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003063 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3064 "is not self");
3065 return NULL;
3066 }
Tim Peters52dcce22003-01-23 16:36:11 +00003067
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003068 off = datetime_utcoffset(dt, NULL);
3069 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003070 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003071 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003072 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3073 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003074 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003075 }
Tim Peters52dcce22003-01-23 16:36:11 +00003076
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003077 dst = datetime_dst(dt, NULL);
3078 if (dst == NULL)
3079 goto Fail;
3080 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003081 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3082 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003083 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003084 }
Tim Peters52dcce22003-01-23 16:36:11 +00003085
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003086 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3087 if (delta == NULL)
3088 goto Fail;
3089 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003090 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003091 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003092
3093 Py_DECREF(dst);
3094 dst = call_dst(GET_DT_TZINFO(dt), result);
3095 if (dst == NULL)
3096 goto Fail;
3097 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003098 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003099 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003100 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003101 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003102 if (result == NULL)
3103 goto Fail;
3104 }
3105 Py_DECREF(delta);
3106 Py_DECREF(dst);
3107 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003108 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003109
3110Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003111 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3112 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003114 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003115Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003116 Py_XDECREF(off);
3117 Py_XDECREF(dst);
3118 Py_XDECREF(delta);
3119 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003120 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003121}
3122
Tim Peters2a799bf2002-12-16 20:18:38 +00003123/*
3124 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003125 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003126 */
3127
Guido van Rossum177e41a2003-01-30 22:06:23 +00003128static PyObject *
3129tzinfo_reduce(PyObject *self)
3130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003131 PyObject *args, *state, *tmp;
3132 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003133 _Py_IDENTIFIER(__getinitargs__);
3134 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003136 tmp = PyTuple_New(0);
3137 if (tmp == NULL)
3138 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003139
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003140 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003141 if (getinitargs != NULL) {
3142 args = PyObject_CallObject(getinitargs, tmp);
3143 Py_DECREF(getinitargs);
3144 if (args == NULL) {
3145 Py_DECREF(tmp);
3146 return NULL;
3147 }
3148 }
3149 else {
3150 PyErr_Clear();
3151 args = tmp;
3152 Py_INCREF(args);
3153 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003154
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003155 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003156 if (getstate != NULL) {
3157 state = PyObject_CallObject(getstate, tmp);
3158 Py_DECREF(getstate);
3159 if (state == NULL) {
3160 Py_DECREF(args);
3161 Py_DECREF(tmp);
3162 return NULL;
3163 }
3164 }
3165 else {
3166 PyObject **dictptr;
3167 PyErr_Clear();
3168 state = Py_None;
3169 dictptr = _PyObject_GetDictPtr(self);
3170 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3171 state = *dictptr;
3172 Py_INCREF(state);
3173 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003175 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003177 if (state == Py_None) {
3178 Py_DECREF(state);
3179 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3180 }
3181 else
3182 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003183}
Tim Peters2a799bf2002-12-16 20:18:38 +00003184
3185static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003187 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3188 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003190 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003191 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3192 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003194 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3195 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003197 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003198 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003200 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3201 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003203 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003204};
3205
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003206static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003207PyDoc_STR("Abstract base class for time zone info objects.");
3208
Neal Norwitz227b5332006-03-22 09:28:35 +00003209static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003210 PyVarObject_HEAD_INIT(NULL, 0)
3211 "datetime.tzinfo", /* tp_name */
3212 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3213 0, /* tp_itemsize */
3214 0, /* tp_dealloc */
3215 0, /* tp_print */
3216 0, /* tp_getattr */
3217 0, /* tp_setattr */
3218 0, /* tp_reserved */
3219 0, /* tp_repr */
3220 0, /* tp_as_number */
3221 0, /* tp_as_sequence */
3222 0, /* tp_as_mapping */
3223 0, /* tp_hash */
3224 0, /* tp_call */
3225 0, /* tp_str */
3226 PyObject_GenericGetAttr, /* tp_getattro */
3227 0, /* tp_setattro */
3228 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003229 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003230 tzinfo_doc, /* tp_doc */
3231 0, /* tp_traverse */
3232 0, /* tp_clear */
3233 0, /* tp_richcompare */
3234 0, /* tp_weaklistoffset */
3235 0, /* tp_iter */
3236 0, /* tp_iternext */
3237 tzinfo_methods, /* tp_methods */
3238 0, /* tp_members */
3239 0, /* tp_getset */
3240 0, /* tp_base */
3241 0, /* tp_dict */
3242 0, /* tp_descr_get */
3243 0, /* tp_descr_set */
3244 0, /* tp_dictoffset */
3245 0, /* tp_init */
3246 0, /* tp_alloc */
3247 PyType_GenericNew, /* tp_new */
3248 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003249};
3250
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003251static char *timezone_kws[] = {"offset", "name", NULL};
3252
3253static PyObject *
3254timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3255{
3256 PyObject *offset;
3257 PyObject *name = NULL;
3258 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3259 &PyDateTime_DeltaType, &offset,
3260 &PyUnicode_Type, &name))
3261 return new_timezone(offset, name);
3262
3263 return NULL;
3264}
3265
3266static void
3267timezone_dealloc(PyDateTime_TimeZone *self)
3268{
3269 Py_CLEAR(self->offset);
3270 Py_CLEAR(self->name);
3271 Py_TYPE(self)->tp_free((PyObject *)self);
3272}
3273
3274static PyObject *
3275timezone_richcompare(PyDateTime_TimeZone *self,
3276 PyDateTime_TimeZone *other, int op)
3277{
Brian Curtindfc80e32011-08-10 20:28:54 -05003278 if (op != Py_EQ && op != Py_NE)
3279 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003280 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003281 if (op == Py_EQ)
3282 Py_RETURN_FALSE;
3283 else
3284 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003285 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003286 return delta_richcompare(self->offset, other->offset, op);
3287}
3288
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003289static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003290timezone_hash(PyDateTime_TimeZone *self)
3291{
3292 return delta_hash((PyDateTime_Delta *)self->offset);
3293}
3294
3295/* Check argument type passed to tzname, utcoffset, or dst methods.
3296 Returns 0 for good argument. Returns -1 and sets exception info
3297 otherwise.
3298 */
3299static int
3300_timezone_check_argument(PyObject *dt, const char *meth)
3301{
3302 if (dt == Py_None || PyDateTime_Check(dt))
3303 return 0;
3304 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3305 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3306 return -1;
3307}
3308
3309static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003310timezone_repr(PyDateTime_TimeZone *self)
3311{
3312 /* Note that although timezone is not subclassable, it is convenient
3313 to use Py_TYPE(self)->tp_name here. */
3314 const char *type_name = Py_TYPE(self)->tp_name;
3315
3316 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3317 return PyUnicode_FromFormat("%s.utc", type_name);
3318
3319 if (self->name == NULL)
3320 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3321
3322 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3323 self->name);
3324}
3325
3326
3327static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003328timezone_str(PyDateTime_TimeZone *self)
3329{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003330 int hours, minutes, seconds;
3331 PyObject *offset;
3332 char sign;
3333
3334 if (self->name != NULL) {
3335 Py_INCREF(self->name);
3336 return self->name;
3337 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003338 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003339 (GET_TD_DAYS(self->offset) == 0 &&
3340 GET_TD_SECONDS(self->offset) == 0 &&
3341 GET_TD_MICROSECONDS(self->offset) == 0))
3342 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003343 /* Offset is normalized, so it is negative if days < 0 */
3344 if (GET_TD_DAYS(self->offset) < 0) {
3345 sign = '-';
3346 offset = delta_negative((PyDateTime_Delta *)self->offset);
3347 if (offset == NULL)
3348 return NULL;
3349 }
3350 else {
3351 sign = '+';
3352 offset = self->offset;
3353 Py_INCREF(offset);
3354 }
3355 /* Offset is not negative here. */
3356 seconds = GET_TD_SECONDS(offset);
3357 Py_DECREF(offset);
3358 minutes = divmod(seconds, 60, &seconds);
3359 hours = divmod(minutes, 60, &minutes);
Martin Pantere26da7c2016-06-02 10:07:09 +00003360 /* XXX ignore sub-minute data, currently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003361 assert(seconds == 0);
3362 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003363}
3364
3365static PyObject *
3366timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3367{
3368 if (_timezone_check_argument(dt, "tzname") == -1)
3369 return NULL;
3370
3371 return timezone_str(self);
3372}
3373
3374static PyObject *
3375timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3376{
3377 if (_timezone_check_argument(dt, "utcoffset") == -1)
3378 return NULL;
3379
3380 Py_INCREF(self->offset);
3381 return self->offset;
3382}
3383
3384static PyObject *
3385timezone_dst(PyObject *self, PyObject *dt)
3386{
3387 if (_timezone_check_argument(dt, "dst") == -1)
3388 return NULL;
3389
3390 Py_RETURN_NONE;
3391}
3392
3393static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003394timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3395{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003396 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003397 PyErr_SetString(PyExc_TypeError,
3398 "fromutc: argument must be a datetime");
3399 return NULL;
3400 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003401 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003402 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3403 "is not self");
3404 return NULL;
3405 }
3406
3407 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3408}
3409
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003410static PyObject *
3411timezone_getinitargs(PyDateTime_TimeZone *self)
3412{
3413 if (self->name == NULL)
3414 return Py_BuildValue("(O)", self->offset);
3415 return Py_BuildValue("(OO)", self->offset, self->name);
3416}
3417
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003418static PyMethodDef timezone_methods[] = {
3419 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3420 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003421 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003422
3423 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003424 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003425
3426 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003427 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003428
3429 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3430 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3431
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003432 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3433 PyDoc_STR("pickle support")},
3434
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003435 {NULL, NULL}
3436};
3437
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003438static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003439PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3440
3441static PyTypeObject PyDateTime_TimeZoneType = {
3442 PyVarObject_HEAD_INIT(NULL, 0)
3443 "datetime.timezone", /* tp_name */
3444 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3445 0, /* tp_itemsize */
3446 (destructor)timezone_dealloc, /* tp_dealloc */
3447 0, /* tp_print */
3448 0, /* tp_getattr */
3449 0, /* tp_setattr */
3450 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003451 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003452 0, /* tp_as_number */
3453 0, /* tp_as_sequence */
3454 0, /* tp_as_mapping */
3455 (hashfunc)timezone_hash, /* tp_hash */
3456 0, /* tp_call */
3457 (reprfunc)timezone_str, /* tp_str */
3458 0, /* tp_getattro */
3459 0, /* tp_setattro */
3460 0, /* tp_as_buffer */
3461 Py_TPFLAGS_DEFAULT, /* tp_flags */
3462 timezone_doc, /* tp_doc */
3463 0, /* tp_traverse */
3464 0, /* tp_clear */
3465 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3466 0, /* tp_weaklistoffset */
3467 0, /* tp_iter */
3468 0, /* tp_iternext */
3469 timezone_methods, /* tp_methods */
3470 0, /* tp_members */
3471 0, /* tp_getset */
3472 &PyDateTime_TZInfoType, /* tp_base */
3473 0, /* tp_dict */
3474 0, /* tp_descr_get */
3475 0, /* tp_descr_set */
3476 0, /* tp_dictoffset */
3477 0, /* tp_init */
3478 0, /* tp_alloc */
3479 timezone_new, /* tp_new */
3480};
3481
Tim Peters2a799bf2002-12-16 20:18:38 +00003482/*
Tim Peters37f39822003-01-10 03:49:02 +00003483 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003484 */
3485
Tim Peters37f39822003-01-10 03:49:02 +00003486/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003487 */
3488
3489static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003490time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003492 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003493}
3494
Tim Peters37f39822003-01-10 03:49:02 +00003495static PyObject *
3496time_minute(PyDateTime_Time *self, void *unused)
3497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003498 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003499}
3500
3501/* The name time_second conflicted with some platform header file. */
3502static PyObject *
3503py_time_second(PyDateTime_Time *self, void *unused)
3504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003505 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003506}
3507
3508static PyObject *
3509time_microsecond(PyDateTime_Time *self, void *unused)
3510{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003511 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003512}
3513
3514static PyObject *
3515time_tzinfo(PyDateTime_Time *self, void *unused)
3516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003517 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3518 Py_INCREF(result);
3519 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003520}
3521
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003522static PyObject *
3523time_fold(PyDateTime_Time *self, void *unused)
3524{
3525 return PyLong_FromLong(TIME_GET_FOLD(self));
3526}
3527
Tim Peters37f39822003-01-10 03:49:02 +00003528static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003529 {"hour", (getter)time_hour},
3530 {"minute", (getter)time_minute},
3531 {"second", (getter)py_time_second},
3532 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003533 {"tzinfo", (getter)time_tzinfo},
3534 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003535 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003536};
3537
3538/*
3539 * Constructors.
3540 */
3541
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003542static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003543 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003544
Tim Peters2a799bf2002-12-16 20:18:38 +00003545static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003546time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003548 PyObject *self = NULL;
3549 PyObject *state;
3550 int hour = 0;
3551 int minute = 0;
3552 int second = 0;
3553 int usecond = 0;
3554 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003555 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003557 /* Check for invocation from pickle with __getstate__ state */
3558 if (PyTuple_GET_SIZE(args) >= 1 &&
3559 PyTuple_GET_SIZE(args) <= 2 &&
3560 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3561 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003562 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003563 {
3564 PyDateTime_Time *me;
3565 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003567 if (PyTuple_GET_SIZE(args) == 2) {
3568 tzinfo = PyTuple_GET_ITEM(args, 1);
3569 if (check_tzinfo_subclass(tzinfo) < 0) {
3570 PyErr_SetString(PyExc_TypeError, "bad "
3571 "tzinfo state arg");
3572 return NULL;
3573 }
3574 }
3575 aware = (char)(tzinfo != Py_None);
3576 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3577 if (me != NULL) {
3578 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003580 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3581 me->hashcode = -1;
3582 me->hastzinfo = aware;
3583 if (aware) {
3584 Py_INCREF(tzinfo);
3585 me->tzinfo = tzinfo;
3586 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003587 if (pdata[0] & (1 << 7)) {
3588 me->data[0] -= 128;
3589 me->fold = 1;
3590 }
3591 else {
3592 me->fold = 0;
3593 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003594 }
3595 return (PyObject *)me;
3596 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003597
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003598 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003599 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003600 &tzinfo, &fold)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003601 if (check_time_args(hour, minute, second, usecond) < 0)
3602 return NULL;
3603 if (check_tzinfo_subclass(tzinfo) < 0)
3604 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003605 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3606 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003607 }
3608 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003609}
3610
3611/*
3612 * Destructor.
3613 */
3614
3615static void
Tim Peters37f39822003-01-10 03:49:02 +00003616time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003617{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003618 if (HASTZINFO(self)) {
3619 Py_XDECREF(self->tzinfo);
3620 }
3621 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003622}
3623
3624/*
Tim Peters855fe882002-12-22 03:43:39 +00003625 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003626 */
3627
Tim Peters2a799bf2002-12-16 20:18:38 +00003628/* These are all METH_NOARGS, so don't need to check the arglist. */
3629static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003630time_utcoffset(PyObject *self, PyObject *unused) {
3631 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003632}
3633
3634static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003635time_dst(PyObject *self, PyObject *unused) {
3636 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003637}
3638
3639static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003640time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003641 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003642}
3643
3644/*
Tim Peters37f39822003-01-10 03:49:02 +00003645 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003646 */
3647
3648static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003649time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003650{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003651 const char *type_name = Py_TYPE(self)->tp_name;
3652 int h = TIME_GET_HOUR(self);
3653 int m = TIME_GET_MINUTE(self);
3654 int s = TIME_GET_SECOND(self);
3655 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003656 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003657 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003659 if (us)
3660 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3661 type_name, h, m, s, us);
3662 else if (s)
3663 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3664 type_name, h, m, s);
3665 else
3666 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3667 if (result != NULL && HASTZINFO(self))
3668 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003669 if (result != NULL && fold)
3670 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003671 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003672}
3673
Tim Peters37f39822003-01-10 03:49:02 +00003674static PyObject *
3675time_str(PyDateTime_Time *self)
3676{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003677 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
Tim Peters37f39822003-01-10 03:49:02 +00003678}
Tim Peters2a799bf2002-12-16 20:18:38 +00003679
3680static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003681time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003682{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003683 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003684 char *timespec = NULL;
3685 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003686 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003687 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003688 static char *specs[][2] = {
3689 {"hours", "%02d"},
3690 {"minutes", "%02d:%02d"},
3691 {"seconds", "%02d:%02d:%02d"},
3692 {"milliseconds", "%02d:%02d:%02d.%03d"},
3693 {"microseconds", "%02d:%02d:%02d.%06d"},
3694 };
3695 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003696
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003697 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3698 return NULL;
3699
3700 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3701 if (us == 0) {
3702 /* seconds */
3703 given_spec = 2;
3704 }
3705 else {
3706 /* microseconds */
3707 given_spec = 4;
3708 }
3709 }
3710 else {
3711 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3712 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3713 if (given_spec == 3) {
3714 /* milliseconds */
3715 us = us / 1000;
3716 }
3717 break;
3718 }
3719 }
3720 }
3721
3722 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3723 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3724 return NULL;
3725 }
3726 else {
3727 result = PyUnicode_FromFormat(specs[given_spec][1],
3728 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3729 TIME_GET_SECOND(self), us);
3730 }
Tim Peters37f39822003-01-10 03:49:02 +00003731
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003732 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003733 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003735 /* We need to append the UTC offset. */
3736 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3737 Py_None) < 0) {
3738 Py_DECREF(result);
3739 return NULL;
3740 }
3741 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3742 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003743}
3744
Tim Peters37f39822003-01-10 03:49:02 +00003745static PyObject *
3746time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003748 PyObject *result;
3749 PyObject *tuple;
3750 PyObject *format;
3751 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003752
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003753 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3754 &format))
3755 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003757 /* Python's strftime does insane things with the year part of the
3758 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003759 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003760 */
3761 tuple = Py_BuildValue("iiiiiiiii",
3762 1900, 1, 1, /* year, month, day */
3763 TIME_GET_HOUR(self),
3764 TIME_GET_MINUTE(self),
3765 TIME_GET_SECOND(self),
3766 0, 1, -1); /* weekday, daynum, dst */
3767 if (tuple == NULL)
3768 return NULL;
3769 assert(PyTuple_Size(tuple) == 9);
3770 result = wrap_strftime((PyObject *)self, format, tuple,
3771 Py_None);
3772 Py_DECREF(tuple);
3773 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003774}
Tim Peters2a799bf2002-12-16 20:18:38 +00003775
3776/*
3777 * Miscellaneous methods.
3778 */
3779
Tim Peters37f39822003-01-10 03:49:02 +00003780static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003781time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003782{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003783 PyObject *result = NULL;
3784 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003785 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003786
Brian Curtindfc80e32011-08-10 20:28:54 -05003787 if (! PyTime_Check(other))
3788 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003789
3790 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003791 diff = memcmp(((PyDateTime_Time *)self)->data,
3792 ((PyDateTime_Time *)other)->data,
3793 _PyDateTime_TIME_DATASIZE);
3794 return diff_to_bool(diff, op);
3795 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003796 offset1 = time_utcoffset(self, NULL);
3797 if (offset1 == NULL)
3798 return NULL;
3799 offset2 = time_utcoffset(other, NULL);
3800 if (offset2 == NULL)
3801 goto done;
3802 /* If they're both naive, or both aware and have the same offsets,
3803 * we get off cheap. Note that if they're both naive, offset1 ==
3804 * offset2 == Py_None at this point.
3805 */
3806 if ((offset1 == offset2) ||
3807 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3808 delta_cmp(offset1, offset2) == 0)) {
3809 diff = memcmp(((PyDateTime_Time *)self)->data,
3810 ((PyDateTime_Time *)other)->data,
3811 _PyDateTime_TIME_DATASIZE);
3812 result = diff_to_bool(diff, op);
3813 }
3814 /* The hard case: both aware with different UTC offsets */
3815 else if (offset1 != Py_None && offset2 != Py_None) {
3816 int offsecs1, offsecs2;
3817 assert(offset1 != offset2); /* else last "if" handled it */
3818 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3819 TIME_GET_MINUTE(self) * 60 +
3820 TIME_GET_SECOND(self) -
3821 GET_TD_DAYS(offset1) * 86400 -
3822 GET_TD_SECONDS(offset1);
3823 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3824 TIME_GET_MINUTE(other) * 60 +
3825 TIME_GET_SECOND(other) -
3826 GET_TD_DAYS(offset2) * 86400 -
3827 GET_TD_SECONDS(offset2);
3828 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003829 if (diff == 0)
3830 diff = TIME_GET_MICROSECOND(self) -
3831 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003832 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003833 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003834 else if (op == Py_EQ) {
3835 result = Py_False;
3836 Py_INCREF(result);
3837 }
3838 else if (op == Py_NE) {
3839 result = Py_True;
3840 Py_INCREF(result);
3841 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003842 else {
3843 PyErr_SetString(PyExc_TypeError,
3844 "can't compare offset-naive and "
3845 "offset-aware times");
3846 }
3847 done:
3848 Py_DECREF(offset1);
3849 Py_XDECREF(offset2);
3850 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003851}
3852
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003853static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003854time_hash(PyDateTime_Time *self)
3855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003856 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003857 PyObject *offset, *self0;
3858 if (DATE_GET_FOLD(self)) {
3859 self0 = new_time_ex2(DATE_GET_HOUR(self),
3860 DATE_GET_MINUTE(self),
3861 DATE_GET_SECOND(self),
3862 DATE_GET_MICROSECOND(self),
3863 HASTZINFO(self) ? self->tzinfo : Py_None,
3864 0, Py_TYPE(self));
3865 if (self0 == NULL)
3866 return -1;
3867 }
3868 else {
3869 self0 = (PyObject *)self;
3870 Py_INCREF(self0);
3871 }
3872 offset = time_utcoffset(self0, NULL);
3873 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003874
3875 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003876 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003878 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003879 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003880 self->hashcode = generic_hash(
3881 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003882 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003883 PyObject *temp1, *temp2;
3884 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003885 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003886 seconds = TIME_GET_HOUR(self) * 3600 +
3887 TIME_GET_MINUTE(self) * 60 +
3888 TIME_GET_SECOND(self);
3889 microseconds = TIME_GET_MICROSECOND(self);
3890 temp1 = new_delta(0, seconds, microseconds, 1);
3891 if (temp1 == NULL) {
3892 Py_DECREF(offset);
3893 return -1;
3894 }
3895 temp2 = delta_subtract(temp1, offset);
3896 Py_DECREF(temp1);
3897 if (temp2 == NULL) {
3898 Py_DECREF(offset);
3899 return -1;
3900 }
3901 self->hashcode = PyObject_Hash(temp2);
3902 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003903 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003904 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003905 }
3906 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003907}
Tim Peters2a799bf2002-12-16 20:18:38 +00003908
Tim Peters12bf3392002-12-24 05:41:27 +00003909static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003910time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003911{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003912 PyObject *clone;
3913 PyObject *tuple;
3914 int hh = TIME_GET_HOUR(self);
3915 int mm = TIME_GET_MINUTE(self);
3916 int ss = TIME_GET_SECOND(self);
3917 int us = TIME_GET_MICROSECOND(self);
3918 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003919 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003920
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003921 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003922 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003923 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003924 return NULL;
3925 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3926 if (tuple == NULL)
3927 return NULL;
3928 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003929 if (clone != NULL)
3930 TIME_SET_FOLD(clone, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003931 Py_DECREF(tuple);
3932 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003933}
3934
Tim Peters371935f2003-02-01 01:52:50 +00003935/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003936
Tim Peters33e0f382003-01-10 02:05:14 +00003937/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003938 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3939 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003940 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003941 */
3942static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003943time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00003944{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003945 PyObject *basestate;
3946 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003948 basestate = PyBytes_FromStringAndSize((char *)self->data,
3949 _PyDateTime_TIME_DATASIZE);
3950 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003951 if (proto > 3 && TIME_GET_FOLD(self))
3952 /* Set the first bit of the first byte */
3953 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003954 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3955 result = PyTuple_Pack(1, basestate);
3956 else
3957 result = PyTuple_Pack(2, basestate, self->tzinfo);
3958 Py_DECREF(basestate);
3959 }
3960 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003961}
3962
3963static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003964time_reduce(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00003965{
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003966 int proto = 0;
3967 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
3968 return NULL;
3969
3970 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00003971}
3972
Tim Peters37f39822003-01-10 03:49:02 +00003973static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003974
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003975 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
3976 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
3977 "[+HH:MM].\n\n"
3978 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3981 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003983 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3984 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003986 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3987 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003989 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3990 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003992 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3993 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003995 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3996 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003997
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003998 {"__reduce_ex__", (PyCFunction)time_reduce, METH_VARARGS,
3999 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004002};
4003
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004004static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004005PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4006\n\
4007All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004008a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004009
Neal Norwitz227b5332006-03-22 09:28:35 +00004010static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004011 PyVarObject_HEAD_INIT(NULL, 0)
4012 "datetime.time", /* tp_name */
4013 sizeof(PyDateTime_Time), /* tp_basicsize */
4014 0, /* tp_itemsize */
4015 (destructor)time_dealloc, /* tp_dealloc */
4016 0, /* tp_print */
4017 0, /* tp_getattr */
4018 0, /* tp_setattr */
4019 0, /* tp_reserved */
4020 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004021 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004022 0, /* tp_as_sequence */
4023 0, /* tp_as_mapping */
4024 (hashfunc)time_hash, /* tp_hash */
4025 0, /* tp_call */
4026 (reprfunc)time_str, /* tp_str */
4027 PyObject_GenericGetAttr, /* tp_getattro */
4028 0, /* tp_setattro */
4029 0, /* tp_as_buffer */
4030 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4031 time_doc, /* tp_doc */
4032 0, /* tp_traverse */
4033 0, /* tp_clear */
4034 time_richcompare, /* tp_richcompare */
4035 0, /* tp_weaklistoffset */
4036 0, /* tp_iter */
4037 0, /* tp_iternext */
4038 time_methods, /* tp_methods */
4039 0, /* tp_members */
4040 time_getset, /* tp_getset */
4041 0, /* tp_base */
4042 0, /* tp_dict */
4043 0, /* tp_descr_get */
4044 0, /* tp_descr_set */
4045 0, /* tp_dictoffset */
4046 0, /* tp_init */
4047 time_alloc, /* tp_alloc */
4048 time_new, /* tp_new */
4049 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004050};
4051
4052/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004053 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004054 */
4055
Tim Petersa9bc1682003-01-11 03:39:11 +00004056/* Accessor properties. Properties for day, month, and year are inherited
4057 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004058 */
4059
4060static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004061datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004062{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004063 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004064}
4065
Tim Petersa9bc1682003-01-11 03:39:11 +00004066static PyObject *
4067datetime_minute(PyDateTime_DateTime *self, void *unused)
4068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004069 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004070}
4071
4072static PyObject *
4073datetime_second(PyDateTime_DateTime *self, void *unused)
4074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004075 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004076}
4077
4078static PyObject *
4079datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004081 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004082}
4083
4084static PyObject *
4085datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004087 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4088 Py_INCREF(result);
4089 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004090}
4091
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004092static PyObject *
4093datetime_fold(PyDateTime_DateTime *self, void *unused)
4094{
4095 return PyLong_FromLong(DATE_GET_FOLD(self));
4096}
4097
Tim Petersa9bc1682003-01-11 03:39:11 +00004098static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 {"hour", (getter)datetime_hour},
4100 {"minute", (getter)datetime_minute},
4101 {"second", (getter)datetime_second},
4102 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004103 {"tzinfo", (getter)datetime_tzinfo},
4104 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004105 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004106};
4107
4108/*
4109 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004110 */
4111
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004112static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004113 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004114 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004115};
4116
Tim Peters2a799bf2002-12-16 20:18:38 +00004117static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004118datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004120 PyObject *self = NULL;
4121 PyObject *state;
4122 int year;
4123 int month;
4124 int day;
4125 int hour = 0;
4126 int minute = 0;
4127 int second = 0;
4128 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004129 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004132 /* Check for invocation from pickle with __getstate__ state */
4133 if (PyTuple_GET_SIZE(args) >= 1 &&
4134 PyTuple_GET_SIZE(args) <= 2 &&
4135 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4136 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004137 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004138 {
4139 PyDateTime_DateTime *me;
4140 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004142 if (PyTuple_GET_SIZE(args) == 2) {
4143 tzinfo = PyTuple_GET_ITEM(args, 1);
4144 if (check_tzinfo_subclass(tzinfo) < 0) {
4145 PyErr_SetString(PyExc_TypeError, "bad "
4146 "tzinfo state arg");
4147 return NULL;
4148 }
4149 }
4150 aware = (char)(tzinfo != Py_None);
4151 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4152 if (me != NULL) {
4153 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004155 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4156 me->hashcode = -1;
4157 me->hastzinfo = aware;
4158 if (aware) {
4159 Py_INCREF(tzinfo);
4160 me->tzinfo = tzinfo;
4161 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004162 if (pdata[2] & (1 << 7)) {
4163 me->data[2] -= 128;
4164 me->fold = 1;
4165 }
4166 else {
4167 me->fold = 0;
4168 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004169 }
4170 return (PyObject *)me;
4171 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004172
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004173 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004174 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004175 &second, &usecond, &tzinfo, &fold)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004176 if (check_date_args(year, month, day) < 0)
4177 return NULL;
4178 if (check_time_args(hour, minute, second, usecond) < 0)
4179 return NULL;
4180 if (check_tzinfo_subclass(tzinfo) < 0)
4181 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004182 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004184 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004185 }
4186 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004187}
4188
Tim Petersa9bc1682003-01-11 03:39:11 +00004189/* TM_FUNC is the shared type of localtime() and gmtime(). */
4190typedef struct tm *(*TM_FUNC)(const time_t *timer);
4191
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004192/* As of version 2015f max fold in IANA database is
4193 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
4194static PY_LONG_LONG max_fold_seconds = 24 * 3600;
4195/* NB: date(1970,1,1).toordinal() == 719163 */
4196static PY_LONG_LONG epoch = Py_LL(719163) * 24 * 60 * 60;
4197
4198static PY_LONG_LONG
4199utc_to_seconds(int year, int month, int day,
4200 int hour, int minute, int second)
4201{
4202 PY_LONG_LONG ordinal = ymd_to_ord(year, month, day);
4203 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4204}
4205
4206static PY_LONG_LONG
4207local(PY_LONG_LONG u)
4208{
4209 struct tm local_time;
4210 time_t t = u - epoch;
4211 /* XXX: add bounds checking */
4212 if (localtime_r(&t, &local_time) == NULL) {
4213 PyErr_SetFromErrno(PyExc_OSError);
4214 return -1;
4215 }
4216 return utc_to_seconds(local_time.tm_year + 1900,
4217 local_time.tm_mon + 1,
4218 local_time.tm_mday,
4219 local_time.tm_hour,
4220 local_time.tm_min,
4221 local_time.tm_sec);
4222}
4223
Tim Petersa9bc1682003-01-11 03:39:11 +00004224/* Internal helper.
4225 * Build datetime from a time_t and a distinct count of microseconds.
4226 * Pass localtime or gmtime for f, to control the interpretation of timet.
4227 */
4228static PyObject *
4229datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004230 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 struct tm *tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004233 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004235 tm = f(&timet);
Victor Stinner21f58932012-03-14 00:15:40 +01004236 if (tm == NULL) {
4237#ifdef EINVAL
4238 if (errno == 0)
4239 errno = EINVAL;
4240#endif
4241 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004242 }
Victor Stinner21f58932012-03-14 00:15:40 +01004243
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004244 year = tm->tm_year + 1900;
4245 month = tm->tm_mon + 1;
4246 day = tm->tm_mday;
4247 hour = tm->tm_hour;
4248 minute = tm->tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004249 /* The platform localtime/gmtime may insert leap seconds,
4250 * indicated by tm->tm_sec > 59. We don't care about them,
4251 * except to the extent that passing them on to the datetime
4252 * constructor would raise ValueError for a reason that
4253 * made no sense to the user.
4254 */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004255 second = Py_MIN(59, tm->tm_sec);
4256
4257 if (tzinfo == Py_None && f == localtime) {
4258 PY_LONG_LONG probe_seconds, result_seconds, transition;
4259
4260 result_seconds = utc_to_seconds(year, month, day,
4261 hour, minute, second);
4262 /* Probe max_fold_seconds to detect a fold. */
4263 probe_seconds = local(epoch + timet - max_fold_seconds);
4264 if (probe_seconds == -1)
4265 return NULL;
4266 transition = result_seconds - probe_seconds - max_fold_seconds;
4267 if (transition < 0) {
4268 probe_seconds = local(epoch + timet + transition);
4269 if (probe_seconds == -1)
4270 return NULL;
4271 if (probe_seconds == result_seconds)
4272 fold = 1;
4273 }
4274 }
4275 return new_datetime_ex2(year, month, day, hour,
4276 minute, second, us, tzinfo, fold,
4277 (PyTypeObject *)cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004278}
4279
4280/* Internal helper.
4281 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4282 * to control the interpretation of the timestamp. Since a double doesn't
4283 * have enough bits to cover a datetime's full range of precision, it's
4284 * better to call datetime_from_timet_and_us provided you have a way
4285 * to get that much precision (e.g., C time() isn't good enough).
4286 */
4287static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004288datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004289 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004291 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004292 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004293
Victor Stinnere4a994d2015-03-30 01:10:14 +02004294 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004295 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004296 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004297
Victor Stinner21f58932012-03-14 00:15:40 +01004298 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004299}
4300
4301/* Internal helper.
4302 * Build most accurate possible datetime for current time. Pass localtime or
4303 * gmtime for f as appropriate.
4304 */
4305static PyObject *
4306datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4307{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004308 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004309 time_t secs;
4310 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004311
Victor Stinner1e2b6882015-09-18 13:23:02 +02004312 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004313 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004314 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004315
Victor Stinner1e2b6882015-09-18 13:23:02 +02004316 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004317}
4318
Larry Hastings61272b72014-01-07 12:41:53 -08004319/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004320
4321@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004322datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004323
4324 tz: object = None
4325 Timezone object.
4326
4327Returns new datetime object representing current time local to tz.
4328
4329If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004330[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004331
Larry Hastings31826802013-10-19 00:09:25 -07004332static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004333datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004334/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004336 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004337
Larry Hastings31826802013-10-19 00:09:25 -07004338 /* Return best possible local time -- this isn't constrained by the
4339 * precision of a timestamp.
4340 */
4341 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004342 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004343
Larry Hastings5c661892014-01-24 06:17:25 -08004344 self = datetime_best_possible((PyObject *)type,
Larry Hastings31826802013-10-19 00:09:25 -07004345 tz == Py_None ? localtime : gmtime,
4346 tz);
4347 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004348 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004349 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004350 }
4351 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004352}
4353
Tim Petersa9bc1682003-01-11 03:39:11 +00004354/* Return best possible UTC time -- this isn't constrained by the
4355 * precision of a timestamp.
4356 */
4357static PyObject *
4358datetime_utcnow(PyObject *cls, PyObject *dummy)
4359{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004360 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004361}
4362
Tim Peters2a799bf2002-12-16 20:18:38 +00004363/* Return new local datetime from timestamp (Python timestamp -- a double). */
4364static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004365datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004367 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004368 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004369 PyObject *tzinfo = Py_None;
4370 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004371
Victor Stinner5d272cc2012-03-13 13:35:55 +01004372 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004373 keywords, &timestamp, &tzinfo))
4374 return NULL;
4375 if (check_tzinfo_subclass(tzinfo) < 0)
4376 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004378 self = datetime_from_timestamp(cls,
4379 tzinfo == Py_None ? localtime : gmtime,
4380 timestamp,
4381 tzinfo);
4382 if (self != NULL && tzinfo != Py_None) {
4383 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004384 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004385 }
4386 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004387}
4388
Tim Petersa9bc1682003-01-11 03:39:11 +00004389/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4390static PyObject *
4391datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4392{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004393 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004394 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004395
Victor Stinner5d272cc2012-03-13 13:35:55 +01004396 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004397 result = datetime_from_timestamp(cls, gmtime, timestamp,
4398 Py_None);
4399 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004400}
4401
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004402/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004403static PyObject *
4404datetime_strptime(PyObject *cls, PyObject *args)
4405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004406 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004407 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004408 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004409
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004410 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004412
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004413 if (module == NULL) {
4414 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004415 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004416 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004417 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004418 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4419 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004420}
4421
Tim Petersa9bc1682003-01-11 03:39:11 +00004422/* Return new datetime from date/datetime and time arguments. */
4423static PyObject *
4424datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004426 static char *keywords[] = {"date", "time", NULL};
4427 PyObject *date;
4428 PyObject *time;
4429 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004431 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4432 &PyDateTime_DateType, &date,
4433 &PyDateTime_TimeType, &time)) {
4434 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004436 if (HASTZINFO(time))
4437 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4438 result = PyObject_CallFunction(cls, "iiiiiiiO",
4439 GET_YEAR(date),
4440 GET_MONTH(date),
4441 GET_DAY(date),
4442 TIME_GET_HOUR(time),
4443 TIME_GET_MINUTE(time),
4444 TIME_GET_SECOND(time),
4445 TIME_GET_MICROSECOND(time),
4446 tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004447 DATE_SET_FOLD(result, TIME_GET_FOLD(time));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004448 }
4449 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004450}
Tim Peters2a799bf2002-12-16 20:18:38 +00004451
4452/*
4453 * Destructor.
4454 */
4455
4456static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004457datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004459 if (HASTZINFO(self)) {
4460 Py_XDECREF(self->tzinfo);
4461 }
4462 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004463}
4464
4465/*
4466 * Indirect access to tzinfo methods.
4467 */
4468
Tim Peters2a799bf2002-12-16 20:18:38 +00004469/* These are all METH_NOARGS, so don't need to check the arglist. */
4470static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004471datetime_utcoffset(PyObject *self, PyObject *unused) {
4472 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004473}
4474
4475static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004476datetime_dst(PyObject *self, PyObject *unused) {
4477 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004478}
4479
4480static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004481datetime_tzname(PyObject *self, PyObject *unused) {
4482 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004483}
4484
4485/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004486 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004487 */
4488
Tim Petersa9bc1682003-01-11 03:39:11 +00004489/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4490 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004491 */
4492static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004493add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004494 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004496 /* Note that the C-level additions can't overflow, because of
4497 * invariant bounds on the member values.
4498 */
4499 int year = GET_YEAR(date);
4500 int month = GET_MONTH(date);
4501 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4502 int hour = DATE_GET_HOUR(date);
4503 int minute = DATE_GET_MINUTE(date);
4504 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4505 int microsecond = DATE_GET_MICROSECOND(date) +
4506 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004508 assert(factor == 1 || factor == -1);
4509 if (normalize_datetime(&year, &month, &day,
4510 &hour, &minute, &second, &microsecond) < 0)
4511 return NULL;
4512 else
4513 return new_datetime(year, month, day,
4514 hour, minute, second, microsecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004515 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004516}
4517
4518static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004519datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004521 if (PyDateTime_Check(left)) {
4522 /* datetime + ??? */
4523 if (PyDelta_Check(right))
4524 /* datetime + delta */
4525 return add_datetime_timedelta(
4526 (PyDateTime_DateTime *)left,
4527 (PyDateTime_Delta *)right,
4528 1);
4529 }
4530 else if (PyDelta_Check(left)) {
4531 /* delta + datetime */
4532 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4533 (PyDateTime_Delta *) left,
4534 1);
4535 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004536 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004537}
4538
4539static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004540datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004541{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004542 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 if (PyDateTime_Check(left)) {
4545 /* datetime - ??? */
4546 if (PyDateTime_Check(right)) {
4547 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004548 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004549 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004550
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004551 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4552 offset2 = offset1 = Py_None;
4553 Py_INCREF(offset1);
4554 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004555 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004556 else {
4557 offset1 = datetime_utcoffset(left, NULL);
4558 if (offset1 == NULL)
4559 return NULL;
4560 offset2 = datetime_utcoffset(right, NULL);
4561 if (offset2 == NULL) {
4562 Py_DECREF(offset1);
4563 return NULL;
4564 }
4565 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4566 PyErr_SetString(PyExc_TypeError,
4567 "can't subtract offset-naive and "
4568 "offset-aware datetimes");
4569 Py_DECREF(offset1);
4570 Py_DECREF(offset2);
4571 return NULL;
4572 }
4573 }
4574 if ((offset1 != offset2) &&
4575 delta_cmp(offset1, offset2) != 0) {
4576 offdiff = delta_subtract(offset1, offset2);
4577 if (offdiff == NULL) {
4578 Py_DECREF(offset1);
4579 Py_DECREF(offset2);
4580 return NULL;
4581 }
4582 }
4583 Py_DECREF(offset1);
4584 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004585 delta_d = ymd_to_ord(GET_YEAR(left),
4586 GET_MONTH(left),
4587 GET_DAY(left)) -
4588 ymd_to_ord(GET_YEAR(right),
4589 GET_MONTH(right),
4590 GET_DAY(right));
4591 /* These can't overflow, since the values are
4592 * normalized. At most this gives the number of
4593 * seconds in one day.
4594 */
4595 delta_s = (DATE_GET_HOUR(left) -
4596 DATE_GET_HOUR(right)) * 3600 +
4597 (DATE_GET_MINUTE(left) -
4598 DATE_GET_MINUTE(right)) * 60 +
4599 (DATE_GET_SECOND(left) -
4600 DATE_GET_SECOND(right));
4601 delta_us = DATE_GET_MICROSECOND(left) -
4602 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004603 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004604 if (result == NULL)
4605 return NULL;
4606
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004607 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004608 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004609 Py_DECREF(offdiff);
4610 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004611 }
4612 else if (PyDelta_Check(right)) {
4613 /* datetime - delta */
4614 result = add_datetime_timedelta(
4615 (PyDateTime_DateTime *)left,
4616 (PyDateTime_Delta *)right,
4617 -1);
4618 }
4619 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004621 if (result == Py_NotImplemented)
4622 Py_INCREF(result);
4623 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004624}
4625
4626/* Various ways to turn a datetime into a string. */
4627
4628static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004629datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 const char *type_name = Py_TYPE(self)->tp_name;
4632 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004634 if (DATE_GET_MICROSECOND(self)) {
4635 baserepr = PyUnicode_FromFormat(
4636 "%s(%d, %d, %d, %d, %d, %d, %d)",
4637 type_name,
4638 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4639 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4640 DATE_GET_SECOND(self),
4641 DATE_GET_MICROSECOND(self));
4642 }
4643 else if (DATE_GET_SECOND(self)) {
4644 baserepr = PyUnicode_FromFormat(
4645 "%s(%d, %d, %d, %d, %d, %d)",
4646 type_name,
4647 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4648 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4649 DATE_GET_SECOND(self));
4650 }
4651 else {
4652 baserepr = PyUnicode_FromFormat(
4653 "%s(%d, %d, %d, %d, %d)",
4654 type_name,
4655 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4656 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4657 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004658 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4659 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004660 if (baserepr == NULL || ! HASTZINFO(self))
4661 return baserepr;
4662 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004663}
4664
Tim Petersa9bc1682003-01-11 03:39:11 +00004665static PyObject *
4666datetime_str(PyDateTime_DateTime *self)
4667{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004668 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004669}
Tim Peters2a799bf2002-12-16 20:18:38 +00004670
4671static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004672datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004674 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004675 char *timespec = NULL;
4676 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004677 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004678 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004679 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004680 static char *specs[][2] = {
4681 {"hours", "%04d-%02d-%02d%c%02d"},
4682 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4683 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4684 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4685 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4686 };
4687 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004688
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004689 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004690 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004691
4692 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4693 if (us == 0) {
4694 /* seconds */
4695 given_spec = 2;
4696 }
4697 else {
4698 /* microseconds */
4699 given_spec = 4;
4700 }
4701 }
4702 else {
4703 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4704 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4705 if (given_spec == 3) {
4706 us = us / 1000;
4707 }
4708 break;
4709 }
4710 }
4711 }
4712
4713 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4714 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4715 return NULL;
4716 }
4717 else {
4718 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004719 GET_YEAR(self), GET_MONTH(self),
4720 GET_DAY(self), (int)sep,
4721 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4722 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004723 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004724
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004725 if (!result || !HASTZINFO(self))
4726 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004728 /* We need to append the UTC offset. */
4729 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4730 (PyObject *)self) < 0) {
4731 Py_DECREF(result);
4732 return NULL;
4733 }
4734 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4735 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004736}
4737
Tim Petersa9bc1682003-01-11 03:39:11 +00004738static PyObject *
4739datetime_ctime(PyDateTime_DateTime *self)
4740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004741 return format_ctime((PyDateTime_Date *)self,
4742 DATE_GET_HOUR(self),
4743 DATE_GET_MINUTE(self),
4744 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004745}
4746
Tim Peters2a799bf2002-12-16 20:18:38 +00004747/* Miscellaneous methods. */
4748
Tim Petersa9bc1682003-01-11 03:39:11 +00004749static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004750flip_fold(PyObject *dt)
4751{
4752 return new_datetime_ex2(GET_YEAR(dt),
4753 GET_MONTH(dt),
4754 GET_DAY(dt),
4755 DATE_GET_HOUR(dt),
4756 DATE_GET_MINUTE(dt),
4757 DATE_GET_SECOND(dt),
4758 DATE_GET_MICROSECOND(dt),
4759 HASTZINFO(dt) ?
4760 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4761 !DATE_GET_FOLD(dt),
4762 Py_TYPE(dt));
4763}
4764
4765static PyObject *
4766get_flip_fold_offset(PyObject *dt)
4767{
4768 PyObject *result, *flip_dt;
4769
4770 flip_dt = flip_fold(dt);
4771 if (flip_dt == NULL)
4772 return NULL;
4773 result = datetime_utcoffset(flip_dt, NULL);
4774 Py_DECREF(flip_dt);
4775 return result;
4776}
4777
4778/* PEP 495 exception: Whenever one or both of the operands in
4779 * inter-zone comparison is such that its utcoffset() depends
4780 * on the value of its fold fold attribute, the result is False.
4781 *
4782 * Return 1 if exception applies, 0 if not, and -1 on error.
4783 */
4784static int
4785pep495_eq_exception(PyObject *self, PyObject *other,
4786 PyObject *offset_self, PyObject *offset_other)
4787{
4788 int result = 0;
4789 PyObject *flip_offset;
4790
4791 flip_offset = get_flip_fold_offset(self);
4792 if (flip_offset == NULL)
4793 return -1;
4794 if (flip_offset != offset_self &&
4795 delta_cmp(flip_offset, offset_self))
4796 {
4797 result = 1;
4798 goto done;
4799 }
4800 Py_DECREF(flip_offset);
4801
4802 flip_offset = get_flip_fold_offset(other);
4803 if (flip_offset == NULL)
4804 return -1;
4805 if (flip_offset != offset_other &&
4806 delta_cmp(flip_offset, offset_other))
4807 result = 1;
4808 done:
4809 Py_DECREF(flip_offset);
4810 return result;
4811}
4812
4813static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004814datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004815{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004816 PyObject *result = NULL;
4817 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004818 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004820 if (! PyDateTime_Check(other)) {
4821 if (PyDate_Check(other)) {
4822 /* Prevent invocation of date_richcompare. We want to
4823 return NotImplemented here to give the other object
4824 a chance. But since DateTime is a subclass of
4825 Date, if the other object is a Date, it would
4826 compute an ordering based on the date part alone,
4827 and we don't want that. So force unequal or
4828 uncomparable here in that case. */
4829 if (op == Py_EQ)
4830 Py_RETURN_FALSE;
4831 if (op == Py_NE)
4832 Py_RETURN_TRUE;
4833 return cmperror(self, other);
4834 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004835 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004836 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004837
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004838 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004839 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4840 ((PyDateTime_DateTime *)other)->data,
4841 _PyDateTime_DATETIME_DATASIZE);
4842 return diff_to_bool(diff, op);
4843 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004844 offset1 = datetime_utcoffset(self, NULL);
4845 if (offset1 == NULL)
4846 return NULL;
4847 offset2 = datetime_utcoffset(other, NULL);
4848 if (offset2 == NULL)
4849 goto done;
4850 /* If they're both naive, or both aware and have the same offsets,
4851 * we get off cheap. Note that if they're both naive, offset1 ==
4852 * offset2 == Py_None at this point.
4853 */
4854 if ((offset1 == offset2) ||
4855 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4856 delta_cmp(offset1, offset2) == 0)) {
4857 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4858 ((PyDateTime_DateTime *)other)->data,
4859 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004860 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4861 int ex = pep495_eq_exception(self, other, offset1, offset2);
4862 if (ex == -1)
4863 goto done;
4864 if (ex)
4865 diff = 1;
4866 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004867 result = diff_to_bool(diff, op);
4868 }
4869 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004870 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004871
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004872 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004873 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4874 other);
4875 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004876 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004877 diff = GET_TD_DAYS(delta);
4878 if (diff == 0)
4879 diff = GET_TD_SECONDS(delta) |
4880 GET_TD_MICROSECONDS(delta);
4881 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004882 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4883 int ex = pep495_eq_exception(self, other, offset1, offset2);
4884 if (ex == -1)
4885 goto done;
4886 if (ex)
4887 diff = 1;
4888 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004889 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004891 else if (op == Py_EQ) {
4892 result = Py_False;
4893 Py_INCREF(result);
4894 }
4895 else if (op == Py_NE) {
4896 result = Py_True;
4897 Py_INCREF(result);
4898 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004899 else {
4900 PyErr_SetString(PyExc_TypeError,
4901 "can't compare offset-naive and "
4902 "offset-aware datetimes");
4903 }
4904 done:
4905 Py_DECREF(offset1);
4906 Py_XDECREF(offset2);
4907 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004908}
4909
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004910static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004911datetime_hash(PyDateTime_DateTime *self)
4912{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004913 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004914 PyObject *offset, *self0;
4915 if (DATE_GET_FOLD(self)) {
4916 self0 = new_datetime_ex2(GET_YEAR(self),
4917 GET_MONTH(self),
4918 GET_DAY(self),
4919 DATE_GET_HOUR(self),
4920 DATE_GET_MINUTE(self),
4921 DATE_GET_SECOND(self),
4922 DATE_GET_MICROSECOND(self),
4923 HASTZINFO(self) ? self->tzinfo : Py_None,
4924 0, Py_TYPE(self));
4925 if (self0 == NULL)
4926 return -1;
4927 }
4928 else {
4929 self0 = (PyObject *)self;
4930 Py_INCREF(self0);
4931 }
4932 offset = datetime_utcoffset(self0, NULL);
4933 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004934
4935 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004936 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004938 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004939 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004940 self->hashcode = generic_hash(
4941 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004942 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004943 PyObject *temp1, *temp2;
4944 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004946 assert(HASTZINFO(self));
4947 days = ymd_to_ord(GET_YEAR(self),
4948 GET_MONTH(self),
4949 GET_DAY(self));
4950 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004951 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004952 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004953 temp1 = new_delta(days, seconds,
4954 DATE_GET_MICROSECOND(self),
4955 1);
4956 if (temp1 == NULL) {
4957 Py_DECREF(offset);
4958 return -1;
4959 }
4960 temp2 = delta_subtract(temp1, offset);
4961 Py_DECREF(temp1);
4962 if (temp2 == NULL) {
4963 Py_DECREF(offset);
4964 return -1;
4965 }
4966 self->hashcode = PyObject_Hash(temp2);
4967 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004968 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004969 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004970 }
4971 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004972}
Tim Peters2a799bf2002-12-16 20:18:38 +00004973
4974static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004975datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004976{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004977 PyObject *clone;
4978 PyObject *tuple;
4979 int y = GET_YEAR(self);
4980 int m = GET_MONTH(self);
4981 int d = GET_DAY(self);
4982 int hh = DATE_GET_HOUR(self);
4983 int mm = DATE_GET_MINUTE(self);
4984 int ss = DATE_GET_SECOND(self);
4985 int us = DATE_GET_MICROSECOND(self);
4986 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004987 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004988
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004989 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004990 datetime_kws,
4991 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004992 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004993 return NULL;
4994 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4995 if (tuple == NULL)
4996 return NULL;
4997 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004998 if (clone != NULL)
4999 DATE_SET_FOLD(clone, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005000 Py_DECREF(tuple);
5001 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005002}
5003
5004static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005005local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005006{
5007 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005008 PyObject *delta;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005009 struct tm *local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005010 PyObject *nameo = NULL;
5011 const char *zone = NULL;
5012
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005013 local_time_tm = localtime(&timestamp);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005014#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005015 zone = local_time_tm->tm_zone;
5016 delta = new_delta(0, local_time_tm->tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005017#else /* HAVE_STRUCT_TM_TM_ZONE */
5018 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005019 PyObject *local_time, *utc_time;
5020 struct tm *utc_time_tm;
5021 char buf[100];
5022 strftime(buf, sizeof(buf), "%Z", local_time_tm);
5023 zone = buf;
5024 local_time = new_datetime(local_time_tm->tm_year + 1900,
5025 local_time_tm->tm_mon + 1,
5026 local_time_tm->tm_mday,
5027 local_time_tm->tm_hour,
5028 local_time_tm->tm_min,
5029 local_time_tm->tm_sec, 0, Py_None, 0);
5030 if (local_time == NULL) {
5031 return NULL;
5032 }
5033 utc_time_tm = gmtime(&timestamp);
5034 utc_time = new_datetime(utc_time_tm->tm_year + 1900,
5035 utc_time_tm->tm_mon + 1,
5036 utc_time_tm->tm_mday,
5037 utc_time_tm->tm_hour,
5038 utc_time_tm->tm_min,
5039 utc_time_tm->tm_sec, 0, Py_None, 0);
5040 if (utc_time == NULL) {
5041 Py_DECREF(local_time);
5042 return NULL;
5043 }
5044 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005045 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005046 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005047 }
5048#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005049 if (delta == NULL) {
5050 return NULL;
5051 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005052 if (zone != NULL) {
5053 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5054 if (nameo == NULL)
5055 goto error;
5056 }
5057 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005058 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005059 error:
5060 Py_DECREF(delta);
5061 return result;
5062}
5063
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005064static PyObject *
5065local_timezone(PyDateTime_DateTime *utc_time)
5066{
5067 time_t timestamp;
5068 PyObject *delta;
5069 PyObject *one_second;
5070 PyObject *seconds;
5071
5072 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5073 if (delta == NULL)
5074 return NULL;
5075 one_second = new_delta(0, 1, 0, 0);
5076 if (one_second == NULL) {
5077 Py_DECREF(delta);
5078 return NULL;
5079 }
5080 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5081 (PyDateTime_Delta *)one_second);
5082 Py_DECREF(one_second);
5083 Py_DECREF(delta);
5084 if (seconds == NULL)
5085 return NULL;
5086 timestamp = _PyLong_AsTime_t(seconds);
5087 Py_DECREF(seconds);
5088 if (timestamp == -1 && PyErr_Occurred())
5089 return NULL;
5090 return local_timezone_from_timestamp(timestamp);
5091}
5092
5093static PY_LONG_LONG
5094local_to_seconds(int year, int month, int day,
5095 int hour, int minute, int second, int fold);
5096
5097static PyObject *
5098local_timezone_from_local(PyDateTime_DateTime *local_dt)
5099{
5100 PY_LONG_LONG seconds;
5101 time_t timestamp;
5102 seconds = local_to_seconds(GET_YEAR(local_dt),
5103 GET_MONTH(local_dt),
5104 GET_DAY(local_dt),
5105 DATE_GET_HOUR(local_dt),
5106 DATE_GET_MINUTE(local_dt),
5107 DATE_GET_SECOND(local_dt),
5108 DATE_GET_FOLD(local_dt));
5109 if (seconds == -1)
5110 return NULL;
5111 /* XXX: add bounds check */
5112 timestamp = seconds - epoch;
5113 return local_timezone_from_timestamp(timestamp);
5114}
5115
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005116static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005117datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005118{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005119 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005120 PyObject *offset;
5121 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005122 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005123 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005124 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005125
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005126 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005127 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005128 return NULL;
5129
5130 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005131 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005132
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005133 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5134 self_tzinfo = local_timezone_from_local(self);
5135 if (self_tzinfo == NULL)
5136 return NULL;
5137 } else {
5138 self_tzinfo = self->tzinfo;
5139 Py_INCREF(self_tzinfo);
5140 }
Tim Peters521fc152002-12-31 17:36:56 +00005141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005142 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005143 if (self_tzinfo == tzinfo) {
5144 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005145 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005146 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005147 }
Tim Peters521fc152002-12-31 17:36:56 +00005148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005149 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005150 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5151 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005152 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005153 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005154 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005155 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5156 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005157 Py_DECREF(offset);
5158 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005159 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005160
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005161 /* Make sure result is aware and UTC. */
5162 if (!HASTZINFO(result)) {
5163 temp = (PyObject *)result;
5164 result = (PyDateTime_DateTime *)
5165 new_datetime_ex2(GET_YEAR(result),
5166 GET_MONTH(result),
5167 GET_DAY(result),
5168 DATE_GET_HOUR(result),
5169 DATE_GET_MINUTE(result),
5170 DATE_GET_SECOND(result),
5171 DATE_GET_MICROSECOND(result),
5172 PyDateTime_TimeZone_UTC,
5173 DATE_GET_FOLD(result),
5174 Py_TYPE(result));
5175 Py_DECREF(temp);
5176 if (result == NULL)
5177 return NULL;
5178 }
5179 else {
5180 /* Result is already aware - just replace tzinfo. */
5181 temp = result->tzinfo;
5182 result->tzinfo = PyDateTime_TimeZone_UTC;
5183 Py_INCREF(result->tzinfo);
5184 Py_DECREF(temp);
5185 }
5186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005187 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005188 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005189 if (tzinfo == Py_None) {
5190 tzinfo = local_timezone(result);
5191 if (tzinfo == NULL) {
5192 Py_DECREF(result);
5193 return NULL;
5194 }
5195 }
5196 else
5197 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005198 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005199 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005200
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005201 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005202 result = (PyDateTime_DateTime *)
5203 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005204 Py_DECREF(temp);
5205
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005206 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005207}
5208
5209static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005210datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005212 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005214 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005215 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005216
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005217 dst = call_dst(self->tzinfo, (PyObject *)self);
5218 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005219 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005220
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005221 if (dst != Py_None)
5222 dstflag = delta_bool((PyDateTime_Delta *)dst);
5223 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005224 }
5225 return build_struct_time(GET_YEAR(self),
5226 GET_MONTH(self),
5227 GET_DAY(self),
5228 DATE_GET_HOUR(self),
5229 DATE_GET_MINUTE(self),
5230 DATE_GET_SECOND(self),
5231 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005232}
5233
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005234static PY_LONG_LONG
5235local_to_seconds(int year, int month, int day,
5236 int hour, int minute, int second, int fold)
5237{
5238 PY_LONG_LONG t, a, b, u1, u2, t1, t2, lt;
5239 t = utc_to_seconds(year, month, day, hour, minute, second);
5240 /* Our goal is to solve t = local(u) for u. */
5241 lt = local(t);
5242 if (lt == -1)
5243 return -1;
5244 a = lt - t;
5245 u1 = t - a;
5246 t1 = local(u1);
5247 if (t1 == -1)
5248 return -1;
5249 if (t1 == t) {
5250 /* We found one solution, but it may not be the one we need.
5251 * Look for an earlier solution (if `fold` is 0), or a
5252 * later one (if `fold` is 1). */
5253 if (fold)
5254 u2 = u1 + max_fold_seconds;
5255 else
5256 u2 = u1 - max_fold_seconds;
5257 lt = local(u2);
5258 if (lt == -1)
5259 return -1;
5260 b = lt - u2;
5261 if (a == b)
5262 return u1;
5263 }
5264 else {
5265 b = t1 - u1;
5266 assert(a != b);
5267 }
5268 u2 = t - b;
5269 t2 = local(u2);
5270 if (t2 == -1)
5271 return -1;
5272 if (t2 == t)
5273 return u2;
5274 if (t1 == t)
5275 return u1;
5276 /* We have found both offsets a and b, but neither t - a nor t - b is
5277 * a solution. This means t is in the gap. */
5278 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5279}
5280
5281/* date(1970,1,1).toordinal() == 719163 */
5282#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5283
Tim Peters2a799bf2002-12-16 20:18:38 +00005284static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005285datetime_timestamp(PyDateTime_DateTime *self)
5286{
5287 PyObject *result;
5288
5289 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5290 PyObject *delta;
5291 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5292 if (delta == NULL)
5293 return NULL;
5294 result = delta_total_seconds(delta);
5295 Py_DECREF(delta);
5296 }
5297 else {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005298 PY_LONG_LONG seconds;
5299 seconds = local_to_seconds(GET_YEAR(self),
5300 GET_MONTH(self),
5301 GET_DAY(self),
5302 DATE_GET_HOUR(self),
5303 DATE_GET_MINUTE(self),
5304 DATE_GET_SECOND(self),
5305 DATE_GET_FOLD(self));
5306 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005307 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005308 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5309 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005310 }
5311 return result;
5312}
5313
5314static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005315datetime_getdate(PyDateTime_DateTime *self)
5316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005317 return new_date(GET_YEAR(self),
5318 GET_MONTH(self),
5319 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005320}
5321
5322static PyObject *
5323datetime_gettime(PyDateTime_DateTime *self)
5324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005325 return new_time(DATE_GET_HOUR(self),
5326 DATE_GET_MINUTE(self),
5327 DATE_GET_SECOND(self),
5328 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005329 Py_None,
5330 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005331}
5332
5333static PyObject *
5334datetime_gettimetz(PyDateTime_DateTime *self)
5335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005336 return new_time(DATE_GET_HOUR(self),
5337 DATE_GET_MINUTE(self),
5338 DATE_GET_SECOND(self),
5339 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005340 GET_DT_TZINFO(self),
5341 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005342}
5343
5344static PyObject *
5345datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005346{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005347 int y, m, d, hh, mm, ss;
5348 PyObject *tzinfo;
5349 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005350
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005351 tzinfo = GET_DT_TZINFO(self);
5352 if (tzinfo == Py_None) {
5353 utcself = self;
5354 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005355 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005356 else {
5357 PyObject *offset;
5358 offset = call_utcoffset(tzinfo, (PyObject *)self);
5359 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005360 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005361 if (offset == Py_None) {
5362 Py_DECREF(offset);
5363 utcself = self;
5364 Py_INCREF(utcself);
5365 }
5366 else {
5367 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5368 (PyDateTime_Delta *)offset, -1);
5369 Py_DECREF(offset);
5370 if (utcself == NULL)
5371 return NULL;
5372 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005373 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005374 y = GET_YEAR(utcself);
5375 m = GET_MONTH(utcself);
5376 d = GET_DAY(utcself);
5377 hh = DATE_GET_HOUR(utcself);
5378 mm = DATE_GET_MINUTE(utcself);
5379 ss = DATE_GET_SECOND(utcself);
5380
5381 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005382 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005383}
5384
Tim Peters371935f2003-02-01 01:52:50 +00005385/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005386
Tim Petersa9bc1682003-01-11 03:39:11 +00005387/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005388 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5389 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005390 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005391 */
5392static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005393datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005394{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005395 PyObject *basestate;
5396 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005398 basestate = PyBytes_FromStringAndSize((char *)self->data,
5399 _PyDateTime_DATETIME_DATASIZE);
5400 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005401 if (proto > 3 && DATE_GET_FOLD(self))
5402 /* Set the first bit of the third byte */
5403 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005404 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5405 result = PyTuple_Pack(1, basestate);
5406 else
5407 result = PyTuple_Pack(2, basestate, self->tzinfo);
5408 Py_DECREF(basestate);
5409 }
5410 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005411}
5412
5413static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005414datetime_reduce(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005415{
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005416 int proto = 0;
5417 if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
5418 return NULL;
5419
5420 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005421}
5422
Tim Petersa9bc1682003-01-11 03:39:11 +00005423static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005425 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005426
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005427 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005429 {"utcnow", (PyCFunction)datetime_utcnow,
5430 METH_NOARGS | METH_CLASS,
5431 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005433 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5434 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5435 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005437 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5438 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005439 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005441 {"strptime", (PyCFunction)datetime_strptime,
5442 METH_VARARGS | METH_CLASS,
5443 PyDoc_STR("string, format -> new datetime parsed from a string "
5444 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005446 {"combine", (PyCFunction)datetime_combine,
5447 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5448 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005450 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005452 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5453 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005455 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5456 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005458 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5459 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005461 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5462 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005464 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5465 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005466
Alexander Belopolskya4415142012-06-08 12:33:09 -04005467 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5468 PyDoc_STR("Return POSIX timestamp as float.")},
5469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005470 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5471 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005473 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5474 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005475 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005476 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005477 "defaults to 'T'.\n"
5478 "timespec specifies what components of the time to include"
5479 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5480 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005482 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5483 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005485 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5486 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005488 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5489 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005491 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5492 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005494 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5495 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005496
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005497 {"__reduce_ex__", (PyCFunction)datetime_reduce, METH_VARARGS,
5498 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005500 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005501};
5502
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005503static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005504PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5505\n\
5506The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005507instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005508
Tim Petersa9bc1682003-01-11 03:39:11 +00005509static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005510 datetime_add, /* nb_add */
5511 datetime_subtract, /* nb_subtract */
5512 0, /* nb_multiply */
5513 0, /* nb_remainder */
5514 0, /* nb_divmod */
5515 0, /* nb_power */
5516 0, /* nb_negative */
5517 0, /* nb_positive */
5518 0, /* nb_absolute */
5519 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005520};
5521
Neal Norwitz227b5332006-03-22 09:28:35 +00005522static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005523 PyVarObject_HEAD_INIT(NULL, 0)
5524 "datetime.datetime", /* tp_name */
5525 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5526 0, /* tp_itemsize */
5527 (destructor)datetime_dealloc, /* tp_dealloc */
5528 0, /* tp_print */
5529 0, /* tp_getattr */
5530 0, /* tp_setattr */
5531 0, /* tp_reserved */
5532 (reprfunc)datetime_repr, /* tp_repr */
5533 &datetime_as_number, /* tp_as_number */
5534 0, /* tp_as_sequence */
5535 0, /* tp_as_mapping */
5536 (hashfunc)datetime_hash, /* tp_hash */
5537 0, /* tp_call */
5538 (reprfunc)datetime_str, /* tp_str */
5539 PyObject_GenericGetAttr, /* tp_getattro */
5540 0, /* tp_setattro */
5541 0, /* tp_as_buffer */
5542 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5543 datetime_doc, /* tp_doc */
5544 0, /* tp_traverse */
5545 0, /* tp_clear */
5546 datetime_richcompare, /* tp_richcompare */
5547 0, /* tp_weaklistoffset */
5548 0, /* tp_iter */
5549 0, /* tp_iternext */
5550 datetime_methods, /* tp_methods */
5551 0, /* tp_members */
5552 datetime_getset, /* tp_getset */
5553 &PyDateTime_DateType, /* tp_base */
5554 0, /* tp_dict */
5555 0, /* tp_descr_get */
5556 0, /* tp_descr_set */
5557 0, /* tp_dictoffset */
5558 0, /* tp_init */
5559 datetime_alloc, /* tp_alloc */
5560 datetime_new, /* tp_new */
5561 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005562};
5563
5564/* ---------------------------------------------------------------------------
5565 * Module methods and initialization.
5566 */
5567
5568static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005569 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005570};
5571
Tim Peters9ddf40b2004-06-20 22:41:32 +00005572/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5573 * datetime.h.
5574 */
5575static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005576 &PyDateTime_DateType,
5577 &PyDateTime_DateTimeType,
5578 &PyDateTime_TimeType,
5579 &PyDateTime_DeltaType,
5580 &PyDateTime_TZInfoType,
5581 new_date_ex,
5582 new_datetime_ex,
5583 new_time_ex,
5584 new_delta_ex,
5585 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005586 date_fromtimestamp,
5587 new_datetime_ex2,
5588 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00005589};
5590
5591
Martin v. Löwis1a214512008-06-11 05:26:20 +00005592
5593static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005594 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005595 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005596 "Fast implementation of the datetime type.",
5597 -1,
5598 module_methods,
5599 NULL,
5600 NULL,
5601 NULL,
5602 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005603};
5604
Tim Peters2a799bf2002-12-16 20:18:38 +00005605PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005606PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005608 PyObject *m; /* a module object */
5609 PyObject *d; /* its dict */
5610 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005611 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005613 m = PyModule_Create(&datetimemodule);
5614 if (m == NULL)
5615 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005617 if (PyType_Ready(&PyDateTime_DateType) < 0)
5618 return NULL;
5619 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5620 return NULL;
5621 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5622 return NULL;
5623 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5624 return NULL;
5625 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5626 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005627 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5628 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005630 /* timedelta values */
5631 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005633 x = new_delta(0, 0, 1, 0);
5634 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5635 return NULL;
5636 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005638 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5639 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5640 return NULL;
5641 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005643 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5644 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5645 return NULL;
5646 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005648 /* date values */
5649 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005651 x = new_date(1, 1, 1);
5652 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5653 return NULL;
5654 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005656 x = new_date(MAXYEAR, 12, 31);
5657 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5658 return NULL;
5659 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005661 x = new_delta(1, 0, 0, 0);
5662 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5663 return NULL;
5664 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005666 /* time values */
5667 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005668
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005669 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005670 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5671 return NULL;
5672 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005673
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005674 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005675 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5676 return NULL;
5677 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005679 x = new_delta(0, 0, 1, 0);
5680 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5681 return NULL;
5682 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005684 /* datetime values */
5685 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005686
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005687 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005688 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5689 return NULL;
5690 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005691
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005692 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005693 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5694 return NULL;
5695 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005697 x = new_delta(0, 0, 1, 0);
5698 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5699 return NULL;
5700 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005701
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005702 /* timezone values */
5703 d = PyDateTime_TimeZoneType.tp_dict;
5704
5705 delta = new_delta(0, 0, 0, 0);
5706 if (delta == NULL)
5707 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005708 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005709 Py_DECREF(delta);
5710 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5711 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005712 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005713
5714 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5715 if (delta == NULL)
5716 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005717 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005718 Py_DECREF(delta);
5719 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5720 return NULL;
5721 Py_DECREF(x);
5722
5723 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5724 if (delta == NULL)
5725 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005726 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005727 Py_DECREF(delta);
5728 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5729 return NULL;
5730 Py_DECREF(x);
5731
Alexander Belopolskya4415142012-06-08 12:33:09 -04005732 /* Epoch */
5733 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005734 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005735 if (PyDateTime_Epoch == NULL)
5736 return NULL;
5737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005738 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005739 PyModule_AddIntMacro(m, MINYEAR);
5740 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005742 Py_INCREF(&PyDateTime_DateType);
5743 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005745 Py_INCREF(&PyDateTime_DateTimeType);
5746 PyModule_AddObject(m, "datetime",
5747 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005749 Py_INCREF(&PyDateTime_TimeType);
5750 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005752 Py_INCREF(&PyDateTime_DeltaType);
5753 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005755 Py_INCREF(&PyDateTime_TZInfoType);
5756 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005757
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005758 Py_INCREF(&PyDateTime_TimeZoneType);
5759 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005761 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5762 if (x == NULL)
5763 return NULL;
5764 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005766 /* A 4-year cycle has an extra leap day over what we'd get from
5767 * pasting together 4 single years.
5768 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005769 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005770 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005772 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5773 * get from pasting together 4 100-year cycles.
5774 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005775 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005776 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005778 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5779 * pasting together 25 4-year cycles.
5780 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005781 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005782 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005783
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005784 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005785 us_per_ms = PyLong_FromLong(1000);
5786 us_per_second = PyLong_FromLong(1000000);
5787 us_per_minute = PyLong_FromLong(60000000);
5788 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005789 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005790 us_per_minute == NULL || seconds_per_day == NULL)
5791 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005793 /* The rest are too big for 32-bit ints, but even
5794 * us_per_week fits in 40 bits, so doubles should be exact.
5795 */
5796 us_per_hour = PyLong_FromDouble(3600000000.0);
5797 us_per_day = PyLong_FromDouble(86400000000.0);
5798 us_per_week = PyLong_FromDouble(604800000000.0);
5799 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5800 return NULL;
5801 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005802}
Tim Petersf3615152003-01-01 21:51:37 +00005803
5804/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005805Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005806 x.n = x stripped of its timezone -- its naive time.
5807 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005808 return None
Tim Petersf3615152003-01-01 21:51:37 +00005809 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005810 return None
Tim Petersf3615152003-01-01 21:51:37 +00005811 x.s = x's standard offset, x.o - x.d
5812
5813Now some derived rules, where k is a duration (timedelta).
5814
58151. x.o = x.s + x.d
5816 This follows from the definition of x.s.
5817
Tim Petersc5dc4da2003-01-02 17:55:03 +000058182. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005819 This is actually a requirement, an assumption we need to make about
5820 sane tzinfo classes.
5821
58223. The naive UTC time corresponding to x is x.n - x.o.
5823 This is again a requirement for a sane tzinfo class.
5824
58254. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005826 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005827
Tim Petersc5dc4da2003-01-02 17:55:03 +000058285. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005829 Again follows from how arithmetic is defined.
5830
Tim Peters8bb5ad22003-01-24 02:44:45 +00005831Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005832(meaning that the various tzinfo methods exist, and don't blow up or return
5833None when called).
5834
Tim Petersa9bc1682003-01-11 03:39:11 +00005835The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005836x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005837
5838By #3, we want
5839
Tim Peters8bb5ad22003-01-24 02:44:45 +00005840 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005841
5842The algorithm starts by attaching tz to x.n, and calling that y. So
5843x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5844becomes true; in effect, we want to solve [2] for k:
5845
Tim Peters8bb5ad22003-01-24 02:44:45 +00005846 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005847
5848By #1, this is the same as
5849
Tim Peters8bb5ad22003-01-24 02:44:45 +00005850 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005851
5852By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5853Substituting that into [3],
5854
Tim Peters8bb5ad22003-01-24 02:44:45 +00005855 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5856 k - (y+k).s - (y+k).d = 0; rearranging,
5857 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5858 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005859
Tim Peters8bb5ad22003-01-24 02:44:45 +00005860On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5861approximate k by ignoring the (y+k).d term at first. Note that k can't be
5862very large, since all offset-returning methods return a duration of magnitude
5863less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5864be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005865
5866In any case, the new value is
5867
Tim Peters8bb5ad22003-01-24 02:44:45 +00005868 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005869
Tim Peters8bb5ad22003-01-24 02:44:45 +00005870It's helpful to step back at look at [4] from a higher level: it's simply
5871mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005872
5873At this point, if
5874
Tim Peters8bb5ad22003-01-24 02:44:45 +00005875 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005876
5877we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005878at the start of daylight time. Picture US Eastern for concreteness. The wall
5879time 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 +00005880sense then. The docs ask that an Eastern tzinfo class consider such a time to
5881be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5882on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005883the only spelling that makes sense on the local wall clock.
5884
Tim Petersc5dc4da2003-01-02 17:55:03 +00005885In fact, if [5] holds at this point, we do have the standard-time spelling,
5886but that takes a bit of proof. We first prove a stronger result. What's the
5887difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005888
Tim Peters8bb5ad22003-01-24 02:44:45 +00005889 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005890
Tim Petersc5dc4da2003-01-02 17:55:03 +00005891Now
5892 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005893 (y + y.s).n = by #5
5894 y.n + y.s = since y.n = x.n
5895 x.n + y.s = since z and y are have the same tzinfo member,
5896 y.s = z.s by #2
5897 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005898
Tim Petersc5dc4da2003-01-02 17:55:03 +00005899Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005900
Tim Petersc5dc4da2003-01-02 17:55:03 +00005901 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005902 x.n - ((x.n + z.s) - z.o) = expanding
5903 x.n - x.n - z.s + z.o = cancelling
5904 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005905 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005906
Tim Petersc5dc4da2003-01-02 17:55:03 +00005907So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005908
Tim Petersc5dc4da2003-01-02 17:55:03 +00005909If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005910spelling we wanted in the endcase described above. We're done. Contrarily,
5911if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005912
Tim Petersc5dc4da2003-01-02 17:55:03 +00005913If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5914add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005915local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005916
Tim Petersc5dc4da2003-01-02 17:55:03 +00005917Let
Tim Petersf3615152003-01-01 21:51:37 +00005918
Tim Peters4fede1a2003-01-04 00:26:59 +00005919 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005920
Tim Peters4fede1a2003-01-04 00:26:59 +00005921and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005922
Tim Peters8bb5ad22003-01-24 02:44:45 +00005923 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005924
Tim Peters8bb5ad22003-01-24 02:44:45 +00005925If so, we're done. If not, the tzinfo class is insane, according to the
5926assumptions we've made. This also requires a bit of proof. As before, let's
5927compute the difference between the LHS and RHS of [8] (and skipping some of
5928the justifications for the kinds of substitutions we've done several times
5929already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005930
Tim Peters8bb5ad22003-01-24 02:44:45 +00005931 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005932 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5933 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5934 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5935 - z.n + z.n - z.o + z'.o = cancel z.n
5936 - z.o + z'.o = #1 twice
5937 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5938 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005939
5940So 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 +00005941we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5942return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005943
Tim Peters8bb5ad22003-01-24 02:44:45 +00005944How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5945a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5946would have to change the result dst() returns: we start in DST, and moving
5947a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005948
Tim Peters8bb5ad22003-01-24 02:44:45 +00005949There isn't a sane case where this can happen. The closest it gets is at
5950the end of DST, where there's an hour in UTC with no spelling in a hybrid
5951tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5952that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5953UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5954time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5955clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5956standard time. Since that's what the local clock *does*, we want to map both
5957UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005958in local time, but so it goes -- it's the way the local clock works.
5959
Tim Peters8bb5ad22003-01-24 02:44:45 +00005960When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5961so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5962z' = 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 +00005963(correctly) concludes that z' is not UTC-equivalent to x.
5964
5965Because we know z.d said z was in daylight time (else [5] would have held and
5966we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005967and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005968return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5969but the reasoning doesn't depend on the example -- it depends on there being
5970two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005971z' must be in standard time, and is the spelling we want in this case.
5972
5973Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5974concerned (because it takes z' as being in standard time rather than the
5975daylight time we intend here), but returning it gives the real-life "local
5976clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5977tz.
5978
5979When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5980the 1:MM standard time spelling we want.
5981
5982So how can this break? One of the assumptions must be violated. Two
5983possibilities:
5984
59851) [2] effectively says that y.s is invariant across all y belong to a given
5986 time zone. This isn't true if, for political reasons or continental drift,
5987 a region decides to change its base offset from UTC.
5988
59892) There may be versions of "double daylight" time where the tail end of
5990 the analysis gives up a step too early. I haven't thought about that
5991 enough to say.
5992
5993In any case, it's clear that the default fromutc() is strong enough to handle
5994"almost all" time zones: so long as the standard offset is invariant, it
5995doesn't matter if daylight time transition points change from year to year, or
5996if daylight time is skipped in some years; it doesn't matter how large or
5997small dst() may get within its bounds; and it doesn't even matter if some
5998perverse time zone returns a negative dst()). So a breaking case must be
5999pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006000--------------------------------------------------------------------------- */