blob: 7b0da79a701c48759d9d7d500d3d4e8b0d8a7491 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
Tim Peters2a799bf2002-12-16 20:18:38 +00006#include "structmember.h"
7
8#include <time.h>
9
Victor Stinner09e5cf22015-03-30 00:09:18 +020010#ifdef MS_WINDOWS
11# include <winsock2.h> /* struct timeval */
12#endif
13
Tim Peters9ddf40b2004-06-20 22:41:32 +000014/* Differentiate between building the core module and building extension
15 * modules.
16 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000017#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000018#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000019#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000020#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000021#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000022
Larry Hastings61272b72014-01-07 12:41:53 -080023/*[clinic input]
Larry Hastings44e2eaa2013-11-23 15:37:55 -080024module datetime
Larry Hastingsc2047262014-01-25 20:43:29 -080025class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
Larry Hastings61272b72014-01-07 12:41:53 -080026[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -080027/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -080028
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030029#include "clinic/_datetimemodule.c.h"
30
Tim Peters2a799bf2002-12-16 20:18:38 +000031/* We require that C int be at least 32 bits, and use int virtually
32 * everywhere. In just a few cases we use a temp long, where a Python
33 * API returns a C long. In such cases, we have to ensure that the
34 * final result fits in a C int (this can be an issue on 64-bit boxes).
35 */
36#if SIZEOF_INT < 4
Alexander Belopolskycf86e362010-07-23 19:25:47 +000037# error "_datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000038#endif
39
40#define MINYEAR 1
41#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000042#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000043
44/* Nine decimal digits is easy to communicate, and leaves enough room
45 * so that two delta days can be added w/o fear of overflowing a signed
46 * 32-bit int, and with plenty of room left over to absorb any possible
47 * carries from adding seconds.
48 */
49#define MAX_DELTA_DAYS 999999999
50
51/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define GET_YEAR PyDateTime_GET_YEAR
53#define GET_MONTH PyDateTime_GET_MONTH
54#define GET_DAY PyDateTime_GET_DAY
55#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
56#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
57#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
58#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040059#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
Tim Peters2a799bf2002-12-16 20:18:38 +000060
61/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
63 ((o)->data[1] = ((v) & 0x00ff)))
64#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
65#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000066
67/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
69#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
70#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
71#define DATE_SET_MICROSECOND(o, v) \
72 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
73 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
74 ((o)->data[9] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040075#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000076
77/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
79#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
80#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
81#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040082#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
84#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
85#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
86#define TIME_SET_MICROSECOND(o, v) \
87 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
88 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
89 ((o)->data[5] = ((v) & 0x0000ff)))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -040090#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000091
92/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
94#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
95#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097#define SET_TD_DAYS(o, v) ((o)->days = (v))
98#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000099#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
100
Tim Petersa032d2e2003-01-11 00:15:54 +0000101/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
102 * p->hastzinfo.
103 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000104#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
105#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
106 ((PyDateTime_Time *)(p))->tzinfo : Py_None)
107#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
108 ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
Tim Peters3f606292004-03-21 23:38:41 +0000109/* M is a char or int claiming to be a valid month. The macro is equivalent
110 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +0000112 */
113#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
114
Tim Peters2a799bf2002-12-16 20:18:38 +0000115/* Forward declarations. */
116static PyTypeObject PyDateTime_DateType;
117static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000118static PyTypeObject PyDateTime_DeltaType;
119static PyTypeObject PyDateTime_TimeType;
120static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000121static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000122
Martin v. Löwise75fc142013-11-07 18:46:53 +0100123_Py_IDENTIFIER(as_integer_ratio);
124_Py_IDENTIFIER(fromutc);
125_Py_IDENTIFIER(isoformat);
126_Py_IDENTIFIER(strftime);
127
Tim Peters2a799bf2002-12-16 20:18:38 +0000128/* ---------------------------------------------------------------------------
129 * Math utilities.
130 */
131
132/* k = i+j overflows iff k differs in sign from both inputs,
133 * iff k^i has sign bit set and k^j has sign bit set,
134 * iff (k^i)&(k^j) has sign bit set.
135 */
136#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000138
139/* Compute Python divmod(x, y), returning the quotient and storing the
140 * remainder into *r. The quotient is the floor of x/y, and that's
141 * the real point of this. C will probably truncate instead (C99
142 * requires truncation; C89 left it implementation-defined).
143 * Simplification: we *require* that y > 0 here. That's appropriate
144 * for all the uses made of it. This simplifies the code and makes
145 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
146 * overflow case).
147 */
148static int
149divmod(int x, int y, int *r)
150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 assert(y > 0);
154 quo = x / y;
155 *r = x - quo * y;
156 if (*r < 0) {
157 --quo;
158 *r += y;
159 }
160 assert(0 <= *r && *r < y);
161 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000162}
163
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000164/* Nearest integer to m / n for integers m and n. Half-integer results
165 * are rounded to even.
166 */
167static PyObject *
168divide_nearest(PyObject *m, PyObject *n)
169{
170 PyObject *result;
171 PyObject *temp;
172
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000173 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000174 if (temp == NULL)
175 return NULL;
176 result = PyTuple_GET_ITEM(temp, 0);
177 Py_INCREF(result);
178 Py_DECREF(temp);
179
180 return result;
181}
182
Tim Peters2a799bf2002-12-16 20:18:38 +0000183/* ---------------------------------------------------------------------------
184 * General calendrical helper functions
185 */
186
187/* For each month ordinal in 1..12, the number of days in that month,
188 * and the number of days before that month in the same year. These
189 * are correct for non-leap years only.
190 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200191static const int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 0, /* unused; this vector uses 1-based indexing */
193 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000194};
195
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200196static const int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 0, /* unused; this vector uses 1-based indexing */
198 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000199};
200
201/* year -> 1 if leap year, else 0. */
202static int
203is_leap(int year)
204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 /* Cast year to unsigned. The result is the same either way, but
206 * C can generate faster code for unsigned mod than for signed
207 * mod (especially for % 4 -- a good compiler should just grab
208 * the last 2 bits when the LHS is unsigned).
209 */
210 const unsigned int ayear = (unsigned int)year;
211 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000212}
213
214/* year, month -> number of days in that month in that year */
215static int
216days_in_month(int year, int month)
217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 assert(month >= 1);
219 assert(month <= 12);
220 if (month == 2 && is_leap(year))
221 return 29;
222 else
223 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000224}
225
Martin Panter46f50722016-05-26 05:35:26 +0000226/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000227static int
228days_before_month(int year, int month)
229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 assert(month >= 1);
233 assert(month <= 12);
234 days = _days_before_month[month];
235 if (month > 2 && is_leap(year))
236 ++days;
237 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000238}
239
240/* year -> number of days before January 1st of year. Remember that we
241 * start with year 1, so days_before_year(1) == 0.
242 */
243static int
244days_before_year(int year)
245{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 int y = year - 1;
247 /* This is incorrect if year <= 0; we really want the floor
248 * here. But so long as MINYEAR is 1, the smallest year this
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000249 * can see is 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000251 assert (year >= 1);
252 return y*365 + y/4 - y/100 + y/400;
Tim Peters2a799bf2002-12-16 20:18:38 +0000253}
254
255/* Number of days in 4, 100, and 400 year cycles. That these have
256 * the correct values is asserted in the module init function.
257 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258#define DI4Y 1461 /* days_before_year(5); days in 4 years */
259#define DI100Y 36524 /* days_before_year(101); days in 100 years */
260#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000261
262/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
263static void
264ord_to_ymd(int ordinal, int *year, int *month, int *day)
265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
269 * leap years repeats exactly every 400 years. The basic strategy is
270 * to find the closest 400-year boundary at or before ordinal, then
271 * work with the offset from that boundary to ordinal. Life is much
272 * clearer if we subtract 1 from ordinal first -- then the values
273 * of ordinal at 400-year boundaries are exactly those divisible
274 * by DI400Y:
275 *
276 * D M Y n n-1
277 * -- --- ---- ---------- ----------------
278 * 31 Dec -400 -DI400Y -DI400Y -1
279 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
280 * ...
281 * 30 Dec 000 -1 -2
282 * 31 Dec 000 0 -1
283 * 1 Jan 001 1 0 400-year boundary
284 * 2 Jan 001 2 1
285 * 3 Jan 001 3 2
286 * ...
287 * 31 Dec 400 DI400Y DI400Y -1
288 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
289 */
290 assert(ordinal >= 1);
291 --ordinal;
292 n400 = ordinal / DI400Y;
293 n = ordinal % DI400Y;
294 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 /* Now n is the (non-negative) offset, in days, from January 1 of
297 * year, to the desired date. Now compute how many 100-year cycles
298 * precede n.
299 * Note that it's possible for n100 to equal 4! In that case 4 full
300 * 100-year cycles precede the desired day, which implies the
301 * desired day is December 31 at the end of a 400-year cycle.
302 */
303 n100 = n / DI100Y;
304 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 /* Now compute how many 4-year cycles precede it. */
307 n4 = n / DI4Y;
308 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 /* And now how many single years. Again n1 can be 4, and again
311 * meaning that the desired day is December 31 at the end of the
312 * 4-year cycle.
313 */
314 n1 = n / 365;
315 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 *year += n100 * 100 + n4 * 4 + n1;
318 if (n1 == 4 || n100 == 4) {
319 assert(n == 0);
320 *year -= 1;
321 *month = 12;
322 *day = 31;
323 return;
324 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 /* Now the year is correct, and n is the offset from January 1. We
327 * find the month via an estimate that's either exact or one too
328 * large.
329 */
330 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
331 assert(leapyear == is_leap(*year));
332 *month = (n + 50) >> 5;
333 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
334 if (preceding > n) {
335 /* estimate is too large */
336 *month -= 1;
337 preceding -= days_in_month(*year, *month);
338 }
339 n -= preceding;
340 assert(0 <= n);
341 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000344}
345
346/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
347static int
348ymd_to_ord(int year, int month, int day)
349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000351}
352
353/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
354static int
355weekday(int year, int month, int day)
356{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000358}
359
360/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
361 * first calendar week containing a Thursday.
362 */
363static int
364iso_week1_monday(int year)
365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
367 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
368 int first_weekday = (first_day + 6) % 7;
369 /* ordinal of closest Monday at or before 1/1 */
370 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
373 week1_monday += 7;
374 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000375}
376
377/* ---------------------------------------------------------------------------
378 * Range checkers.
379 */
380
381/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
382 * If not, raise OverflowError and return -1.
383 */
384static int
385check_delta_day_range(int days)
386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
388 return 0;
389 PyErr_Format(PyExc_OverflowError,
390 "days=%d; must have magnitude <= %d",
391 days, MAX_DELTA_DAYS);
392 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000393}
394
395/* Check that date arguments are in range. Return 0 if they are. If they
396 * aren't, raise ValueError and return -1.
397 */
398static int
399check_date_args(int year, int month, int day)
400{
401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 if (year < MINYEAR || year > MAXYEAR) {
403 PyErr_SetString(PyExc_ValueError,
404 "year is out of range");
405 return -1;
406 }
407 if (month < 1 || month > 12) {
408 PyErr_SetString(PyExc_ValueError,
409 "month must be in 1..12");
410 return -1;
411 }
412 if (day < 1 || day > days_in_month(year, month)) {
413 PyErr_SetString(PyExc_ValueError,
414 "day is out of range for month");
415 return -1;
416 }
417 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000418}
419
420/* Check that time arguments are in range. Return 0 if they are. If they
421 * aren't, raise ValueError and return -1.
422 */
423static int
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400424check_time_args(int h, int m, int s, int us, int fold)
Tim Peters2a799bf2002-12-16 20:18:38 +0000425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 if (h < 0 || h > 23) {
427 PyErr_SetString(PyExc_ValueError,
428 "hour must be in 0..23");
429 return -1;
430 }
431 if (m < 0 || m > 59) {
432 PyErr_SetString(PyExc_ValueError,
433 "minute must be in 0..59");
434 return -1;
435 }
436 if (s < 0 || s > 59) {
437 PyErr_SetString(PyExc_ValueError,
438 "second must be in 0..59");
439 return -1;
440 }
441 if (us < 0 || us > 999999) {
442 PyErr_SetString(PyExc_ValueError,
443 "microsecond must be in 0..999999");
444 return -1;
445 }
Alexander Belopolsky47649ab2016-08-08 17:05:40 -0400446 if (fold != 0 && fold != 1) {
447 PyErr_SetString(PyExc_ValueError,
448 "fold must be either 0 or 1");
449 return -1;
450 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000452}
453
454/* ---------------------------------------------------------------------------
455 * Normalization utilities.
456 */
457
458/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
459 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
460 * at least factor, enough of *lo is converted into "hi" units so that
461 * 0 <= *lo < factor. The input values must be such that int overflow
462 * is impossible.
463 */
464static void
465normalize_pair(int *hi, int *lo, int factor)
466{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 assert(factor > 0);
468 assert(lo != hi);
469 if (*lo < 0 || *lo >= factor) {
470 const int num_hi = divmod(*lo, factor, lo);
471 const int new_hi = *hi + num_hi;
472 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
473 *hi = new_hi;
474 }
475 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000476}
477
478/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 * 0 <= *s < 24*3600
480 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000481 * The input values must be such that the internals don't overflow.
482 * The way this routine is used, we don't get close.
483 */
484static void
485normalize_d_s_us(int *d, int *s, int *us)
486{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 if (*us < 0 || *us >= 1000000) {
488 normalize_pair(s, us, 1000000);
489 /* |s| can't be bigger than about
490 * |original s| + |original us|/1000000 now.
491 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 }
494 if (*s < 0 || *s >= 24*3600) {
495 normalize_pair(d, s, 24*3600);
496 /* |d| can't be bigger than about
497 * |original d| +
498 * (|original s| + |original us|/1000000) / (24*3600) now.
499 */
500 }
501 assert(0 <= *s && *s < 24*3600);
502 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000503}
504
505/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 * 1 <= *m <= 12
507 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000508 * The input values must be such that the internals don't overflow.
509 * The way this routine is used, we don't get close.
510 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000511static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000512normalize_y_m_d(int *y, int *m, int *d)
513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000515
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000516 /* In actual use, m is always the month component extracted from a
517 * date/datetime object. Therefore it is always in [1, 12] range.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 */
Alexander Belopolsky59a289d2010-10-13 22:54:34 +0000519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 /* Now only day can be out of bounds (year may also be out of bounds
523 * for a datetime object, but we don't care about that here).
524 * If day is out of bounds, what to do is arguable, but at least the
525 * method here is principled and explainable.
526 */
527 dim = days_in_month(*y, *m);
528 if (*d < 1 || *d > dim) {
529 /* Move day-1 days from the first of the month. First try to
530 * get off cheap if we're only one day out of range
531 * (adjustments for timezone alone can't be worse than that).
532 */
533 if (*d == 0) {
534 --*m;
535 if (*m > 0)
536 *d = days_in_month(*y, *m);
537 else {
538 --*y;
539 *m = 12;
540 *d = 31;
541 }
542 }
543 else if (*d == dim + 1) {
544 /* move forward a day */
545 ++*m;
546 *d = 1;
547 if (*m > 12) {
548 *m = 1;
549 ++*y;
550 }
551 }
552 else {
553 int ordinal = ymd_to_ord(*y, *m, 1) +
554 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000555 if (ordinal < 1 || ordinal > MAXORDINAL) {
556 goto error;
557 } else {
558 ord_to_ymd(ordinal, y, m, d);
559 return 0;
560 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 }
562 }
563 assert(*m > 0);
564 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000565 if (MINYEAR <= *y && *y <= MAXYEAR)
566 return 0;
567 error:
568 PyErr_SetString(PyExc_OverflowError,
569 "date value out of range");
570 return -1;
571
Tim Peters2a799bf2002-12-16 20:18:38 +0000572}
573
574/* Fiddle out-of-bounds months and days so that the result makes some kind
575 * of sense. The parameters are both inputs and outputs. Returns < 0 on
576 * failure, where failure means the adjusted year is out of bounds.
577 */
578static int
579normalize_date(int *year, int *month, int *day)
580{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000581 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000582}
583
584/* Force all the datetime fields into range. The parameters are both
585 * inputs and outputs. Returns < 0 on error.
586 */
587static int
588normalize_datetime(int *year, int *month, int *day,
589 int *hour, int *minute, int *second,
590 int *microsecond)
591{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 normalize_pair(second, microsecond, 1000000);
593 normalize_pair(minute, second, 60);
594 normalize_pair(hour, minute, 60);
595 normalize_pair(day, hour, 24);
596 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000597}
598
599/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000600 * Basic object allocation: tp_alloc implementations. These allocate
601 * Python objects of the right size and type, and do the Python object-
602 * initialization bit. If there's not enough memory, they return NULL after
603 * setting MemoryError. All data members remain uninitialized trash.
604 *
605 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000606 * member is needed. This is ugly, imprecise, and possibly insecure.
607 * tp_basicsize for the time and datetime types is set to the size of the
608 * struct that has room for the tzinfo member, so subclasses in Python will
609 * allocate enough space for a tzinfo member whether or not one is actually
610 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
611 * part is that PyType_GenericAlloc() (which subclasses in Python end up
612 * using) just happens today to effectively ignore the nitems argument
613 * when tp_itemsize is 0, which it is for these type objects. If that
614 * changes, perhaps the callers of tp_alloc slots in this file should
615 * be changed to force a 0 nitems argument unless the type being allocated
616 * is a base type implemented in this file (so that tp_alloc is time_alloc
617 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000618 */
619
620static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000621time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 self = (PyObject *)
626 PyObject_MALLOC(aware ?
627 sizeof(PyDateTime_Time) :
628 sizeof(_PyDateTime_BaseTime));
629 if (self == NULL)
630 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100631 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000633}
634
635static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000636datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 self = (PyObject *)
641 PyObject_MALLOC(aware ?
642 sizeof(PyDateTime_DateTime) :
643 sizeof(_PyDateTime_BaseDateTime));
644 if (self == NULL)
645 return (PyObject *)PyErr_NoMemory();
Christian Heimesecb4e6a2013-12-04 09:34:29 +0100646 (void)PyObject_INIT(self, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000648}
649
650/* ---------------------------------------------------------------------------
651 * Helpers for setting object fields. These work on pointers to the
652 * appropriate base class.
653 */
654
655/* For date and datetime. */
656static void
657set_date_fields(PyDateTime_Date *self, int y, int m, int d)
658{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 self->hashcode = -1;
660 SET_YEAR(self, y);
661 SET_MONTH(self, m);
662 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000663}
664
665/* ---------------------------------------------------------------------------
666 * Create various objects, mostly without range checking.
667 */
668
669/* Create a date instance with no range checking. */
670static PyObject *
671new_date_ex(int year, int month, int day, PyTypeObject *type)
672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
676 if (self != NULL)
677 set_date_fields(self, year, month, day);
678 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000679}
680
681#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000683
684/* Create a datetime instance with no range checking. */
685static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400686new_datetime_ex2(int year, int month, int day, int hour, int minute,
687 int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 PyDateTime_DateTime *self;
690 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
693 if (self != NULL) {
694 self->hastzinfo = aware;
695 set_date_fields((PyDateTime_Date *)self, year, month, day);
696 DATE_SET_HOUR(self, hour);
697 DATE_SET_MINUTE(self, minute);
698 DATE_SET_SECOND(self, second);
699 DATE_SET_MICROSECOND(self, usecond);
700 if (aware) {
701 Py_INCREF(tzinfo);
702 self->tzinfo = tzinfo;
703 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400704 DATE_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 }
706 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000707}
708
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400709static PyObject *
710new_datetime_ex(int year, int month, int day, int hour, int minute,
711 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
712{
713 return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
714 tzinfo, 0, type);
715}
716
717#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
718 new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000720
721/* Create a time instance with no range checking. */
722static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400723new_time_ex2(int hour, int minute, int second, int usecond,
724 PyObject *tzinfo, int fold, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 PyDateTime_Time *self;
727 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
730 if (self != NULL) {
731 self->hastzinfo = aware;
732 self->hashcode = -1;
733 TIME_SET_HOUR(self, hour);
734 TIME_SET_MINUTE(self, minute);
735 TIME_SET_SECOND(self, second);
736 TIME_SET_MICROSECOND(self, usecond);
737 if (aware) {
738 Py_INCREF(tzinfo);
739 self->tzinfo = tzinfo;
740 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400741 TIME_SET_FOLD(self, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 }
743 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000744}
745
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400746static PyObject *
747new_time_ex(int hour, int minute, int second, int usecond,
748 PyObject *tzinfo, PyTypeObject *type)
749{
750 return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
751}
752
753#define new_time(hh, mm, ss, us, tzinfo, fold) \
754 new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000755
756/* Create a timedelta instance. Normalize the members iff normalize is
757 * true. Passing false is a speed optimization, if you know for sure
758 * that seconds and microseconds are already in their proper ranges. In any
759 * case, raises OverflowError and returns NULL if the normalized days is out
760 * of range).
761 */
762static PyObject *
763new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 if (normalize)
769 normalize_d_s_us(&days, &seconds, &microseconds);
770 assert(0 <= seconds && seconds < 24*3600);
771 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 if (check_delta_day_range(days) < 0)
774 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
777 if (self != NULL) {
778 self->hashcode = -1;
779 SET_TD_DAYS(self, days);
780 SET_TD_SECONDS(self, seconds);
781 SET_TD_MICROSECONDS(self, microseconds);
782 }
783 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000784}
785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786#define new_delta(d, s, us, normalize) \
787 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000788
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000789
790typedef struct
791{
792 PyObject_HEAD
793 PyObject *offset;
794 PyObject *name;
795} PyDateTime_TimeZone;
796
Victor Stinner6ced7c42011-03-21 18:15:42 +0100797/* The interned UTC timezone instance */
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000798static PyObject *PyDateTime_TimeZone_UTC;
Alexander Belopolskya4415142012-06-08 12:33:09 -0400799/* The interned Epoch datetime instance */
800static PyObject *PyDateTime_Epoch;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000801
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000802/* Create new timezone instance checking offset range. This
803 function does not check the name argument. Caller must assure
804 that offset is a timedelta instance and name is either NULL
805 or a unicode object. */
806static PyObject *
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000807create_timezone(PyObject *offset, PyObject *name)
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000808{
809 PyDateTime_TimeZone *self;
810 PyTypeObject *type = &PyDateTime_TimeZoneType;
811
812 assert(offset != NULL);
813 assert(PyDelta_Check(offset));
814 assert(name == NULL || PyUnicode_Check(name));
815
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000816 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
817 if (self == NULL) {
818 return NULL;
819 }
820 Py_INCREF(offset);
821 self->offset = offset;
822 Py_XINCREF(name);
823 self->name = name;
824 return (PyObject *)self;
825}
826
827static int delta_bool(PyDateTime_Delta *self);
828
829static PyObject *
830new_timezone(PyObject *offset, PyObject *name)
831{
832 assert(offset != NULL);
833 assert(PyDelta_Check(offset));
834 assert(name == NULL || PyUnicode_Check(name));
835
836 if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
837 Py_INCREF(PyDateTime_TimeZone_UTC);
838 return PyDateTime_TimeZone_UTC;
839 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000840 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
841 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400842 " representing a whole number of minutes,"
843 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000844 return NULL;
845 }
846 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
847 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
848 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
849 " strictly between -timedelta(hours=24) and"
Alexander Belopolsky31227ca2012-06-22 13:23:21 -0400850 " timedelta(hours=24),"
851 " not %R.", offset);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000852 return NULL;
853 }
854
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +0000855 return create_timezone(offset, name);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000856}
857
Tim Petersb0c854d2003-05-17 15:57:00 +0000858/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000859 * tzinfo helpers.
860 */
861
Tim Peters855fe882002-12-22 03:43:39 +0000862/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
863 * raise TypeError and return -1.
864 */
865static int
866check_tzinfo_subclass(PyObject *p)
867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 if (p == Py_None || PyTZInfo_Check(p))
869 return 0;
870 PyErr_Format(PyExc_TypeError,
871 "tzinfo argument must be None or of a tzinfo subclass, "
872 "not type '%s'",
873 Py_TYPE(p)->tp_name);
874 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000875}
876
Tim Peters2a799bf2002-12-16 20:18:38 +0000877/* If self has a tzinfo member, return a BORROWED reference to it. Else
878 * return NULL, which is NOT AN ERROR. There are no error returns here,
879 * and the caller must not decref the result.
880 */
881static PyObject *
882get_tzinfo_member(PyObject *self)
883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 if (PyDateTime_Check(self) && HASTZINFO(self))
887 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
888 else if (PyTime_Check(self) && HASTZINFO(self))
889 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000892}
893
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000894/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
895 * be an instance of the tzinfo class. If the method returns None, this
896 * returns None. If the method doesn't return None or timedelta, TypeError is
897 * raised and this returns NULL. If it returns a timedelta and the value is
898 * out of range or isn't a whole number of minutes, ValueError is raised and
899 * this returns NULL. Else result is returned.
Tim Peters2a799bf2002-12-16 20:18:38 +0000900 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000901static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200902call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000903{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000904 PyObject *offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 assert(tzinfo != NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000907 assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000909
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000910 if (tzinfo == Py_None)
911 Py_RETURN_NONE;
912 offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
913 if (offset == Py_None || offset == NULL)
914 return offset;
915 if (PyDelta_Check(offset)) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400916 if (GET_TD_MICROSECONDS(offset) != 0) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000917 Py_DECREF(offset);
918 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -0400919 " representing a whole number of seconds");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000920 return NULL;
921 }
922 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
923 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
924 Py_DECREF(offset);
925 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
926 " strictly between -timedelta(hours=24) and"
927 " timedelta(hours=24).");
928 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 }
930 }
931 else {
932 PyErr_Format(PyExc_TypeError,
933 "tzinfo.%s() must return None or "
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000934 "timedelta, not '%.200s'",
935 name, Py_TYPE(offset)->tp_name);
Raymond Hettinger5a2146a2014-07-25 14:59:48 -0700936 Py_DECREF(offset);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000937 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000939
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000940 return offset;
Tim Peters2a799bf2002-12-16 20:18:38 +0000941}
942
943/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
944 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
945 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000946 * doesn't return None or timedelta, TypeError is raised and this returns -1.
947 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
948 * # of minutes), ValueError is raised and this returns -1. Else *none is
949 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000950 */
Tim Peters855fe882002-12-22 03:43:39 +0000951static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000952call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
953{
954 return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000955}
956
Tim Peters2a799bf2002-12-16 20:18:38 +0000957/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
958 * result. tzinfo must be an instance of the tzinfo class. If dst()
959 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000960 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000961 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000962 * ValueError is raised and this returns -1. Else *none is set to 0 and
963 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000964 */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000965static PyObject *
966call_dst(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000967{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000968 return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000969}
970
Tim Petersbad8ff02002-12-30 20:52:32 +0000971/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000972 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000973 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000974 * returns NULL. If the result is a string, we ensure it is a Unicode
975 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000976 */
977static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000978call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200981 _Py_IDENTIFIER(tzname);
Tim Peters2a799bf2002-12-16 20:18:38 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 assert(tzinfo != NULL);
984 assert(check_tzinfo_subclass(tzinfo) >= 0);
985 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 if (tzinfo == Py_None)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000988 Py_RETURN_NONE;
Tim Peters2a799bf2002-12-16 20:18:38 +0000989
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200990 result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000991
992 if (result == NULL || result == Py_None)
993 return result;
994
995 if (!PyUnicode_Check(result)) {
996 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
997 "return None or a string, not '%s'",
998 Py_TYPE(result)->tp_name);
999 Py_DECREF(result);
1000 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001002
1003 return result;
Tim Peters00237032002-12-27 02:21:51 +00001004}
1005
Tim Peters2a799bf2002-12-16 20:18:38 +00001006/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1007 * stuff
1008 * ", tzinfo=" + repr(tzinfo)
1009 * before the closing ")".
1010 */
1011static PyObject *
1012append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1013{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 assert(PyUnicode_Check(repr));
1017 assert(tzinfo);
1018 if (tzinfo == Py_None)
1019 return repr;
1020 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001021 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1022 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 Py_DECREF(repr);
1024 if (temp == NULL)
1025 return NULL;
1026 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1027 Py_DECREF(temp);
1028 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001029}
1030
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001031/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1032 * stuff
1033 * ", fold=" + repr(tzinfo)
1034 * before the closing ")".
1035 */
1036static PyObject *
1037append_keyword_fold(PyObject *repr, int fold)
1038{
1039 PyObject *temp;
1040
1041 assert(PyUnicode_Check(repr));
1042 if (fold == 0)
1043 return repr;
1044 /* Get rid of the trailing ')'. */
1045 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1046 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1047 Py_DECREF(repr);
1048 if (temp == NULL)
1049 return NULL;
1050 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1051 Py_DECREF(temp);
1052 return repr;
1053}
1054
Tim Peters2a799bf2002-12-16 20:18:38 +00001055/* ---------------------------------------------------------------------------
1056 * String format helpers.
1057 */
1058
1059static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001060format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001061{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001062 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1064 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001065 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1067 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1068 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1073 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1074 GET_DAY(date), hours, minutes, seconds,
1075 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001076}
1077
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001078static PyObject *delta_negative(PyDateTime_Delta *self);
1079
Tim Peters2a799bf2002-12-16 20:18:38 +00001080/* Add an hours & minutes UTC offset string to buf. buf has no more than
1081 * buflen bytes remaining. The UTC offset is gotten by calling
1082 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1083 * *buf, and that's all. Else the returned value is checked for sanity (an
1084 * integer in range), and if that's OK it's converted to an hours & minutes
1085 * string of the form
1086 * sign HH sep MM
1087 * Returns 0 if everything is OK. If the return value from utcoffset() is
1088 * bogus, an appropriate exception is set and -1 is returned.
1089 */
1090static int
Tim Peters328fff72002-12-20 01:31:27 +00001091format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001093{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001094 PyObject *offset;
1095 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001099
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001100 offset = call_utcoffset(tzinfo, tzinfoarg);
1101 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001103 if (offset == Py_None) {
1104 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 *buf = '\0';
1106 return 0;
1107 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001108 /* Offset is normalized, so it is negative if days < 0 */
1109 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001111 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001112 if (offset == NULL)
1113 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001115 else {
1116 sign = '+';
1117 }
1118 /* Offset is not negative here. */
1119 seconds = GET_TD_SECONDS(offset);
1120 Py_DECREF(offset);
1121 minutes = divmod(seconds, 60, &seconds);
1122 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001123 if (seconds == 0)
1124 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1125 else
1126 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1127 sep, minutes, sep, seconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001129}
1130
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001131static PyObject *
1132make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 PyObject *temp;
1135 PyObject *tzinfo = get_tzinfo_member(object);
1136 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001137 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 if (Zreplacement == NULL)
1140 return NULL;
1141 if (tzinfo == Py_None || tzinfo == NULL)
1142 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 assert(tzinfoarg != NULL);
1145 temp = call_tzname(tzinfo, tzinfoarg);
1146 if (temp == NULL)
1147 goto Error;
1148 if (temp == Py_None) {
1149 Py_DECREF(temp);
1150 return Zreplacement;
1151 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 assert(PyUnicode_Check(temp));
1154 /* Since the tzname is getting stuffed into the
1155 * format, we have to double any % signs so that
1156 * strftime doesn't treat them as format codes.
1157 */
1158 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001159 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 Py_DECREF(temp);
1161 if (Zreplacement == NULL)
1162 return NULL;
1163 if (!PyUnicode_Check(Zreplacement)) {
1164 PyErr_SetString(PyExc_TypeError,
1165 "tzname.replace() did not return a string");
1166 goto Error;
1167 }
1168 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001169
1170 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 Py_DECREF(Zreplacement);
1172 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001173}
1174
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001175static PyObject *
1176make_freplacement(PyObject *object)
1177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 char freplacement[64];
1179 if (PyTime_Check(object))
1180 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1181 else if (PyDateTime_Check(object))
1182 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1183 else
1184 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001187}
1188
Tim Peters2a799bf2002-12-16 20:18:38 +00001189/* I sure don't want to reproduce the strftime code from the time module,
1190 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001191 * giving special meanings to the %z, %Z and %f format codes via a
1192 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001193 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1194 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001195 */
1196static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001197wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1203 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1204 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 const char *pin; /* pointer to next char in input format */
1207 Py_ssize_t flen; /* length of input format */
1208 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 PyObject *newfmt = NULL; /* py string, the output format */
1211 char *pnew; /* pointer to available byte in output format */
1212 size_t totalnew; /* number bytes total in output format buffer,
1213 exclusive of trailing \0 */
1214 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 const char *ptoappend; /* ptr to string to append to output buffer */
1217 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 assert(object && format && timetuple);
1220 assert(PyUnicode_Check(format));
1221 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001222 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 if (!pin)
1224 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 /* Scan the input format, looking for %z/%Z/%f escapes, building
1227 * a new format. Since computing the replacements for those codes
1228 * is expensive, don't unless they're actually used.
1229 */
1230 if (flen > INT_MAX - 1) {
1231 PyErr_NoMemory();
1232 goto Done;
1233 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 totalnew = flen + 1; /* realistic if no %z/%Z */
1236 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1237 if (newfmt == NULL) goto Done;
1238 pnew = PyBytes_AsString(newfmt);
1239 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 while ((ch = *pin++) != '\0') {
1242 if (ch != '%') {
1243 ptoappend = pin - 1;
1244 ntoappend = 1;
1245 }
1246 else if ((ch = *pin++) == '\0') {
1247 /* There's a lone trailing %; doesn't make sense. */
1248 PyErr_SetString(PyExc_ValueError, "strftime format "
1249 "ends with raw %");
1250 goto Done;
1251 }
1252 /* A % has been seen and ch is the character after it. */
1253 else if (ch == 'z') {
1254 if (zreplacement == NULL) {
1255 /* format utcoffset */
1256 char buf[100];
1257 PyObject *tzinfo = get_tzinfo_member(object);
1258 zreplacement = PyBytes_FromStringAndSize("", 0);
1259 if (zreplacement == NULL) goto Done;
1260 if (tzinfo != Py_None && tzinfo != NULL) {
1261 assert(tzinfoarg != NULL);
1262 if (format_utcoffset(buf,
1263 sizeof(buf),
1264 "",
1265 tzinfo,
1266 tzinfoarg) < 0)
1267 goto Done;
1268 Py_DECREF(zreplacement);
1269 zreplacement =
1270 PyBytes_FromStringAndSize(buf,
1271 strlen(buf));
1272 if (zreplacement == NULL)
1273 goto Done;
1274 }
1275 }
1276 assert(zreplacement != NULL);
1277 ptoappend = PyBytes_AS_STRING(zreplacement);
1278 ntoappend = PyBytes_GET_SIZE(zreplacement);
1279 }
1280 else if (ch == 'Z') {
1281 /* format tzname */
1282 if (Zreplacement == NULL) {
1283 Zreplacement = make_Zreplacement(object,
1284 tzinfoarg);
1285 if (Zreplacement == NULL)
1286 goto Done;
1287 }
1288 assert(Zreplacement != NULL);
1289 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001290 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001292 if (ptoappend == NULL)
1293 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 }
1295 else if (ch == 'f') {
1296 /* format microseconds */
1297 if (freplacement == NULL) {
1298 freplacement = make_freplacement(object);
1299 if (freplacement == NULL)
1300 goto Done;
1301 }
1302 assert(freplacement != NULL);
1303 assert(PyBytes_Check(freplacement));
1304 ptoappend = PyBytes_AS_STRING(freplacement);
1305 ntoappend = PyBytes_GET_SIZE(freplacement);
1306 }
1307 else {
1308 /* percent followed by neither z nor Z */
1309 ptoappend = pin - 2;
1310 ntoappend = 2;
1311 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 /* Append the ntoappend chars starting at ptoappend to
1314 * the new format.
1315 */
1316 if (ntoappend == 0)
1317 continue;
1318 assert(ptoappend != NULL);
1319 assert(ntoappend > 0);
1320 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001321 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 PyErr_NoMemory();
1323 goto Done;
1324 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001325 totalnew <<= 1;
1326 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 pnew = PyBytes_AsString(newfmt) + usednew;
1329 }
1330 memcpy(pnew, ptoappend, ntoappend);
1331 pnew += ntoappend;
1332 usednew += ntoappend;
1333 assert(usednew <= totalnew);
1334 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1337 goto Done;
1338 {
1339 PyObject *format;
1340 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 if (time == NULL)
1343 goto Done;
1344 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1345 if (format != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001346 result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
1347 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 Py_DECREF(format);
1349 }
1350 Py_DECREF(time);
1351 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001352 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 Py_XDECREF(freplacement);
1354 Py_XDECREF(zreplacement);
1355 Py_XDECREF(Zreplacement);
1356 Py_XDECREF(newfmt);
1357 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001358}
1359
Tim Peters2a799bf2002-12-16 20:18:38 +00001360/* ---------------------------------------------------------------------------
1361 * Wrap functions from the time module. These aren't directly available
1362 * from C. Perhaps they should be.
1363 */
1364
1365/* Call time.time() and return its result (a Python float). */
1366static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001367time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 PyObject *result = NULL;
1370 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001373 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001374
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001375 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 Py_DECREF(time);
1377 }
1378 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001379}
1380
1381/* Build a time.struct_time. The weekday and day number are automatically
1382 * computed from the y,m,d args.
1383 */
1384static PyObject *
1385build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001388 PyObject *result;
1389 _Py_IDENTIFIER(struct_time);
1390 PyObject *args;
1391
Tim Peters2a799bf2002-12-16 20:18:38 +00001392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001394 if (time == NULL) {
1395 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 }
Victor Stinner2b635972016-12-09 00:38:16 +01001397
1398 args = Py_BuildValue("iiiiiiiii",
1399 y, m, d,
1400 hh, mm, ss,
1401 weekday(y, m, d),
1402 days_before_month(y, m) + d,
1403 dstflag);
1404 if (args == NULL) {
1405 Py_DECREF(time);
1406 return NULL;
1407 }
1408
1409 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1410 args, NULL);
1411 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001412 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001414}
1415
1416/* ---------------------------------------------------------------------------
1417 * Miscellaneous helpers.
1418 */
1419
Mark Dickinsone94c6792009-02-02 20:36:42 +00001420/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001421 * The comparisons here all most naturally compute a cmp()-like result.
1422 * This little helper turns that into a bool result for rich comparisons.
1423 */
1424static PyObject *
1425diff_to_bool(int diff, int op)
1426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 PyObject *result;
1428 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 switch (op) {
1431 case Py_EQ: istrue = diff == 0; break;
1432 case Py_NE: istrue = diff != 0; break;
1433 case Py_LE: istrue = diff <= 0; break;
1434 case Py_GE: istrue = diff >= 0; break;
1435 case Py_LT: istrue = diff < 0; break;
1436 case Py_GT: istrue = diff > 0; break;
1437 default:
1438 assert(! "op unknown");
1439 istrue = 0; /* To shut up compiler */
1440 }
1441 result = istrue ? Py_True : Py_False;
1442 Py_INCREF(result);
1443 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001444}
1445
Tim Peters07534a62003-02-07 22:50:28 +00001446/* Raises a "can't compare" TypeError and returns NULL. */
1447static PyObject *
1448cmperror(PyObject *a, PyObject *b)
1449{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 PyErr_Format(PyExc_TypeError,
1451 "can't compare %s to %s",
1452 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1453 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001454}
1455
Tim Peters2a799bf2002-12-16 20:18:38 +00001456/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001457 * Cached Python objects; these are set by the module init function.
1458 */
1459
1460/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001461static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462static PyObject *us_per_ms = NULL; /* 1000 */
1463static PyObject *us_per_second = NULL; /* 1000000 */
1464static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001465static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1466static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1467static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001468static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1469
Tim Peters2a799bf2002-12-16 20:18:38 +00001470/* ---------------------------------------------------------------------------
1471 * Class implementations.
1472 */
1473
1474/*
1475 * PyDateTime_Delta implementation.
1476 */
1477
1478/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001480 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001481 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1482 * due to ubiquitous overflow possibilities.
1483 */
1484static PyObject *
1485delta_to_microseconds(PyDateTime_Delta *self)
1486{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 PyObject *x1 = NULL;
1488 PyObject *x2 = NULL;
1489 PyObject *x3 = NULL;
1490 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1493 if (x1 == NULL)
1494 goto Done;
1495 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1496 if (x2 == NULL)
1497 goto Done;
1498 Py_DECREF(x1);
1499 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 /* x2 has days in seconds */
1502 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1503 if (x1 == NULL)
1504 goto Done;
1505 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1506 if (x3 == NULL)
1507 goto Done;
1508 Py_DECREF(x1);
1509 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001510 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 /* x3 has days+seconds in seconds */
1513 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1514 if (x1 == NULL)
1515 goto Done;
1516 Py_DECREF(x3);
1517 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 /* x1 has days+seconds in us */
1520 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1521 if (x2 == NULL)
1522 goto Done;
1523 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001524
1525Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 Py_XDECREF(x1);
1527 Py_XDECREF(x2);
1528 Py_XDECREF(x3);
1529 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001530}
1531
Serhiy Storchaka95949422013-08-27 19:40:23 +03001532/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001533 */
1534static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001535microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001536{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 int us;
1538 int s;
1539 int d;
1540 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 PyObject *tuple = NULL;
1543 PyObject *num = NULL;
1544 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 tuple = PyNumber_Divmod(pyus, us_per_second);
1547 if (tuple == NULL)
1548 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 num = PyTuple_GetItem(tuple, 1); /* us */
1551 if (num == NULL)
1552 goto Done;
1553 temp = PyLong_AsLong(num);
1554 num = NULL;
1555 if (temp == -1 && PyErr_Occurred())
1556 goto Done;
1557 assert(0 <= temp && temp < 1000000);
1558 us = (int)temp;
1559 if (us < 0) {
1560 /* The divisor was positive, so this must be an error. */
1561 assert(PyErr_Occurred());
1562 goto Done;
1563 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1566 if (num == NULL)
1567 goto Done;
1568 Py_INCREF(num);
1569 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 tuple = PyNumber_Divmod(num, seconds_per_day);
1572 if (tuple == NULL)
1573 goto Done;
1574 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 num = PyTuple_GetItem(tuple, 1); /* seconds */
1577 if (num == NULL)
1578 goto Done;
1579 temp = PyLong_AsLong(num);
1580 num = NULL;
1581 if (temp == -1 && PyErr_Occurred())
1582 goto Done;
1583 assert(0 <= temp && temp < 24*3600);
1584 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 if (s < 0) {
1587 /* The divisor was positive, so this must be an error. */
1588 assert(PyErr_Occurred());
1589 goto Done;
1590 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1593 if (num == NULL)
1594 goto Done;
1595 Py_INCREF(num);
1596 temp = PyLong_AsLong(num);
1597 if (temp == -1 && PyErr_Occurred())
1598 goto Done;
1599 d = (int)temp;
1600 if ((long)d != temp) {
1601 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1602 "large to fit in a C int");
1603 goto Done;
1604 }
1605 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001606
1607Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 Py_XDECREF(tuple);
1609 Py_XDECREF(num);
1610 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001611}
1612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613#define microseconds_to_delta(pymicros) \
1614 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001615
Tim Peters2a799bf2002-12-16 20:18:38 +00001616static PyObject *
1617multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 PyObject *pyus_in;
1620 PyObject *pyus_out;
1621 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 pyus_in = delta_to_microseconds(delta);
1624 if (pyus_in == NULL)
1625 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1628 Py_DECREF(pyus_in);
1629 if (pyus_out == NULL)
1630 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 result = microseconds_to_delta(pyus_out);
1633 Py_DECREF(pyus_out);
1634 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001635}
1636
1637static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001638multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1639{
1640 PyObject *result = NULL;
1641 PyObject *pyus_in = NULL, *temp, *pyus_out;
1642 PyObject *ratio = NULL;
1643
1644 pyus_in = delta_to_microseconds(delta);
1645 if (pyus_in == NULL)
1646 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001647 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001648 if (ratio == NULL)
1649 goto error;
1650 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1651 Py_DECREF(pyus_in);
1652 pyus_in = NULL;
1653 if (temp == NULL)
1654 goto error;
1655 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1656 Py_DECREF(temp);
1657 if (pyus_out == NULL)
1658 goto error;
1659 result = microseconds_to_delta(pyus_out);
1660 Py_DECREF(pyus_out);
1661 error:
1662 Py_XDECREF(pyus_in);
1663 Py_XDECREF(ratio);
1664
1665 return result;
1666}
1667
1668static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001669divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 PyObject *pyus_in;
1672 PyObject *pyus_out;
1673 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 pyus_in = delta_to_microseconds(delta);
1676 if (pyus_in == NULL)
1677 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1680 Py_DECREF(pyus_in);
1681 if (pyus_out == NULL)
1682 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 result = microseconds_to_delta(pyus_out);
1685 Py_DECREF(pyus_out);
1686 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001687}
1688
1689static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001690divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 PyObject *pyus_left;
1693 PyObject *pyus_right;
1694 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001695
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001696 pyus_left = delta_to_microseconds(left);
1697 if (pyus_left == NULL)
1698 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700 pyus_right = delta_to_microseconds(right);
1701 if (pyus_right == NULL) {
1702 Py_DECREF(pyus_left);
1703 return NULL;
1704 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1707 Py_DECREF(pyus_left);
1708 Py_DECREF(pyus_right);
1709 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001710}
1711
1712static PyObject *
1713truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 PyObject *pyus_left;
1716 PyObject *pyus_right;
1717 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001718
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001719 pyus_left = delta_to_microseconds(left);
1720 if (pyus_left == NULL)
1721 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001723 pyus_right = delta_to_microseconds(right);
1724 if (pyus_right == NULL) {
1725 Py_DECREF(pyus_left);
1726 return NULL;
1727 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1730 Py_DECREF(pyus_left);
1731 Py_DECREF(pyus_right);
1732 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001733}
1734
1735static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001736truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1737{
1738 PyObject *result = NULL;
1739 PyObject *pyus_in = NULL, *temp, *pyus_out;
1740 PyObject *ratio = NULL;
1741
1742 pyus_in = delta_to_microseconds(delta);
1743 if (pyus_in == NULL)
1744 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001745 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001746 if (ratio == NULL)
1747 goto error;
1748 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1749 Py_DECREF(pyus_in);
1750 pyus_in = NULL;
1751 if (temp == NULL)
1752 goto error;
1753 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1754 Py_DECREF(temp);
1755 if (pyus_out == NULL)
1756 goto error;
1757 result = microseconds_to_delta(pyus_out);
1758 Py_DECREF(pyus_out);
1759 error:
1760 Py_XDECREF(pyus_in);
1761 Py_XDECREF(ratio);
1762
1763 return result;
1764}
1765
1766static PyObject *
1767truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1768{
1769 PyObject *result;
1770 PyObject *pyus_in, *pyus_out;
1771 pyus_in = delta_to_microseconds(delta);
1772 if (pyus_in == NULL)
1773 return NULL;
1774 pyus_out = divide_nearest(pyus_in, i);
1775 Py_DECREF(pyus_in);
1776 if (pyus_out == NULL)
1777 return NULL;
1778 result = microseconds_to_delta(pyus_out);
1779 Py_DECREF(pyus_out);
1780
1781 return result;
1782}
1783
1784static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001785delta_add(PyObject *left, PyObject *right)
1786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1790 /* delta + delta */
1791 /* The C-level additions can't overflow because of the
1792 * invariant bounds.
1793 */
1794 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1795 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1796 int microseconds = GET_TD_MICROSECONDS(left) +
1797 GET_TD_MICROSECONDS(right);
1798 result = new_delta(days, seconds, microseconds, 1);
1799 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 if (result == Py_NotImplemented)
1802 Py_INCREF(result);
1803 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001804}
1805
1806static PyObject *
1807delta_negative(PyDateTime_Delta *self)
1808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 return new_delta(-GET_TD_DAYS(self),
1810 -GET_TD_SECONDS(self),
1811 -GET_TD_MICROSECONDS(self),
1812 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001813}
1814
1815static PyObject *
1816delta_positive(PyDateTime_Delta *self)
1817{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001818 /* Could optimize this (by returning self) if this isn't a
1819 * subclass -- but who uses unary + ? Approximately nobody.
1820 */
1821 return new_delta(GET_TD_DAYS(self),
1822 GET_TD_SECONDS(self),
1823 GET_TD_MICROSECONDS(self),
1824 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001825}
1826
1827static PyObject *
1828delta_abs(PyDateTime_Delta *self)
1829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 assert(GET_TD_MICROSECONDS(self) >= 0);
1833 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 if (GET_TD_DAYS(self) < 0)
1836 result = delta_negative(self);
1837 else
1838 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001841}
1842
1843static PyObject *
1844delta_subtract(PyObject *left, PyObject *right)
1845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1849 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001850 /* The C-level additions can't overflow because of the
1851 * invariant bounds.
1852 */
1853 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1854 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1855 int microseconds = GET_TD_MICROSECONDS(left) -
1856 GET_TD_MICROSECONDS(right);
1857 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 if (result == Py_NotImplemented)
1861 Py_INCREF(result);
1862 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001863}
1864
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001865static int
1866delta_cmp(PyObject *self, PyObject *other)
1867{
1868 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1869 if (diff == 0) {
1870 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1871 if (diff == 0)
1872 diff = GET_TD_MICROSECONDS(self) -
1873 GET_TD_MICROSECONDS(other);
1874 }
1875 return diff;
1876}
1877
Tim Peters2a799bf2002-12-16 20:18:38 +00001878static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001879delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001882 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001883 return diff_to_bool(diff, op);
1884 }
1885 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001886 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001888}
1889
1890static PyObject *delta_getstate(PyDateTime_Delta *self);
1891
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001892static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001893delta_hash(PyDateTime_Delta *self)
1894{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 if (self->hashcode == -1) {
1896 PyObject *temp = delta_getstate(self);
1897 if (temp != NULL) {
1898 self->hashcode = PyObject_Hash(temp);
1899 Py_DECREF(temp);
1900 }
1901 }
1902 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001903}
1904
1905static PyObject *
1906delta_multiply(PyObject *left, PyObject *right)
1907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 if (PyDelta_Check(left)) {
1911 /* delta * ??? */
1912 if (PyLong_Check(right))
1913 result = multiply_int_timedelta(right,
1914 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001915 else if (PyFloat_Check(right))
1916 result = multiply_float_timedelta(right,
1917 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 }
1919 else if (PyLong_Check(left))
1920 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001921 (PyDateTime_Delta *) right);
1922 else if (PyFloat_Check(left))
1923 result = multiply_float_timedelta(left,
1924 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 if (result == Py_NotImplemented)
1927 Py_INCREF(result);
1928 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001929}
1930
1931static PyObject *
1932delta_divide(PyObject *left, PyObject *right)
1933{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 if (PyDelta_Check(left)) {
1937 /* delta * ??? */
1938 if (PyLong_Check(right))
1939 result = divide_timedelta_int(
1940 (PyDateTime_Delta *)left,
1941 right);
1942 else if (PyDelta_Check(right))
1943 result = divide_timedelta_timedelta(
1944 (PyDateTime_Delta *)left,
1945 (PyDateTime_Delta *)right);
1946 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 if (result == Py_NotImplemented)
1949 Py_INCREF(result);
1950 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001951}
1952
Mark Dickinson7c186e22010-04-20 22:32:49 +00001953static PyObject *
1954delta_truedivide(PyObject *left, PyObject *right)
1955{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 if (PyDelta_Check(left)) {
1959 if (PyDelta_Check(right))
1960 result = truedivide_timedelta_timedelta(
1961 (PyDateTime_Delta *)left,
1962 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001963 else if (PyFloat_Check(right))
1964 result = truedivide_timedelta_float(
1965 (PyDateTime_Delta *)left, right);
1966 else if (PyLong_Check(right))
1967 result = truedivide_timedelta_int(
1968 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 if (result == Py_NotImplemented)
1972 Py_INCREF(result);
1973 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001974}
1975
1976static PyObject *
1977delta_remainder(PyObject *left, PyObject *right)
1978{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 PyObject *pyus_left;
1980 PyObject *pyus_right;
1981 PyObject *pyus_remainder;
1982 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001983
Brian Curtindfc80e32011-08-10 20:28:54 -05001984 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1985 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1988 if (pyus_left == NULL)
1989 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1992 if (pyus_right == NULL) {
1993 Py_DECREF(pyus_left);
1994 return NULL;
1995 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1998 Py_DECREF(pyus_left);
1999 Py_DECREF(pyus_right);
2000 if (pyus_remainder == NULL)
2001 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 remainder = microseconds_to_delta(pyus_remainder);
2004 Py_DECREF(pyus_remainder);
2005 if (remainder == NULL)
2006 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002009}
2010
2011static PyObject *
2012delta_divmod(PyObject *left, PyObject *right)
2013{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 PyObject *pyus_left;
2015 PyObject *pyus_right;
2016 PyObject *divmod;
2017 PyObject *delta;
2018 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002019
Brian Curtindfc80e32011-08-10 20:28:54 -05002020 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2021 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2024 if (pyus_left == NULL)
2025 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2028 if (pyus_right == NULL) {
2029 Py_DECREF(pyus_left);
2030 return NULL;
2031 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002033 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2034 Py_DECREF(pyus_left);
2035 Py_DECREF(pyus_right);
2036 if (divmod == NULL)
2037 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 assert(PyTuple_Size(divmod) == 2);
2040 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2041 if (delta == NULL) {
2042 Py_DECREF(divmod);
2043 return NULL;
2044 }
2045 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2046 Py_DECREF(delta);
2047 Py_DECREF(divmod);
2048 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002049}
2050
Tim Peters2a799bf2002-12-16 20:18:38 +00002051/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2052 * timedelta constructor. sofar is the # of microseconds accounted for
2053 * so far, and there are factor microseconds per current unit, the number
2054 * of which is given by num. num * factor is added to sofar in a
2055 * numerically careful way, and that's the result. Any fractional
2056 * microseconds left over (this can happen if num is a float type) are
2057 * added into *leftover.
2058 * Note that there are many ways this can give an error (NULL) return.
2059 */
2060static PyObject *
2061accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2062 double *leftover)
2063{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 PyObject *prod;
2065 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 if (PyLong_Check(num)) {
2070 prod = PyNumber_Multiply(num, factor);
2071 if (prod == NULL)
2072 return NULL;
2073 sum = PyNumber_Add(sofar, prod);
2074 Py_DECREF(prod);
2075 return sum;
2076 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 if (PyFloat_Check(num)) {
2079 double dnum;
2080 double fracpart;
2081 double intpart;
2082 PyObject *x;
2083 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 /* The Plan: decompose num into an integer part and a
2086 * fractional part, num = intpart + fracpart.
2087 * Then num * factor ==
2088 * intpart * factor + fracpart * factor
2089 * and the LHS can be computed exactly in long arithmetic.
2090 * The RHS is again broken into an int part and frac part.
2091 * and the frac part is added into *leftover.
2092 */
2093 dnum = PyFloat_AsDouble(num);
2094 if (dnum == -1.0 && PyErr_Occurred())
2095 return NULL;
2096 fracpart = modf(dnum, &intpart);
2097 x = PyLong_FromDouble(intpart);
2098 if (x == NULL)
2099 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 prod = PyNumber_Multiply(x, factor);
2102 Py_DECREF(x);
2103 if (prod == NULL)
2104 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 sum = PyNumber_Add(sofar, prod);
2107 Py_DECREF(prod);
2108 if (sum == NULL)
2109 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 if (fracpart == 0.0)
2112 return sum;
2113 /* So far we've lost no information. Dealing with the
2114 * fractional part requires float arithmetic, and may
2115 * lose a little info.
2116 */
2117 assert(PyLong_Check(factor));
2118 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 dnum *= fracpart;
2121 fracpart = modf(dnum, &intpart);
2122 x = PyLong_FromDouble(intpart);
2123 if (x == NULL) {
2124 Py_DECREF(sum);
2125 return NULL;
2126 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 y = PyNumber_Add(sum, x);
2129 Py_DECREF(sum);
2130 Py_DECREF(x);
2131 *leftover += fracpart;
2132 return y;
2133 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 PyErr_Format(PyExc_TypeError,
2136 "unsupported type for timedelta %s component: %s",
2137 tag, Py_TYPE(num)->tp_name);
2138 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002139}
2140
2141static PyObject *
2142delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 /* Argument objects. */
2147 PyObject *day = NULL;
2148 PyObject *second = NULL;
2149 PyObject *us = NULL;
2150 PyObject *ms = NULL;
2151 PyObject *minute = NULL;
2152 PyObject *hour = NULL;
2153 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 PyObject *x = NULL; /* running sum of microseconds */
2156 PyObject *y = NULL; /* temp sum of microseconds */
2157 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 static char *keywords[] = {
2160 "days", "seconds", "microseconds", "milliseconds",
2161 "minutes", "hours", "weeks", NULL
2162 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2165 keywords,
2166 &day, &second, &us,
2167 &ms, &minute, &hour, &week) == 0)
2168 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 x = PyLong_FromLong(0);
2171 if (x == NULL)
2172 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174#define CLEANUP \
2175 Py_DECREF(x); \
2176 x = y; \
2177 if (x == NULL) \
2178 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002180 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002181 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 CLEANUP;
2183 }
2184 if (ms) {
2185 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2186 CLEANUP;
2187 }
2188 if (second) {
2189 y = accum("seconds", x, second, us_per_second, &leftover_us);
2190 CLEANUP;
2191 }
2192 if (minute) {
2193 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2194 CLEANUP;
2195 }
2196 if (hour) {
2197 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2198 CLEANUP;
2199 }
2200 if (day) {
2201 y = accum("days", x, day, us_per_day, &leftover_us);
2202 CLEANUP;
2203 }
2204 if (week) {
2205 y = accum("weeks", x, week, us_per_week, &leftover_us);
2206 CLEANUP;
2207 }
2208 if (leftover_us) {
2209 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002210 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002211 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002212 PyObject *temp;
2213
Victor Stinner69cc4872015-09-08 23:58:54 +02002214 whole_us = round(leftover_us);
2215 if (fabs(whole_us - leftover_us) == 0.5) {
2216 /* We're exactly halfway between two integers. In order
2217 * to do round-half-to-even, we must determine whether x
2218 * is odd. Note that x is odd when it's last bit is 1. The
2219 * code below uses bitwise and operation to check the last
2220 * bit. */
2221 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2222 if (temp == NULL) {
2223 Py_DECREF(x);
2224 goto Done;
2225 }
2226 x_is_odd = PyObject_IsTrue(temp);
2227 Py_DECREF(temp);
2228 if (x_is_odd == -1) {
2229 Py_DECREF(x);
2230 goto Done;
2231 }
2232 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2233 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002234
Victor Stinner36a5a062013-08-28 01:53:39 +02002235 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 if (temp == NULL) {
2238 Py_DECREF(x);
2239 goto Done;
2240 }
2241 y = PyNumber_Add(x, temp);
2242 Py_DECREF(temp);
2243 CLEANUP;
2244 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 self = microseconds_to_delta_ex(x, type);
2247 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002248Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002250
2251#undef CLEANUP
2252}
2253
2254static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002255delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 return (GET_TD_DAYS(self) != 0
2258 || GET_TD_SECONDS(self) != 0
2259 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002260}
2261
2262static PyObject *
2263delta_repr(PyDateTime_Delta *self)
2264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 if (GET_TD_MICROSECONDS(self) != 0)
2266 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2267 Py_TYPE(self)->tp_name,
2268 GET_TD_DAYS(self),
2269 GET_TD_SECONDS(self),
2270 GET_TD_MICROSECONDS(self));
2271 if (GET_TD_SECONDS(self) != 0)
2272 return PyUnicode_FromFormat("%s(%d, %d)",
2273 Py_TYPE(self)->tp_name,
2274 GET_TD_DAYS(self),
2275 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 return PyUnicode_FromFormat("%s(%d)",
2278 Py_TYPE(self)->tp_name,
2279 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002280}
2281
2282static PyObject *
2283delta_str(PyDateTime_Delta *self)
2284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 int us = GET_TD_MICROSECONDS(self);
2286 int seconds = GET_TD_SECONDS(self);
2287 int minutes = divmod(seconds, 60, &seconds);
2288 int hours = divmod(minutes, 60, &minutes);
2289 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 if (days) {
2292 if (us)
2293 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2294 days, (days == 1 || days == -1) ? "" : "s",
2295 hours, minutes, seconds, us);
2296 else
2297 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2298 days, (days == 1 || days == -1) ? "" : "s",
2299 hours, minutes, seconds);
2300 } else {
2301 if (us)
2302 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2303 hours, minutes, seconds, us);
2304 else
2305 return PyUnicode_FromFormat("%d:%02d:%02d",
2306 hours, minutes, seconds);
2307 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002308
Tim Peters2a799bf2002-12-16 20:18:38 +00002309}
2310
Tim Peters371935f2003-02-01 01:52:50 +00002311/* Pickle support, a simple use of __reduce__. */
2312
Tim Petersb57f8f02003-02-01 02:54:15 +00002313/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002314static PyObject *
2315delta_getstate(PyDateTime_Delta *self)
2316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002317 return Py_BuildValue("iii", GET_TD_DAYS(self),
2318 GET_TD_SECONDS(self),
2319 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002320}
2321
Tim Peters2a799bf2002-12-16 20:18:38 +00002322static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002323delta_total_seconds(PyObject *self)
2324{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 PyObject *total_seconds;
2326 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002328 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2329 if (total_microseconds == NULL)
2330 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002331
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002332 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002334 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002336}
2337
2338static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002339delta_reduce(PyDateTime_Delta* self)
2340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002342}
2343
2344#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2345
2346static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 {"days", T_INT, OFFSET(days), READONLY,
2349 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 {"seconds", T_INT, OFFSET(seconds), READONLY,
2352 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002354 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2355 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2356 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002357};
2358
2359static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2361 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2364 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002366 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002367};
2368
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002369static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002370PyDoc_STR("Difference between two datetime values.");
2371
2372static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 delta_add, /* nb_add */
2374 delta_subtract, /* nb_subtract */
2375 delta_multiply, /* nb_multiply */
2376 delta_remainder, /* nb_remainder */
2377 delta_divmod, /* nb_divmod */
2378 0, /* nb_power */
2379 (unaryfunc)delta_negative, /* nb_negative */
2380 (unaryfunc)delta_positive, /* nb_positive */
2381 (unaryfunc)delta_abs, /* nb_absolute */
2382 (inquiry)delta_bool, /* nb_bool */
2383 0, /*nb_invert*/
2384 0, /*nb_lshift*/
2385 0, /*nb_rshift*/
2386 0, /*nb_and*/
2387 0, /*nb_xor*/
2388 0, /*nb_or*/
2389 0, /*nb_int*/
2390 0, /*nb_reserved*/
2391 0, /*nb_float*/
2392 0, /*nb_inplace_add*/
2393 0, /*nb_inplace_subtract*/
2394 0, /*nb_inplace_multiply*/
2395 0, /*nb_inplace_remainder*/
2396 0, /*nb_inplace_power*/
2397 0, /*nb_inplace_lshift*/
2398 0, /*nb_inplace_rshift*/
2399 0, /*nb_inplace_and*/
2400 0, /*nb_inplace_xor*/
2401 0, /*nb_inplace_or*/
2402 delta_divide, /* nb_floor_divide */
2403 delta_truedivide, /* nb_true_divide */
2404 0, /* nb_inplace_floor_divide */
2405 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002406};
2407
2408static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 PyVarObject_HEAD_INIT(NULL, 0)
2410 "datetime.timedelta", /* tp_name */
2411 sizeof(PyDateTime_Delta), /* tp_basicsize */
2412 0, /* tp_itemsize */
2413 0, /* tp_dealloc */
2414 0, /* tp_print */
2415 0, /* tp_getattr */
2416 0, /* tp_setattr */
2417 0, /* tp_reserved */
2418 (reprfunc)delta_repr, /* tp_repr */
2419 &delta_as_number, /* tp_as_number */
2420 0, /* tp_as_sequence */
2421 0, /* tp_as_mapping */
2422 (hashfunc)delta_hash, /* tp_hash */
2423 0, /* tp_call */
2424 (reprfunc)delta_str, /* tp_str */
2425 PyObject_GenericGetAttr, /* tp_getattro */
2426 0, /* tp_setattro */
2427 0, /* tp_as_buffer */
2428 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2429 delta_doc, /* tp_doc */
2430 0, /* tp_traverse */
2431 0, /* tp_clear */
2432 delta_richcompare, /* tp_richcompare */
2433 0, /* tp_weaklistoffset */
2434 0, /* tp_iter */
2435 0, /* tp_iternext */
2436 delta_methods, /* tp_methods */
2437 delta_members, /* tp_members */
2438 0, /* tp_getset */
2439 0, /* tp_base */
2440 0, /* tp_dict */
2441 0, /* tp_descr_get */
2442 0, /* tp_descr_set */
2443 0, /* tp_dictoffset */
2444 0, /* tp_init */
2445 0, /* tp_alloc */
2446 delta_new, /* tp_new */
2447 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002448};
2449
2450/*
2451 * PyDateTime_Date implementation.
2452 */
2453
2454/* Accessor properties. */
2455
2456static PyObject *
2457date_year(PyDateTime_Date *self, void *unused)
2458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002459 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002460}
2461
2462static PyObject *
2463date_month(PyDateTime_Date *self, void *unused)
2464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002466}
2467
2468static PyObject *
2469date_day(PyDateTime_Date *self, void *unused)
2470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002472}
2473
2474static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002475 {"year", (getter)date_year},
2476 {"month", (getter)date_month},
2477 {"day", (getter)date_day},
2478 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002479};
2480
2481/* Constructors. */
2482
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002483static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002484
Tim Peters2a799bf2002-12-16 20:18:38 +00002485static PyObject *
2486date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002488 PyObject *self = NULL;
2489 PyObject *state;
2490 int year;
2491 int month;
2492 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002494 /* Check for invocation from pickle with __getstate__ state */
2495 if (PyTuple_GET_SIZE(args) == 1 &&
2496 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2497 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2498 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2499 {
2500 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2503 if (me != NULL) {
2504 char *pdata = PyBytes_AS_STRING(state);
2505 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2506 me->hashcode = -1;
2507 }
2508 return (PyObject *)me;
2509 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002511 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2512 &year, &month, &day)) {
2513 if (check_date_args(year, month, day) < 0)
2514 return NULL;
2515 self = new_date_ex(year, month, day, type);
2516 }
2517 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002518}
2519
2520/* Return new date from localtime(t). */
2521static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002522date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002523{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002524 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002525 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002526
Victor Stinnere4a994d2015-03-30 01:10:14 +02002527 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002529
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002530 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002531 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002532
2533 return PyObject_CallFunction(cls, "iii",
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002534 tm.tm_year + 1900,
2535 tm.tm_mon + 1,
2536 tm.tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002537}
2538
2539/* Return new date from current time.
2540 * We say this is equivalent to fromtimestamp(time.time()), and the
2541 * only way to be sure of that is to *call* time.time(). That's not
2542 * generally the same as calling C's time.
2543 */
2544static PyObject *
2545date_today(PyObject *cls, PyObject *dummy)
2546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002547 PyObject *time;
2548 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002549 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 time = time_time();
2552 if (time == NULL)
2553 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002555 /* Note well: today() is a class method, so this may not call
2556 * date.fromtimestamp. For example, it may call
2557 * datetime.fromtimestamp. That's why we need all the accuracy
2558 * time.time() delivers; if someone were gonzo about optimization,
2559 * date.today() could get away with plain C time().
2560 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002561 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002562 Py_DECREF(time);
2563 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002564}
2565
2566/* Return new date from given timestamp (Python timestamp -- a double). */
2567static PyObject *
2568date_fromtimestamp(PyObject *cls, PyObject *args)
2569{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002570 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002572
Victor Stinner5d272cc2012-03-13 13:35:55 +01002573 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2574 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002576}
2577
2578/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2579 * the ordinal is out of range.
2580 */
2581static PyObject *
2582date_fromordinal(PyObject *cls, PyObject *args)
2583{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002584 PyObject *result = NULL;
2585 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002587 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2588 int year;
2589 int month;
2590 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002592 if (ordinal < 1)
2593 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2594 ">= 1");
2595 else {
2596 ord_to_ymd(ordinal, &year, &month, &day);
2597 result = PyObject_CallFunction(cls, "iii",
2598 year, month, day);
2599 }
2600 }
2601 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002602}
2603
2604/*
2605 * Date arithmetic.
2606 */
2607
2608/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2609 * instead.
2610 */
2611static PyObject *
2612add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002614 PyObject *result = NULL;
2615 int year = GET_YEAR(date);
2616 int month = GET_MONTH(date);
2617 int deltadays = GET_TD_DAYS(delta);
2618 /* C-level overflow is impossible because |deltadays| < 1e9. */
2619 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 if (normalize_date(&year, &month, &day) >= 0)
2622 result = new_date(year, month, day);
2623 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002624}
2625
2626static PyObject *
2627date_add(PyObject *left, PyObject *right)
2628{
Brian Curtindfc80e32011-08-10 20:28:54 -05002629 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2630 Py_RETURN_NOTIMPLEMENTED;
2631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002632 if (PyDate_Check(left)) {
2633 /* date + ??? */
2634 if (PyDelta_Check(right))
2635 /* date + delta */
2636 return add_date_timedelta((PyDateTime_Date *) left,
2637 (PyDateTime_Delta *) right,
2638 0);
2639 }
2640 else {
2641 /* ??? + date
2642 * 'right' must be one of us, or we wouldn't have been called
2643 */
2644 if (PyDelta_Check(left))
2645 /* delta + date */
2646 return add_date_timedelta((PyDateTime_Date *) right,
2647 (PyDateTime_Delta *) left,
2648 0);
2649 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002650 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002651}
2652
2653static PyObject *
2654date_subtract(PyObject *left, PyObject *right)
2655{
Brian Curtindfc80e32011-08-10 20:28:54 -05002656 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2657 Py_RETURN_NOTIMPLEMENTED;
2658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 if (PyDate_Check(left)) {
2660 if (PyDate_Check(right)) {
2661 /* date - date */
2662 int left_ord = ymd_to_ord(GET_YEAR(left),
2663 GET_MONTH(left),
2664 GET_DAY(left));
2665 int right_ord = ymd_to_ord(GET_YEAR(right),
2666 GET_MONTH(right),
2667 GET_DAY(right));
2668 return new_delta(left_ord - right_ord, 0, 0, 0);
2669 }
2670 if (PyDelta_Check(right)) {
2671 /* date - delta */
2672 return add_date_timedelta((PyDateTime_Date *) left,
2673 (PyDateTime_Delta *) right,
2674 1);
2675 }
2676 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002677 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002678}
2679
2680
2681/* Various ways to turn a date into a string. */
2682
2683static PyObject *
2684date_repr(PyDateTime_Date *self)
2685{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002686 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2687 Py_TYPE(self)->tp_name,
2688 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002689}
2690
2691static PyObject *
2692date_isoformat(PyDateTime_Date *self)
2693{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002694 return PyUnicode_FromFormat("%04d-%02d-%02d",
2695 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002696}
2697
Tim Peterse2df5ff2003-05-02 18:39:55 +00002698/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002699static PyObject *
2700date_str(PyDateTime_Date *self)
2701{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002702 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002703}
2704
2705
2706static PyObject *
2707date_ctime(PyDateTime_Date *self)
2708{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002709 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002710}
2711
2712static PyObject *
2713date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2714{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002715 /* This method can be inherited, and needs to call the
2716 * timetuple() method appropriate to self's class.
2717 */
2718 PyObject *result;
2719 PyObject *tuple;
2720 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002721 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002722 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002723
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002724 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2725 &format))
2726 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002727
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002728 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002729 if (tuple == NULL)
2730 return NULL;
2731 result = wrap_strftime((PyObject *)self, format, tuple,
2732 (PyObject *)self);
2733 Py_DECREF(tuple);
2734 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002735}
2736
Eric Smith1ba31142007-09-11 18:06:02 +00002737static PyObject *
2738date_format(PyDateTime_Date *self, PyObject *args)
2739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002740 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002742 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2743 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002745 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002746 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002747 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002748
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002749 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002750}
2751
Tim Peters2a799bf2002-12-16 20:18:38 +00002752/* ISO methods. */
2753
2754static PyObject *
2755date_isoweekday(PyDateTime_Date *self)
2756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002757 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002759 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002760}
2761
2762static PyObject *
2763date_isocalendar(PyDateTime_Date *self)
2764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002765 int year = GET_YEAR(self);
2766 int week1_monday = iso_week1_monday(year);
2767 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2768 int week;
2769 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002771 week = divmod(today - week1_monday, 7, &day);
2772 if (week < 0) {
2773 --year;
2774 week1_monday = iso_week1_monday(year);
2775 week = divmod(today - week1_monday, 7, &day);
2776 }
2777 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2778 ++year;
2779 week = 0;
2780 }
2781 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002782}
2783
2784/* Miscellaneous methods. */
2785
Tim Peters2a799bf2002-12-16 20:18:38 +00002786static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002787date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002789 if (PyDate_Check(other)) {
2790 int diff = memcmp(((PyDateTime_Date *)self)->data,
2791 ((PyDateTime_Date *)other)->data,
2792 _PyDateTime_DATE_DATASIZE);
2793 return diff_to_bool(diff, op);
2794 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002795 else
2796 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002797}
2798
2799static PyObject *
2800date_timetuple(PyDateTime_Date *self)
2801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002802 return build_struct_time(GET_YEAR(self),
2803 GET_MONTH(self),
2804 GET_DAY(self),
2805 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002806}
2807
Tim Peters12bf3392002-12-24 05:41:27 +00002808static PyObject *
2809date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2810{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002811 PyObject *clone;
2812 PyObject *tuple;
2813 int year = GET_YEAR(self);
2814 int month = GET_MONTH(self);
2815 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002817 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2818 &year, &month, &day))
2819 return NULL;
2820 tuple = Py_BuildValue("iii", year, month, day);
2821 if (tuple == NULL)
2822 return NULL;
2823 clone = date_new(Py_TYPE(self), tuple, NULL);
2824 Py_DECREF(tuple);
2825 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002826}
2827
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002828static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002829generic_hash(unsigned char *data, int len)
2830{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002831 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002832}
2833
2834
2835static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002836
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002837static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002838date_hash(PyDateTime_Date *self)
2839{
Benjamin Petersondec2df32016-09-09 17:46:24 -07002840 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002841 self->hashcode = generic_hash(
2842 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07002843 }
Guido van Rossum254348e2007-11-21 19:29:53 +00002844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002845 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002846}
2847
2848static PyObject *
2849date_toordinal(PyDateTime_Date *self)
2850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2852 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002853}
2854
2855static PyObject *
2856date_weekday(PyDateTime_Date *self)
2857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002858 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002859
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002860 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002861}
2862
Tim Peters371935f2003-02-01 01:52:50 +00002863/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002864
Tim Petersb57f8f02003-02-01 02:54:15 +00002865/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002866static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002867date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002869 PyObject* field;
2870 field = PyBytes_FromStringAndSize((char*)self->data,
2871 _PyDateTime_DATE_DATASIZE);
2872 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002873}
2874
2875static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002876date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002877{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002879}
2880
2881static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002883 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002885 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2886 METH_CLASS,
2887 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2888 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2891 METH_CLASS,
2892 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2893 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002895 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2896 PyDoc_STR("Current date or datetime: same as "
2897 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002899 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002901 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2902 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002904 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2905 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002907 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2908 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002910 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2911 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002913 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2914 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2915 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002917 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2918 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002920 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2921 PyDoc_STR("Return the day of the week represented by the date.\n"
2922 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002924 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2925 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2926 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002928 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2929 PyDoc_STR("Return the day of the week represented by the date.\n"
2930 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002932 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2933 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002935 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2936 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002938 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002939};
2940
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002941static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002942PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002943
2944static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002945 date_add, /* nb_add */
2946 date_subtract, /* nb_subtract */
2947 0, /* nb_multiply */
2948 0, /* nb_remainder */
2949 0, /* nb_divmod */
2950 0, /* nb_power */
2951 0, /* nb_negative */
2952 0, /* nb_positive */
2953 0, /* nb_absolute */
2954 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002955};
2956
2957static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002958 PyVarObject_HEAD_INIT(NULL, 0)
2959 "datetime.date", /* tp_name */
2960 sizeof(PyDateTime_Date), /* tp_basicsize */
2961 0, /* tp_itemsize */
2962 0, /* tp_dealloc */
2963 0, /* tp_print */
2964 0, /* tp_getattr */
2965 0, /* tp_setattr */
2966 0, /* tp_reserved */
2967 (reprfunc)date_repr, /* tp_repr */
2968 &date_as_number, /* tp_as_number */
2969 0, /* tp_as_sequence */
2970 0, /* tp_as_mapping */
2971 (hashfunc)date_hash, /* tp_hash */
2972 0, /* tp_call */
2973 (reprfunc)date_str, /* tp_str */
2974 PyObject_GenericGetAttr, /* tp_getattro */
2975 0, /* tp_setattro */
2976 0, /* tp_as_buffer */
2977 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2978 date_doc, /* tp_doc */
2979 0, /* tp_traverse */
2980 0, /* tp_clear */
2981 date_richcompare, /* tp_richcompare */
2982 0, /* tp_weaklistoffset */
2983 0, /* tp_iter */
2984 0, /* tp_iternext */
2985 date_methods, /* tp_methods */
2986 0, /* tp_members */
2987 date_getset, /* tp_getset */
2988 0, /* tp_base */
2989 0, /* tp_dict */
2990 0, /* tp_descr_get */
2991 0, /* tp_descr_set */
2992 0, /* tp_dictoffset */
2993 0, /* tp_init */
2994 0, /* tp_alloc */
2995 date_new, /* tp_new */
2996 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002997};
2998
2999/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003000 * PyDateTime_TZInfo implementation.
3001 */
3002
3003/* This is a pure abstract base class, so doesn't do anything beyond
3004 * raising NotImplemented exceptions. Real tzinfo classes need
3005 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003006 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003007 * be subclasses of this tzinfo class, which is easy and quick to check).
3008 *
3009 * Note: For reasons having to do with pickling of subclasses, we have
3010 * to allow tzinfo objects to be instantiated. This wasn't an issue
3011 * in the Python implementation (__init__() could raise NotImplementedError
3012 * there without ill effect), but doing so in the C implementation hit a
3013 * brick wall.
3014 */
3015
3016static PyObject *
3017tzinfo_nogo(const char* methodname)
3018{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003019 PyErr_Format(PyExc_NotImplementedError,
3020 "a tzinfo subclass must implement %s()",
3021 methodname);
3022 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003023}
3024
3025/* Methods. A subclass must implement these. */
3026
Tim Peters52dcce22003-01-23 16:36:11 +00003027static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003028tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003030 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003031}
3032
Tim Peters52dcce22003-01-23 16:36:11 +00003033static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003034tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003036 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003037}
3038
Tim Peters52dcce22003-01-23 16:36:11 +00003039static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003040tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3041{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003042 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003043}
3044
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003045
3046static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3047 PyDateTime_Delta *delta,
3048 int factor);
3049static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3050static PyObject *datetime_dst(PyObject *self, PyObject *);
3051
Tim Peters52dcce22003-01-23 16:36:11 +00003052static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003053tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003054{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003055 PyObject *result = NULL;
3056 PyObject *off = NULL, *dst = NULL;
3057 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003058
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003059 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003060 PyErr_SetString(PyExc_TypeError,
3061 "fromutc: argument must be a datetime");
3062 return NULL;
3063 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003064 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003065 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3066 "is not self");
3067 return NULL;
3068 }
Tim Peters52dcce22003-01-23 16:36:11 +00003069
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003070 off = datetime_utcoffset(dt, NULL);
3071 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003072 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003073 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003074 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3075 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003076 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003077 }
Tim Peters52dcce22003-01-23 16:36:11 +00003078
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003079 dst = datetime_dst(dt, NULL);
3080 if (dst == NULL)
3081 goto Fail;
3082 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3084 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003085 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003086 }
Tim Peters52dcce22003-01-23 16:36:11 +00003087
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003088 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3089 if (delta == NULL)
3090 goto Fail;
3091 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003092 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003093 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003094
3095 Py_DECREF(dst);
3096 dst = call_dst(GET_DT_TZINFO(dt), result);
3097 if (dst == NULL)
3098 goto Fail;
3099 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003100 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003101 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003102 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003103 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003104 if (result == NULL)
3105 goto Fail;
3106 }
3107 Py_DECREF(delta);
3108 Py_DECREF(dst);
3109 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003111
3112Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003113 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3114 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003115
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003116 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003117Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003118 Py_XDECREF(off);
3119 Py_XDECREF(dst);
3120 Py_XDECREF(delta);
3121 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003123}
3124
Tim Peters2a799bf2002-12-16 20:18:38 +00003125/*
3126 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003127 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003128 */
3129
Guido van Rossum177e41a2003-01-30 22:06:23 +00003130static PyObject *
3131tzinfo_reduce(PyObject *self)
3132{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003133 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003134 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003135 _Py_IDENTIFIER(__getinitargs__);
3136 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003137
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003138 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003140 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003141 Py_DECREF(getinitargs);
3142 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 return NULL;
3144 }
3145 }
3146 else {
3147 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003148
3149 args = PyTuple_New(0);
3150 if (args == NULL) {
3151 return NULL;
3152 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003153 }
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) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003157 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003158 Py_DECREF(getstate);
3159 if (state == NULL) {
3160 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003161 return NULL;
3162 }
3163 }
3164 else {
3165 PyObject **dictptr;
3166 PyErr_Clear();
3167 state = Py_None;
3168 dictptr = _PyObject_GetDictPtr(self);
Victor Stinnerd1584d32016-08-23 00:11:04 +02003169 if (dictptr && *dictptr && PyDict_Size(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003170 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003171 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 Py_INCREF(state);
3173 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003175 if (state == Py_None) {
3176 Py_DECREF(state);
3177 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3178 }
3179 else
3180 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003181}
Tim Peters2a799bf2002-12-16 20:18:38 +00003182
3183static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003185 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3186 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003188 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003189 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3190 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003192 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3193 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003195 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003196 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3199 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003201 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003202};
3203
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003204static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003205PyDoc_STR("Abstract base class for time zone info objects.");
3206
Neal Norwitz227b5332006-03-22 09:28:35 +00003207static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003208 PyVarObject_HEAD_INIT(NULL, 0)
3209 "datetime.tzinfo", /* tp_name */
3210 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3211 0, /* tp_itemsize */
3212 0, /* tp_dealloc */
3213 0, /* tp_print */
3214 0, /* tp_getattr */
3215 0, /* tp_setattr */
3216 0, /* tp_reserved */
3217 0, /* tp_repr */
3218 0, /* tp_as_number */
3219 0, /* tp_as_sequence */
3220 0, /* tp_as_mapping */
3221 0, /* tp_hash */
3222 0, /* tp_call */
3223 0, /* tp_str */
3224 PyObject_GenericGetAttr, /* tp_getattro */
3225 0, /* tp_setattro */
3226 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003227 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003228 tzinfo_doc, /* tp_doc */
3229 0, /* tp_traverse */
3230 0, /* tp_clear */
3231 0, /* tp_richcompare */
3232 0, /* tp_weaklistoffset */
3233 0, /* tp_iter */
3234 0, /* tp_iternext */
3235 tzinfo_methods, /* tp_methods */
3236 0, /* tp_members */
3237 0, /* tp_getset */
3238 0, /* tp_base */
3239 0, /* tp_dict */
3240 0, /* tp_descr_get */
3241 0, /* tp_descr_set */
3242 0, /* tp_dictoffset */
3243 0, /* tp_init */
3244 0, /* tp_alloc */
3245 PyType_GenericNew, /* tp_new */
3246 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003247};
3248
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003249static char *timezone_kws[] = {"offset", "name", NULL};
3250
3251static PyObject *
3252timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3253{
3254 PyObject *offset;
3255 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003256 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3257 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003258 return new_timezone(offset, name);
3259
3260 return NULL;
3261}
3262
3263static void
3264timezone_dealloc(PyDateTime_TimeZone *self)
3265{
3266 Py_CLEAR(self->offset);
3267 Py_CLEAR(self->name);
3268 Py_TYPE(self)->tp_free((PyObject *)self);
3269}
3270
3271static PyObject *
3272timezone_richcompare(PyDateTime_TimeZone *self,
3273 PyDateTime_TimeZone *other, int op)
3274{
Brian Curtindfc80e32011-08-10 20:28:54 -05003275 if (op != Py_EQ && op != Py_NE)
3276 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003277 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003278 if (op == Py_EQ)
3279 Py_RETURN_FALSE;
3280 else
3281 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003282 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003283 return delta_richcompare(self->offset, other->offset, op);
3284}
3285
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003286static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003287timezone_hash(PyDateTime_TimeZone *self)
3288{
3289 return delta_hash((PyDateTime_Delta *)self->offset);
3290}
3291
3292/* Check argument type passed to tzname, utcoffset, or dst methods.
3293 Returns 0 for good argument. Returns -1 and sets exception info
3294 otherwise.
3295 */
3296static int
3297_timezone_check_argument(PyObject *dt, const char *meth)
3298{
3299 if (dt == Py_None || PyDateTime_Check(dt))
3300 return 0;
3301 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3302 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3303 return -1;
3304}
3305
3306static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003307timezone_repr(PyDateTime_TimeZone *self)
3308{
3309 /* Note that although timezone is not subclassable, it is convenient
3310 to use Py_TYPE(self)->tp_name here. */
3311 const char *type_name = Py_TYPE(self)->tp_name;
3312
3313 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3314 return PyUnicode_FromFormat("%s.utc", type_name);
3315
3316 if (self->name == NULL)
3317 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3318
3319 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3320 self->name);
3321}
3322
3323
3324static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003325timezone_str(PyDateTime_TimeZone *self)
3326{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003327 int hours, minutes, seconds;
3328 PyObject *offset;
3329 char sign;
3330
3331 if (self->name != NULL) {
3332 Py_INCREF(self->name);
3333 return self->name;
3334 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003335 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003336 (GET_TD_DAYS(self->offset) == 0 &&
3337 GET_TD_SECONDS(self->offset) == 0 &&
3338 GET_TD_MICROSECONDS(self->offset) == 0))
3339 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003340 /* Offset is normalized, so it is negative if days < 0 */
3341 if (GET_TD_DAYS(self->offset) < 0) {
3342 sign = '-';
3343 offset = delta_negative((PyDateTime_Delta *)self->offset);
3344 if (offset == NULL)
3345 return NULL;
3346 }
3347 else {
3348 sign = '+';
3349 offset = self->offset;
3350 Py_INCREF(offset);
3351 }
3352 /* Offset is not negative here. */
3353 seconds = GET_TD_SECONDS(offset);
3354 Py_DECREF(offset);
3355 minutes = divmod(seconds, 60, &seconds);
3356 hours = divmod(minutes, 60, &minutes);
Martin Pantere26da7c2016-06-02 10:07:09 +00003357 /* XXX ignore sub-minute data, currently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003358 assert(seconds == 0);
3359 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003360}
3361
3362static PyObject *
3363timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3364{
3365 if (_timezone_check_argument(dt, "tzname") == -1)
3366 return NULL;
3367
3368 return timezone_str(self);
3369}
3370
3371static PyObject *
3372timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3373{
3374 if (_timezone_check_argument(dt, "utcoffset") == -1)
3375 return NULL;
3376
3377 Py_INCREF(self->offset);
3378 return self->offset;
3379}
3380
3381static PyObject *
3382timezone_dst(PyObject *self, PyObject *dt)
3383{
3384 if (_timezone_check_argument(dt, "dst") == -1)
3385 return NULL;
3386
3387 Py_RETURN_NONE;
3388}
3389
3390static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003391timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3392{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003393 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003394 PyErr_SetString(PyExc_TypeError,
3395 "fromutc: argument must be a datetime");
3396 return NULL;
3397 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003398 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003399 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3400 "is not self");
3401 return NULL;
3402 }
3403
3404 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3405}
3406
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003407static PyObject *
3408timezone_getinitargs(PyDateTime_TimeZone *self)
3409{
3410 if (self->name == NULL)
3411 return Py_BuildValue("(O)", self->offset);
3412 return Py_BuildValue("(OO)", self->offset, self->name);
3413}
3414
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003415static PyMethodDef timezone_methods[] = {
3416 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3417 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003418 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003419
3420 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003421 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003422
3423 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003424 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003425
3426 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3427 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3428
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003429 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3430 PyDoc_STR("pickle support")},
3431
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003432 {NULL, NULL}
3433};
3434
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003435static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003436PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3437
3438static PyTypeObject PyDateTime_TimeZoneType = {
3439 PyVarObject_HEAD_INIT(NULL, 0)
3440 "datetime.timezone", /* tp_name */
3441 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3442 0, /* tp_itemsize */
3443 (destructor)timezone_dealloc, /* tp_dealloc */
3444 0, /* tp_print */
3445 0, /* tp_getattr */
3446 0, /* tp_setattr */
3447 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003448 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003449 0, /* tp_as_number */
3450 0, /* tp_as_sequence */
3451 0, /* tp_as_mapping */
3452 (hashfunc)timezone_hash, /* tp_hash */
3453 0, /* tp_call */
3454 (reprfunc)timezone_str, /* tp_str */
3455 0, /* tp_getattro */
3456 0, /* tp_setattro */
3457 0, /* tp_as_buffer */
3458 Py_TPFLAGS_DEFAULT, /* tp_flags */
3459 timezone_doc, /* tp_doc */
3460 0, /* tp_traverse */
3461 0, /* tp_clear */
3462 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3463 0, /* tp_weaklistoffset */
3464 0, /* tp_iter */
3465 0, /* tp_iternext */
3466 timezone_methods, /* tp_methods */
3467 0, /* tp_members */
3468 0, /* tp_getset */
3469 &PyDateTime_TZInfoType, /* tp_base */
3470 0, /* tp_dict */
3471 0, /* tp_descr_get */
3472 0, /* tp_descr_set */
3473 0, /* tp_dictoffset */
3474 0, /* tp_init */
3475 0, /* tp_alloc */
3476 timezone_new, /* tp_new */
3477};
3478
Tim Peters2a799bf2002-12-16 20:18:38 +00003479/*
Tim Peters37f39822003-01-10 03:49:02 +00003480 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003481 */
3482
Tim Peters37f39822003-01-10 03:49:02 +00003483/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003484 */
3485
3486static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003487time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003490}
3491
Tim Peters37f39822003-01-10 03:49:02 +00003492static PyObject *
3493time_minute(PyDateTime_Time *self, void *unused)
3494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003495 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003496}
3497
3498/* The name time_second conflicted with some platform header file. */
3499static PyObject *
3500py_time_second(PyDateTime_Time *self, void *unused)
3501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003502 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003503}
3504
3505static PyObject *
3506time_microsecond(PyDateTime_Time *self, void *unused)
3507{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003509}
3510
3511static PyObject *
3512time_tzinfo(PyDateTime_Time *self, void *unused)
3513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003514 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3515 Py_INCREF(result);
3516 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003517}
3518
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003519static PyObject *
3520time_fold(PyDateTime_Time *self, void *unused)
3521{
3522 return PyLong_FromLong(TIME_GET_FOLD(self));
3523}
3524
Tim Peters37f39822003-01-10 03:49:02 +00003525static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003526 {"hour", (getter)time_hour},
3527 {"minute", (getter)time_minute},
3528 {"second", (getter)py_time_second},
3529 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003530 {"tzinfo", (getter)time_tzinfo},
3531 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003532 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003533};
3534
3535/*
3536 * Constructors.
3537 */
3538
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003539static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003540 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003541
Tim Peters2a799bf2002-12-16 20:18:38 +00003542static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003543time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003545 PyObject *self = NULL;
3546 PyObject *state;
3547 int hour = 0;
3548 int minute = 0;
3549 int second = 0;
3550 int usecond = 0;
3551 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003552 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003554 /* Check for invocation from pickle with __getstate__ state */
3555 if (PyTuple_GET_SIZE(args) >= 1 &&
3556 PyTuple_GET_SIZE(args) <= 2 &&
3557 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3558 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003559 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003560 {
3561 PyDateTime_Time *me;
3562 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003564 if (PyTuple_GET_SIZE(args) == 2) {
3565 tzinfo = PyTuple_GET_ITEM(args, 1);
3566 if (check_tzinfo_subclass(tzinfo) < 0) {
3567 PyErr_SetString(PyExc_TypeError, "bad "
3568 "tzinfo state arg");
3569 return NULL;
3570 }
3571 }
3572 aware = (char)(tzinfo != Py_None);
3573 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3574 if (me != NULL) {
3575 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003577 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3578 me->hashcode = -1;
3579 me->hastzinfo = aware;
3580 if (aware) {
3581 Py_INCREF(tzinfo);
3582 me->tzinfo = tzinfo;
3583 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003584 if (pdata[0] & (1 << 7)) {
3585 me->data[0] -= 128;
3586 me->fold = 1;
3587 }
3588 else {
3589 me->fold = 0;
3590 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003591 }
3592 return (PyObject *)me;
3593 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003594
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003595 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003596 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003597 &tzinfo, &fold)) {
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003598 if (check_time_args(hour, minute, second, usecond, fold) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003599 return NULL;
3600 if (check_tzinfo_subclass(tzinfo) < 0)
3601 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003602 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3603 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003604 }
3605 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003606}
3607
3608/*
3609 * Destructor.
3610 */
3611
3612static void
Tim Peters37f39822003-01-10 03:49:02 +00003613time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003614{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003615 if (HASTZINFO(self)) {
3616 Py_XDECREF(self->tzinfo);
3617 }
3618 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003619}
3620
3621/*
Tim Peters855fe882002-12-22 03:43:39 +00003622 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003623 */
3624
Tim Peters2a799bf2002-12-16 20:18:38 +00003625/* These are all METH_NOARGS, so don't need to check the arglist. */
3626static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003627time_utcoffset(PyObject *self, PyObject *unused) {
3628 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003629}
3630
3631static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003632time_dst(PyObject *self, PyObject *unused) {
3633 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003634}
3635
3636static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003637time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003638 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003639}
3640
3641/*
Tim Peters37f39822003-01-10 03:49:02 +00003642 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003643 */
3644
3645static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003646time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003647{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003648 const char *type_name = Py_TYPE(self)->tp_name;
3649 int h = TIME_GET_HOUR(self);
3650 int m = TIME_GET_MINUTE(self);
3651 int s = TIME_GET_SECOND(self);
3652 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003653 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003654 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003656 if (us)
3657 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3658 type_name, h, m, s, us);
3659 else if (s)
3660 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3661 type_name, h, m, s);
3662 else
3663 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3664 if (result != NULL && HASTZINFO(self))
3665 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003666 if (result != NULL && fold)
3667 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003668 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003669}
3670
Tim Peters37f39822003-01-10 03:49:02 +00003671static PyObject *
3672time_str(PyDateTime_Time *self)
3673{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003674 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003675}
Tim Peters2a799bf2002-12-16 20:18:38 +00003676
3677static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003678time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003680 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003681 char *timespec = NULL;
3682 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003683 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003684 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003685 static char *specs[][2] = {
3686 {"hours", "%02d"},
3687 {"minutes", "%02d:%02d"},
3688 {"seconds", "%02d:%02d:%02d"},
3689 {"milliseconds", "%02d:%02d:%02d.%03d"},
3690 {"microseconds", "%02d:%02d:%02d.%06d"},
3691 };
3692 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003693
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003694 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3695 return NULL;
3696
3697 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3698 if (us == 0) {
3699 /* seconds */
3700 given_spec = 2;
3701 }
3702 else {
3703 /* microseconds */
3704 given_spec = 4;
3705 }
3706 }
3707 else {
3708 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3709 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3710 if (given_spec == 3) {
3711 /* milliseconds */
3712 us = us / 1000;
3713 }
3714 break;
3715 }
3716 }
3717 }
3718
3719 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3720 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3721 return NULL;
3722 }
3723 else {
3724 result = PyUnicode_FromFormat(specs[given_spec][1],
3725 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3726 TIME_GET_SECOND(self), us);
3727 }
Tim Peters37f39822003-01-10 03:49:02 +00003728
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003729 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003730 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003731
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003732 /* We need to append the UTC offset. */
3733 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3734 Py_None) < 0) {
3735 Py_DECREF(result);
3736 return NULL;
3737 }
3738 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3739 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003740}
3741
Tim Peters37f39822003-01-10 03:49:02 +00003742static PyObject *
3743time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3744{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003745 PyObject *result;
3746 PyObject *tuple;
3747 PyObject *format;
3748 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003750 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3751 &format))
3752 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003754 /* Python's strftime does insane things with the year part of the
3755 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003756 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003757 */
3758 tuple = Py_BuildValue("iiiiiiiii",
3759 1900, 1, 1, /* year, month, day */
3760 TIME_GET_HOUR(self),
3761 TIME_GET_MINUTE(self),
3762 TIME_GET_SECOND(self),
3763 0, 1, -1); /* weekday, daynum, dst */
3764 if (tuple == NULL)
3765 return NULL;
3766 assert(PyTuple_Size(tuple) == 9);
3767 result = wrap_strftime((PyObject *)self, format, tuple,
3768 Py_None);
3769 Py_DECREF(tuple);
3770 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003771}
Tim Peters2a799bf2002-12-16 20:18:38 +00003772
3773/*
3774 * Miscellaneous methods.
3775 */
3776
Tim Peters37f39822003-01-10 03:49:02 +00003777static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003778time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003779{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003780 PyObject *result = NULL;
3781 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003782 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003783
Brian Curtindfc80e32011-08-10 20:28:54 -05003784 if (! PyTime_Check(other))
3785 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003786
3787 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003788 diff = memcmp(((PyDateTime_Time *)self)->data,
3789 ((PyDateTime_Time *)other)->data,
3790 _PyDateTime_TIME_DATASIZE);
3791 return diff_to_bool(diff, op);
3792 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003793 offset1 = time_utcoffset(self, NULL);
3794 if (offset1 == NULL)
3795 return NULL;
3796 offset2 = time_utcoffset(other, NULL);
3797 if (offset2 == NULL)
3798 goto done;
3799 /* If they're both naive, or both aware and have the same offsets,
3800 * we get off cheap. Note that if they're both naive, offset1 ==
3801 * offset2 == Py_None at this point.
3802 */
3803 if ((offset1 == offset2) ||
3804 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3805 delta_cmp(offset1, offset2) == 0)) {
3806 diff = memcmp(((PyDateTime_Time *)self)->data,
3807 ((PyDateTime_Time *)other)->data,
3808 _PyDateTime_TIME_DATASIZE);
3809 result = diff_to_bool(diff, op);
3810 }
3811 /* The hard case: both aware with different UTC offsets */
3812 else if (offset1 != Py_None && offset2 != Py_None) {
3813 int offsecs1, offsecs2;
3814 assert(offset1 != offset2); /* else last "if" handled it */
3815 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3816 TIME_GET_MINUTE(self) * 60 +
3817 TIME_GET_SECOND(self) -
3818 GET_TD_DAYS(offset1) * 86400 -
3819 GET_TD_SECONDS(offset1);
3820 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3821 TIME_GET_MINUTE(other) * 60 +
3822 TIME_GET_SECOND(other) -
3823 GET_TD_DAYS(offset2) * 86400 -
3824 GET_TD_SECONDS(offset2);
3825 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003826 if (diff == 0)
3827 diff = TIME_GET_MICROSECOND(self) -
3828 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003829 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003830 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003831 else if (op == Py_EQ) {
3832 result = Py_False;
3833 Py_INCREF(result);
3834 }
3835 else if (op == Py_NE) {
3836 result = Py_True;
3837 Py_INCREF(result);
3838 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003839 else {
3840 PyErr_SetString(PyExc_TypeError,
3841 "can't compare offset-naive and "
3842 "offset-aware times");
3843 }
3844 done:
3845 Py_DECREF(offset1);
3846 Py_XDECREF(offset2);
3847 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003848}
3849
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003850static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003851time_hash(PyDateTime_Time *self)
3852{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003853 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003854 PyObject *offset, *self0;
3855 if (DATE_GET_FOLD(self)) {
3856 self0 = new_time_ex2(DATE_GET_HOUR(self),
3857 DATE_GET_MINUTE(self),
3858 DATE_GET_SECOND(self),
3859 DATE_GET_MICROSECOND(self),
3860 HASTZINFO(self) ? self->tzinfo : Py_None,
3861 0, Py_TYPE(self));
3862 if (self0 == NULL)
3863 return -1;
3864 }
3865 else {
3866 self0 = (PyObject *)self;
3867 Py_INCREF(self0);
3868 }
3869 offset = time_utcoffset(self0, NULL);
3870 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003871
3872 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003873 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003875 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003876 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003877 self->hashcode = generic_hash(
3878 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003879 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003880 PyObject *temp1, *temp2;
3881 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003882 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003883 seconds = TIME_GET_HOUR(self) * 3600 +
3884 TIME_GET_MINUTE(self) * 60 +
3885 TIME_GET_SECOND(self);
3886 microseconds = TIME_GET_MICROSECOND(self);
3887 temp1 = new_delta(0, seconds, microseconds, 1);
3888 if (temp1 == NULL) {
3889 Py_DECREF(offset);
3890 return -1;
3891 }
3892 temp2 = delta_subtract(temp1, offset);
3893 Py_DECREF(temp1);
3894 if (temp2 == NULL) {
3895 Py_DECREF(offset);
3896 return -1;
3897 }
3898 self->hashcode = PyObject_Hash(temp2);
3899 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003900 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003901 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003902 }
3903 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003904}
Tim Peters2a799bf2002-12-16 20:18:38 +00003905
Tim Peters12bf3392002-12-24 05:41:27 +00003906static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003907time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003909 PyObject *clone;
3910 PyObject *tuple;
3911 int hh = TIME_GET_HOUR(self);
3912 int mm = TIME_GET_MINUTE(self);
3913 int ss = TIME_GET_SECOND(self);
3914 int us = TIME_GET_MICROSECOND(self);
3915 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003916 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003917
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003918 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003919 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003920 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003921 return NULL;
3922 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3923 if (tuple == NULL)
3924 return NULL;
3925 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003926 if (clone != NULL) {
3927 if (fold != 0 && fold != 1) {
3928 PyErr_SetString(PyExc_ValueError,
3929 "fold must be either 0 or 1");
3930 return NULL;
3931 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003932 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003933 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003934 Py_DECREF(tuple);
3935 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003936}
3937
Tim Peters371935f2003-02-01 01:52:50 +00003938/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003939
Tim Peters33e0f382003-01-10 02:05:14 +00003940/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003941 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3942 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003943 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003944 */
3945static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003946time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00003947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003948 PyObject *basestate;
3949 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003951 basestate = PyBytes_FromStringAndSize((char *)self->data,
3952 _PyDateTime_TIME_DATASIZE);
3953 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003954 if (proto > 3 && TIME_GET_FOLD(self))
3955 /* Set the first bit of the first byte */
3956 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003957 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3958 result = PyTuple_Pack(1, basestate);
3959 else
3960 result = PyTuple_Pack(2, basestate, self->tzinfo);
3961 Py_DECREF(basestate);
3962 }
3963 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003964}
3965
3966static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003967time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00003968{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003969 int proto;
3970 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003971 return NULL;
3972
3973 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00003974}
3975
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003976static PyObject *
3977time_reduce(PyDateTime_Time *self, PyObject *arg)
3978{
3979 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
3980}
3981
Tim Peters37f39822003-01-10 03:49:02 +00003982static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003983
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003984 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
3985 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
3986 "[+HH:MM].\n\n"
3987 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003989 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3990 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003992 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3993 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003995 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3996 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003998 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3999 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4002 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4005 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004006
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004007 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004008 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004009
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004010 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4011 PyDoc_STR("__reduce__() -> (cls, state)")},
4012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004013 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004014};
4015
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004016static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004017PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4018\n\
4019All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004020a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004021
Neal Norwitz227b5332006-03-22 09:28:35 +00004022static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004023 PyVarObject_HEAD_INIT(NULL, 0)
4024 "datetime.time", /* tp_name */
4025 sizeof(PyDateTime_Time), /* tp_basicsize */
4026 0, /* tp_itemsize */
4027 (destructor)time_dealloc, /* tp_dealloc */
4028 0, /* tp_print */
4029 0, /* tp_getattr */
4030 0, /* tp_setattr */
4031 0, /* tp_reserved */
4032 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004033 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004034 0, /* tp_as_sequence */
4035 0, /* tp_as_mapping */
4036 (hashfunc)time_hash, /* tp_hash */
4037 0, /* tp_call */
4038 (reprfunc)time_str, /* tp_str */
4039 PyObject_GenericGetAttr, /* tp_getattro */
4040 0, /* tp_setattro */
4041 0, /* tp_as_buffer */
4042 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4043 time_doc, /* tp_doc */
4044 0, /* tp_traverse */
4045 0, /* tp_clear */
4046 time_richcompare, /* tp_richcompare */
4047 0, /* tp_weaklistoffset */
4048 0, /* tp_iter */
4049 0, /* tp_iternext */
4050 time_methods, /* tp_methods */
4051 0, /* tp_members */
4052 time_getset, /* tp_getset */
4053 0, /* tp_base */
4054 0, /* tp_dict */
4055 0, /* tp_descr_get */
4056 0, /* tp_descr_set */
4057 0, /* tp_dictoffset */
4058 0, /* tp_init */
4059 time_alloc, /* tp_alloc */
4060 time_new, /* tp_new */
4061 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004062};
4063
4064/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004065 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004066 */
4067
Tim Petersa9bc1682003-01-11 03:39:11 +00004068/* Accessor properties. Properties for day, month, and year are inherited
4069 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004070 */
4071
4072static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004073datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004074{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004075 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004076}
4077
Tim Petersa9bc1682003-01-11 03:39:11 +00004078static PyObject *
4079datetime_minute(PyDateTime_DateTime *self, void *unused)
4080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004081 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004082}
4083
4084static PyObject *
4085datetime_second(PyDateTime_DateTime *self, void *unused)
4086{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004087 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004088}
4089
4090static PyObject *
4091datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004093 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004094}
4095
4096static PyObject *
4097datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004099 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4100 Py_INCREF(result);
4101 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004102}
4103
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004104static PyObject *
4105datetime_fold(PyDateTime_DateTime *self, void *unused)
4106{
4107 return PyLong_FromLong(DATE_GET_FOLD(self));
4108}
4109
Tim Petersa9bc1682003-01-11 03:39:11 +00004110static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004111 {"hour", (getter)datetime_hour},
4112 {"minute", (getter)datetime_minute},
4113 {"second", (getter)datetime_second},
4114 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004115 {"tzinfo", (getter)datetime_tzinfo},
4116 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004117 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004118};
4119
4120/*
4121 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004122 */
4123
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004124static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004125 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004126 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004127};
4128
Tim Peters2a799bf2002-12-16 20:18:38 +00004129static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004130datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004132 PyObject *self = NULL;
4133 PyObject *state;
4134 int year;
4135 int month;
4136 int day;
4137 int hour = 0;
4138 int minute = 0;
4139 int second = 0;
4140 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004141 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004142 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004144 /* Check for invocation from pickle with __getstate__ state */
4145 if (PyTuple_GET_SIZE(args) >= 1 &&
4146 PyTuple_GET_SIZE(args) <= 2 &&
4147 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4148 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004149 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004150 {
4151 PyDateTime_DateTime *me;
4152 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004154 if (PyTuple_GET_SIZE(args) == 2) {
4155 tzinfo = PyTuple_GET_ITEM(args, 1);
4156 if (check_tzinfo_subclass(tzinfo) < 0) {
4157 PyErr_SetString(PyExc_TypeError, "bad "
4158 "tzinfo state arg");
4159 return NULL;
4160 }
4161 }
4162 aware = (char)(tzinfo != Py_None);
4163 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4164 if (me != NULL) {
4165 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004167 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4168 me->hashcode = -1;
4169 me->hastzinfo = aware;
4170 if (aware) {
4171 Py_INCREF(tzinfo);
4172 me->tzinfo = tzinfo;
4173 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004174 if (pdata[2] & (1 << 7)) {
4175 me->data[2] -= 128;
4176 me->fold = 1;
4177 }
4178 else {
4179 me->fold = 0;
4180 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004181 }
4182 return (PyObject *)me;
4183 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004184
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004185 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004186 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004187 &second, &usecond, &tzinfo, &fold)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004188 if (check_date_args(year, month, day) < 0)
4189 return NULL;
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004190 if (check_time_args(hour, minute, second, usecond, fold) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 return NULL;
4192 if (check_tzinfo_subclass(tzinfo) < 0)
4193 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004194 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004195 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004196 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004197 }
4198 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004199}
4200
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004201/* TM_FUNC is the shared type of _PyTime_localtime() and
4202 * _PyTime_gmtime(). */
4203typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004204
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004205/* As of version 2015f max fold in IANA database is
4206 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004207static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004208/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004209static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004210
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004211static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004212utc_to_seconds(int year, int month, int day,
4213 int hour, int minute, int second)
4214{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004215 long long ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004216 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4217}
4218
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004219static long long
4220local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004221{
4222 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004223 time_t t;
4224 u -= epoch;
4225 t = u;
4226 if (t != u) {
4227 PyErr_SetString(PyExc_OverflowError,
4228 "timestamp out of range for platform time_t");
4229 return -1;
4230 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004231 /* XXX: add bounds checking */
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004232 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004233 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004234 return utc_to_seconds(local_time.tm_year + 1900,
4235 local_time.tm_mon + 1,
4236 local_time.tm_mday,
4237 local_time.tm_hour,
4238 local_time.tm_min,
4239 local_time.tm_sec);
4240}
4241
Tim Petersa9bc1682003-01-11 03:39:11 +00004242/* Internal helper.
4243 * Build datetime from a time_t and a distinct count of microseconds.
4244 * Pass localtime or gmtime for f, to control the interpretation of timet.
4245 */
4246static PyObject *
4247datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004248 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004249{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004250 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004251 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004252
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004253 if (f(timet, &tm) != 0)
4254 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004255
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004256 year = tm.tm_year + 1900;
4257 month = tm.tm_mon + 1;
4258 day = tm.tm_mday;
4259 hour = tm.tm_hour;
4260 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004261 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004262 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004263 * except to the extent that passing them on to the datetime
4264 * constructor would raise ValueError for a reason that
4265 * made no sense to the user.
4266 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004267 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004268
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004269 if (tzinfo == Py_None && f == _PyTime_localtime) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004270 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004271
4272 result_seconds = utc_to_seconds(year, month, day,
4273 hour, minute, second);
4274 /* Probe max_fold_seconds to detect a fold. */
4275 probe_seconds = local(epoch + timet - max_fold_seconds);
4276 if (probe_seconds == -1)
4277 return NULL;
4278 transition = result_seconds - probe_seconds - max_fold_seconds;
4279 if (transition < 0) {
4280 probe_seconds = local(epoch + timet + transition);
4281 if (probe_seconds == -1)
4282 return NULL;
4283 if (probe_seconds == result_seconds)
4284 fold = 1;
4285 }
4286 }
4287 return new_datetime_ex2(year, month, day, hour,
4288 minute, second, us, tzinfo, fold,
4289 (PyTypeObject *)cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004290}
4291
4292/* Internal helper.
4293 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4294 * to control the interpretation of the timestamp. Since a double doesn't
4295 * have enough bits to cover a datetime's full range of precision, it's
4296 * better to call datetime_from_timet_and_us provided you have a way
4297 * to get that much precision (e.g., C time() isn't good enough).
4298 */
4299static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004300datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004301 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004304 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004305
Victor Stinnere4a994d2015-03-30 01:10:14 +02004306 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004307 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004308 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004309
Victor Stinner21f58932012-03-14 00:15:40 +01004310 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004311}
4312
4313/* Internal helper.
4314 * Build most accurate possible datetime for current time. Pass localtime or
4315 * gmtime for f as appropriate.
4316 */
4317static PyObject *
4318datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4319{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004320 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004321 time_t secs;
4322 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004323
Victor Stinner1e2b6882015-09-18 13:23:02 +02004324 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004325 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004326 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004327
Victor Stinner1e2b6882015-09-18 13:23:02 +02004328 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004329}
4330
Larry Hastings61272b72014-01-07 12:41:53 -08004331/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004332
4333@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004334datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004335
4336 tz: object = None
4337 Timezone object.
4338
4339Returns new datetime object representing current time local to tz.
4340
4341If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004342[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004343
Larry Hastings31826802013-10-19 00:09:25 -07004344static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004345datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004346/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004348 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004349
Larry Hastings31826802013-10-19 00:09:25 -07004350 /* Return best possible local time -- this isn't constrained by the
4351 * precision of a timestamp.
4352 */
4353 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004354 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004355
Larry Hastings5c661892014-01-24 06:17:25 -08004356 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004357 tz == Py_None ? _PyTime_localtime :
4358 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004359 tz);
4360 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004361 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004362 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004363 }
4364 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004365}
4366
Tim Petersa9bc1682003-01-11 03:39:11 +00004367/* Return best possible UTC time -- this isn't constrained by the
4368 * precision of a timestamp.
4369 */
4370static PyObject *
4371datetime_utcnow(PyObject *cls, PyObject *dummy)
4372{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004373 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004374}
4375
Tim Peters2a799bf2002-12-16 20:18:38 +00004376/* Return new local datetime from timestamp (Python timestamp -- a double). */
4377static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004378datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004380 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004381 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004382 PyObject *tzinfo = Py_None;
4383 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004384
Victor Stinner5d272cc2012-03-13 13:35:55 +01004385 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004386 keywords, &timestamp, &tzinfo))
4387 return NULL;
4388 if (check_tzinfo_subclass(tzinfo) < 0)
4389 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004391 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004392 tzinfo == Py_None ? _PyTime_localtime :
4393 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004394 timestamp,
4395 tzinfo);
4396 if (self != NULL && tzinfo != Py_None) {
4397 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004398 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004399 }
4400 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004401}
4402
Tim Petersa9bc1682003-01-11 03:39:11 +00004403/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4404static PyObject *
4405datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4406{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004407 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004408 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004409
Victor Stinner5d272cc2012-03-13 13:35:55 +01004410 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004411 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004412 Py_None);
4413 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004414}
4415
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004416/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004417static PyObject *
4418datetime_strptime(PyObject *cls, PyObject *args)
4419{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004420 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004421 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004422 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004423
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004424 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004425 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004426
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004427 if (module == NULL) {
4428 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004429 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004430 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004431 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004432 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4433 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004434}
4435
Tim Petersa9bc1682003-01-11 03:39:11 +00004436/* Return new datetime from date/datetime and time arguments. */
4437static PyObject *
4438datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4439{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004440 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004441 PyObject *date;
4442 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004443 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004444 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004445
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004446 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004447 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004448 &PyDateTime_TimeType, &time, &tzinfo)) {
4449 if (tzinfo == NULL) {
4450 if (HASTZINFO(time))
4451 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4452 else
4453 tzinfo = Py_None;
4454 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004455 result = PyObject_CallFunction(cls, "iiiiiiiO",
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004456 GET_YEAR(date),
4457 GET_MONTH(date),
4458 GET_DAY(date),
4459 TIME_GET_HOUR(time),
4460 TIME_GET_MINUTE(time),
4461 TIME_GET_SECOND(time),
4462 TIME_GET_MICROSECOND(time),
4463 tzinfo);
4464 if (result)
4465 DATE_SET_FOLD(result, TIME_GET_FOLD(time));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004466 }
4467 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004468}
Tim Peters2a799bf2002-12-16 20:18:38 +00004469
4470/*
4471 * Destructor.
4472 */
4473
4474static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004475datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004477 if (HASTZINFO(self)) {
4478 Py_XDECREF(self->tzinfo);
4479 }
4480 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004481}
4482
4483/*
4484 * Indirect access to tzinfo methods.
4485 */
4486
Tim Peters2a799bf2002-12-16 20:18:38 +00004487/* These are all METH_NOARGS, so don't need to check the arglist. */
4488static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004489datetime_utcoffset(PyObject *self, PyObject *unused) {
4490 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004491}
4492
4493static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004494datetime_dst(PyObject *self, PyObject *unused) {
4495 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004496}
4497
4498static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004499datetime_tzname(PyObject *self, PyObject *unused) {
4500 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004501}
4502
4503/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004504 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004505 */
4506
Tim Petersa9bc1682003-01-11 03:39:11 +00004507/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4508 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004509 */
4510static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004511add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004512 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004514 /* Note that the C-level additions can't overflow, because of
4515 * invariant bounds on the member values.
4516 */
4517 int year = GET_YEAR(date);
4518 int month = GET_MONTH(date);
4519 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4520 int hour = DATE_GET_HOUR(date);
4521 int minute = DATE_GET_MINUTE(date);
4522 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4523 int microsecond = DATE_GET_MICROSECOND(date) +
4524 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004526 assert(factor == 1 || factor == -1);
4527 if (normalize_datetime(&year, &month, &day,
4528 &hour, &minute, &second, &microsecond) < 0)
4529 return NULL;
4530 else
4531 return new_datetime(year, month, day,
4532 hour, minute, second, microsecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004533 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004534}
4535
4536static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004537datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004539 if (PyDateTime_Check(left)) {
4540 /* datetime + ??? */
4541 if (PyDelta_Check(right))
4542 /* datetime + delta */
4543 return add_datetime_timedelta(
4544 (PyDateTime_DateTime *)left,
4545 (PyDateTime_Delta *)right,
4546 1);
4547 }
4548 else if (PyDelta_Check(left)) {
4549 /* delta + datetime */
4550 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4551 (PyDateTime_Delta *) left,
4552 1);
4553 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004554 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004555}
4556
4557static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004558datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004560 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004562 if (PyDateTime_Check(left)) {
4563 /* datetime - ??? */
4564 if (PyDateTime_Check(right)) {
4565 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004566 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004567 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004568
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004569 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4570 offset2 = offset1 = Py_None;
4571 Py_INCREF(offset1);
4572 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004574 else {
4575 offset1 = datetime_utcoffset(left, NULL);
4576 if (offset1 == NULL)
4577 return NULL;
4578 offset2 = datetime_utcoffset(right, NULL);
4579 if (offset2 == NULL) {
4580 Py_DECREF(offset1);
4581 return NULL;
4582 }
4583 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4584 PyErr_SetString(PyExc_TypeError,
4585 "can't subtract offset-naive and "
4586 "offset-aware datetimes");
4587 Py_DECREF(offset1);
4588 Py_DECREF(offset2);
4589 return NULL;
4590 }
4591 }
4592 if ((offset1 != offset2) &&
4593 delta_cmp(offset1, offset2) != 0) {
4594 offdiff = delta_subtract(offset1, offset2);
4595 if (offdiff == NULL) {
4596 Py_DECREF(offset1);
4597 Py_DECREF(offset2);
4598 return NULL;
4599 }
4600 }
4601 Py_DECREF(offset1);
4602 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004603 delta_d = ymd_to_ord(GET_YEAR(left),
4604 GET_MONTH(left),
4605 GET_DAY(left)) -
4606 ymd_to_ord(GET_YEAR(right),
4607 GET_MONTH(right),
4608 GET_DAY(right));
4609 /* These can't overflow, since the values are
4610 * normalized. At most this gives the number of
4611 * seconds in one day.
4612 */
4613 delta_s = (DATE_GET_HOUR(left) -
4614 DATE_GET_HOUR(right)) * 3600 +
4615 (DATE_GET_MINUTE(left) -
4616 DATE_GET_MINUTE(right)) * 60 +
4617 (DATE_GET_SECOND(left) -
4618 DATE_GET_SECOND(right));
4619 delta_us = DATE_GET_MICROSECOND(left) -
4620 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004621 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004622 if (result == NULL)
4623 return NULL;
4624
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004625 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004626 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004627 Py_DECREF(offdiff);
4628 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004629 }
4630 else if (PyDelta_Check(right)) {
4631 /* datetime - delta */
4632 result = add_datetime_timedelta(
4633 (PyDateTime_DateTime *)left,
4634 (PyDateTime_Delta *)right,
4635 -1);
4636 }
4637 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004639 if (result == Py_NotImplemented)
4640 Py_INCREF(result);
4641 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004642}
4643
4644/* Various ways to turn a datetime into a string. */
4645
4646static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004647datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004649 const char *type_name = Py_TYPE(self)->tp_name;
4650 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004652 if (DATE_GET_MICROSECOND(self)) {
4653 baserepr = PyUnicode_FromFormat(
4654 "%s(%d, %d, %d, %d, %d, %d, %d)",
4655 type_name,
4656 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4657 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4658 DATE_GET_SECOND(self),
4659 DATE_GET_MICROSECOND(self));
4660 }
4661 else if (DATE_GET_SECOND(self)) {
4662 baserepr = PyUnicode_FromFormat(
4663 "%s(%d, %d, %d, %d, %d, %d)",
4664 type_name,
4665 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4666 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4667 DATE_GET_SECOND(self));
4668 }
4669 else {
4670 baserepr = PyUnicode_FromFormat(
4671 "%s(%d, %d, %d, %d, %d)",
4672 type_name,
4673 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4674 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4675 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004676 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4677 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004678 if (baserepr == NULL || ! HASTZINFO(self))
4679 return baserepr;
4680 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004681}
4682
Tim Petersa9bc1682003-01-11 03:39:11 +00004683static PyObject *
4684datetime_str(PyDateTime_DateTime *self)
4685{
Victor Stinner4c381542016-12-09 00:33:39 +01004686 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004687}
Tim Peters2a799bf2002-12-16 20:18:38 +00004688
4689static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004690datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004692 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004693 char *timespec = NULL;
4694 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004695 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004696 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004697 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004698 static char *specs[][2] = {
4699 {"hours", "%04d-%02d-%02d%c%02d"},
4700 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4701 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4702 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4703 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4704 };
4705 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004706
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004707 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004708 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004709
4710 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4711 if (us == 0) {
4712 /* seconds */
4713 given_spec = 2;
4714 }
4715 else {
4716 /* microseconds */
4717 given_spec = 4;
4718 }
4719 }
4720 else {
4721 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4722 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4723 if (given_spec == 3) {
4724 us = us / 1000;
4725 }
4726 break;
4727 }
4728 }
4729 }
4730
4731 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4732 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4733 return NULL;
4734 }
4735 else {
4736 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004737 GET_YEAR(self), GET_MONTH(self),
4738 GET_DAY(self), (int)sep,
4739 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4740 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004741 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004743 if (!result || !HASTZINFO(self))
4744 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004746 /* We need to append the UTC offset. */
4747 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4748 (PyObject *)self) < 0) {
4749 Py_DECREF(result);
4750 return NULL;
4751 }
4752 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4753 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004754}
4755
Tim Petersa9bc1682003-01-11 03:39:11 +00004756static PyObject *
4757datetime_ctime(PyDateTime_DateTime *self)
4758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004759 return format_ctime((PyDateTime_Date *)self,
4760 DATE_GET_HOUR(self),
4761 DATE_GET_MINUTE(self),
4762 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004763}
4764
Tim Peters2a799bf2002-12-16 20:18:38 +00004765/* Miscellaneous methods. */
4766
Tim Petersa9bc1682003-01-11 03:39:11 +00004767static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004768flip_fold(PyObject *dt)
4769{
4770 return new_datetime_ex2(GET_YEAR(dt),
4771 GET_MONTH(dt),
4772 GET_DAY(dt),
4773 DATE_GET_HOUR(dt),
4774 DATE_GET_MINUTE(dt),
4775 DATE_GET_SECOND(dt),
4776 DATE_GET_MICROSECOND(dt),
4777 HASTZINFO(dt) ?
4778 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4779 !DATE_GET_FOLD(dt),
4780 Py_TYPE(dt));
4781}
4782
4783static PyObject *
4784get_flip_fold_offset(PyObject *dt)
4785{
4786 PyObject *result, *flip_dt;
4787
4788 flip_dt = flip_fold(dt);
4789 if (flip_dt == NULL)
4790 return NULL;
4791 result = datetime_utcoffset(flip_dt, NULL);
4792 Py_DECREF(flip_dt);
4793 return result;
4794}
4795
4796/* PEP 495 exception: Whenever one or both of the operands in
4797 * inter-zone comparison is such that its utcoffset() depends
4798 * on the value of its fold fold attribute, the result is False.
4799 *
4800 * Return 1 if exception applies, 0 if not, and -1 on error.
4801 */
4802static int
4803pep495_eq_exception(PyObject *self, PyObject *other,
4804 PyObject *offset_self, PyObject *offset_other)
4805{
4806 int result = 0;
4807 PyObject *flip_offset;
4808
4809 flip_offset = get_flip_fold_offset(self);
4810 if (flip_offset == NULL)
4811 return -1;
4812 if (flip_offset != offset_self &&
4813 delta_cmp(flip_offset, offset_self))
4814 {
4815 result = 1;
4816 goto done;
4817 }
4818 Py_DECREF(flip_offset);
4819
4820 flip_offset = get_flip_fold_offset(other);
4821 if (flip_offset == NULL)
4822 return -1;
4823 if (flip_offset != offset_other &&
4824 delta_cmp(flip_offset, offset_other))
4825 result = 1;
4826 done:
4827 Py_DECREF(flip_offset);
4828 return result;
4829}
4830
4831static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004832datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004833{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004834 PyObject *result = NULL;
4835 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004836 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004838 if (! PyDateTime_Check(other)) {
4839 if (PyDate_Check(other)) {
4840 /* Prevent invocation of date_richcompare. We want to
4841 return NotImplemented here to give the other object
4842 a chance. But since DateTime is a subclass of
4843 Date, if the other object is a Date, it would
4844 compute an ordering based on the date part alone,
4845 and we don't want that. So force unequal or
4846 uncomparable here in that case. */
4847 if (op == Py_EQ)
4848 Py_RETURN_FALSE;
4849 if (op == Py_NE)
4850 Py_RETURN_TRUE;
4851 return cmperror(self, other);
4852 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004853 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004854 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004855
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004856 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004857 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4858 ((PyDateTime_DateTime *)other)->data,
4859 _PyDateTime_DATETIME_DATASIZE);
4860 return diff_to_bool(diff, op);
4861 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004862 offset1 = datetime_utcoffset(self, NULL);
4863 if (offset1 == NULL)
4864 return NULL;
4865 offset2 = datetime_utcoffset(other, NULL);
4866 if (offset2 == NULL)
4867 goto done;
4868 /* If they're both naive, or both aware and have the same offsets,
4869 * we get off cheap. Note that if they're both naive, offset1 ==
4870 * offset2 == Py_None at this point.
4871 */
4872 if ((offset1 == offset2) ||
4873 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4874 delta_cmp(offset1, offset2) == 0)) {
4875 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4876 ((PyDateTime_DateTime *)other)->data,
4877 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004878 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4879 int ex = pep495_eq_exception(self, other, offset1, offset2);
4880 if (ex == -1)
4881 goto done;
4882 if (ex)
4883 diff = 1;
4884 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004885 result = diff_to_bool(diff, op);
4886 }
4887 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004888 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004889
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004890 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004891 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4892 other);
4893 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004894 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004895 diff = GET_TD_DAYS(delta);
4896 if (diff == 0)
4897 diff = GET_TD_SECONDS(delta) |
4898 GET_TD_MICROSECONDS(delta);
4899 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004900 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4901 int ex = pep495_eq_exception(self, other, offset1, offset2);
4902 if (ex == -1)
4903 goto done;
4904 if (ex)
4905 diff = 1;
4906 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004907 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004908 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004909 else if (op == Py_EQ) {
4910 result = Py_False;
4911 Py_INCREF(result);
4912 }
4913 else if (op == Py_NE) {
4914 result = Py_True;
4915 Py_INCREF(result);
4916 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004917 else {
4918 PyErr_SetString(PyExc_TypeError,
4919 "can't compare offset-naive and "
4920 "offset-aware datetimes");
4921 }
4922 done:
4923 Py_DECREF(offset1);
4924 Py_XDECREF(offset2);
4925 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004926}
4927
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004928static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004929datetime_hash(PyDateTime_DateTime *self)
4930{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004931 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004932 PyObject *offset, *self0;
4933 if (DATE_GET_FOLD(self)) {
4934 self0 = new_datetime_ex2(GET_YEAR(self),
4935 GET_MONTH(self),
4936 GET_DAY(self),
4937 DATE_GET_HOUR(self),
4938 DATE_GET_MINUTE(self),
4939 DATE_GET_SECOND(self),
4940 DATE_GET_MICROSECOND(self),
4941 HASTZINFO(self) ? self->tzinfo : Py_None,
4942 0, Py_TYPE(self));
4943 if (self0 == NULL)
4944 return -1;
4945 }
4946 else {
4947 self0 = (PyObject *)self;
4948 Py_INCREF(self0);
4949 }
4950 offset = datetime_utcoffset(self0, NULL);
4951 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004952
4953 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004954 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004956 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004957 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004958 self->hashcode = generic_hash(
4959 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004960 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004961 PyObject *temp1, *temp2;
4962 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004964 assert(HASTZINFO(self));
4965 days = ymd_to_ord(GET_YEAR(self),
4966 GET_MONTH(self),
4967 GET_DAY(self));
4968 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004969 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004970 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004971 temp1 = new_delta(days, seconds,
4972 DATE_GET_MICROSECOND(self),
4973 1);
4974 if (temp1 == NULL) {
4975 Py_DECREF(offset);
4976 return -1;
4977 }
4978 temp2 = delta_subtract(temp1, offset);
4979 Py_DECREF(temp1);
4980 if (temp2 == NULL) {
4981 Py_DECREF(offset);
4982 return -1;
4983 }
4984 self->hashcode = PyObject_Hash(temp2);
4985 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004986 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004987 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004988 }
4989 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004990}
Tim Peters2a799bf2002-12-16 20:18:38 +00004991
4992static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004993datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004995 PyObject *clone;
4996 PyObject *tuple;
4997 int y = GET_YEAR(self);
4998 int m = GET_MONTH(self);
4999 int d = GET_DAY(self);
5000 int hh = DATE_GET_HOUR(self);
5001 int mm = DATE_GET_MINUTE(self);
5002 int ss = DATE_GET_SECOND(self);
5003 int us = DATE_GET_MICROSECOND(self);
5004 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005005 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005006
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005007 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005008 datetime_kws,
5009 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005010 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005011 return NULL;
5012 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5013 if (tuple == NULL)
5014 return NULL;
5015 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005016
5017 if (clone != NULL) {
5018 if (fold != 0 && fold != 1) {
5019 PyErr_SetString(PyExc_ValueError,
5020 "fold must be either 0 or 1");
5021 return NULL;
5022 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005023 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005024 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005025 Py_DECREF(tuple);
5026 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005027}
5028
5029static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005030local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005031{
5032 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005033 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005034 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005035 PyObject *nameo = NULL;
5036 const char *zone = NULL;
5037
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005038 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005039 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005040#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005041 zone = local_time_tm.tm_zone;
5042 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005043#else /* HAVE_STRUCT_TM_TM_ZONE */
5044 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005045 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005046 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005047 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005048 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005049 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005050 local_time = new_datetime(local_time_tm.tm_year + 1900,
5051 local_time_tm.tm_mon + 1,
5052 local_time_tm.tm_mday,
5053 local_time_tm.tm_hour,
5054 local_time_tm.tm_min,
5055 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005056 if (local_time == NULL) {
5057 return NULL;
5058 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005059 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005060 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005061 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5062 utc_time_tm.tm_mon + 1,
5063 utc_time_tm.tm_mday,
5064 utc_time_tm.tm_hour,
5065 utc_time_tm.tm_min,
5066 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005067 if (utc_time == NULL) {
5068 Py_DECREF(local_time);
5069 return NULL;
5070 }
5071 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005072 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005073 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005074 }
5075#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005076 if (delta == NULL) {
5077 return NULL;
5078 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005079 if (zone != NULL) {
5080 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5081 if (nameo == NULL)
5082 goto error;
5083 }
5084 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005085 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005086 error:
5087 Py_DECREF(delta);
5088 return result;
5089}
5090
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005091static PyObject *
5092local_timezone(PyDateTime_DateTime *utc_time)
5093{
5094 time_t timestamp;
5095 PyObject *delta;
5096 PyObject *one_second;
5097 PyObject *seconds;
5098
5099 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5100 if (delta == NULL)
5101 return NULL;
5102 one_second = new_delta(0, 1, 0, 0);
5103 if (one_second == NULL) {
5104 Py_DECREF(delta);
5105 return NULL;
5106 }
5107 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5108 (PyDateTime_Delta *)one_second);
5109 Py_DECREF(one_second);
5110 Py_DECREF(delta);
5111 if (seconds == NULL)
5112 return NULL;
5113 timestamp = _PyLong_AsTime_t(seconds);
5114 Py_DECREF(seconds);
5115 if (timestamp == -1 && PyErr_Occurred())
5116 return NULL;
5117 return local_timezone_from_timestamp(timestamp);
5118}
5119
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005120static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005121local_to_seconds(int year, int month, int day,
5122 int hour, int minute, int second, int fold);
5123
5124static PyObject *
5125local_timezone_from_local(PyDateTime_DateTime *local_dt)
5126{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005127 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005128 time_t timestamp;
5129 seconds = local_to_seconds(GET_YEAR(local_dt),
5130 GET_MONTH(local_dt),
5131 GET_DAY(local_dt),
5132 DATE_GET_HOUR(local_dt),
5133 DATE_GET_MINUTE(local_dt),
5134 DATE_GET_SECOND(local_dt),
5135 DATE_GET_FOLD(local_dt));
5136 if (seconds == -1)
5137 return NULL;
5138 /* XXX: add bounds check */
5139 timestamp = seconds - epoch;
5140 return local_timezone_from_timestamp(timestamp);
5141}
5142
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005143static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005144datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005145{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005146 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005147 PyObject *offset;
5148 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005149 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005150 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005151 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005152
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005153 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005154 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005155 return NULL;
5156
5157 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005158 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005159
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005160 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5161 self_tzinfo = local_timezone_from_local(self);
5162 if (self_tzinfo == NULL)
5163 return NULL;
5164 } else {
5165 self_tzinfo = self->tzinfo;
5166 Py_INCREF(self_tzinfo);
5167 }
Tim Peters521fc152002-12-31 17:36:56 +00005168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005169 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005170 if (self_tzinfo == tzinfo) {
5171 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005172 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005173 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005174 }
Tim Peters521fc152002-12-31 17:36:56 +00005175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005176 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005177 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5178 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005179 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005180 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005181 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005182 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5183 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005184 Py_DECREF(offset);
5185 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005186 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005187
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005188 /* Make sure result is aware and UTC. */
5189 if (!HASTZINFO(result)) {
5190 temp = (PyObject *)result;
5191 result = (PyDateTime_DateTime *)
5192 new_datetime_ex2(GET_YEAR(result),
5193 GET_MONTH(result),
5194 GET_DAY(result),
5195 DATE_GET_HOUR(result),
5196 DATE_GET_MINUTE(result),
5197 DATE_GET_SECOND(result),
5198 DATE_GET_MICROSECOND(result),
5199 PyDateTime_TimeZone_UTC,
5200 DATE_GET_FOLD(result),
5201 Py_TYPE(result));
5202 Py_DECREF(temp);
5203 if (result == NULL)
5204 return NULL;
5205 }
5206 else {
5207 /* Result is already aware - just replace tzinfo. */
5208 temp = result->tzinfo;
5209 result->tzinfo = PyDateTime_TimeZone_UTC;
5210 Py_INCREF(result->tzinfo);
5211 Py_DECREF(temp);
5212 }
5213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005214 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005215 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005216 if (tzinfo == Py_None) {
5217 tzinfo = local_timezone(result);
5218 if (tzinfo == NULL) {
5219 Py_DECREF(result);
5220 return NULL;
5221 }
5222 }
5223 else
5224 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005225 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005226 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005227
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005228 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005229 result = (PyDateTime_DateTime *)
5230 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005231 Py_DECREF(temp);
5232
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005233 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005234}
5235
5236static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005237datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005239 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005241 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005242 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005243
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005244 dst = call_dst(self->tzinfo, (PyObject *)self);
5245 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005246 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005247
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005248 if (dst != Py_None)
5249 dstflag = delta_bool((PyDateTime_Delta *)dst);
5250 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005251 }
5252 return build_struct_time(GET_YEAR(self),
5253 GET_MONTH(self),
5254 GET_DAY(self),
5255 DATE_GET_HOUR(self),
5256 DATE_GET_MINUTE(self),
5257 DATE_GET_SECOND(self),
5258 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005259}
5260
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005261static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005262local_to_seconds(int year, int month, int day,
5263 int hour, int minute, int second, int fold)
5264{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005265 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005266 t = utc_to_seconds(year, month, day, hour, minute, second);
5267 /* Our goal is to solve t = local(u) for u. */
5268 lt = local(t);
5269 if (lt == -1)
5270 return -1;
5271 a = lt - t;
5272 u1 = t - a;
5273 t1 = local(u1);
5274 if (t1 == -1)
5275 return -1;
5276 if (t1 == t) {
5277 /* We found one solution, but it may not be the one we need.
5278 * Look for an earlier solution (if `fold` is 0), or a
5279 * later one (if `fold` is 1). */
5280 if (fold)
5281 u2 = u1 + max_fold_seconds;
5282 else
5283 u2 = u1 - max_fold_seconds;
5284 lt = local(u2);
5285 if (lt == -1)
5286 return -1;
5287 b = lt - u2;
5288 if (a == b)
5289 return u1;
5290 }
5291 else {
5292 b = t1 - u1;
5293 assert(a != b);
5294 }
5295 u2 = t - b;
5296 t2 = local(u2);
5297 if (t2 == -1)
5298 return -1;
5299 if (t2 == t)
5300 return u2;
5301 if (t1 == t)
5302 return u1;
5303 /* We have found both offsets a and b, but neither t - a nor t - b is
5304 * a solution. This means t is in the gap. */
5305 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5306}
5307
5308/* date(1970,1,1).toordinal() == 719163 */
5309#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5310
Tim Peters2a799bf2002-12-16 20:18:38 +00005311static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005312datetime_timestamp(PyDateTime_DateTime *self)
5313{
5314 PyObject *result;
5315
5316 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5317 PyObject *delta;
5318 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5319 if (delta == NULL)
5320 return NULL;
5321 result = delta_total_seconds(delta);
5322 Py_DECREF(delta);
5323 }
5324 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005325 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005326 seconds = local_to_seconds(GET_YEAR(self),
5327 GET_MONTH(self),
5328 GET_DAY(self),
5329 DATE_GET_HOUR(self),
5330 DATE_GET_MINUTE(self),
5331 DATE_GET_SECOND(self),
5332 DATE_GET_FOLD(self));
5333 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005334 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005335 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5336 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005337 }
5338 return result;
5339}
5340
5341static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005342datetime_getdate(PyDateTime_DateTime *self)
5343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005344 return new_date(GET_YEAR(self),
5345 GET_MONTH(self),
5346 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005347}
5348
5349static PyObject *
5350datetime_gettime(PyDateTime_DateTime *self)
5351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005352 return new_time(DATE_GET_HOUR(self),
5353 DATE_GET_MINUTE(self),
5354 DATE_GET_SECOND(self),
5355 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005356 Py_None,
5357 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005358}
5359
5360static PyObject *
5361datetime_gettimetz(PyDateTime_DateTime *self)
5362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005363 return new_time(DATE_GET_HOUR(self),
5364 DATE_GET_MINUTE(self),
5365 DATE_GET_SECOND(self),
5366 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005367 GET_DT_TZINFO(self),
5368 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005369}
5370
5371static PyObject *
5372datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005373{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005374 int y, m, d, hh, mm, ss;
5375 PyObject *tzinfo;
5376 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005377
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005378 tzinfo = GET_DT_TZINFO(self);
5379 if (tzinfo == Py_None) {
5380 utcself = self;
5381 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005382 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005383 else {
5384 PyObject *offset;
5385 offset = call_utcoffset(tzinfo, (PyObject *)self);
5386 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005387 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005388 if (offset == Py_None) {
5389 Py_DECREF(offset);
5390 utcself = self;
5391 Py_INCREF(utcself);
5392 }
5393 else {
5394 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5395 (PyDateTime_Delta *)offset, -1);
5396 Py_DECREF(offset);
5397 if (utcself == NULL)
5398 return NULL;
5399 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005400 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005401 y = GET_YEAR(utcself);
5402 m = GET_MONTH(utcself);
5403 d = GET_DAY(utcself);
5404 hh = DATE_GET_HOUR(utcself);
5405 mm = DATE_GET_MINUTE(utcself);
5406 ss = DATE_GET_SECOND(utcself);
5407
5408 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005409 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005410}
5411
Tim Peters371935f2003-02-01 01:52:50 +00005412/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005413
Tim Petersa9bc1682003-01-11 03:39:11 +00005414/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005415 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5416 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005417 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005418 */
5419static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005420datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005422 PyObject *basestate;
5423 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005425 basestate = PyBytes_FromStringAndSize((char *)self->data,
5426 _PyDateTime_DATETIME_DATASIZE);
5427 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005428 if (proto > 3 && DATE_GET_FOLD(self))
5429 /* Set the first bit of the third byte */
5430 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005431 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5432 result = PyTuple_Pack(1, basestate);
5433 else
5434 result = PyTuple_Pack(2, basestate, self->tzinfo);
5435 Py_DECREF(basestate);
5436 }
5437 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005438}
5439
5440static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005441datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005442{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005443 int proto;
5444 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005445 return NULL;
5446
5447 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005448}
5449
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005450static PyObject *
5451datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5452{
5453 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5454}
5455
Tim Petersa9bc1682003-01-11 03:39:11 +00005456static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005458 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005459
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005460 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005462 {"utcnow", (PyCFunction)datetime_utcnow,
5463 METH_NOARGS | METH_CLASS,
5464 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005466 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5467 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5468 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005470 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5471 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005472 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005474 {"strptime", (PyCFunction)datetime_strptime,
5475 METH_VARARGS | METH_CLASS,
5476 PyDoc_STR("string, format -> new datetime parsed from a string "
5477 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005479 {"combine", (PyCFunction)datetime_combine,
5480 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5481 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005483 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005485 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5486 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005488 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5489 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005491 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5492 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005494 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5495 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005497 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5498 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005499
Alexander Belopolskya4415142012-06-08 12:33:09 -04005500 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5501 PyDoc_STR("Return POSIX timestamp as float.")},
5502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005503 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5504 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005506 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5507 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005508 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005509 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005510 "defaults to 'T'.\n"
5511 "timespec specifies what components of the time to include"
5512 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5513 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005515 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5516 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005518 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5519 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005521 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5522 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005524 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5525 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005527 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5528 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005529
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005530 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005531 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005532
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005533 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5534 PyDoc_STR("__reduce__() -> (cls, state)")},
5535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005536 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005537};
5538
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005539static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005540PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5541\n\
5542The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005543instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005544
Tim Petersa9bc1682003-01-11 03:39:11 +00005545static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005546 datetime_add, /* nb_add */
5547 datetime_subtract, /* nb_subtract */
5548 0, /* nb_multiply */
5549 0, /* nb_remainder */
5550 0, /* nb_divmod */
5551 0, /* nb_power */
5552 0, /* nb_negative */
5553 0, /* nb_positive */
5554 0, /* nb_absolute */
5555 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005556};
5557
Neal Norwitz227b5332006-03-22 09:28:35 +00005558static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005559 PyVarObject_HEAD_INIT(NULL, 0)
5560 "datetime.datetime", /* tp_name */
5561 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5562 0, /* tp_itemsize */
5563 (destructor)datetime_dealloc, /* tp_dealloc */
5564 0, /* tp_print */
5565 0, /* tp_getattr */
5566 0, /* tp_setattr */
5567 0, /* tp_reserved */
5568 (reprfunc)datetime_repr, /* tp_repr */
5569 &datetime_as_number, /* tp_as_number */
5570 0, /* tp_as_sequence */
5571 0, /* tp_as_mapping */
5572 (hashfunc)datetime_hash, /* tp_hash */
5573 0, /* tp_call */
5574 (reprfunc)datetime_str, /* tp_str */
5575 PyObject_GenericGetAttr, /* tp_getattro */
5576 0, /* tp_setattro */
5577 0, /* tp_as_buffer */
5578 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5579 datetime_doc, /* tp_doc */
5580 0, /* tp_traverse */
5581 0, /* tp_clear */
5582 datetime_richcompare, /* tp_richcompare */
5583 0, /* tp_weaklistoffset */
5584 0, /* tp_iter */
5585 0, /* tp_iternext */
5586 datetime_methods, /* tp_methods */
5587 0, /* tp_members */
5588 datetime_getset, /* tp_getset */
5589 &PyDateTime_DateType, /* tp_base */
5590 0, /* tp_dict */
5591 0, /* tp_descr_get */
5592 0, /* tp_descr_set */
5593 0, /* tp_dictoffset */
5594 0, /* tp_init */
5595 datetime_alloc, /* tp_alloc */
5596 datetime_new, /* tp_new */
5597 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005598};
5599
5600/* ---------------------------------------------------------------------------
5601 * Module methods and initialization.
5602 */
5603
5604static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005605 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005606};
5607
Tim Peters9ddf40b2004-06-20 22:41:32 +00005608/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5609 * datetime.h.
5610 */
5611static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005612 &PyDateTime_DateType,
5613 &PyDateTime_DateTimeType,
5614 &PyDateTime_TimeType,
5615 &PyDateTime_DeltaType,
5616 &PyDateTime_TZInfoType,
5617 new_date_ex,
5618 new_datetime_ex,
5619 new_time_ex,
5620 new_delta_ex,
5621 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005622 date_fromtimestamp,
5623 new_datetime_ex2,
5624 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00005625};
5626
5627
Martin v. Löwis1a214512008-06-11 05:26:20 +00005628
5629static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005630 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005631 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005632 "Fast implementation of the datetime type.",
5633 -1,
5634 module_methods,
5635 NULL,
5636 NULL,
5637 NULL,
5638 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005639};
5640
Tim Peters2a799bf2002-12-16 20:18:38 +00005641PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005642PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005644 PyObject *m; /* a module object */
5645 PyObject *d; /* its dict */
5646 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005647 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005649 m = PyModule_Create(&datetimemodule);
5650 if (m == NULL)
5651 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005653 if (PyType_Ready(&PyDateTime_DateType) < 0)
5654 return NULL;
5655 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5656 return NULL;
5657 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5658 return NULL;
5659 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5660 return NULL;
5661 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5662 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005663 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5664 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005666 /* timedelta values */
5667 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005669 x = new_delta(0, 0, 1, 0);
5670 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5671 return NULL;
5672 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005674 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5675 if (x == NULL || PyDict_SetItemString(d, "min", 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(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5680 if (x == NULL || PyDict_SetItemString(d, "max", 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 /* date values */
5685 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005687 x = new_date(1, 1, 1);
5688 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5689 return NULL;
5690 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005692 x = new_date(MAXYEAR, 12, 31);
5693 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(1, 0, 0, 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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005702 /* time values */
5703 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005704
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005705 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005706 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5707 return NULL;
5708 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005709
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005710 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005711 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5712 return NULL;
5713 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005714
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005715 x = new_delta(0, 0, 1, 0);
5716 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5717 return NULL;
5718 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005720 /* datetime values */
5721 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005722
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005723 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005724 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5725 return NULL;
5726 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005727
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005728 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005729 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5730 return NULL;
5731 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005733 x = new_delta(0, 0, 1, 0);
5734 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5735 return NULL;
5736 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005737
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005738 /* timezone values */
5739 d = PyDateTime_TimeZoneType.tp_dict;
5740
5741 delta = new_delta(0, 0, 0, 0);
5742 if (delta == NULL)
5743 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005744 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005745 Py_DECREF(delta);
5746 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5747 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005748 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005749
5750 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5751 if (delta == NULL)
5752 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005753 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005754 Py_DECREF(delta);
5755 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5756 return NULL;
5757 Py_DECREF(x);
5758
5759 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5760 if (delta == NULL)
5761 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005762 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005763 Py_DECREF(delta);
5764 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5765 return NULL;
5766 Py_DECREF(x);
5767
Alexander Belopolskya4415142012-06-08 12:33:09 -04005768 /* Epoch */
5769 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005770 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005771 if (PyDateTime_Epoch == NULL)
5772 return NULL;
5773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005774 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005775 PyModule_AddIntMacro(m, MINYEAR);
5776 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005778 Py_INCREF(&PyDateTime_DateType);
5779 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005781 Py_INCREF(&PyDateTime_DateTimeType);
5782 PyModule_AddObject(m, "datetime",
5783 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005784
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005785 Py_INCREF(&PyDateTime_TimeType);
5786 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005788 Py_INCREF(&PyDateTime_DeltaType);
5789 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005791 Py_INCREF(&PyDateTime_TZInfoType);
5792 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005793
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005794 Py_INCREF(&PyDateTime_TimeZoneType);
5795 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5796
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005797 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5798 if (x == NULL)
5799 return NULL;
5800 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005802 /* A 4-year cycle has an extra leap day over what we'd get from
5803 * pasting together 4 single years.
5804 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005805 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005806 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005808 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5809 * get from pasting together 4 100-year cycles.
5810 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005811 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005812 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005814 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5815 * pasting together 25 4-year cycles.
5816 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005817 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005818 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005819
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005820 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005821 us_per_ms = PyLong_FromLong(1000);
5822 us_per_second = PyLong_FromLong(1000000);
5823 us_per_minute = PyLong_FromLong(60000000);
5824 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005825 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005826 us_per_minute == NULL || seconds_per_day == NULL)
5827 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005829 /* The rest are too big for 32-bit ints, but even
5830 * us_per_week fits in 40 bits, so doubles should be exact.
5831 */
5832 us_per_hour = PyLong_FromDouble(3600000000.0);
5833 us_per_day = PyLong_FromDouble(86400000000.0);
5834 us_per_week = PyLong_FromDouble(604800000000.0);
5835 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5836 return NULL;
5837 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005838}
Tim Petersf3615152003-01-01 21:51:37 +00005839
5840/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005841Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005842 x.n = x stripped of its timezone -- its naive time.
5843 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005844 return None
Tim Petersf3615152003-01-01 21:51:37 +00005845 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005846 return None
Tim Petersf3615152003-01-01 21:51:37 +00005847 x.s = x's standard offset, x.o - x.d
5848
5849Now some derived rules, where k is a duration (timedelta).
5850
58511. x.o = x.s + x.d
5852 This follows from the definition of x.s.
5853
Tim Petersc5dc4da2003-01-02 17:55:03 +000058542. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005855 This is actually a requirement, an assumption we need to make about
5856 sane tzinfo classes.
5857
58583. The naive UTC time corresponding to x is x.n - x.o.
5859 This is again a requirement for a sane tzinfo class.
5860
58614. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005862 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005863
Tim Petersc5dc4da2003-01-02 17:55:03 +000058645. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005865 Again follows from how arithmetic is defined.
5866
Tim Peters8bb5ad22003-01-24 02:44:45 +00005867Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005868(meaning that the various tzinfo methods exist, and don't blow up or return
5869None when called).
5870
Tim Petersa9bc1682003-01-11 03:39:11 +00005871The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005872x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005873
5874By #3, we want
5875
Tim Peters8bb5ad22003-01-24 02:44:45 +00005876 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005877
5878The algorithm starts by attaching tz to x.n, and calling that y. So
5879x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5880becomes true; in effect, we want to solve [2] for k:
5881
Tim Peters8bb5ad22003-01-24 02:44:45 +00005882 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005883
5884By #1, this is the same as
5885
Tim Peters8bb5ad22003-01-24 02:44:45 +00005886 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005887
5888By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5889Substituting that into [3],
5890
Tim Peters8bb5ad22003-01-24 02:44:45 +00005891 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5892 k - (y+k).s - (y+k).d = 0; rearranging,
5893 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5894 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005895
Tim Peters8bb5ad22003-01-24 02:44:45 +00005896On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5897approximate k by ignoring the (y+k).d term at first. Note that k can't be
5898very large, since all offset-returning methods return a duration of magnitude
5899less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5900be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005901
5902In any case, the new value is
5903
Tim Peters8bb5ad22003-01-24 02:44:45 +00005904 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005905
Tim Peters8bb5ad22003-01-24 02:44:45 +00005906It's helpful to step back at look at [4] from a higher level: it's simply
5907mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005908
5909At this point, if
5910
Tim Peters8bb5ad22003-01-24 02:44:45 +00005911 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005912
5913we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005914at the start of daylight time. Picture US Eastern for concreteness. The wall
5915time 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 +00005916sense then. The docs ask that an Eastern tzinfo class consider such a time to
5917be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5918on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005919the only spelling that makes sense on the local wall clock.
5920
Tim Petersc5dc4da2003-01-02 17:55:03 +00005921In fact, if [5] holds at this point, we do have the standard-time spelling,
5922but that takes a bit of proof. We first prove a stronger result. What's the
5923difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005924
Tim Peters8bb5ad22003-01-24 02:44:45 +00005925 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005926
Tim Petersc5dc4da2003-01-02 17:55:03 +00005927Now
5928 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005929 (y + y.s).n = by #5
5930 y.n + y.s = since y.n = x.n
5931 x.n + y.s = since z and y are have the same tzinfo member,
5932 y.s = z.s by #2
5933 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005934
Tim Petersc5dc4da2003-01-02 17:55:03 +00005935Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005936
Tim Petersc5dc4da2003-01-02 17:55:03 +00005937 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005938 x.n - ((x.n + z.s) - z.o) = expanding
5939 x.n - x.n - z.s + z.o = cancelling
5940 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005941 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005942
Tim Petersc5dc4da2003-01-02 17:55:03 +00005943So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005944
Tim Petersc5dc4da2003-01-02 17:55:03 +00005945If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005946spelling we wanted in the endcase described above. We're done. Contrarily,
5947if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005948
Tim Petersc5dc4da2003-01-02 17:55:03 +00005949If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5950add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005951local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005952
Tim Petersc5dc4da2003-01-02 17:55:03 +00005953Let
Tim Petersf3615152003-01-01 21:51:37 +00005954
Tim Peters4fede1a2003-01-04 00:26:59 +00005955 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005956
Tim Peters4fede1a2003-01-04 00:26:59 +00005957and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005958
Tim Peters8bb5ad22003-01-24 02:44:45 +00005959 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005960
Tim Peters8bb5ad22003-01-24 02:44:45 +00005961If so, we're done. If not, the tzinfo class is insane, according to the
5962assumptions we've made. This also requires a bit of proof. As before, let's
5963compute the difference between the LHS and RHS of [8] (and skipping some of
5964the justifications for the kinds of substitutions we've done several times
5965already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005966
Tim Peters8bb5ad22003-01-24 02:44:45 +00005967 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005968 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5969 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5970 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5971 - z.n + z.n - z.o + z'.o = cancel z.n
5972 - z.o + z'.o = #1 twice
5973 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5974 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005975
5976So 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 +00005977we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5978return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005979
Tim Peters8bb5ad22003-01-24 02:44:45 +00005980How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5981a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5982would have to change the result dst() returns: we start in DST, and moving
5983a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005984
Tim Peters8bb5ad22003-01-24 02:44:45 +00005985There isn't a sane case where this can happen. The closest it gets is at
5986the end of DST, where there's an hour in UTC with no spelling in a hybrid
5987tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5988that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5989UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5990time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5991clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5992standard time. Since that's what the local clock *does*, we want to map both
5993UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005994in local time, but so it goes -- it's the way the local clock works.
5995
Tim Peters8bb5ad22003-01-24 02:44:45 +00005996When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5997so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5998z' = 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 +00005999(correctly) concludes that z' is not UTC-equivalent to x.
6000
6001Because we know z.d said z was in daylight time (else [5] would have held and
6002we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006003and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006004return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6005but the reasoning doesn't depend on the example -- it depends on there being
6006two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006007z' must be in standard time, and is the spelling we want in this case.
6008
6009Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6010concerned (because it takes z' as being in standard time rather than the
6011daylight time we intend here), but returning it gives the real-life "local
6012clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6013tz.
6014
6015When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6016the 1:MM standard time spelling we want.
6017
6018So how can this break? One of the assumptions must be violated. Two
6019possibilities:
6020
60211) [2] effectively says that y.s is invariant across all y belong to a given
6022 time zone. This isn't true if, for political reasons or continental drift,
6023 a region decides to change its base offset from UTC.
6024
60252) There may be versions of "double daylight" time where the tail end of
6026 the analysis gives up a step too early. I haven't thought about that
6027 enough to say.
6028
6029In any case, it's clear that the default fromutc() is strong enough to handle
6030"almost all" time zones: so long as the standard offset is invariant, it
6031doesn't matter if daylight time transition points change from year to year, or
6032if daylight time is skipped in some years; it doesn't matter how large or
6033small dst() may get within its bounds; and it doesn't even matter if some
6034perverse time zone returns a negative dst()). So a breaking case must be
6035pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006036--------------------------------------------------------------------------- */