blob: c09cce9da725aaa80731085e9e372359a0640e71 [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;
1388 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 time = PyImport_ImportModuleNoBlock("time");
1391 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001392 _Py_IDENTIFIER(struct_time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001393
1394 result = _PyObject_CallMethodId(time, &PyId_struct_time,
1395 "((iiiiiiiii))",
1396 y, m, d,
1397 hh, mm, ss,
1398 weekday(y, m, d),
1399 days_before_month(y, m) + d,
1400 dstflag);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 Py_DECREF(time);
1402 }
1403 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001404}
1405
1406/* ---------------------------------------------------------------------------
1407 * Miscellaneous helpers.
1408 */
1409
Mark Dickinsone94c6792009-02-02 20:36:42 +00001410/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001411 * The comparisons here all most naturally compute a cmp()-like result.
1412 * This little helper turns that into a bool result for rich comparisons.
1413 */
1414static PyObject *
1415diff_to_bool(int diff, int op)
1416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 PyObject *result;
1418 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 switch (op) {
1421 case Py_EQ: istrue = diff == 0; break;
1422 case Py_NE: istrue = diff != 0; break;
1423 case Py_LE: istrue = diff <= 0; break;
1424 case Py_GE: istrue = diff >= 0; break;
1425 case Py_LT: istrue = diff < 0; break;
1426 case Py_GT: istrue = diff > 0; break;
1427 default:
1428 assert(! "op unknown");
1429 istrue = 0; /* To shut up compiler */
1430 }
1431 result = istrue ? Py_True : Py_False;
1432 Py_INCREF(result);
1433 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001434}
1435
Tim Peters07534a62003-02-07 22:50:28 +00001436/* Raises a "can't compare" TypeError and returns NULL. */
1437static PyObject *
1438cmperror(PyObject *a, PyObject *b)
1439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 PyErr_Format(PyExc_TypeError,
1441 "can't compare %s to %s",
1442 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1443 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001444}
1445
Tim Peters2a799bf2002-12-16 20:18:38 +00001446/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001447 * Cached Python objects; these are set by the module init function.
1448 */
1449
1450/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001451static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452static PyObject *us_per_ms = NULL; /* 1000 */
1453static PyObject *us_per_second = NULL; /* 1000000 */
1454static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001455static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1456static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1457static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001458static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1459
Tim Peters2a799bf2002-12-16 20:18:38 +00001460/* ---------------------------------------------------------------------------
1461 * Class implementations.
1462 */
1463
1464/*
1465 * PyDateTime_Delta implementation.
1466 */
1467
1468/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001470 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001471 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1472 * due to ubiquitous overflow possibilities.
1473 */
1474static PyObject *
1475delta_to_microseconds(PyDateTime_Delta *self)
1476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 PyObject *x1 = NULL;
1478 PyObject *x2 = NULL;
1479 PyObject *x3 = NULL;
1480 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1483 if (x1 == NULL)
1484 goto Done;
1485 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1486 if (x2 == NULL)
1487 goto Done;
1488 Py_DECREF(x1);
1489 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001491 /* x2 has days in seconds */
1492 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1493 if (x1 == NULL)
1494 goto Done;
1495 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1496 if (x3 == NULL)
1497 goto Done;
1498 Py_DECREF(x1);
1499 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001500 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 /* x3 has days+seconds in seconds */
1503 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1504 if (x1 == NULL)
1505 goto Done;
1506 Py_DECREF(x3);
1507 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 /* x1 has days+seconds in us */
1510 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1511 if (x2 == NULL)
1512 goto Done;
1513 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001514
1515Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 Py_XDECREF(x1);
1517 Py_XDECREF(x2);
1518 Py_XDECREF(x3);
1519 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001520}
1521
Serhiy Storchaka95949422013-08-27 19:40:23 +03001522/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001523 */
1524static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001525microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001526{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 int us;
1528 int s;
1529 int d;
1530 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 PyObject *tuple = NULL;
1533 PyObject *num = NULL;
1534 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 tuple = PyNumber_Divmod(pyus, us_per_second);
1537 if (tuple == NULL)
1538 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 num = PyTuple_GetItem(tuple, 1); /* us */
1541 if (num == NULL)
1542 goto Done;
1543 temp = PyLong_AsLong(num);
1544 num = NULL;
1545 if (temp == -1 && PyErr_Occurred())
1546 goto Done;
1547 assert(0 <= temp && temp < 1000000);
1548 us = (int)temp;
1549 if (us < 0) {
1550 /* The divisor was positive, so this must be an error. */
1551 assert(PyErr_Occurred());
1552 goto Done;
1553 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1556 if (num == NULL)
1557 goto Done;
1558 Py_INCREF(num);
1559 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 tuple = PyNumber_Divmod(num, seconds_per_day);
1562 if (tuple == NULL)
1563 goto Done;
1564 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 num = PyTuple_GetItem(tuple, 1); /* seconds */
1567 if (num == NULL)
1568 goto Done;
1569 temp = PyLong_AsLong(num);
1570 num = NULL;
1571 if (temp == -1 && PyErr_Occurred())
1572 goto Done;
1573 assert(0 <= temp && temp < 24*3600);
1574 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 if (s < 0) {
1577 /* The divisor was positive, so this must be an error. */
1578 assert(PyErr_Occurred());
1579 goto Done;
1580 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1583 if (num == NULL)
1584 goto Done;
1585 Py_INCREF(num);
1586 temp = PyLong_AsLong(num);
1587 if (temp == -1 && PyErr_Occurred())
1588 goto Done;
1589 d = (int)temp;
1590 if ((long)d != temp) {
1591 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1592 "large to fit in a C int");
1593 goto Done;
1594 }
1595 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001596
1597Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 Py_XDECREF(tuple);
1599 Py_XDECREF(num);
1600 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001601}
1602
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603#define microseconds_to_delta(pymicros) \
1604 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001605
Tim Peters2a799bf2002-12-16 20:18:38 +00001606static PyObject *
1607multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1608{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 PyObject *pyus_in;
1610 PyObject *pyus_out;
1611 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 pyus_in = delta_to_microseconds(delta);
1614 if (pyus_in == NULL)
1615 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001617 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1618 Py_DECREF(pyus_in);
1619 if (pyus_out == NULL)
1620 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 result = microseconds_to_delta(pyus_out);
1623 Py_DECREF(pyus_out);
1624 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001625}
1626
1627static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001628multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1629{
1630 PyObject *result = NULL;
1631 PyObject *pyus_in = NULL, *temp, *pyus_out;
1632 PyObject *ratio = NULL;
1633
1634 pyus_in = delta_to_microseconds(delta);
1635 if (pyus_in == NULL)
1636 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001637 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001638 if (ratio == NULL)
1639 goto error;
1640 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1641 Py_DECREF(pyus_in);
1642 pyus_in = NULL;
1643 if (temp == NULL)
1644 goto error;
1645 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1646 Py_DECREF(temp);
1647 if (pyus_out == NULL)
1648 goto error;
1649 result = microseconds_to_delta(pyus_out);
1650 Py_DECREF(pyus_out);
1651 error:
1652 Py_XDECREF(pyus_in);
1653 Py_XDECREF(ratio);
1654
1655 return result;
1656}
1657
1658static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001659divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1660{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 PyObject *pyus_in;
1662 PyObject *pyus_out;
1663 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 pyus_in = delta_to_microseconds(delta);
1666 if (pyus_in == NULL)
1667 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1670 Py_DECREF(pyus_in);
1671 if (pyus_out == NULL)
1672 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001673
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 result = microseconds_to_delta(pyus_out);
1675 Py_DECREF(pyus_out);
1676 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001677}
1678
1679static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001680divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1681{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001682 PyObject *pyus_left;
1683 PyObject *pyus_right;
1684 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 pyus_left = delta_to_microseconds(left);
1687 if (pyus_left == NULL)
1688 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 pyus_right = delta_to_microseconds(right);
1691 if (pyus_right == NULL) {
1692 Py_DECREF(pyus_left);
1693 return NULL;
1694 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001695
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001696 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1697 Py_DECREF(pyus_left);
1698 Py_DECREF(pyus_right);
1699 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001700}
1701
1702static PyObject *
1703truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1704{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001705 PyObject *pyus_left;
1706 PyObject *pyus_right;
1707 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001709 pyus_left = delta_to_microseconds(left);
1710 if (pyus_left == NULL)
1711 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001713 pyus_right = delta_to_microseconds(right);
1714 if (pyus_right == NULL) {
1715 Py_DECREF(pyus_left);
1716 return NULL;
1717 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001718
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001719 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1720 Py_DECREF(pyus_left);
1721 Py_DECREF(pyus_right);
1722 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001723}
1724
1725static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001726truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1727{
1728 PyObject *result = NULL;
1729 PyObject *pyus_in = NULL, *temp, *pyus_out;
1730 PyObject *ratio = NULL;
1731
1732 pyus_in = delta_to_microseconds(delta);
1733 if (pyus_in == NULL)
1734 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001735 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001736 if (ratio == NULL)
1737 goto error;
1738 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1739 Py_DECREF(pyus_in);
1740 pyus_in = NULL;
1741 if (temp == NULL)
1742 goto error;
1743 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1744 Py_DECREF(temp);
1745 if (pyus_out == NULL)
1746 goto error;
1747 result = microseconds_to_delta(pyus_out);
1748 Py_DECREF(pyus_out);
1749 error:
1750 Py_XDECREF(pyus_in);
1751 Py_XDECREF(ratio);
1752
1753 return result;
1754}
1755
1756static PyObject *
1757truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1758{
1759 PyObject *result;
1760 PyObject *pyus_in, *pyus_out;
1761 pyus_in = delta_to_microseconds(delta);
1762 if (pyus_in == NULL)
1763 return NULL;
1764 pyus_out = divide_nearest(pyus_in, i);
1765 Py_DECREF(pyus_in);
1766 if (pyus_out == NULL)
1767 return NULL;
1768 result = microseconds_to_delta(pyus_out);
1769 Py_DECREF(pyus_out);
1770
1771 return result;
1772}
1773
1774static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001775delta_add(PyObject *left, PyObject *right)
1776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1780 /* delta + delta */
1781 /* The C-level additions can't overflow because of the
1782 * invariant bounds.
1783 */
1784 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1785 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1786 int microseconds = GET_TD_MICROSECONDS(left) +
1787 GET_TD_MICROSECONDS(right);
1788 result = new_delta(days, seconds, microseconds, 1);
1789 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 if (result == Py_NotImplemented)
1792 Py_INCREF(result);
1793 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001794}
1795
1796static PyObject *
1797delta_negative(PyDateTime_Delta *self)
1798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 return new_delta(-GET_TD_DAYS(self),
1800 -GET_TD_SECONDS(self),
1801 -GET_TD_MICROSECONDS(self),
1802 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001803}
1804
1805static PyObject *
1806delta_positive(PyDateTime_Delta *self)
1807{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 /* Could optimize this (by returning self) if this isn't a
1809 * subclass -- but who uses unary + ? Approximately nobody.
1810 */
1811 return new_delta(GET_TD_DAYS(self),
1812 GET_TD_SECONDS(self),
1813 GET_TD_MICROSECONDS(self),
1814 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001815}
1816
1817static PyObject *
1818delta_abs(PyDateTime_Delta *self)
1819{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001820 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 assert(GET_TD_MICROSECONDS(self) >= 0);
1823 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001824
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 if (GET_TD_DAYS(self) < 0)
1826 result = delta_negative(self);
1827 else
1828 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001831}
1832
1833static PyObject *
1834delta_subtract(PyObject *left, PyObject *right)
1835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1839 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001840 /* The C-level additions can't overflow because of the
1841 * invariant bounds.
1842 */
1843 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1844 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1845 int microseconds = GET_TD_MICROSECONDS(left) -
1846 GET_TD_MICROSECONDS(right);
1847 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 if (result == Py_NotImplemented)
1851 Py_INCREF(result);
1852 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001853}
1854
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001855static int
1856delta_cmp(PyObject *self, PyObject *other)
1857{
1858 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1859 if (diff == 0) {
1860 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1861 if (diff == 0)
1862 diff = GET_TD_MICROSECONDS(self) -
1863 GET_TD_MICROSECONDS(other);
1864 }
1865 return diff;
1866}
1867
Tim Peters2a799bf2002-12-16 20:18:38 +00001868static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001869delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001870{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001872 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 return diff_to_bool(diff, op);
1874 }
1875 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001876 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001878}
1879
1880static PyObject *delta_getstate(PyDateTime_Delta *self);
1881
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001882static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001883delta_hash(PyDateTime_Delta *self)
1884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 if (self->hashcode == -1) {
1886 PyObject *temp = delta_getstate(self);
1887 if (temp != NULL) {
1888 self->hashcode = PyObject_Hash(temp);
1889 Py_DECREF(temp);
1890 }
1891 }
1892 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001893}
1894
1895static PyObject *
1896delta_multiply(PyObject *left, PyObject *right)
1897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 if (PyDelta_Check(left)) {
1901 /* delta * ??? */
1902 if (PyLong_Check(right))
1903 result = multiply_int_timedelta(right,
1904 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001905 else if (PyFloat_Check(right))
1906 result = multiply_float_timedelta(right,
1907 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 }
1909 else if (PyLong_Check(left))
1910 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001911 (PyDateTime_Delta *) right);
1912 else if (PyFloat_Check(left))
1913 result = multiply_float_timedelta(left,
1914 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 if (result == Py_NotImplemented)
1917 Py_INCREF(result);
1918 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001919}
1920
1921static PyObject *
1922delta_divide(PyObject *left, PyObject *right)
1923{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 if (PyDelta_Check(left)) {
1927 /* delta * ??? */
1928 if (PyLong_Check(right))
1929 result = divide_timedelta_int(
1930 (PyDateTime_Delta *)left,
1931 right);
1932 else if (PyDelta_Check(right))
1933 result = divide_timedelta_timedelta(
1934 (PyDateTime_Delta *)left,
1935 (PyDateTime_Delta *)right);
1936 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 if (result == Py_NotImplemented)
1939 Py_INCREF(result);
1940 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001941}
1942
Mark Dickinson7c186e22010-04-20 22:32:49 +00001943static PyObject *
1944delta_truedivide(PyObject *left, PyObject *right)
1945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 if (PyDelta_Check(left)) {
1949 if (PyDelta_Check(right))
1950 result = truedivide_timedelta_timedelta(
1951 (PyDateTime_Delta *)left,
1952 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001953 else if (PyFloat_Check(right))
1954 result = truedivide_timedelta_float(
1955 (PyDateTime_Delta *)left, right);
1956 else if (PyLong_Check(right))
1957 result = truedivide_timedelta_int(
1958 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001961 if (result == Py_NotImplemented)
1962 Py_INCREF(result);
1963 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001964}
1965
1966static PyObject *
1967delta_remainder(PyObject *left, PyObject *right)
1968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 PyObject *pyus_left;
1970 PyObject *pyus_right;
1971 PyObject *pyus_remainder;
1972 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001973
Brian Curtindfc80e32011-08-10 20:28:54 -05001974 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1975 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1978 if (pyus_left == NULL)
1979 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1982 if (pyus_right == NULL) {
1983 Py_DECREF(pyus_left);
1984 return NULL;
1985 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1988 Py_DECREF(pyus_left);
1989 Py_DECREF(pyus_right);
1990 if (pyus_remainder == NULL)
1991 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 remainder = microseconds_to_delta(pyus_remainder);
1994 Py_DECREF(pyus_remainder);
1995 if (remainder == NULL)
1996 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001999}
2000
2001static PyObject *
2002delta_divmod(PyObject *left, PyObject *right)
2003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 PyObject *pyus_left;
2005 PyObject *pyus_right;
2006 PyObject *divmod;
2007 PyObject *delta;
2008 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002009
Brian Curtindfc80e32011-08-10 20:28:54 -05002010 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2011 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002013 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2014 if (pyus_left == NULL)
2015 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2018 if (pyus_right == NULL) {
2019 Py_DECREF(pyus_left);
2020 return NULL;
2021 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2024 Py_DECREF(pyus_left);
2025 Py_DECREF(pyus_right);
2026 if (divmod == NULL)
2027 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 assert(PyTuple_Size(divmod) == 2);
2030 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2031 if (delta == NULL) {
2032 Py_DECREF(divmod);
2033 return NULL;
2034 }
2035 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2036 Py_DECREF(delta);
2037 Py_DECREF(divmod);
2038 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002039}
2040
Tim Peters2a799bf2002-12-16 20:18:38 +00002041/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2042 * timedelta constructor. sofar is the # of microseconds accounted for
2043 * so far, and there are factor microseconds per current unit, the number
2044 * of which is given by num. num * factor is added to sofar in a
2045 * numerically careful way, and that's the result. Any fractional
2046 * microseconds left over (this can happen if num is a float type) are
2047 * added into *leftover.
2048 * Note that there are many ways this can give an error (NULL) return.
2049 */
2050static PyObject *
2051accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2052 double *leftover)
2053{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002054 PyObject *prod;
2055 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002057 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002059 if (PyLong_Check(num)) {
2060 prod = PyNumber_Multiply(num, factor);
2061 if (prod == NULL)
2062 return NULL;
2063 sum = PyNumber_Add(sofar, prod);
2064 Py_DECREF(prod);
2065 return sum;
2066 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 if (PyFloat_Check(num)) {
2069 double dnum;
2070 double fracpart;
2071 double intpart;
2072 PyObject *x;
2073 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 /* The Plan: decompose num into an integer part and a
2076 * fractional part, num = intpart + fracpart.
2077 * Then num * factor ==
2078 * intpart * factor + fracpart * factor
2079 * and the LHS can be computed exactly in long arithmetic.
2080 * The RHS is again broken into an int part and frac part.
2081 * and the frac part is added into *leftover.
2082 */
2083 dnum = PyFloat_AsDouble(num);
2084 if (dnum == -1.0 && PyErr_Occurred())
2085 return NULL;
2086 fracpart = modf(dnum, &intpart);
2087 x = PyLong_FromDouble(intpart);
2088 if (x == NULL)
2089 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 prod = PyNumber_Multiply(x, factor);
2092 Py_DECREF(x);
2093 if (prod == NULL)
2094 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 sum = PyNumber_Add(sofar, prod);
2097 Py_DECREF(prod);
2098 if (sum == NULL)
2099 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 if (fracpart == 0.0)
2102 return sum;
2103 /* So far we've lost no information. Dealing with the
2104 * fractional part requires float arithmetic, and may
2105 * lose a little info.
2106 */
2107 assert(PyLong_Check(factor));
2108 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002110 dnum *= fracpart;
2111 fracpart = modf(dnum, &intpart);
2112 x = PyLong_FromDouble(intpart);
2113 if (x == NULL) {
2114 Py_DECREF(sum);
2115 return NULL;
2116 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 y = PyNumber_Add(sum, x);
2119 Py_DECREF(sum);
2120 Py_DECREF(x);
2121 *leftover += fracpart;
2122 return y;
2123 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002125 PyErr_Format(PyExc_TypeError,
2126 "unsupported type for timedelta %s component: %s",
2127 tag, Py_TYPE(num)->tp_name);
2128 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002129}
2130
2131static PyObject *
2132delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2133{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002134 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 /* Argument objects. */
2137 PyObject *day = NULL;
2138 PyObject *second = NULL;
2139 PyObject *us = NULL;
2140 PyObject *ms = NULL;
2141 PyObject *minute = NULL;
2142 PyObject *hour = NULL;
2143 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002145 PyObject *x = NULL; /* running sum of microseconds */
2146 PyObject *y = NULL; /* temp sum of microseconds */
2147 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002149 static char *keywords[] = {
2150 "days", "seconds", "microseconds", "milliseconds",
2151 "minutes", "hours", "weeks", NULL
2152 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002154 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2155 keywords,
2156 &day, &second, &us,
2157 &ms, &minute, &hour, &week) == 0)
2158 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 x = PyLong_FromLong(0);
2161 if (x == NULL)
2162 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164#define CLEANUP \
2165 Py_DECREF(x); \
2166 x = y; \
2167 if (x == NULL) \
2168 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002171 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 CLEANUP;
2173 }
2174 if (ms) {
2175 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2176 CLEANUP;
2177 }
2178 if (second) {
2179 y = accum("seconds", x, second, us_per_second, &leftover_us);
2180 CLEANUP;
2181 }
2182 if (minute) {
2183 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2184 CLEANUP;
2185 }
2186 if (hour) {
2187 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2188 CLEANUP;
2189 }
2190 if (day) {
2191 y = accum("days", x, day, us_per_day, &leftover_us);
2192 CLEANUP;
2193 }
2194 if (week) {
2195 y = accum("weeks", x, week, us_per_week, &leftover_us);
2196 CLEANUP;
2197 }
2198 if (leftover_us) {
2199 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002200 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002201 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002202 PyObject *temp;
2203
Victor Stinner69cc4872015-09-08 23:58:54 +02002204 whole_us = round(leftover_us);
2205 if (fabs(whole_us - leftover_us) == 0.5) {
2206 /* We're exactly halfway between two integers. In order
2207 * to do round-half-to-even, we must determine whether x
2208 * is odd. Note that x is odd when it's last bit is 1. The
2209 * code below uses bitwise and operation to check the last
2210 * bit. */
2211 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2212 if (temp == NULL) {
2213 Py_DECREF(x);
2214 goto Done;
2215 }
2216 x_is_odd = PyObject_IsTrue(temp);
2217 Py_DECREF(temp);
2218 if (x_is_odd == -1) {
2219 Py_DECREF(x);
2220 goto Done;
2221 }
2222 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2223 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002224
Victor Stinner36a5a062013-08-28 01:53:39 +02002225 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 if (temp == NULL) {
2228 Py_DECREF(x);
2229 goto Done;
2230 }
2231 y = PyNumber_Add(x, temp);
2232 Py_DECREF(temp);
2233 CLEANUP;
2234 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002236 self = microseconds_to_delta_ex(x, type);
2237 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002238Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002240
2241#undef CLEANUP
2242}
2243
2244static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002245delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 return (GET_TD_DAYS(self) != 0
2248 || GET_TD_SECONDS(self) != 0
2249 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002250}
2251
2252static PyObject *
2253delta_repr(PyDateTime_Delta *self)
2254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002255 if (GET_TD_MICROSECONDS(self) != 0)
2256 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2257 Py_TYPE(self)->tp_name,
2258 GET_TD_DAYS(self),
2259 GET_TD_SECONDS(self),
2260 GET_TD_MICROSECONDS(self));
2261 if (GET_TD_SECONDS(self) != 0)
2262 return PyUnicode_FromFormat("%s(%d, %d)",
2263 Py_TYPE(self)->tp_name,
2264 GET_TD_DAYS(self),
2265 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 return PyUnicode_FromFormat("%s(%d)",
2268 Py_TYPE(self)->tp_name,
2269 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002270}
2271
2272static PyObject *
2273delta_str(PyDateTime_Delta *self)
2274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002275 int us = GET_TD_MICROSECONDS(self);
2276 int seconds = GET_TD_SECONDS(self);
2277 int minutes = divmod(seconds, 60, &seconds);
2278 int hours = divmod(minutes, 60, &minutes);
2279 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002281 if (days) {
2282 if (us)
2283 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2284 days, (days == 1 || days == -1) ? "" : "s",
2285 hours, minutes, seconds, us);
2286 else
2287 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2288 days, (days == 1 || days == -1) ? "" : "s",
2289 hours, minutes, seconds);
2290 } else {
2291 if (us)
2292 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2293 hours, minutes, seconds, us);
2294 else
2295 return PyUnicode_FromFormat("%d:%02d:%02d",
2296 hours, minutes, seconds);
2297 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002298
Tim Peters2a799bf2002-12-16 20:18:38 +00002299}
2300
Tim Peters371935f2003-02-01 01:52:50 +00002301/* Pickle support, a simple use of __reduce__. */
2302
Tim Petersb57f8f02003-02-01 02:54:15 +00002303/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002304static PyObject *
2305delta_getstate(PyDateTime_Delta *self)
2306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 return Py_BuildValue("iii", GET_TD_DAYS(self),
2308 GET_TD_SECONDS(self),
2309 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002310}
2311
Tim Peters2a799bf2002-12-16 20:18:38 +00002312static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002313delta_total_seconds(PyObject *self)
2314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 PyObject *total_seconds;
2316 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2319 if (total_microseconds == NULL)
2320 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002321
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002322 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002324 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002326}
2327
2328static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002329delta_reduce(PyDateTime_Delta* self)
2330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002331 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002332}
2333
2334#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2335
2336static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002338 {"days", T_INT, OFFSET(days), READONLY,
2339 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 {"seconds", T_INT, OFFSET(seconds), READONLY,
2342 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2345 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2346 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002347};
2348
2349static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2351 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2354 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002356 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002357};
2358
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002359static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002360PyDoc_STR("Difference between two datetime values.");
2361
2362static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 delta_add, /* nb_add */
2364 delta_subtract, /* nb_subtract */
2365 delta_multiply, /* nb_multiply */
2366 delta_remainder, /* nb_remainder */
2367 delta_divmod, /* nb_divmod */
2368 0, /* nb_power */
2369 (unaryfunc)delta_negative, /* nb_negative */
2370 (unaryfunc)delta_positive, /* nb_positive */
2371 (unaryfunc)delta_abs, /* nb_absolute */
2372 (inquiry)delta_bool, /* nb_bool */
2373 0, /*nb_invert*/
2374 0, /*nb_lshift*/
2375 0, /*nb_rshift*/
2376 0, /*nb_and*/
2377 0, /*nb_xor*/
2378 0, /*nb_or*/
2379 0, /*nb_int*/
2380 0, /*nb_reserved*/
2381 0, /*nb_float*/
2382 0, /*nb_inplace_add*/
2383 0, /*nb_inplace_subtract*/
2384 0, /*nb_inplace_multiply*/
2385 0, /*nb_inplace_remainder*/
2386 0, /*nb_inplace_power*/
2387 0, /*nb_inplace_lshift*/
2388 0, /*nb_inplace_rshift*/
2389 0, /*nb_inplace_and*/
2390 0, /*nb_inplace_xor*/
2391 0, /*nb_inplace_or*/
2392 delta_divide, /* nb_floor_divide */
2393 delta_truedivide, /* nb_true_divide */
2394 0, /* nb_inplace_floor_divide */
2395 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002396};
2397
2398static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 PyVarObject_HEAD_INIT(NULL, 0)
2400 "datetime.timedelta", /* tp_name */
2401 sizeof(PyDateTime_Delta), /* tp_basicsize */
2402 0, /* tp_itemsize */
2403 0, /* tp_dealloc */
2404 0, /* tp_print */
2405 0, /* tp_getattr */
2406 0, /* tp_setattr */
2407 0, /* tp_reserved */
2408 (reprfunc)delta_repr, /* tp_repr */
2409 &delta_as_number, /* tp_as_number */
2410 0, /* tp_as_sequence */
2411 0, /* tp_as_mapping */
2412 (hashfunc)delta_hash, /* tp_hash */
2413 0, /* tp_call */
2414 (reprfunc)delta_str, /* tp_str */
2415 PyObject_GenericGetAttr, /* tp_getattro */
2416 0, /* tp_setattro */
2417 0, /* tp_as_buffer */
2418 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2419 delta_doc, /* tp_doc */
2420 0, /* tp_traverse */
2421 0, /* tp_clear */
2422 delta_richcompare, /* tp_richcompare */
2423 0, /* tp_weaklistoffset */
2424 0, /* tp_iter */
2425 0, /* tp_iternext */
2426 delta_methods, /* tp_methods */
2427 delta_members, /* tp_members */
2428 0, /* tp_getset */
2429 0, /* tp_base */
2430 0, /* tp_dict */
2431 0, /* tp_descr_get */
2432 0, /* tp_descr_set */
2433 0, /* tp_dictoffset */
2434 0, /* tp_init */
2435 0, /* tp_alloc */
2436 delta_new, /* tp_new */
2437 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002438};
2439
2440/*
2441 * PyDateTime_Date implementation.
2442 */
2443
2444/* Accessor properties. */
2445
2446static PyObject *
2447date_year(PyDateTime_Date *self, void *unused)
2448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002449 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002450}
2451
2452static PyObject *
2453date_month(PyDateTime_Date *self, void *unused)
2454{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002456}
2457
2458static PyObject *
2459date_day(PyDateTime_Date *self, void *unused)
2460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002461 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002462}
2463
2464static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 {"year", (getter)date_year},
2466 {"month", (getter)date_month},
2467 {"day", (getter)date_day},
2468 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002469};
2470
2471/* Constructors. */
2472
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002473static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002474
Tim Peters2a799bf2002-12-16 20:18:38 +00002475static PyObject *
2476date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 PyObject *self = NULL;
2479 PyObject *state;
2480 int year;
2481 int month;
2482 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002484 /* Check for invocation from pickle with __getstate__ state */
2485 if (PyTuple_GET_SIZE(args) == 1 &&
2486 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2487 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2488 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2489 {
2490 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2493 if (me != NULL) {
2494 char *pdata = PyBytes_AS_STRING(state);
2495 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2496 me->hashcode = -1;
2497 }
2498 return (PyObject *)me;
2499 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002501 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2502 &year, &month, &day)) {
2503 if (check_date_args(year, month, day) < 0)
2504 return NULL;
2505 self = new_date_ex(year, month, day, type);
2506 }
2507 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002508}
2509
2510/* Return new date from localtime(t). */
2511static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002512date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002513{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002514 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002515 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002516
Victor Stinnere4a994d2015-03-30 01:10:14 +02002517 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002518 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002519
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002520 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002521 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002522
2523 return PyObject_CallFunction(cls, "iii",
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002524 tm.tm_year + 1900,
2525 tm.tm_mon + 1,
2526 tm.tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002527}
2528
2529/* Return new date from current time.
2530 * We say this is equivalent to fromtimestamp(time.time()), and the
2531 * only way to be sure of that is to *call* time.time(). That's not
2532 * generally the same as calling C's time.
2533 */
2534static PyObject *
2535date_today(PyObject *cls, PyObject *dummy)
2536{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002537 PyObject *time;
2538 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002539 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002541 time = time_time();
2542 if (time == NULL)
2543 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002545 /* Note well: today() is a class method, so this may not call
2546 * date.fromtimestamp. For example, it may call
2547 * datetime.fromtimestamp. That's why we need all the accuracy
2548 * time.time() delivers; if someone were gonzo about optimization,
2549 * date.today() could get away with plain C time().
2550 */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002551 result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002552 Py_DECREF(time);
2553 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002554}
2555
2556/* Return new date from given timestamp (Python timestamp -- a double). */
2557static PyObject *
2558date_fromtimestamp(PyObject *cls, PyObject *args)
2559{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002560 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002561 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002562
Victor Stinner5d272cc2012-03-13 13:35:55 +01002563 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2564 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002566}
2567
2568/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2569 * the ordinal is out of range.
2570 */
2571static PyObject *
2572date_fromordinal(PyObject *cls, PyObject *args)
2573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002574 PyObject *result = NULL;
2575 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002577 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2578 int year;
2579 int month;
2580 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002582 if (ordinal < 1)
2583 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2584 ">= 1");
2585 else {
2586 ord_to_ymd(ordinal, &year, &month, &day);
2587 result = PyObject_CallFunction(cls, "iii",
2588 year, month, day);
2589 }
2590 }
2591 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002592}
2593
2594/*
2595 * Date arithmetic.
2596 */
2597
2598/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2599 * instead.
2600 */
2601static PyObject *
2602add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2603{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002604 PyObject *result = NULL;
2605 int year = GET_YEAR(date);
2606 int month = GET_MONTH(date);
2607 int deltadays = GET_TD_DAYS(delta);
2608 /* C-level overflow is impossible because |deltadays| < 1e9. */
2609 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002611 if (normalize_date(&year, &month, &day) >= 0)
2612 result = new_date(year, month, day);
2613 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002614}
2615
2616static PyObject *
2617date_add(PyObject *left, PyObject *right)
2618{
Brian Curtindfc80e32011-08-10 20:28:54 -05002619 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2620 Py_RETURN_NOTIMPLEMENTED;
2621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 if (PyDate_Check(left)) {
2623 /* date + ??? */
2624 if (PyDelta_Check(right))
2625 /* date + delta */
2626 return add_date_timedelta((PyDateTime_Date *) left,
2627 (PyDateTime_Delta *) right,
2628 0);
2629 }
2630 else {
2631 /* ??? + date
2632 * 'right' must be one of us, or we wouldn't have been called
2633 */
2634 if (PyDelta_Check(left))
2635 /* delta + date */
2636 return add_date_timedelta((PyDateTime_Date *) right,
2637 (PyDateTime_Delta *) left,
2638 0);
2639 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002640 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002641}
2642
2643static PyObject *
2644date_subtract(PyObject *left, PyObject *right)
2645{
Brian Curtindfc80e32011-08-10 20:28:54 -05002646 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2647 Py_RETURN_NOTIMPLEMENTED;
2648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002649 if (PyDate_Check(left)) {
2650 if (PyDate_Check(right)) {
2651 /* date - date */
2652 int left_ord = ymd_to_ord(GET_YEAR(left),
2653 GET_MONTH(left),
2654 GET_DAY(left));
2655 int right_ord = ymd_to_ord(GET_YEAR(right),
2656 GET_MONTH(right),
2657 GET_DAY(right));
2658 return new_delta(left_ord - right_ord, 0, 0, 0);
2659 }
2660 if (PyDelta_Check(right)) {
2661 /* date - delta */
2662 return add_date_timedelta((PyDateTime_Date *) left,
2663 (PyDateTime_Delta *) right,
2664 1);
2665 }
2666 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002667 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002668}
2669
2670
2671/* Various ways to turn a date into a string. */
2672
2673static PyObject *
2674date_repr(PyDateTime_Date *self)
2675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002676 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2677 Py_TYPE(self)->tp_name,
2678 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002679}
2680
2681static PyObject *
2682date_isoformat(PyDateTime_Date *self)
2683{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002684 return PyUnicode_FromFormat("%04d-%02d-%02d",
2685 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002686}
2687
Tim Peterse2df5ff2003-05-02 18:39:55 +00002688/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002689static PyObject *
2690date_str(PyDateTime_Date *self)
2691{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002692 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002693}
2694
2695
2696static PyObject *
2697date_ctime(PyDateTime_Date *self)
2698{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002699 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002700}
2701
2702static PyObject *
2703date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2704{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002705 /* This method can be inherited, and needs to call the
2706 * timetuple() method appropriate to self's class.
2707 */
2708 PyObject *result;
2709 PyObject *tuple;
2710 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002711 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002712 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002714 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2715 &format))
2716 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002717
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002718 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002719 if (tuple == NULL)
2720 return NULL;
2721 result = wrap_strftime((PyObject *)self, format, tuple,
2722 (PyObject *)self);
2723 Py_DECREF(tuple);
2724 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002725}
2726
Eric Smith1ba31142007-09-11 18:06:02 +00002727static PyObject *
2728date_format(PyDateTime_Date *self, PyObject *args)
2729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002730 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002731
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002732 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2733 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002735 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002736 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002737 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002738
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002739 return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002740}
2741
Tim Peters2a799bf2002-12-16 20:18:38 +00002742/* ISO methods. */
2743
2744static PyObject *
2745date_isoweekday(PyDateTime_Date *self)
2746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002747 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002749 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002750}
2751
2752static PyObject *
2753date_isocalendar(PyDateTime_Date *self)
2754{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002755 int year = GET_YEAR(self);
2756 int week1_monday = iso_week1_monday(year);
2757 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2758 int week;
2759 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002761 week = divmod(today - week1_monday, 7, &day);
2762 if (week < 0) {
2763 --year;
2764 week1_monday = iso_week1_monday(year);
2765 week = divmod(today - week1_monday, 7, &day);
2766 }
2767 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2768 ++year;
2769 week = 0;
2770 }
2771 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002772}
2773
2774/* Miscellaneous methods. */
2775
Tim Peters2a799bf2002-12-16 20:18:38 +00002776static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002777date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002779 if (PyDate_Check(other)) {
2780 int diff = memcmp(((PyDateTime_Date *)self)->data,
2781 ((PyDateTime_Date *)other)->data,
2782 _PyDateTime_DATE_DATASIZE);
2783 return diff_to_bool(diff, op);
2784 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002785 else
2786 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002787}
2788
2789static PyObject *
2790date_timetuple(PyDateTime_Date *self)
2791{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002792 return build_struct_time(GET_YEAR(self),
2793 GET_MONTH(self),
2794 GET_DAY(self),
2795 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002796}
2797
Tim Peters12bf3392002-12-24 05:41:27 +00002798static PyObject *
2799date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2800{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002801 PyObject *clone;
2802 PyObject *tuple;
2803 int year = GET_YEAR(self);
2804 int month = GET_MONTH(self);
2805 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002807 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2808 &year, &month, &day))
2809 return NULL;
2810 tuple = Py_BuildValue("iii", year, month, day);
2811 if (tuple == NULL)
2812 return NULL;
2813 clone = date_new(Py_TYPE(self), tuple, NULL);
2814 Py_DECREF(tuple);
2815 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002816}
2817
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002818static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002819generic_hash(unsigned char *data, int len)
2820{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002821 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002822}
2823
2824
2825static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002826
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002827static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002828date_hash(PyDateTime_Date *self)
2829{
Benjamin Petersondec2df32016-09-09 17:46:24 -07002830 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002831 self->hashcode = generic_hash(
2832 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07002833 }
Guido van Rossum254348e2007-11-21 19:29:53 +00002834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002835 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002836}
2837
2838static PyObject *
2839date_toordinal(PyDateTime_Date *self)
2840{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002841 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2842 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002843}
2844
2845static PyObject *
2846date_weekday(PyDateTime_Date *self)
2847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002848 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002851}
2852
Tim Peters371935f2003-02-01 01:52:50 +00002853/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002854
Tim Petersb57f8f02003-02-01 02:54:15 +00002855/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002856static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002857date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002858{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002859 PyObject* field;
2860 field = PyBytes_FromStringAndSize((char*)self->data,
2861 _PyDateTime_DATE_DATASIZE);
2862 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002863}
2864
2865static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002866date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002869}
2870
2871static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002873 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2876 METH_CLASS,
2877 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2878 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002880 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2881 METH_CLASS,
2882 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2883 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002885 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2886 PyDoc_STR("Current date or datetime: same as "
2887 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002889 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002891 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2892 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002894 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2895 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002897 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2898 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002900 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2901 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002903 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2904 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2905 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002907 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2908 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002910 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2911 PyDoc_STR("Return the day of the week represented by the date.\n"
2912 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002914 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2915 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2916 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002918 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2919 PyDoc_STR("Return the day of the week represented by the date.\n"
2920 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002922 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2923 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002925 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2926 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002928 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002929};
2930
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002931static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002932PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002933
2934static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002935 date_add, /* nb_add */
2936 date_subtract, /* nb_subtract */
2937 0, /* nb_multiply */
2938 0, /* nb_remainder */
2939 0, /* nb_divmod */
2940 0, /* nb_power */
2941 0, /* nb_negative */
2942 0, /* nb_positive */
2943 0, /* nb_absolute */
2944 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002945};
2946
2947static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002948 PyVarObject_HEAD_INIT(NULL, 0)
2949 "datetime.date", /* tp_name */
2950 sizeof(PyDateTime_Date), /* tp_basicsize */
2951 0, /* tp_itemsize */
2952 0, /* tp_dealloc */
2953 0, /* tp_print */
2954 0, /* tp_getattr */
2955 0, /* tp_setattr */
2956 0, /* tp_reserved */
2957 (reprfunc)date_repr, /* tp_repr */
2958 &date_as_number, /* tp_as_number */
2959 0, /* tp_as_sequence */
2960 0, /* tp_as_mapping */
2961 (hashfunc)date_hash, /* tp_hash */
2962 0, /* tp_call */
2963 (reprfunc)date_str, /* tp_str */
2964 PyObject_GenericGetAttr, /* tp_getattro */
2965 0, /* tp_setattro */
2966 0, /* tp_as_buffer */
2967 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2968 date_doc, /* tp_doc */
2969 0, /* tp_traverse */
2970 0, /* tp_clear */
2971 date_richcompare, /* tp_richcompare */
2972 0, /* tp_weaklistoffset */
2973 0, /* tp_iter */
2974 0, /* tp_iternext */
2975 date_methods, /* tp_methods */
2976 0, /* tp_members */
2977 date_getset, /* tp_getset */
2978 0, /* tp_base */
2979 0, /* tp_dict */
2980 0, /* tp_descr_get */
2981 0, /* tp_descr_set */
2982 0, /* tp_dictoffset */
2983 0, /* tp_init */
2984 0, /* tp_alloc */
2985 date_new, /* tp_new */
2986 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002987};
2988
2989/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002990 * PyDateTime_TZInfo implementation.
2991 */
2992
2993/* This is a pure abstract base class, so doesn't do anything beyond
2994 * raising NotImplemented exceptions. Real tzinfo classes need
2995 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002996 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002997 * be subclasses of this tzinfo class, which is easy and quick to check).
2998 *
2999 * Note: For reasons having to do with pickling of subclasses, we have
3000 * to allow tzinfo objects to be instantiated. This wasn't an issue
3001 * in the Python implementation (__init__() could raise NotImplementedError
3002 * there without ill effect), but doing so in the C implementation hit a
3003 * brick wall.
3004 */
3005
3006static PyObject *
3007tzinfo_nogo(const char* methodname)
3008{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003009 PyErr_Format(PyExc_NotImplementedError,
3010 "a tzinfo subclass must implement %s()",
3011 methodname);
3012 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003013}
3014
3015/* Methods. A subclass must implement these. */
3016
Tim Peters52dcce22003-01-23 16:36:11 +00003017static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003018tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3019{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003020 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003021}
3022
Tim Peters52dcce22003-01-23 16:36:11 +00003023static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003024tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3025{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003026 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003027}
3028
Tim Peters52dcce22003-01-23 16:36:11 +00003029static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003030tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003032 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003033}
3034
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003035
3036static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3037 PyDateTime_Delta *delta,
3038 int factor);
3039static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3040static PyObject *datetime_dst(PyObject *self, PyObject *);
3041
Tim Peters52dcce22003-01-23 16:36:11 +00003042static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003043tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003044{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003045 PyObject *result = NULL;
3046 PyObject *off = NULL, *dst = NULL;
3047 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003048
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003049 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003050 PyErr_SetString(PyExc_TypeError,
3051 "fromutc: argument must be a datetime");
3052 return NULL;
3053 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003054 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003055 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3056 "is not self");
3057 return NULL;
3058 }
Tim Peters52dcce22003-01-23 16:36:11 +00003059
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003060 off = datetime_utcoffset(dt, NULL);
3061 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003062 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003063 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003064 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3065 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003066 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003067 }
Tim Peters52dcce22003-01-23 16:36:11 +00003068
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003069 dst = datetime_dst(dt, NULL);
3070 if (dst == NULL)
3071 goto Fail;
3072 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003073 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3074 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003075 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003076 }
Tim Peters52dcce22003-01-23 16:36:11 +00003077
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003078 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3079 if (delta == NULL)
3080 goto Fail;
3081 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003082 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003084
3085 Py_DECREF(dst);
3086 dst = call_dst(GET_DT_TZINFO(dt), result);
3087 if (dst == NULL)
3088 goto Fail;
3089 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003090 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003091 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003092 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003093 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003094 if (result == NULL)
3095 goto Fail;
3096 }
3097 Py_DECREF(delta);
3098 Py_DECREF(dst);
3099 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003100 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003101
3102Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003103 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3104 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003106 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003107Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003108 Py_XDECREF(off);
3109 Py_XDECREF(dst);
3110 Py_XDECREF(delta);
3111 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003112 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003113}
3114
Tim Peters2a799bf2002-12-16 20:18:38 +00003115/*
3116 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003117 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003118 */
3119
Guido van Rossum177e41a2003-01-30 22:06:23 +00003120static PyObject *
3121tzinfo_reduce(PyObject *self)
3122{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003123 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003124 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003125 _Py_IDENTIFIER(__getinitargs__);
3126 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003127
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003128 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003129 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003130 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003131 Py_DECREF(getinitargs);
3132 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003133 return NULL;
3134 }
3135 }
3136 else {
3137 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003138
3139 args = PyTuple_New(0);
3140 if (args == NULL) {
3141 return NULL;
3142 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003144
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003145 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003146 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003147 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003148 Py_DECREF(getstate);
3149 if (state == NULL) {
3150 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003151 return NULL;
3152 }
3153 }
3154 else {
3155 PyObject **dictptr;
3156 PyErr_Clear();
3157 state = Py_None;
3158 dictptr = _PyObject_GetDictPtr(self);
Victor Stinnerd1584d32016-08-23 00:11:04 +02003159 if (dictptr && *dictptr && PyDict_Size(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003160 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003161 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003162 Py_INCREF(state);
3163 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003165 if (state == Py_None) {
3166 Py_DECREF(state);
3167 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3168 }
3169 else
3170 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003171}
Tim Peters2a799bf2002-12-16 20:18:38 +00003172
3173static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003175 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3176 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003178 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003179 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3180 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003182 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3183 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003185 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003186 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003188 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3189 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003191 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003192};
3193
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003194static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003195PyDoc_STR("Abstract base class for time zone info objects.");
3196
Neal Norwitz227b5332006-03-22 09:28:35 +00003197static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 PyVarObject_HEAD_INIT(NULL, 0)
3199 "datetime.tzinfo", /* tp_name */
3200 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3201 0, /* tp_itemsize */
3202 0, /* tp_dealloc */
3203 0, /* tp_print */
3204 0, /* tp_getattr */
3205 0, /* tp_setattr */
3206 0, /* tp_reserved */
3207 0, /* tp_repr */
3208 0, /* tp_as_number */
3209 0, /* tp_as_sequence */
3210 0, /* tp_as_mapping */
3211 0, /* tp_hash */
3212 0, /* tp_call */
3213 0, /* tp_str */
3214 PyObject_GenericGetAttr, /* tp_getattro */
3215 0, /* tp_setattro */
3216 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003217 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003218 tzinfo_doc, /* tp_doc */
3219 0, /* tp_traverse */
3220 0, /* tp_clear */
3221 0, /* tp_richcompare */
3222 0, /* tp_weaklistoffset */
3223 0, /* tp_iter */
3224 0, /* tp_iternext */
3225 tzinfo_methods, /* tp_methods */
3226 0, /* tp_members */
3227 0, /* tp_getset */
3228 0, /* tp_base */
3229 0, /* tp_dict */
3230 0, /* tp_descr_get */
3231 0, /* tp_descr_set */
3232 0, /* tp_dictoffset */
3233 0, /* tp_init */
3234 0, /* tp_alloc */
3235 PyType_GenericNew, /* tp_new */
3236 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003237};
3238
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003239static char *timezone_kws[] = {"offset", "name", NULL};
3240
3241static PyObject *
3242timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3243{
3244 PyObject *offset;
3245 PyObject *name = NULL;
3246 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3247 &PyDateTime_DeltaType, &offset,
3248 &PyUnicode_Type, &name))
3249 return new_timezone(offset, name);
3250
3251 return NULL;
3252}
3253
3254static void
3255timezone_dealloc(PyDateTime_TimeZone *self)
3256{
3257 Py_CLEAR(self->offset);
3258 Py_CLEAR(self->name);
3259 Py_TYPE(self)->tp_free((PyObject *)self);
3260}
3261
3262static PyObject *
3263timezone_richcompare(PyDateTime_TimeZone *self,
3264 PyDateTime_TimeZone *other, int op)
3265{
Brian Curtindfc80e32011-08-10 20:28:54 -05003266 if (op != Py_EQ && op != Py_NE)
3267 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003268 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003269 if (op == Py_EQ)
3270 Py_RETURN_FALSE;
3271 else
3272 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003273 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003274 return delta_richcompare(self->offset, other->offset, op);
3275}
3276
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003277static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003278timezone_hash(PyDateTime_TimeZone *self)
3279{
3280 return delta_hash((PyDateTime_Delta *)self->offset);
3281}
3282
3283/* Check argument type passed to tzname, utcoffset, or dst methods.
3284 Returns 0 for good argument. Returns -1 and sets exception info
3285 otherwise.
3286 */
3287static int
3288_timezone_check_argument(PyObject *dt, const char *meth)
3289{
3290 if (dt == Py_None || PyDateTime_Check(dt))
3291 return 0;
3292 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3293 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3294 return -1;
3295}
3296
3297static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003298timezone_repr(PyDateTime_TimeZone *self)
3299{
3300 /* Note that although timezone is not subclassable, it is convenient
3301 to use Py_TYPE(self)->tp_name here. */
3302 const char *type_name = Py_TYPE(self)->tp_name;
3303
3304 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3305 return PyUnicode_FromFormat("%s.utc", type_name);
3306
3307 if (self->name == NULL)
3308 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3309
3310 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3311 self->name);
3312}
3313
3314
3315static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003316timezone_str(PyDateTime_TimeZone *self)
3317{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003318 int hours, minutes, seconds;
3319 PyObject *offset;
3320 char sign;
3321
3322 if (self->name != NULL) {
3323 Py_INCREF(self->name);
3324 return self->name;
3325 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003326 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003327 (GET_TD_DAYS(self->offset) == 0 &&
3328 GET_TD_SECONDS(self->offset) == 0 &&
3329 GET_TD_MICROSECONDS(self->offset) == 0))
3330 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003331 /* Offset is normalized, so it is negative if days < 0 */
3332 if (GET_TD_DAYS(self->offset) < 0) {
3333 sign = '-';
3334 offset = delta_negative((PyDateTime_Delta *)self->offset);
3335 if (offset == NULL)
3336 return NULL;
3337 }
3338 else {
3339 sign = '+';
3340 offset = self->offset;
3341 Py_INCREF(offset);
3342 }
3343 /* Offset is not negative here. */
3344 seconds = GET_TD_SECONDS(offset);
3345 Py_DECREF(offset);
3346 minutes = divmod(seconds, 60, &seconds);
3347 hours = divmod(minutes, 60, &minutes);
Martin Pantere26da7c2016-06-02 10:07:09 +00003348 /* XXX ignore sub-minute data, currently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003349 assert(seconds == 0);
3350 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003351}
3352
3353static PyObject *
3354timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3355{
3356 if (_timezone_check_argument(dt, "tzname") == -1)
3357 return NULL;
3358
3359 return timezone_str(self);
3360}
3361
3362static PyObject *
3363timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3364{
3365 if (_timezone_check_argument(dt, "utcoffset") == -1)
3366 return NULL;
3367
3368 Py_INCREF(self->offset);
3369 return self->offset;
3370}
3371
3372static PyObject *
3373timezone_dst(PyObject *self, PyObject *dt)
3374{
3375 if (_timezone_check_argument(dt, "dst") == -1)
3376 return NULL;
3377
3378 Py_RETURN_NONE;
3379}
3380
3381static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003382timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3383{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003384 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003385 PyErr_SetString(PyExc_TypeError,
3386 "fromutc: argument must be a datetime");
3387 return NULL;
3388 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003389 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003390 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3391 "is not self");
3392 return NULL;
3393 }
3394
3395 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3396}
3397
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003398static PyObject *
3399timezone_getinitargs(PyDateTime_TimeZone *self)
3400{
3401 if (self->name == NULL)
3402 return Py_BuildValue("(O)", self->offset);
3403 return Py_BuildValue("(OO)", self->offset, self->name);
3404}
3405
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003406static PyMethodDef timezone_methods[] = {
3407 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3408 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003409 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003410
3411 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003412 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003413
3414 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003415 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003416
3417 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3418 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3419
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003420 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3421 PyDoc_STR("pickle support")},
3422
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003423 {NULL, NULL}
3424};
3425
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003426static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003427PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3428
3429static PyTypeObject PyDateTime_TimeZoneType = {
3430 PyVarObject_HEAD_INIT(NULL, 0)
3431 "datetime.timezone", /* tp_name */
3432 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3433 0, /* tp_itemsize */
3434 (destructor)timezone_dealloc, /* tp_dealloc */
3435 0, /* tp_print */
3436 0, /* tp_getattr */
3437 0, /* tp_setattr */
3438 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003439 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003440 0, /* tp_as_number */
3441 0, /* tp_as_sequence */
3442 0, /* tp_as_mapping */
3443 (hashfunc)timezone_hash, /* tp_hash */
3444 0, /* tp_call */
3445 (reprfunc)timezone_str, /* tp_str */
3446 0, /* tp_getattro */
3447 0, /* tp_setattro */
3448 0, /* tp_as_buffer */
3449 Py_TPFLAGS_DEFAULT, /* tp_flags */
3450 timezone_doc, /* tp_doc */
3451 0, /* tp_traverse */
3452 0, /* tp_clear */
3453 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3454 0, /* tp_weaklistoffset */
3455 0, /* tp_iter */
3456 0, /* tp_iternext */
3457 timezone_methods, /* tp_methods */
3458 0, /* tp_members */
3459 0, /* tp_getset */
3460 &PyDateTime_TZInfoType, /* tp_base */
3461 0, /* tp_dict */
3462 0, /* tp_descr_get */
3463 0, /* tp_descr_set */
3464 0, /* tp_dictoffset */
3465 0, /* tp_init */
3466 0, /* tp_alloc */
3467 timezone_new, /* tp_new */
3468};
3469
Tim Peters2a799bf2002-12-16 20:18:38 +00003470/*
Tim Peters37f39822003-01-10 03:49:02 +00003471 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003472 */
3473
Tim Peters37f39822003-01-10 03:49:02 +00003474/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003475 */
3476
3477static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003478time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003479{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003480 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003481}
3482
Tim Peters37f39822003-01-10 03:49:02 +00003483static PyObject *
3484time_minute(PyDateTime_Time *self, void *unused)
3485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003486 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003487}
3488
3489/* The name time_second conflicted with some platform header file. */
3490static PyObject *
3491py_time_second(PyDateTime_Time *self, void *unused)
3492{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003493 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003494}
3495
3496static PyObject *
3497time_microsecond(PyDateTime_Time *self, void *unused)
3498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003499 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003500}
3501
3502static PyObject *
3503time_tzinfo(PyDateTime_Time *self, void *unused)
3504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003505 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3506 Py_INCREF(result);
3507 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003508}
3509
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003510static PyObject *
3511time_fold(PyDateTime_Time *self, void *unused)
3512{
3513 return PyLong_FromLong(TIME_GET_FOLD(self));
3514}
3515
Tim Peters37f39822003-01-10 03:49:02 +00003516static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003517 {"hour", (getter)time_hour},
3518 {"minute", (getter)time_minute},
3519 {"second", (getter)py_time_second},
3520 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003521 {"tzinfo", (getter)time_tzinfo},
3522 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003523 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003524};
3525
3526/*
3527 * Constructors.
3528 */
3529
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003530static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003531 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003532
Tim Peters2a799bf2002-12-16 20:18:38 +00003533static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003534time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003535{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003536 PyObject *self = NULL;
3537 PyObject *state;
3538 int hour = 0;
3539 int minute = 0;
3540 int second = 0;
3541 int usecond = 0;
3542 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003543 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003545 /* Check for invocation from pickle with __getstate__ state */
3546 if (PyTuple_GET_SIZE(args) >= 1 &&
3547 PyTuple_GET_SIZE(args) <= 2 &&
3548 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3549 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003550 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003551 {
3552 PyDateTime_Time *me;
3553 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 if (PyTuple_GET_SIZE(args) == 2) {
3556 tzinfo = PyTuple_GET_ITEM(args, 1);
3557 if (check_tzinfo_subclass(tzinfo) < 0) {
3558 PyErr_SetString(PyExc_TypeError, "bad "
3559 "tzinfo state arg");
3560 return NULL;
3561 }
3562 }
3563 aware = (char)(tzinfo != Py_None);
3564 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3565 if (me != NULL) {
3566 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3569 me->hashcode = -1;
3570 me->hastzinfo = aware;
3571 if (aware) {
3572 Py_INCREF(tzinfo);
3573 me->tzinfo = tzinfo;
3574 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003575 if (pdata[0] & (1 << 7)) {
3576 me->data[0] -= 128;
3577 me->fold = 1;
3578 }
3579 else {
3580 me->fold = 0;
3581 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003582 }
3583 return (PyObject *)me;
3584 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003585
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003586 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003587 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003588 &tzinfo, &fold)) {
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003589 if (check_time_args(hour, minute, second, usecond, fold) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003590 return NULL;
3591 if (check_tzinfo_subclass(tzinfo) < 0)
3592 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003593 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3594 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003595 }
3596 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003597}
3598
3599/*
3600 * Destructor.
3601 */
3602
3603static void
Tim Peters37f39822003-01-10 03:49:02 +00003604time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003605{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003606 if (HASTZINFO(self)) {
3607 Py_XDECREF(self->tzinfo);
3608 }
3609 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003610}
3611
3612/*
Tim Peters855fe882002-12-22 03:43:39 +00003613 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003614 */
3615
Tim Peters2a799bf2002-12-16 20:18:38 +00003616/* These are all METH_NOARGS, so don't need to check the arglist. */
3617static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003618time_utcoffset(PyObject *self, PyObject *unused) {
3619 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003620}
3621
3622static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003623time_dst(PyObject *self, PyObject *unused) {
3624 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003625}
3626
3627static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003628time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003629 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003630}
3631
3632/*
Tim Peters37f39822003-01-10 03:49:02 +00003633 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003634 */
3635
3636static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003637time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003639 const char *type_name = Py_TYPE(self)->tp_name;
3640 int h = TIME_GET_HOUR(self);
3641 int m = TIME_GET_MINUTE(self);
3642 int s = TIME_GET_SECOND(self);
3643 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003644 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003645 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003647 if (us)
3648 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3649 type_name, h, m, s, us);
3650 else if (s)
3651 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3652 type_name, h, m, s);
3653 else
3654 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3655 if (result != NULL && HASTZINFO(self))
3656 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003657 if (result != NULL && fold)
3658 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003659 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003660}
3661
Tim Peters37f39822003-01-10 03:49:02 +00003662static PyObject *
3663time_str(PyDateTime_Time *self)
3664{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003665 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003666}
Tim Peters2a799bf2002-12-16 20:18:38 +00003667
3668static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003669time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003671 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003672 char *timespec = NULL;
3673 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003674 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003675 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003676 static char *specs[][2] = {
3677 {"hours", "%02d"},
3678 {"minutes", "%02d:%02d"},
3679 {"seconds", "%02d:%02d:%02d"},
3680 {"milliseconds", "%02d:%02d:%02d.%03d"},
3681 {"microseconds", "%02d:%02d:%02d.%06d"},
3682 };
3683 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003684
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003685 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3686 return NULL;
3687
3688 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3689 if (us == 0) {
3690 /* seconds */
3691 given_spec = 2;
3692 }
3693 else {
3694 /* microseconds */
3695 given_spec = 4;
3696 }
3697 }
3698 else {
3699 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3700 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3701 if (given_spec == 3) {
3702 /* milliseconds */
3703 us = us / 1000;
3704 }
3705 break;
3706 }
3707 }
3708 }
3709
3710 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3711 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3712 return NULL;
3713 }
3714 else {
3715 result = PyUnicode_FromFormat(specs[given_spec][1],
3716 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3717 TIME_GET_SECOND(self), us);
3718 }
Tim Peters37f39822003-01-10 03:49:02 +00003719
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003720 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003721 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003723 /* We need to append the UTC offset. */
3724 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3725 Py_None) < 0) {
3726 Py_DECREF(result);
3727 return NULL;
3728 }
3729 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3730 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003731}
3732
Tim Peters37f39822003-01-10 03:49:02 +00003733static PyObject *
3734time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003736 PyObject *result;
3737 PyObject *tuple;
3738 PyObject *format;
3739 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003741 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3742 &format))
3743 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003745 /* Python's strftime does insane things with the year part of the
3746 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003747 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003748 */
3749 tuple = Py_BuildValue("iiiiiiiii",
3750 1900, 1, 1, /* year, month, day */
3751 TIME_GET_HOUR(self),
3752 TIME_GET_MINUTE(self),
3753 TIME_GET_SECOND(self),
3754 0, 1, -1); /* weekday, daynum, dst */
3755 if (tuple == NULL)
3756 return NULL;
3757 assert(PyTuple_Size(tuple) == 9);
3758 result = wrap_strftime((PyObject *)self, format, tuple,
3759 Py_None);
3760 Py_DECREF(tuple);
3761 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003762}
Tim Peters2a799bf2002-12-16 20:18:38 +00003763
3764/*
3765 * Miscellaneous methods.
3766 */
3767
Tim Peters37f39822003-01-10 03:49:02 +00003768static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003769time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003770{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003771 PyObject *result = NULL;
3772 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003773 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003774
Brian Curtindfc80e32011-08-10 20:28:54 -05003775 if (! PyTime_Check(other))
3776 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003777
3778 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003779 diff = memcmp(((PyDateTime_Time *)self)->data,
3780 ((PyDateTime_Time *)other)->data,
3781 _PyDateTime_TIME_DATASIZE);
3782 return diff_to_bool(diff, op);
3783 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003784 offset1 = time_utcoffset(self, NULL);
3785 if (offset1 == NULL)
3786 return NULL;
3787 offset2 = time_utcoffset(other, NULL);
3788 if (offset2 == NULL)
3789 goto done;
3790 /* If they're both naive, or both aware and have the same offsets,
3791 * we get off cheap. Note that if they're both naive, offset1 ==
3792 * offset2 == Py_None at this point.
3793 */
3794 if ((offset1 == offset2) ||
3795 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3796 delta_cmp(offset1, offset2) == 0)) {
3797 diff = memcmp(((PyDateTime_Time *)self)->data,
3798 ((PyDateTime_Time *)other)->data,
3799 _PyDateTime_TIME_DATASIZE);
3800 result = diff_to_bool(diff, op);
3801 }
3802 /* The hard case: both aware with different UTC offsets */
3803 else if (offset1 != Py_None && offset2 != Py_None) {
3804 int offsecs1, offsecs2;
3805 assert(offset1 != offset2); /* else last "if" handled it */
3806 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3807 TIME_GET_MINUTE(self) * 60 +
3808 TIME_GET_SECOND(self) -
3809 GET_TD_DAYS(offset1) * 86400 -
3810 GET_TD_SECONDS(offset1);
3811 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3812 TIME_GET_MINUTE(other) * 60 +
3813 TIME_GET_SECOND(other) -
3814 GET_TD_DAYS(offset2) * 86400 -
3815 GET_TD_SECONDS(offset2);
3816 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003817 if (diff == 0)
3818 diff = TIME_GET_MICROSECOND(self) -
3819 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003820 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003821 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003822 else if (op == Py_EQ) {
3823 result = Py_False;
3824 Py_INCREF(result);
3825 }
3826 else if (op == Py_NE) {
3827 result = Py_True;
3828 Py_INCREF(result);
3829 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003830 else {
3831 PyErr_SetString(PyExc_TypeError,
3832 "can't compare offset-naive and "
3833 "offset-aware times");
3834 }
3835 done:
3836 Py_DECREF(offset1);
3837 Py_XDECREF(offset2);
3838 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003839}
3840
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003841static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003842time_hash(PyDateTime_Time *self)
3843{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003844 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003845 PyObject *offset, *self0;
3846 if (DATE_GET_FOLD(self)) {
3847 self0 = new_time_ex2(DATE_GET_HOUR(self),
3848 DATE_GET_MINUTE(self),
3849 DATE_GET_SECOND(self),
3850 DATE_GET_MICROSECOND(self),
3851 HASTZINFO(self) ? self->tzinfo : Py_None,
3852 0, Py_TYPE(self));
3853 if (self0 == NULL)
3854 return -1;
3855 }
3856 else {
3857 self0 = (PyObject *)self;
3858 Py_INCREF(self0);
3859 }
3860 offset = time_utcoffset(self0, NULL);
3861 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003862
3863 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003864 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003866 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003867 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003868 self->hashcode = generic_hash(
3869 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003870 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003871 PyObject *temp1, *temp2;
3872 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003873 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003874 seconds = TIME_GET_HOUR(self) * 3600 +
3875 TIME_GET_MINUTE(self) * 60 +
3876 TIME_GET_SECOND(self);
3877 microseconds = TIME_GET_MICROSECOND(self);
3878 temp1 = new_delta(0, seconds, microseconds, 1);
3879 if (temp1 == NULL) {
3880 Py_DECREF(offset);
3881 return -1;
3882 }
3883 temp2 = delta_subtract(temp1, offset);
3884 Py_DECREF(temp1);
3885 if (temp2 == NULL) {
3886 Py_DECREF(offset);
3887 return -1;
3888 }
3889 self->hashcode = PyObject_Hash(temp2);
3890 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003891 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003892 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003893 }
3894 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003895}
Tim Peters2a799bf2002-12-16 20:18:38 +00003896
Tim Peters12bf3392002-12-24 05:41:27 +00003897static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003898time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003900 PyObject *clone;
3901 PyObject *tuple;
3902 int hh = TIME_GET_HOUR(self);
3903 int mm = TIME_GET_MINUTE(self);
3904 int ss = TIME_GET_SECOND(self);
3905 int us = TIME_GET_MICROSECOND(self);
3906 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003907 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003908
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003909 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003910 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003911 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003912 return NULL;
3913 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3914 if (tuple == NULL)
3915 return NULL;
3916 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003917 if (clone != NULL) {
3918 if (fold != 0 && fold != 1) {
3919 PyErr_SetString(PyExc_ValueError,
3920 "fold must be either 0 or 1");
3921 return NULL;
3922 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003923 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003924 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003925 Py_DECREF(tuple);
3926 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003927}
3928
Tim Peters371935f2003-02-01 01:52:50 +00003929/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003930
Tim Peters33e0f382003-01-10 02:05:14 +00003931/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003932 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3933 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003934 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003935 */
3936static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003937time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00003938{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003939 PyObject *basestate;
3940 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003942 basestate = PyBytes_FromStringAndSize((char *)self->data,
3943 _PyDateTime_TIME_DATASIZE);
3944 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003945 if (proto > 3 && TIME_GET_FOLD(self))
3946 /* Set the first bit of the first byte */
3947 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003948 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3949 result = PyTuple_Pack(1, basestate);
3950 else
3951 result = PyTuple_Pack(2, basestate, self->tzinfo);
3952 Py_DECREF(basestate);
3953 }
3954 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003955}
3956
3957static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003958time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00003959{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003960 int proto;
3961 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003962 return NULL;
3963
3964 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00003965}
3966
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003967static PyObject *
3968time_reduce(PyDateTime_Time *self, PyObject *arg)
3969{
3970 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
3971}
3972
Tim Peters37f39822003-01-10 03:49:02 +00003973static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003974
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003975 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
3976 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
3977 "[+HH:MM].\n\n"
3978 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3981 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003983 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3984 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003986 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3987 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003989 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3990 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003992 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3993 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003995 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3996 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003997
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003998 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003999 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004000
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004001 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4002 PyDoc_STR("__reduce__() -> (cls, state)")},
4003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004005};
4006
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004007static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004008PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4009\n\
4010All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004011a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004012
Neal Norwitz227b5332006-03-22 09:28:35 +00004013static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004014 PyVarObject_HEAD_INIT(NULL, 0)
4015 "datetime.time", /* tp_name */
4016 sizeof(PyDateTime_Time), /* tp_basicsize */
4017 0, /* tp_itemsize */
4018 (destructor)time_dealloc, /* tp_dealloc */
4019 0, /* tp_print */
4020 0, /* tp_getattr */
4021 0, /* tp_setattr */
4022 0, /* tp_reserved */
4023 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004024 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004025 0, /* tp_as_sequence */
4026 0, /* tp_as_mapping */
4027 (hashfunc)time_hash, /* tp_hash */
4028 0, /* tp_call */
4029 (reprfunc)time_str, /* tp_str */
4030 PyObject_GenericGetAttr, /* tp_getattro */
4031 0, /* tp_setattro */
4032 0, /* tp_as_buffer */
4033 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4034 time_doc, /* tp_doc */
4035 0, /* tp_traverse */
4036 0, /* tp_clear */
4037 time_richcompare, /* tp_richcompare */
4038 0, /* tp_weaklistoffset */
4039 0, /* tp_iter */
4040 0, /* tp_iternext */
4041 time_methods, /* tp_methods */
4042 0, /* tp_members */
4043 time_getset, /* tp_getset */
4044 0, /* tp_base */
4045 0, /* tp_dict */
4046 0, /* tp_descr_get */
4047 0, /* tp_descr_set */
4048 0, /* tp_dictoffset */
4049 0, /* tp_init */
4050 time_alloc, /* tp_alloc */
4051 time_new, /* tp_new */
4052 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004053};
4054
4055/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004056 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004057 */
4058
Tim Petersa9bc1682003-01-11 03:39:11 +00004059/* Accessor properties. Properties for day, month, and year are inherited
4060 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004061 */
4062
4063static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004064datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004066 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004067}
4068
Tim Petersa9bc1682003-01-11 03:39:11 +00004069static PyObject *
4070datetime_minute(PyDateTime_DateTime *self, void *unused)
4071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004072 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004073}
4074
4075static PyObject *
4076datetime_second(PyDateTime_DateTime *self, void *unused)
4077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004078 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004079}
4080
4081static PyObject *
4082datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004084 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004085}
4086
4087static PyObject *
4088datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004090 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4091 Py_INCREF(result);
4092 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004093}
4094
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004095static PyObject *
4096datetime_fold(PyDateTime_DateTime *self, void *unused)
4097{
4098 return PyLong_FromLong(DATE_GET_FOLD(self));
4099}
4100
Tim Petersa9bc1682003-01-11 03:39:11 +00004101static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 {"hour", (getter)datetime_hour},
4103 {"minute", (getter)datetime_minute},
4104 {"second", (getter)datetime_second},
4105 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004106 {"tzinfo", (getter)datetime_tzinfo},
4107 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004108 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004109};
4110
4111/*
4112 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004113 */
4114
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004115static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004116 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004117 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004118};
4119
Tim Peters2a799bf2002-12-16 20:18:38 +00004120static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004121datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004123 PyObject *self = NULL;
4124 PyObject *state;
4125 int year;
4126 int month;
4127 int day;
4128 int hour = 0;
4129 int minute = 0;
4130 int second = 0;
4131 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004132 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004133 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004135 /* Check for invocation from pickle with __getstate__ state */
4136 if (PyTuple_GET_SIZE(args) >= 1 &&
4137 PyTuple_GET_SIZE(args) <= 2 &&
4138 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4139 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004140 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004141 {
4142 PyDateTime_DateTime *me;
4143 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004145 if (PyTuple_GET_SIZE(args) == 2) {
4146 tzinfo = PyTuple_GET_ITEM(args, 1);
4147 if (check_tzinfo_subclass(tzinfo) < 0) {
4148 PyErr_SetString(PyExc_TypeError, "bad "
4149 "tzinfo state arg");
4150 return NULL;
4151 }
4152 }
4153 aware = (char)(tzinfo != Py_None);
4154 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4155 if (me != NULL) {
4156 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004158 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4159 me->hashcode = -1;
4160 me->hastzinfo = aware;
4161 if (aware) {
4162 Py_INCREF(tzinfo);
4163 me->tzinfo = tzinfo;
4164 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004165 if (pdata[2] & (1 << 7)) {
4166 me->data[2] -= 128;
4167 me->fold = 1;
4168 }
4169 else {
4170 me->fold = 0;
4171 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004172 }
4173 return (PyObject *)me;
4174 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004175
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004176 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004178 &second, &usecond, &tzinfo, &fold)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004179 if (check_date_args(year, month, day) < 0)
4180 return NULL;
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004181 if (check_time_args(hour, minute, second, usecond, fold) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004182 return NULL;
4183 if (check_tzinfo_subclass(tzinfo) < 0)
4184 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004185 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004186 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004187 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004188 }
4189 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004190}
4191
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004192/* TM_FUNC is the shared type of _PyTime_localtime() and
4193 * _PyTime_gmtime(). */
4194typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004195
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004196/* As of version 2015f max fold in IANA database is
4197 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004198static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004199/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004200static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004201
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004202static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004203utc_to_seconds(int year, int month, int day,
4204 int hour, int minute, int second)
4205{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004206 long long ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004207 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4208}
4209
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004210static long long
4211local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004212{
4213 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004214 time_t t;
4215 u -= epoch;
4216 t = u;
4217 if (t != u) {
4218 PyErr_SetString(PyExc_OverflowError,
4219 "timestamp out of range for platform time_t");
4220 return -1;
4221 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004222 /* XXX: add bounds checking */
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004223 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004224 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004225 return utc_to_seconds(local_time.tm_year + 1900,
4226 local_time.tm_mon + 1,
4227 local_time.tm_mday,
4228 local_time.tm_hour,
4229 local_time.tm_min,
4230 local_time.tm_sec);
4231}
4232
Tim Petersa9bc1682003-01-11 03:39:11 +00004233/* Internal helper.
4234 * Build datetime from a time_t and a distinct count of microseconds.
4235 * Pass localtime or gmtime for f, to control the interpretation of timet.
4236 */
4237static PyObject *
4238datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004239 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004240{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004241 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004242 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004243
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004244 if (f(timet, &tm) != 0)
4245 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004246
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004247 year = tm.tm_year + 1900;
4248 month = tm.tm_mon + 1;
4249 day = tm.tm_mday;
4250 hour = tm.tm_hour;
4251 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004252 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004253 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004254 * except to the extent that passing them on to the datetime
4255 * constructor would raise ValueError for a reason that
4256 * made no sense to the user.
4257 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004258 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004259
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004260 if (tzinfo == Py_None && f == _PyTime_localtime) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004261 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004262
4263 result_seconds = utc_to_seconds(year, month, day,
4264 hour, minute, second);
4265 /* Probe max_fold_seconds to detect a fold. */
4266 probe_seconds = local(epoch + timet - max_fold_seconds);
4267 if (probe_seconds == -1)
4268 return NULL;
4269 transition = result_seconds - probe_seconds - max_fold_seconds;
4270 if (transition < 0) {
4271 probe_seconds = local(epoch + timet + transition);
4272 if (probe_seconds == -1)
4273 return NULL;
4274 if (probe_seconds == result_seconds)
4275 fold = 1;
4276 }
4277 }
4278 return new_datetime_ex2(year, month, day, hour,
4279 minute, second, us, tzinfo, fold,
4280 (PyTypeObject *)cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004281}
4282
4283/* Internal helper.
4284 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4285 * to control the interpretation of the timestamp. Since a double doesn't
4286 * have enough bits to cover a datetime's full range of precision, it's
4287 * better to call datetime_from_timet_and_us provided you have a way
4288 * to get that much precision (e.g., C time() isn't good enough).
4289 */
4290static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004291datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004292 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004294 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004295 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004296
Victor Stinnere4a994d2015-03-30 01:10:14 +02004297 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004298 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004299 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004300
Victor Stinner21f58932012-03-14 00:15:40 +01004301 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004302}
4303
4304/* Internal helper.
4305 * Build most accurate possible datetime for current time. Pass localtime or
4306 * gmtime for f as appropriate.
4307 */
4308static PyObject *
4309datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4310{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004311 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004312 time_t secs;
4313 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004314
Victor Stinner1e2b6882015-09-18 13:23:02 +02004315 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004316 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004317 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004318
Victor Stinner1e2b6882015-09-18 13:23:02 +02004319 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004320}
4321
Larry Hastings61272b72014-01-07 12:41:53 -08004322/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004323
4324@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004325datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004326
4327 tz: object = None
4328 Timezone object.
4329
4330Returns new datetime object representing current time local to tz.
4331
4332If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004333[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004334
Larry Hastings31826802013-10-19 00:09:25 -07004335static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004336datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004337/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004339 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004340
Larry Hastings31826802013-10-19 00:09:25 -07004341 /* Return best possible local time -- this isn't constrained by the
4342 * precision of a timestamp.
4343 */
4344 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004345 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004346
Larry Hastings5c661892014-01-24 06:17:25 -08004347 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004348 tz == Py_None ? _PyTime_localtime :
4349 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004350 tz);
4351 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004352 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004353 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004354 }
4355 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004356}
4357
Tim Petersa9bc1682003-01-11 03:39:11 +00004358/* Return best possible UTC time -- this isn't constrained by the
4359 * precision of a timestamp.
4360 */
4361static PyObject *
4362datetime_utcnow(PyObject *cls, PyObject *dummy)
4363{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004364 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004365}
4366
Tim Peters2a799bf2002-12-16 20:18:38 +00004367/* Return new local datetime from timestamp (Python timestamp -- a double). */
4368static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004369datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004370{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004371 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004372 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004373 PyObject *tzinfo = Py_None;
4374 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004375
Victor Stinner5d272cc2012-03-13 13:35:55 +01004376 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004377 keywords, &timestamp, &tzinfo))
4378 return NULL;
4379 if (check_tzinfo_subclass(tzinfo) < 0)
4380 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004382 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004383 tzinfo == Py_None ? _PyTime_localtime :
4384 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004385 timestamp,
4386 tzinfo);
4387 if (self != NULL && tzinfo != Py_None) {
4388 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004389 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004390 }
4391 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004392}
4393
Tim Petersa9bc1682003-01-11 03:39:11 +00004394/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4395static PyObject *
4396datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4397{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004398 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004399 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004400
Victor Stinner5d272cc2012-03-13 13:35:55 +01004401 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004402 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004403 Py_None);
4404 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004405}
4406
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004407/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004408static PyObject *
4409datetime_strptime(PyObject *cls, PyObject *args)
4410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004412 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004413 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004414
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004415 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004416 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004417
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004418 if (module == NULL) {
4419 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004420 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004421 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004422 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004423 return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
4424 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004425}
4426
Tim Petersa9bc1682003-01-11 03:39:11 +00004427/* Return new datetime from date/datetime and time arguments. */
4428static PyObject *
4429datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4430{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004431 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004432 PyObject *date;
4433 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004434 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004435 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004436
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004437 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004438 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004439 &PyDateTime_TimeType, &time, &tzinfo)) {
4440 if (tzinfo == NULL) {
4441 if (HASTZINFO(time))
4442 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4443 else
4444 tzinfo = Py_None;
4445 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004446 result = PyObject_CallFunction(cls, "iiiiiiiO",
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004447 GET_YEAR(date),
4448 GET_MONTH(date),
4449 GET_DAY(date),
4450 TIME_GET_HOUR(time),
4451 TIME_GET_MINUTE(time),
4452 TIME_GET_SECOND(time),
4453 TIME_GET_MICROSECOND(time),
4454 tzinfo);
4455 if (result)
4456 DATE_SET_FOLD(result, TIME_GET_FOLD(time));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004457 }
4458 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004459}
Tim Peters2a799bf2002-12-16 20:18:38 +00004460
4461/*
4462 * Destructor.
4463 */
4464
4465static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004466datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004468 if (HASTZINFO(self)) {
4469 Py_XDECREF(self->tzinfo);
4470 }
4471 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004472}
4473
4474/*
4475 * Indirect access to tzinfo methods.
4476 */
4477
Tim Peters2a799bf2002-12-16 20:18:38 +00004478/* These are all METH_NOARGS, so don't need to check the arglist. */
4479static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004480datetime_utcoffset(PyObject *self, PyObject *unused) {
4481 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004482}
4483
4484static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004485datetime_dst(PyObject *self, PyObject *unused) {
4486 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004487}
4488
4489static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004490datetime_tzname(PyObject *self, PyObject *unused) {
4491 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004492}
4493
4494/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004495 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004496 */
4497
Tim Petersa9bc1682003-01-11 03:39:11 +00004498/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4499 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004500 */
4501static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004502add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004503 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004505 /* Note that the C-level additions can't overflow, because of
4506 * invariant bounds on the member values.
4507 */
4508 int year = GET_YEAR(date);
4509 int month = GET_MONTH(date);
4510 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4511 int hour = DATE_GET_HOUR(date);
4512 int minute = DATE_GET_MINUTE(date);
4513 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4514 int microsecond = DATE_GET_MICROSECOND(date) +
4515 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004517 assert(factor == 1 || factor == -1);
4518 if (normalize_datetime(&year, &month, &day,
4519 &hour, &minute, &second, &microsecond) < 0)
4520 return NULL;
4521 else
4522 return new_datetime(year, month, day,
4523 hour, minute, second, microsecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004524 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004525}
4526
4527static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004528datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004530 if (PyDateTime_Check(left)) {
4531 /* datetime + ??? */
4532 if (PyDelta_Check(right))
4533 /* datetime + delta */
4534 return add_datetime_timedelta(
4535 (PyDateTime_DateTime *)left,
4536 (PyDateTime_Delta *)right,
4537 1);
4538 }
4539 else if (PyDelta_Check(left)) {
4540 /* delta + datetime */
4541 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4542 (PyDateTime_Delta *) left,
4543 1);
4544 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004545 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004546}
4547
4548static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004549datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004550{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004551 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004553 if (PyDateTime_Check(left)) {
4554 /* datetime - ??? */
4555 if (PyDateTime_Check(right)) {
4556 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004557 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004558 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004559
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004560 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4561 offset2 = offset1 = Py_None;
4562 Py_INCREF(offset1);
4563 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004564 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004565 else {
4566 offset1 = datetime_utcoffset(left, NULL);
4567 if (offset1 == NULL)
4568 return NULL;
4569 offset2 = datetime_utcoffset(right, NULL);
4570 if (offset2 == NULL) {
4571 Py_DECREF(offset1);
4572 return NULL;
4573 }
4574 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4575 PyErr_SetString(PyExc_TypeError,
4576 "can't subtract offset-naive and "
4577 "offset-aware datetimes");
4578 Py_DECREF(offset1);
4579 Py_DECREF(offset2);
4580 return NULL;
4581 }
4582 }
4583 if ((offset1 != offset2) &&
4584 delta_cmp(offset1, offset2) != 0) {
4585 offdiff = delta_subtract(offset1, offset2);
4586 if (offdiff == NULL) {
4587 Py_DECREF(offset1);
4588 Py_DECREF(offset2);
4589 return NULL;
4590 }
4591 }
4592 Py_DECREF(offset1);
4593 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004594 delta_d = ymd_to_ord(GET_YEAR(left),
4595 GET_MONTH(left),
4596 GET_DAY(left)) -
4597 ymd_to_ord(GET_YEAR(right),
4598 GET_MONTH(right),
4599 GET_DAY(right));
4600 /* These can't overflow, since the values are
4601 * normalized. At most this gives the number of
4602 * seconds in one day.
4603 */
4604 delta_s = (DATE_GET_HOUR(left) -
4605 DATE_GET_HOUR(right)) * 3600 +
4606 (DATE_GET_MINUTE(left) -
4607 DATE_GET_MINUTE(right)) * 60 +
4608 (DATE_GET_SECOND(left) -
4609 DATE_GET_SECOND(right));
4610 delta_us = DATE_GET_MICROSECOND(left) -
4611 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004612 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004613 if (result == NULL)
4614 return NULL;
4615
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004616 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004617 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004618 Py_DECREF(offdiff);
4619 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004620 }
4621 else if (PyDelta_Check(right)) {
4622 /* datetime - delta */
4623 result = add_datetime_timedelta(
4624 (PyDateTime_DateTime *)left,
4625 (PyDateTime_Delta *)right,
4626 -1);
4627 }
4628 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004630 if (result == Py_NotImplemented)
4631 Py_INCREF(result);
4632 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004633}
4634
4635/* Various ways to turn a datetime into a string. */
4636
4637static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004638datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004639{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004640 const char *type_name = Py_TYPE(self)->tp_name;
4641 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004643 if (DATE_GET_MICROSECOND(self)) {
4644 baserepr = PyUnicode_FromFormat(
4645 "%s(%d, %d, %d, %d, %d, %d, %d)",
4646 type_name,
4647 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4648 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4649 DATE_GET_SECOND(self),
4650 DATE_GET_MICROSECOND(self));
4651 }
4652 else if (DATE_GET_SECOND(self)) {
4653 baserepr = PyUnicode_FromFormat(
4654 "%s(%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 }
4660 else {
4661 baserepr = PyUnicode_FromFormat(
4662 "%s(%d, %d, %d, %d, %d)",
4663 type_name,
4664 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4665 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4666 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004667 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4668 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004669 if (baserepr == NULL || ! HASTZINFO(self))
4670 return baserepr;
4671 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004672}
4673
Tim Petersa9bc1682003-01-11 03:39:11 +00004674static PyObject *
4675datetime_str(PyDateTime_DateTime *self)
4676{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004677 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004678}
Tim Peters2a799bf2002-12-16 20:18:38 +00004679
4680static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004681datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004682{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004684 char *timespec = NULL;
4685 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004686 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004687 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004688 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004689 static char *specs[][2] = {
4690 {"hours", "%04d-%02d-%02d%c%02d"},
4691 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4692 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4693 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4694 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4695 };
4696 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004697
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004698 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004699 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004700
4701 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4702 if (us == 0) {
4703 /* seconds */
4704 given_spec = 2;
4705 }
4706 else {
4707 /* microseconds */
4708 given_spec = 4;
4709 }
4710 }
4711 else {
4712 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4713 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4714 if (given_spec == 3) {
4715 us = us / 1000;
4716 }
4717 break;
4718 }
4719 }
4720 }
4721
4722 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4723 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4724 return NULL;
4725 }
4726 else {
4727 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004728 GET_YEAR(self), GET_MONTH(self),
4729 GET_DAY(self), (int)sep,
4730 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4731 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004732 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004734 if (!result || !HASTZINFO(self))
4735 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004736
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004737 /* We need to append the UTC offset. */
4738 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4739 (PyObject *)self) < 0) {
4740 Py_DECREF(result);
4741 return NULL;
4742 }
4743 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4744 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004745}
4746
Tim Petersa9bc1682003-01-11 03:39:11 +00004747static PyObject *
4748datetime_ctime(PyDateTime_DateTime *self)
4749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004750 return format_ctime((PyDateTime_Date *)self,
4751 DATE_GET_HOUR(self),
4752 DATE_GET_MINUTE(self),
4753 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004754}
4755
Tim Peters2a799bf2002-12-16 20:18:38 +00004756/* Miscellaneous methods. */
4757
Tim Petersa9bc1682003-01-11 03:39:11 +00004758static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004759flip_fold(PyObject *dt)
4760{
4761 return new_datetime_ex2(GET_YEAR(dt),
4762 GET_MONTH(dt),
4763 GET_DAY(dt),
4764 DATE_GET_HOUR(dt),
4765 DATE_GET_MINUTE(dt),
4766 DATE_GET_SECOND(dt),
4767 DATE_GET_MICROSECOND(dt),
4768 HASTZINFO(dt) ?
4769 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4770 !DATE_GET_FOLD(dt),
4771 Py_TYPE(dt));
4772}
4773
4774static PyObject *
4775get_flip_fold_offset(PyObject *dt)
4776{
4777 PyObject *result, *flip_dt;
4778
4779 flip_dt = flip_fold(dt);
4780 if (flip_dt == NULL)
4781 return NULL;
4782 result = datetime_utcoffset(flip_dt, NULL);
4783 Py_DECREF(flip_dt);
4784 return result;
4785}
4786
4787/* PEP 495 exception: Whenever one or both of the operands in
4788 * inter-zone comparison is such that its utcoffset() depends
4789 * on the value of its fold fold attribute, the result is False.
4790 *
4791 * Return 1 if exception applies, 0 if not, and -1 on error.
4792 */
4793static int
4794pep495_eq_exception(PyObject *self, PyObject *other,
4795 PyObject *offset_self, PyObject *offset_other)
4796{
4797 int result = 0;
4798 PyObject *flip_offset;
4799
4800 flip_offset = get_flip_fold_offset(self);
4801 if (flip_offset == NULL)
4802 return -1;
4803 if (flip_offset != offset_self &&
4804 delta_cmp(flip_offset, offset_self))
4805 {
4806 result = 1;
4807 goto done;
4808 }
4809 Py_DECREF(flip_offset);
4810
4811 flip_offset = get_flip_fold_offset(other);
4812 if (flip_offset == NULL)
4813 return -1;
4814 if (flip_offset != offset_other &&
4815 delta_cmp(flip_offset, offset_other))
4816 result = 1;
4817 done:
4818 Py_DECREF(flip_offset);
4819 return result;
4820}
4821
4822static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004823datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004824{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004825 PyObject *result = NULL;
4826 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004827 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004829 if (! PyDateTime_Check(other)) {
4830 if (PyDate_Check(other)) {
4831 /* Prevent invocation of date_richcompare. We want to
4832 return NotImplemented here to give the other object
4833 a chance. But since DateTime is a subclass of
4834 Date, if the other object is a Date, it would
4835 compute an ordering based on the date part alone,
4836 and we don't want that. So force unequal or
4837 uncomparable here in that case. */
4838 if (op == Py_EQ)
4839 Py_RETURN_FALSE;
4840 if (op == Py_NE)
4841 Py_RETURN_TRUE;
4842 return cmperror(self, other);
4843 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004844 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004845 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004846
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004847 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004848 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4849 ((PyDateTime_DateTime *)other)->data,
4850 _PyDateTime_DATETIME_DATASIZE);
4851 return diff_to_bool(diff, op);
4852 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004853 offset1 = datetime_utcoffset(self, NULL);
4854 if (offset1 == NULL)
4855 return NULL;
4856 offset2 = datetime_utcoffset(other, NULL);
4857 if (offset2 == NULL)
4858 goto done;
4859 /* If they're both naive, or both aware and have the same offsets,
4860 * we get off cheap. Note that if they're both naive, offset1 ==
4861 * offset2 == Py_None at this point.
4862 */
4863 if ((offset1 == offset2) ||
4864 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4865 delta_cmp(offset1, offset2) == 0)) {
4866 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4867 ((PyDateTime_DateTime *)other)->data,
4868 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004869 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4870 int ex = pep495_eq_exception(self, other, offset1, offset2);
4871 if (ex == -1)
4872 goto done;
4873 if (ex)
4874 diff = 1;
4875 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004876 result = diff_to_bool(diff, op);
4877 }
4878 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004879 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004880
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004881 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4883 other);
4884 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004885 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004886 diff = GET_TD_DAYS(delta);
4887 if (diff == 0)
4888 diff = GET_TD_SECONDS(delta) |
4889 GET_TD_MICROSECONDS(delta);
4890 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004891 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4892 int ex = pep495_eq_exception(self, other, offset1, offset2);
4893 if (ex == -1)
4894 goto done;
4895 if (ex)
4896 diff = 1;
4897 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004898 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004899 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004900 else if (op == Py_EQ) {
4901 result = Py_False;
4902 Py_INCREF(result);
4903 }
4904 else if (op == Py_NE) {
4905 result = Py_True;
4906 Py_INCREF(result);
4907 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004908 else {
4909 PyErr_SetString(PyExc_TypeError,
4910 "can't compare offset-naive and "
4911 "offset-aware datetimes");
4912 }
4913 done:
4914 Py_DECREF(offset1);
4915 Py_XDECREF(offset2);
4916 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004917}
4918
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004919static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004920datetime_hash(PyDateTime_DateTime *self)
4921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004922 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004923 PyObject *offset, *self0;
4924 if (DATE_GET_FOLD(self)) {
4925 self0 = new_datetime_ex2(GET_YEAR(self),
4926 GET_MONTH(self),
4927 GET_DAY(self),
4928 DATE_GET_HOUR(self),
4929 DATE_GET_MINUTE(self),
4930 DATE_GET_SECOND(self),
4931 DATE_GET_MICROSECOND(self),
4932 HASTZINFO(self) ? self->tzinfo : Py_None,
4933 0, Py_TYPE(self));
4934 if (self0 == NULL)
4935 return -1;
4936 }
4937 else {
4938 self0 = (PyObject *)self;
4939 Py_INCREF(self0);
4940 }
4941 offset = datetime_utcoffset(self0, NULL);
4942 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004943
4944 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004945 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004947 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004948 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004949 self->hashcode = generic_hash(
4950 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004951 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004952 PyObject *temp1, *temp2;
4953 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004955 assert(HASTZINFO(self));
4956 days = ymd_to_ord(GET_YEAR(self),
4957 GET_MONTH(self),
4958 GET_DAY(self));
4959 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004960 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004961 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004962 temp1 = new_delta(days, seconds,
4963 DATE_GET_MICROSECOND(self),
4964 1);
4965 if (temp1 == NULL) {
4966 Py_DECREF(offset);
4967 return -1;
4968 }
4969 temp2 = delta_subtract(temp1, offset);
4970 Py_DECREF(temp1);
4971 if (temp2 == NULL) {
4972 Py_DECREF(offset);
4973 return -1;
4974 }
4975 self->hashcode = PyObject_Hash(temp2);
4976 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004977 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004978 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004979 }
4980 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004981}
Tim Peters2a799bf2002-12-16 20:18:38 +00004982
4983static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004984datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004985{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004986 PyObject *clone;
4987 PyObject *tuple;
4988 int y = GET_YEAR(self);
4989 int m = GET_MONTH(self);
4990 int d = GET_DAY(self);
4991 int hh = DATE_GET_HOUR(self);
4992 int mm = DATE_GET_MINUTE(self);
4993 int ss = DATE_GET_SECOND(self);
4994 int us = DATE_GET_MICROSECOND(self);
4995 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004996 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00004997
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004998 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004999 datetime_kws,
5000 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005001 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005002 return NULL;
5003 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5004 if (tuple == NULL)
5005 return NULL;
5006 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005007
5008 if (clone != NULL) {
5009 if (fold != 0 && fold != 1) {
5010 PyErr_SetString(PyExc_ValueError,
5011 "fold must be either 0 or 1");
5012 return NULL;
5013 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005014 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005015 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005016 Py_DECREF(tuple);
5017 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005018}
5019
5020static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005021local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005022{
5023 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005024 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005025 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005026 PyObject *nameo = NULL;
5027 const char *zone = NULL;
5028
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005029 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005030 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005031#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005032 zone = local_time_tm.tm_zone;
5033 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005034#else /* HAVE_STRUCT_TM_TM_ZONE */
5035 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005036 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005037 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005038 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005039 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005040 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005041 local_time = new_datetime(local_time_tm.tm_year + 1900,
5042 local_time_tm.tm_mon + 1,
5043 local_time_tm.tm_mday,
5044 local_time_tm.tm_hour,
5045 local_time_tm.tm_min,
5046 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005047 if (local_time == NULL) {
5048 return NULL;
5049 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005050 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005051 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005052 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5053 utc_time_tm.tm_mon + 1,
5054 utc_time_tm.tm_mday,
5055 utc_time_tm.tm_hour,
5056 utc_time_tm.tm_min,
5057 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005058 if (utc_time == NULL) {
5059 Py_DECREF(local_time);
5060 return NULL;
5061 }
5062 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005063 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005064 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005065 }
5066#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005067 if (delta == NULL) {
5068 return NULL;
5069 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005070 if (zone != NULL) {
5071 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5072 if (nameo == NULL)
5073 goto error;
5074 }
5075 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005076 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005077 error:
5078 Py_DECREF(delta);
5079 return result;
5080}
5081
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005082static PyObject *
5083local_timezone(PyDateTime_DateTime *utc_time)
5084{
5085 time_t timestamp;
5086 PyObject *delta;
5087 PyObject *one_second;
5088 PyObject *seconds;
5089
5090 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5091 if (delta == NULL)
5092 return NULL;
5093 one_second = new_delta(0, 1, 0, 0);
5094 if (one_second == NULL) {
5095 Py_DECREF(delta);
5096 return NULL;
5097 }
5098 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5099 (PyDateTime_Delta *)one_second);
5100 Py_DECREF(one_second);
5101 Py_DECREF(delta);
5102 if (seconds == NULL)
5103 return NULL;
5104 timestamp = _PyLong_AsTime_t(seconds);
5105 Py_DECREF(seconds);
5106 if (timestamp == -1 && PyErr_Occurred())
5107 return NULL;
5108 return local_timezone_from_timestamp(timestamp);
5109}
5110
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005111static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005112local_to_seconds(int year, int month, int day,
5113 int hour, int minute, int second, int fold);
5114
5115static PyObject *
5116local_timezone_from_local(PyDateTime_DateTime *local_dt)
5117{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005118 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005119 time_t timestamp;
5120 seconds = local_to_seconds(GET_YEAR(local_dt),
5121 GET_MONTH(local_dt),
5122 GET_DAY(local_dt),
5123 DATE_GET_HOUR(local_dt),
5124 DATE_GET_MINUTE(local_dt),
5125 DATE_GET_SECOND(local_dt),
5126 DATE_GET_FOLD(local_dt));
5127 if (seconds == -1)
5128 return NULL;
5129 /* XXX: add bounds check */
5130 timestamp = seconds - epoch;
5131 return local_timezone_from_timestamp(timestamp);
5132}
5133
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005134static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005135datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005136{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005137 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005138 PyObject *offset;
5139 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005140 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005141 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005142 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005143
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005144 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005145 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005146 return NULL;
5147
5148 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005149 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005150
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005151 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5152 self_tzinfo = local_timezone_from_local(self);
5153 if (self_tzinfo == NULL)
5154 return NULL;
5155 } else {
5156 self_tzinfo = self->tzinfo;
5157 Py_INCREF(self_tzinfo);
5158 }
Tim Peters521fc152002-12-31 17:36:56 +00005159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005160 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005161 if (self_tzinfo == tzinfo) {
5162 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005163 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005164 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005165 }
Tim Peters521fc152002-12-31 17:36:56 +00005166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005167 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005168 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5169 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005170 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005171 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005172 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005173 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5174 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005175 Py_DECREF(offset);
5176 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005177 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005178
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005179 /* Make sure result is aware and UTC. */
5180 if (!HASTZINFO(result)) {
5181 temp = (PyObject *)result;
5182 result = (PyDateTime_DateTime *)
5183 new_datetime_ex2(GET_YEAR(result),
5184 GET_MONTH(result),
5185 GET_DAY(result),
5186 DATE_GET_HOUR(result),
5187 DATE_GET_MINUTE(result),
5188 DATE_GET_SECOND(result),
5189 DATE_GET_MICROSECOND(result),
5190 PyDateTime_TimeZone_UTC,
5191 DATE_GET_FOLD(result),
5192 Py_TYPE(result));
5193 Py_DECREF(temp);
5194 if (result == NULL)
5195 return NULL;
5196 }
5197 else {
5198 /* Result is already aware - just replace tzinfo. */
5199 temp = result->tzinfo;
5200 result->tzinfo = PyDateTime_TimeZone_UTC;
5201 Py_INCREF(result->tzinfo);
5202 Py_DECREF(temp);
5203 }
5204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005205 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005206 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005207 if (tzinfo == Py_None) {
5208 tzinfo = local_timezone(result);
5209 if (tzinfo == NULL) {
5210 Py_DECREF(result);
5211 return NULL;
5212 }
5213 }
5214 else
5215 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005216 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005217 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005218
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005219 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005220 result = (PyDateTime_DateTime *)
5221 _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005222 Py_DECREF(temp);
5223
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005224 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005225}
5226
5227static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005228datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005230 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005232 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005233 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005234
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005235 dst = call_dst(self->tzinfo, (PyObject *)self);
5236 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005237 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005238
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005239 if (dst != Py_None)
5240 dstflag = delta_bool((PyDateTime_Delta *)dst);
5241 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005242 }
5243 return build_struct_time(GET_YEAR(self),
5244 GET_MONTH(self),
5245 GET_DAY(self),
5246 DATE_GET_HOUR(self),
5247 DATE_GET_MINUTE(self),
5248 DATE_GET_SECOND(self),
5249 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005250}
5251
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005252static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005253local_to_seconds(int year, int month, int day,
5254 int hour, int minute, int second, int fold)
5255{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005256 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005257 t = utc_to_seconds(year, month, day, hour, minute, second);
5258 /* Our goal is to solve t = local(u) for u. */
5259 lt = local(t);
5260 if (lt == -1)
5261 return -1;
5262 a = lt - t;
5263 u1 = t - a;
5264 t1 = local(u1);
5265 if (t1 == -1)
5266 return -1;
5267 if (t1 == t) {
5268 /* We found one solution, but it may not be the one we need.
5269 * Look for an earlier solution (if `fold` is 0), or a
5270 * later one (if `fold` is 1). */
5271 if (fold)
5272 u2 = u1 + max_fold_seconds;
5273 else
5274 u2 = u1 - max_fold_seconds;
5275 lt = local(u2);
5276 if (lt == -1)
5277 return -1;
5278 b = lt - u2;
5279 if (a == b)
5280 return u1;
5281 }
5282 else {
5283 b = t1 - u1;
5284 assert(a != b);
5285 }
5286 u2 = t - b;
5287 t2 = local(u2);
5288 if (t2 == -1)
5289 return -1;
5290 if (t2 == t)
5291 return u2;
5292 if (t1 == t)
5293 return u1;
5294 /* We have found both offsets a and b, but neither t - a nor t - b is
5295 * a solution. This means t is in the gap. */
5296 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5297}
5298
5299/* date(1970,1,1).toordinal() == 719163 */
5300#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5301
Tim Peters2a799bf2002-12-16 20:18:38 +00005302static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005303datetime_timestamp(PyDateTime_DateTime *self)
5304{
5305 PyObject *result;
5306
5307 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5308 PyObject *delta;
5309 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5310 if (delta == NULL)
5311 return NULL;
5312 result = delta_total_seconds(delta);
5313 Py_DECREF(delta);
5314 }
5315 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005316 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005317 seconds = local_to_seconds(GET_YEAR(self),
5318 GET_MONTH(self),
5319 GET_DAY(self),
5320 DATE_GET_HOUR(self),
5321 DATE_GET_MINUTE(self),
5322 DATE_GET_SECOND(self),
5323 DATE_GET_FOLD(self));
5324 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005325 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005326 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5327 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005328 }
5329 return result;
5330}
5331
5332static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005333datetime_getdate(PyDateTime_DateTime *self)
5334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005335 return new_date(GET_YEAR(self),
5336 GET_MONTH(self),
5337 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005338}
5339
5340static PyObject *
5341datetime_gettime(PyDateTime_DateTime *self)
5342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005343 return new_time(DATE_GET_HOUR(self),
5344 DATE_GET_MINUTE(self),
5345 DATE_GET_SECOND(self),
5346 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005347 Py_None,
5348 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005349}
5350
5351static PyObject *
5352datetime_gettimetz(PyDateTime_DateTime *self)
5353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005354 return new_time(DATE_GET_HOUR(self),
5355 DATE_GET_MINUTE(self),
5356 DATE_GET_SECOND(self),
5357 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005358 GET_DT_TZINFO(self),
5359 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005360}
5361
5362static PyObject *
5363datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005364{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005365 int y, m, d, hh, mm, ss;
5366 PyObject *tzinfo;
5367 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005368
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005369 tzinfo = GET_DT_TZINFO(self);
5370 if (tzinfo == Py_None) {
5371 utcself = self;
5372 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005373 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005374 else {
5375 PyObject *offset;
5376 offset = call_utcoffset(tzinfo, (PyObject *)self);
5377 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005378 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005379 if (offset == Py_None) {
5380 Py_DECREF(offset);
5381 utcself = self;
5382 Py_INCREF(utcself);
5383 }
5384 else {
5385 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5386 (PyDateTime_Delta *)offset, -1);
5387 Py_DECREF(offset);
5388 if (utcself == NULL)
5389 return NULL;
5390 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005391 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005392 y = GET_YEAR(utcself);
5393 m = GET_MONTH(utcself);
5394 d = GET_DAY(utcself);
5395 hh = DATE_GET_HOUR(utcself);
5396 mm = DATE_GET_MINUTE(utcself);
5397 ss = DATE_GET_SECOND(utcself);
5398
5399 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005400 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005401}
5402
Tim Peters371935f2003-02-01 01:52:50 +00005403/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005404
Tim Petersa9bc1682003-01-11 03:39:11 +00005405/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005406 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5407 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005408 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005409 */
5410static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005411datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005413 PyObject *basestate;
5414 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005416 basestate = PyBytes_FromStringAndSize((char *)self->data,
5417 _PyDateTime_DATETIME_DATASIZE);
5418 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005419 if (proto > 3 && DATE_GET_FOLD(self))
5420 /* Set the first bit of the third byte */
5421 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005422 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5423 result = PyTuple_Pack(1, basestate);
5424 else
5425 result = PyTuple_Pack(2, basestate, self->tzinfo);
5426 Py_DECREF(basestate);
5427 }
5428 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005429}
5430
5431static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005432datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005433{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005434 int proto;
5435 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005436 return NULL;
5437
5438 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005439}
5440
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005441static PyObject *
5442datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5443{
5444 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5445}
5446
Tim Petersa9bc1682003-01-11 03:39:11 +00005447static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005449 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005450
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005451 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005453 {"utcnow", (PyCFunction)datetime_utcnow,
5454 METH_NOARGS | METH_CLASS,
5455 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005457 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5458 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5459 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005461 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5462 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005463 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005465 {"strptime", (PyCFunction)datetime_strptime,
5466 METH_VARARGS | METH_CLASS,
5467 PyDoc_STR("string, format -> new datetime parsed from a string "
5468 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005470 {"combine", (PyCFunction)datetime_combine,
5471 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5472 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005474 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005476 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5477 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005478
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005479 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5480 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005482 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5483 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005485 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5486 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005488 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5489 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005490
Alexander Belopolskya4415142012-06-08 12:33:09 -04005491 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5492 PyDoc_STR("Return POSIX timestamp as float.")},
5493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005494 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5495 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005497 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5498 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005499 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005500 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005501 "defaults to 'T'.\n"
5502 "timespec specifies what components of the time to include"
5503 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5504 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005506 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5507 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005509 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5510 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005512 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5513 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005515 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5516 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005518 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5519 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005520
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005521 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005522 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005523
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005524 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5525 PyDoc_STR("__reduce__() -> (cls, state)")},
5526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005527 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005528};
5529
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005530static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005531PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5532\n\
5533The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005534instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005535
Tim Petersa9bc1682003-01-11 03:39:11 +00005536static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005537 datetime_add, /* nb_add */
5538 datetime_subtract, /* nb_subtract */
5539 0, /* nb_multiply */
5540 0, /* nb_remainder */
5541 0, /* nb_divmod */
5542 0, /* nb_power */
5543 0, /* nb_negative */
5544 0, /* nb_positive */
5545 0, /* nb_absolute */
5546 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005547};
5548
Neal Norwitz227b5332006-03-22 09:28:35 +00005549static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005550 PyVarObject_HEAD_INIT(NULL, 0)
5551 "datetime.datetime", /* tp_name */
5552 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5553 0, /* tp_itemsize */
5554 (destructor)datetime_dealloc, /* tp_dealloc */
5555 0, /* tp_print */
5556 0, /* tp_getattr */
5557 0, /* tp_setattr */
5558 0, /* tp_reserved */
5559 (reprfunc)datetime_repr, /* tp_repr */
5560 &datetime_as_number, /* tp_as_number */
5561 0, /* tp_as_sequence */
5562 0, /* tp_as_mapping */
5563 (hashfunc)datetime_hash, /* tp_hash */
5564 0, /* tp_call */
5565 (reprfunc)datetime_str, /* tp_str */
5566 PyObject_GenericGetAttr, /* tp_getattro */
5567 0, /* tp_setattro */
5568 0, /* tp_as_buffer */
5569 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5570 datetime_doc, /* tp_doc */
5571 0, /* tp_traverse */
5572 0, /* tp_clear */
5573 datetime_richcompare, /* tp_richcompare */
5574 0, /* tp_weaklistoffset */
5575 0, /* tp_iter */
5576 0, /* tp_iternext */
5577 datetime_methods, /* tp_methods */
5578 0, /* tp_members */
5579 datetime_getset, /* tp_getset */
5580 &PyDateTime_DateType, /* tp_base */
5581 0, /* tp_dict */
5582 0, /* tp_descr_get */
5583 0, /* tp_descr_set */
5584 0, /* tp_dictoffset */
5585 0, /* tp_init */
5586 datetime_alloc, /* tp_alloc */
5587 datetime_new, /* tp_new */
5588 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005589};
5590
5591/* ---------------------------------------------------------------------------
5592 * Module methods and initialization.
5593 */
5594
5595static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005596 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005597};
5598
Tim Peters9ddf40b2004-06-20 22:41:32 +00005599/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5600 * datetime.h.
5601 */
5602static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005603 &PyDateTime_DateType,
5604 &PyDateTime_DateTimeType,
5605 &PyDateTime_TimeType,
5606 &PyDateTime_DeltaType,
5607 &PyDateTime_TZInfoType,
5608 new_date_ex,
5609 new_datetime_ex,
5610 new_time_ex,
5611 new_delta_ex,
5612 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005613 date_fromtimestamp,
5614 new_datetime_ex2,
5615 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00005616};
5617
5618
Martin v. Löwis1a214512008-06-11 05:26:20 +00005619
5620static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005621 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005622 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005623 "Fast implementation of the datetime type.",
5624 -1,
5625 module_methods,
5626 NULL,
5627 NULL,
5628 NULL,
5629 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005630};
5631
Tim Peters2a799bf2002-12-16 20:18:38 +00005632PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005633PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005634{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005635 PyObject *m; /* a module object */
5636 PyObject *d; /* its dict */
5637 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005638 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005640 m = PyModule_Create(&datetimemodule);
5641 if (m == NULL)
5642 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005644 if (PyType_Ready(&PyDateTime_DateType) < 0)
5645 return NULL;
5646 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5647 return NULL;
5648 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5649 return NULL;
5650 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5651 return NULL;
5652 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5653 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005654 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5655 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005657 /* timedelta values */
5658 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005660 x = new_delta(0, 0, 1, 0);
5661 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5662 return NULL;
5663 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005665 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5666 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5667 return NULL;
5668 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005670 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5671 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5672 return NULL;
5673 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005675 /* date values */
5676 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005678 x = new_date(1, 1, 1);
5679 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5680 return NULL;
5681 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005683 x = new_date(MAXYEAR, 12, 31);
5684 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5685 return NULL;
5686 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005688 x = new_delta(1, 0, 0, 0);
5689 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5690 return NULL;
5691 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005693 /* time values */
5694 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005695
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005696 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005697 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5698 return NULL;
5699 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005700
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005701 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005702 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5703 return NULL;
5704 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005706 x = new_delta(0, 0, 1, 0);
5707 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5708 return NULL;
5709 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005711 /* datetime values */
5712 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005713
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005714 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005715 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5716 return NULL;
5717 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005718
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005719 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005720 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5721 return NULL;
5722 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005723
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005724 x = new_delta(0, 0, 1, 0);
5725 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5726 return NULL;
5727 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005728
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005729 /* timezone values */
5730 d = PyDateTime_TimeZoneType.tp_dict;
5731
5732 delta = new_delta(0, 0, 0, 0);
5733 if (delta == NULL)
5734 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005735 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005736 Py_DECREF(delta);
5737 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5738 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005739 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005740
5741 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
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, "min", x) < 0)
5747 return NULL;
5748 Py_DECREF(x);
5749
5750 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +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, "max", x) < 0)
5756 return NULL;
5757 Py_DECREF(x);
5758
Alexander Belopolskya4415142012-06-08 12:33:09 -04005759 /* Epoch */
5760 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005761 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005762 if (PyDateTime_Epoch == NULL)
5763 return NULL;
5764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005765 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005766 PyModule_AddIntMacro(m, MINYEAR);
5767 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005769 Py_INCREF(&PyDateTime_DateType);
5770 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005772 Py_INCREF(&PyDateTime_DateTimeType);
5773 PyModule_AddObject(m, "datetime",
5774 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005776 Py_INCREF(&PyDateTime_TimeType);
5777 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005779 Py_INCREF(&PyDateTime_DeltaType);
5780 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005782 Py_INCREF(&PyDateTime_TZInfoType);
5783 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005784
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005785 Py_INCREF(&PyDateTime_TimeZoneType);
5786 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005788 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5789 if (x == NULL)
5790 return NULL;
5791 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005793 /* A 4-year cycle has an extra leap day over what we'd get from
5794 * pasting together 4 single years.
5795 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005796 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005797 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005799 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5800 * get from pasting together 4 100-year cycles.
5801 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005802 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005803 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005805 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5806 * pasting together 25 4-year cycles.
5807 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005808 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005809 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005810
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005811 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005812 us_per_ms = PyLong_FromLong(1000);
5813 us_per_second = PyLong_FromLong(1000000);
5814 us_per_minute = PyLong_FromLong(60000000);
5815 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005816 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005817 us_per_minute == NULL || seconds_per_day == NULL)
5818 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005820 /* The rest are too big for 32-bit ints, but even
5821 * us_per_week fits in 40 bits, so doubles should be exact.
5822 */
5823 us_per_hour = PyLong_FromDouble(3600000000.0);
5824 us_per_day = PyLong_FromDouble(86400000000.0);
5825 us_per_week = PyLong_FromDouble(604800000000.0);
5826 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5827 return NULL;
5828 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005829}
Tim Petersf3615152003-01-01 21:51:37 +00005830
5831/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005832Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005833 x.n = x stripped of its timezone -- its naive time.
5834 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005835 return None
Tim Petersf3615152003-01-01 21:51:37 +00005836 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005837 return None
Tim Petersf3615152003-01-01 21:51:37 +00005838 x.s = x's standard offset, x.o - x.d
5839
5840Now some derived rules, where k is a duration (timedelta).
5841
58421. x.o = x.s + x.d
5843 This follows from the definition of x.s.
5844
Tim Petersc5dc4da2003-01-02 17:55:03 +000058452. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005846 This is actually a requirement, an assumption we need to make about
5847 sane tzinfo classes.
5848
58493. The naive UTC time corresponding to x is x.n - x.o.
5850 This is again a requirement for a sane tzinfo class.
5851
58524. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005853 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005854
Tim Petersc5dc4da2003-01-02 17:55:03 +000058555. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005856 Again follows from how arithmetic is defined.
5857
Tim Peters8bb5ad22003-01-24 02:44:45 +00005858Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005859(meaning that the various tzinfo methods exist, and don't blow up or return
5860None when called).
5861
Tim Petersa9bc1682003-01-11 03:39:11 +00005862The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005863x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005864
5865By #3, we want
5866
Tim Peters8bb5ad22003-01-24 02:44:45 +00005867 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005868
5869The algorithm starts by attaching tz to x.n, and calling that y. So
5870x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5871becomes true; in effect, we want to solve [2] for k:
5872
Tim Peters8bb5ad22003-01-24 02:44:45 +00005873 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005874
5875By #1, this is the same as
5876
Tim Peters8bb5ad22003-01-24 02:44:45 +00005877 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005878
5879By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5880Substituting that into [3],
5881
Tim Peters8bb5ad22003-01-24 02:44:45 +00005882 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5883 k - (y+k).s - (y+k).d = 0; rearranging,
5884 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5885 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005886
Tim Peters8bb5ad22003-01-24 02:44:45 +00005887On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5888approximate k by ignoring the (y+k).d term at first. Note that k can't be
5889very large, since all offset-returning methods return a duration of magnitude
5890less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5891be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005892
5893In any case, the new value is
5894
Tim Peters8bb5ad22003-01-24 02:44:45 +00005895 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005896
Tim Peters8bb5ad22003-01-24 02:44:45 +00005897It's helpful to step back at look at [4] from a higher level: it's simply
5898mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005899
5900At this point, if
5901
Tim Peters8bb5ad22003-01-24 02:44:45 +00005902 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005903
5904we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005905at the start of daylight time. Picture US Eastern for concreteness. The wall
5906time 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 +00005907sense then. The docs ask that an Eastern tzinfo class consider such a time to
5908be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5909on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005910the only spelling that makes sense on the local wall clock.
5911
Tim Petersc5dc4da2003-01-02 17:55:03 +00005912In fact, if [5] holds at this point, we do have the standard-time spelling,
5913but that takes a bit of proof. We first prove a stronger result. What's the
5914difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005915
Tim Peters8bb5ad22003-01-24 02:44:45 +00005916 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005917
Tim Petersc5dc4da2003-01-02 17:55:03 +00005918Now
5919 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005920 (y + y.s).n = by #5
5921 y.n + y.s = since y.n = x.n
5922 x.n + y.s = since z and y are have the same tzinfo member,
5923 y.s = z.s by #2
5924 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005925
Tim Petersc5dc4da2003-01-02 17:55:03 +00005926Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005927
Tim Petersc5dc4da2003-01-02 17:55:03 +00005928 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005929 x.n - ((x.n + z.s) - z.o) = expanding
5930 x.n - x.n - z.s + z.o = cancelling
5931 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005932 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005933
Tim Petersc5dc4da2003-01-02 17:55:03 +00005934So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005935
Tim Petersc5dc4da2003-01-02 17:55:03 +00005936If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005937spelling we wanted in the endcase described above. We're done. Contrarily,
5938if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005939
Tim Petersc5dc4da2003-01-02 17:55:03 +00005940If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5941add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005942local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005943
Tim Petersc5dc4da2003-01-02 17:55:03 +00005944Let
Tim Petersf3615152003-01-01 21:51:37 +00005945
Tim Peters4fede1a2003-01-04 00:26:59 +00005946 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005947
Tim Peters4fede1a2003-01-04 00:26:59 +00005948and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005949
Tim Peters8bb5ad22003-01-24 02:44:45 +00005950 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005951
Tim Peters8bb5ad22003-01-24 02:44:45 +00005952If so, we're done. If not, the tzinfo class is insane, according to the
5953assumptions we've made. This also requires a bit of proof. As before, let's
5954compute the difference between the LHS and RHS of [8] (and skipping some of
5955the justifications for the kinds of substitutions we've done several times
5956already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005957
Tim Peters8bb5ad22003-01-24 02:44:45 +00005958 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005959 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5960 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5961 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5962 - z.n + z.n - z.o + z'.o = cancel z.n
5963 - z.o + z'.o = #1 twice
5964 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5965 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005966
5967So 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 +00005968we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5969return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005970
Tim Peters8bb5ad22003-01-24 02:44:45 +00005971How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5972a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5973would have to change the result dst() returns: we start in DST, and moving
5974a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005975
Tim Peters8bb5ad22003-01-24 02:44:45 +00005976There isn't a sane case where this can happen. The closest it gets is at
5977the end of DST, where there's an hour in UTC with no spelling in a hybrid
5978tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5979that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5980UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5981time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5982clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5983standard time. Since that's what the local clock *does*, we want to map both
5984UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005985in local time, but so it goes -- it's the way the local clock works.
5986
Tim Peters8bb5ad22003-01-24 02:44:45 +00005987When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5988so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5989z' = 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 +00005990(correctly) concludes that z' is not UTC-equivalent to x.
5991
5992Because we know z.d said z was in daylight time (else [5] would have held and
5993we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005994and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005995return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5996but the reasoning doesn't depend on the example -- it depends on there being
5997two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005998z' must be in standard time, and is the spelling we want in this case.
5999
6000Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6001concerned (because it takes z' as being in standard time rather than the
6002daylight time we intend here), but returning it gives the real-life "local
6003clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6004tz.
6005
6006When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6007the 1:MM standard time spelling we want.
6008
6009So how can this break? One of the assumptions must be violated. Two
6010possibilities:
6011
60121) [2] effectively says that y.s is invariant across all y belong to a given
6013 time zone. This isn't true if, for political reasons or continental drift,
6014 a region decides to change its base offset from UTC.
6015
60162) There may be versions of "double daylight" time where the tail end of
6017 the analysis gives up a step too early. I haven't thought about that
6018 enough to say.
6019
6020In any case, it's clear that the default fromutc() is strong enough to handle
6021"almost all" time zones: so long as the standard offset is invariant, it
6022doesn't matter if daylight time transition points change from year to year, or
6023if daylight time is skipped in some years; it doesn't matter how large or
6024small dst() may get within its bounds; and it doesn't even matter if some
6025perverse time zone returns a negative dst()). So a breaking case must be
6026pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006027--------------------------------------------------------------------------- */