blob: 205b15bb182f69cd519f6a4f954cdeed8ccd06df [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
Victor Stinner20401de2016-12-09 15:24:31 +0100990 result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname,
991 tzinfoarg, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +0000992
993 if (result == NULL || result == Py_None)
994 return result;
995
996 if (!PyUnicode_Check(result)) {
997 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
998 "return None or a string, not '%s'",
999 Py_TYPE(result)->tp_name);
1000 Py_DECREF(result);
1001 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001002 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001003
1004 return result;
Tim Peters00237032002-12-27 02:21:51 +00001005}
1006
Tim Peters2a799bf2002-12-16 20:18:38 +00001007/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1008 * stuff
1009 * ", tzinfo=" + repr(tzinfo)
1010 * before the closing ")".
1011 */
1012static PyObject *
1013append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1014{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 assert(PyUnicode_Check(repr));
1018 assert(tzinfo);
1019 if (tzinfo == Py_None)
1020 return repr;
1021 /* Get rid of the trailing ')'. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001022 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1023 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 Py_DECREF(repr);
1025 if (temp == NULL)
1026 return NULL;
1027 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1028 Py_DECREF(temp);
1029 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001030}
1031
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001032/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1033 * stuff
1034 * ", fold=" + repr(tzinfo)
1035 * before the closing ")".
1036 */
1037static PyObject *
1038append_keyword_fold(PyObject *repr, int fold)
1039{
1040 PyObject *temp;
1041
1042 assert(PyUnicode_Check(repr));
1043 if (fold == 0)
1044 return repr;
1045 /* Get rid of the trailing ')'. */
1046 assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1047 temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1048 Py_DECREF(repr);
1049 if (temp == NULL)
1050 return NULL;
1051 repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1052 Py_DECREF(temp);
1053 return repr;
1054}
1055
Tim Peters2a799bf2002-12-16 20:18:38 +00001056/* ---------------------------------------------------------------------------
1057 * String format helpers.
1058 */
1059
1060static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001061format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001062{
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001063 static const char * const DayNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1065 };
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001066 static const char * const MonthNames[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1068 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1069 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1074 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1075 GET_DAY(date), hours, minutes, seconds,
1076 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001077}
1078
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001079static PyObject *delta_negative(PyDateTime_Delta *self);
1080
Tim Peters2a799bf2002-12-16 20:18:38 +00001081/* Add an hours & minutes UTC offset string to buf. buf has no more than
1082 * buflen bytes remaining. The UTC offset is gotten by calling
1083 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1084 * *buf, and that's all. Else the returned value is checked for sanity (an
1085 * integer in range), and if that's OK it's converted to an hours & minutes
1086 * string of the form
1087 * sign HH sep MM
1088 * Returns 0 if everything is OK. If the return value from utcoffset() is
1089 * bogus, an appropriate exception is set and -1 is returned.
1090 */
1091static int
Tim Peters328fff72002-12-20 01:31:27 +00001092format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001094{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001095 PyObject *offset;
1096 int hours, minutes, seconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 char sign;
Tim Peters2a799bf2002-12-16 20:18:38 +00001098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001100
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001101 offset = call_utcoffset(tzinfo, tzinfoarg);
1102 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 return -1;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001104 if (offset == Py_None) {
1105 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 *buf = '\0';
1107 return 0;
1108 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001109 /* Offset is normalized, so it is negative if days < 0 */
1110 if (GET_TD_DAYS(offset) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 sign = '-';
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03001112 Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001113 if (offset == NULL)
1114 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001116 else {
1117 sign = '+';
1118 }
1119 /* Offset is not negative here. */
1120 seconds = GET_TD_SECONDS(offset);
1121 Py_DECREF(offset);
1122 minutes = divmod(seconds, 60, &seconds);
1123 hours = divmod(minutes, 60, &minutes);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04001124 if (seconds == 0)
1125 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1126 else
1127 PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1128 sep, minutes, sep, seconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001130}
1131
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001132static PyObject *
1133make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 PyObject *temp;
1136 PyObject *tzinfo = get_tzinfo_member(object);
1137 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001138 _Py_IDENTIFIER(replace);
Victor Stinner9e30aa52011-11-21 02:49:52 +01001139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 if (Zreplacement == NULL)
1141 return NULL;
1142 if (tzinfo == Py_None || tzinfo == NULL)
1143 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 assert(tzinfoarg != NULL);
1146 temp = call_tzname(tzinfo, tzinfoarg);
1147 if (temp == NULL)
1148 goto Error;
1149 if (temp == Py_None) {
1150 Py_DECREF(temp);
1151 return Zreplacement;
1152 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 assert(PyUnicode_Check(temp));
1155 /* Since the tzname is getting stuffed into the
1156 * format, we have to double any % signs so that
1157 * strftime doesn't treat them as format codes.
1158 */
1159 Py_DECREF(Zreplacement);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001160 Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 Py_DECREF(temp);
1162 if (Zreplacement == NULL)
1163 return NULL;
1164 if (!PyUnicode_Check(Zreplacement)) {
1165 PyErr_SetString(PyExc_TypeError,
1166 "tzname.replace() did not return a string");
1167 goto Error;
1168 }
1169 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001170
1171 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 Py_DECREF(Zreplacement);
1173 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001174}
1175
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001176static PyObject *
1177make_freplacement(PyObject *object)
1178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 char freplacement[64];
1180 if (PyTime_Check(object))
1181 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1182 else if (PyDateTime_Check(object))
1183 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1184 else
1185 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001188}
1189
Tim Peters2a799bf2002-12-16 20:18:38 +00001190/* I sure don't want to reproduce the strftime code from the time module,
1191 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001192 * giving special meanings to the %z, %Z and %f format codes via a
1193 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001194 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1195 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001196 */
1197static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001198wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1204 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1205 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 const char *pin; /* pointer to next char in input format */
1208 Py_ssize_t flen; /* length of input format */
1209 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 PyObject *newfmt = NULL; /* py string, the output format */
1212 char *pnew; /* pointer to available byte in output format */
1213 size_t totalnew; /* number bytes total in output format buffer,
1214 exclusive of trailing \0 */
1215 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 const char *ptoappend; /* ptr to string to append to output buffer */
1218 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 assert(object && format && timetuple);
1221 assert(PyUnicode_Check(format));
1222 /* Convert the input format to a C string and size */
Serhiy Storchaka06515832016-11-20 09:13:07 +02001223 pin = PyUnicode_AsUTF8AndSize(format, &flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 if (!pin)
1225 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 /* Scan the input format, looking for %z/%Z/%f escapes, building
1228 * a new format. Since computing the replacements for those codes
1229 * is expensive, don't unless they're actually used.
1230 */
1231 if (flen > INT_MAX - 1) {
1232 PyErr_NoMemory();
1233 goto Done;
1234 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 totalnew = flen + 1; /* realistic if no %z/%Z */
1237 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1238 if (newfmt == NULL) goto Done;
1239 pnew = PyBytes_AsString(newfmt);
1240 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 while ((ch = *pin++) != '\0') {
1243 if (ch != '%') {
1244 ptoappend = pin - 1;
1245 ntoappend = 1;
1246 }
1247 else if ((ch = *pin++) == '\0') {
1248 /* There's a lone trailing %; doesn't make sense. */
1249 PyErr_SetString(PyExc_ValueError, "strftime format "
1250 "ends with raw %");
1251 goto Done;
1252 }
1253 /* A % has been seen and ch is the character after it. */
1254 else if (ch == 'z') {
1255 if (zreplacement == NULL) {
1256 /* format utcoffset */
1257 char buf[100];
1258 PyObject *tzinfo = get_tzinfo_member(object);
1259 zreplacement = PyBytes_FromStringAndSize("", 0);
1260 if (zreplacement == NULL) goto Done;
1261 if (tzinfo != Py_None && tzinfo != NULL) {
1262 assert(tzinfoarg != NULL);
1263 if (format_utcoffset(buf,
1264 sizeof(buf),
1265 "",
1266 tzinfo,
1267 tzinfoarg) < 0)
1268 goto Done;
1269 Py_DECREF(zreplacement);
1270 zreplacement =
1271 PyBytes_FromStringAndSize(buf,
1272 strlen(buf));
1273 if (zreplacement == NULL)
1274 goto Done;
1275 }
1276 }
1277 assert(zreplacement != NULL);
1278 ptoappend = PyBytes_AS_STRING(zreplacement);
1279 ntoappend = PyBytes_GET_SIZE(zreplacement);
1280 }
1281 else if (ch == 'Z') {
1282 /* format tzname */
1283 if (Zreplacement == NULL) {
1284 Zreplacement = make_Zreplacement(object,
1285 tzinfoarg);
1286 if (Zreplacement == NULL)
1287 goto Done;
1288 }
1289 assert(Zreplacement != NULL);
1290 assert(PyUnicode_Check(Zreplacement));
Serhiy Storchaka06515832016-11-20 09:13:07 +02001291 ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 &ntoappend);
Alexander Belopolskye239d232010-12-08 23:31:48 +00001293 if (ptoappend == NULL)
1294 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 }
1296 else if (ch == 'f') {
1297 /* format microseconds */
1298 if (freplacement == NULL) {
1299 freplacement = make_freplacement(object);
1300 if (freplacement == NULL)
1301 goto Done;
1302 }
1303 assert(freplacement != NULL);
1304 assert(PyBytes_Check(freplacement));
1305 ptoappend = PyBytes_AS_STRING(freplacement);
1306 ntoappend = PyBytes_GET_SIZE(freplacement);
1307 }
1308 else {
1309 /* percent followed by neither z nor Z */
1310 ptoappend = pin - 2;
1311 ntoappend = 2;
1312 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 /* Append the ntoappend chars starting at ptoappend to
1315 * the new format.
1316 */
1317 if (ntoappend == 0)
1318 continue;
1319 assert(ptoappend != NULL);
1320 assert(ntoappend > 0);
1321 while (usednew + ntoappend > totalnew) {
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001322 if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 PyErr_NoMemory();
1324 goto Done;
1325 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001326 totalnew <<= 1;
1327 if (_PyBytes_Resize(&newfmt, totalnew) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 goto Done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 pnew = PyBytes_AsString(newfmt) + usednew;
1330 }
1331 memcpy(pnew, ptoappend, ntoappend);
1332 pnew += ntoappend;
1333 usednew += ntoappend;
1334 assert(usednew <= totalnew);
1335 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1338 goto Done;
1339 {
1340 PyObject *format;
1341 PyObject *time = PyImport_ImportModuleNoBlock("time");
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 if (time == NULL)
1344 goto Done;
1345 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1346 if (format != NULL) {
Victor Stinner20401de2016-12-09 15:24:31 +01001347 result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1348 format, timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 Py_DECREF(format);
1350 }
1351 Py_DECREF(time);
1352 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001353 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 Py_XDECREF(freplacement);
1355 Py_XDECREF(zreplacement);
1356 Py_XDECREF(Zreplacement);
1357 Py_XDECREF(newfmt);
1358 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001359}
1360
Tim Peters2a799bf2002-12-16 20:18:38 +00001361/* ---------------------------------------------------------------------------
1362 * Wrap functions from the time module. These aren't directly available
1363 * from C. Perhaps they should be.
1364 */
1365
1366/* Call time.time() and return its result (a Python float). */
1367static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001368time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 PyObject *result = NULL;
1371 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 if (time != NULL) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001374 _Py_IDENTIFIER(time);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001375
Victor Stinnerad8c83a2016-09-05 17:53:15 -07001376 result = _PyObject_CallMethodId(time, &PyId_time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 Py_DECREF(time);
1378 }
1379 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001380}
1381
1382/* Build a time.struct_time. The weekday and day number are automatically
1383 * computed from the y,m,d args.
1384 */
1385static PyObject *
1386build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 PyObject *time;
Victor Stinner2b635972016-12-09 00:38:16 +01001389 PyObject *result;
1390 _Py_IDENTIFIER(struct_time);
1391 PyObject *args;
1392
Tim Peters2a799bf2002-12-16 20:18:38 +00001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 time = PyImport_ImportModuleNoBlock("time");
Victor Stinner2b635972016-12-09 00:38:16 +01001395 if (time == NULL) {
1396 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 }
Victor Stinner2b635972016-12-09 00:38:16 +01001398
1399 args = Py_BuildValue("iiiiiiiii",
1400 y, m, d,
1401 hh, mm, ss,
1402 weekday(y, m, d),
1403 days_before_month(y, m) + d,
1404 dstflag);
1405 if (args == NULL) {
1406 Py_DECREF(time);
1407 return NULL;
1408 }
1409
1410 result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1411 args, NULL);
1412 Py_DECREF(time);
Victor Stinnerddc120f2016-12-09 15:35:40 +01001413 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001415}
1416
1417/* ---------------------------------------------------------------------------
1418 * Miscellaneous helpers.
1419 */
1420
Mark Dickinsone94c6792009-02-02 20:36:42 +00001421/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001422 * The comparisons here all most naturally compute a cmp()-like result.
1423 * This little helper turns that into a bool result for rich comparisons.
1424 */
1425static PyObject *
1426diff_to_bool(int diff, int op)
1427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 PyObject *result;
1429 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 switch (op) {
1432 case Py_EQ: istrue = diff == 0; break;
1433 case Py_NE: istrue = diff != 0; break;
1434 case Py_LE: istrue = diff <= 0; break;
1435 case Py_GE: istrue = diff >= 0; break;
1436 case Py_LT: istrue = diff < 0; break;
1437 case Py_GT: istrue = diff > 0; break;
1438 default:
1439 assert(! "op unknown");
1440 istrue = 0; /* To shut up compiler */
1441 }
1442 result = istrue ? Py_True : Py_False;
1443 Py_INCREF(result);
1444 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001445}
1446
Tim Peters07534a62003-02-07 22:50:28 +00001447/* Raises a "can't compare" TypeError and returns NULL. */
1448static PyObject *
1449cmperror(PyObject *a, PyObject *b)
1450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 PyErr_Format(PyExc_TypeError,
1452 "can't compare %s to %s",
1453 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1454 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001455}
1456
Tim Peters2a799bf2002-12-16 20:18:38 +00001457/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001458 * Cached Python objects; these are set by the module init function.
1459 */
1460
1461/* Conversion factors. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04001462static PyObject *one = NULL; /* 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463static PyObject *us_per_ms = NULL; /* 1000 */
1464static PyObject *us_per_second = NULL; /* 1000000 */
1465static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
Serhiy Storchaka95949422013-08-27 19:40:23 +03001466static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1467static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1468static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
Tim Peters2a799bf2002-12-16 20:18:38 +00001469static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1470
Tim Peters2a799bf2002-12-16 20:18:38 +00001471/* ---------------------------------------------------------------------------
1472 * Class implementations.
1473 */
1474
1475/*
1476 * PyDateTime_Delta implementation.
1477 */
1478
1479/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Serhiy Storchaka95949422013-08-27 19:40:23 +03001481 * as a Python int.
Tim Peters2a799bf2002-12-16 20:18:38 +00001482 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1483 * due to ubiquitous overflow possibilities.
1484 */
1485static PyObject *
1486delta_to_microseconds(PyDateTime_Delta *self)
1487{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 PyObject *x1 = NULL;
1489 PyObject *x2 = NULL;
1490 PyObject *x3 = NULL;
1491 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1494 if (x1 == NULL)
1495 goto Done;
1496 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1497 if (x2 == NULL)
1498 goto Done;
1499 Py_DECREF(x1);
1500 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 /* x2 has days in seconds */
1503 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1504 if (x1 == NULL)
1505 goto Done;
1506 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1507 if (x3 == NULL)
1508 goto Done;
1509 Py_DECREF(x1);
1510 Py_DECREF(x2);
Brett Cannonb94767f2011-02-22 20:15:44 +00001511 /* x1 = */ x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 /* x3 has days+seconds in seconds */
1514 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1515 if (x1 == NULL)
1516 goto Done;
1517 Py_DECREF(x3);
1518 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 /* x1 has days+seconds in us */
1521 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1522 if (x2 == NULL)
1523 goto Done;
1524 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001525
1526Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 Py_XDECREF(x1);
1528 Py_XDECREF(x2);
1529 Py_XDECREF(x3);
1530 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001531}
1532
Serhiy Storchaka95949422013-08-27 19:40:23 +03001533/* Convert a number of us (as a Python int) to a timedelta.
Tim Peters2a799bf2002-12-16 20:18:38 +00001534 */
1535static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001536microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 int us;
1539 int s;
1540 int d;
1541 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 PyObject *tuple = NULL;
1544 PyObject *num = NULL;
1545 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 tuple = PyNumber_Divmod(pyus, us_per_second);
1548 if (tuple == NULL)
1549 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 num = PyTuple_GetItem(tuple, 1); /* us */
1552 if (num == NULL)
1553 goto Done;
1554 temp = PyLong_AsLong(num);
1555 num = NULL;
1556 if (temp == -1 && PyErr_Occurred())
1557 goto Done;
1558 assert(0 <= temp && temp < 1000000);
1559 us = (int)temp;
1560 if (us < 0) {
1561 /* The divisor was positive, so this must be an error. */
1562 assert(PyErr_Occurred());
1563 goto Done;
1564 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1567 if (num == NULL)
1568 goto Done;
1569 Py_INCREF(num);
1570 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 tuple = PyNumber_Divmod(num, seconds_per_day);
1573 if (tuple == NULL)
1574 goto Done;
1575 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 num = PyTuple_GetItem(tuple, 1); /* seconds */
1578 if (num == NULL)
1579 goto Done;
1580 temp = PyLong_AsLong(num);
1581 num = NULL;
1582 if (temp == -1 && PyErr_Occurred())
1583 goto Done;
1584 assert(0 <= temp && temp < 24*3600);
1585 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001587 if (s < 0) {
1588 /* The divisor was positive, so this must be an error. */
1589 assert(PyErr_Occurred());
1590 goto Done;
1591 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1594 if (num == NULL)
1595 goto Done;
1596 Py_INCREF(num);
1597 temp = PyLong_AsLong(num);
1598 if (temp == -1 && PyErr_Occurred())
1599 goto Done;
1600 d = (int)temp;
1601 if ((long)d != temp) {
1602 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1603 "large to fit in a C int");
1604 goto Done;
1605 }
1606 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001607
1608Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001609 Py_XDECREF(tuple);
1610 Py_XDECREF(num);
1611 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001612}
1613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614#define microseconds_to_delta(pymicros) \
1615 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001616
Tim Peters2a799bf2002-12-16 20:18:38 +00001617static PyObject *
1618multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 PyObject *pyus_in;
1621 PyObject *pyus_out;
1622 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 pyus_in = delta_to_microseconds(delta);
1625 if (pyus_in == NULL)
1626 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1629 Py_DECREF(pyus_in);
1630 if (pyus_out == NULL)
1631 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 result = microseconds_to_delta(pyus_out);
1634 Py_DECREF(pyus_out);
1635 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001636}
1637
1638static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001639multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1640{
1641 PyObject *result = NULL;
1642 PyObject *pyus_in = NULL, *temp, *pyus_out;
1643 PyObject *ratio = NULL;
1644
1645 pyus_in = delta_to_microseconds(delta);
1646 if (pyus_in == NULL)
1647 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001648 ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001649 if (ratio == NULL)
1650 goto error;
1651 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1652 Py_DECREF(pyus_in);
1653 pyus_in = NULL;
1654 if (temp == NULL)
1655 goto error;
1656 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1657 Py_DECREF(temp);
1658 if (pyus_out == NULL)
1659 goto error;
1660 result = microseconds_to_delta(pyus_out);
1661 Py_DECREF(pyus_out);
1662 error:
1663 Py_XDECREF(pyus_in);
1664 Py_XDECREF(ratio);
1665
1666 return result;
1667}
1668
1669static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001670divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1671{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001672 PyObject *pyus_in;
1673 PyObject *pyus_out;
1674 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 pyus_in = delta_to_microseconds(delta);
1677 if (pyus_in == NULL)
1678 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1681 Py_DECREF(pyus_in);
1682 if (pyus_out == NULL)
1683 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 result = microseconds_to_delta(pyus_out);
1686 Py_DECREF(pyus_out);
1687 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001688}
1689
1690static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001691divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1692{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693 PyObject *pyus_left;
1694 PyObject *pyus_right;
1695 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 pyus_left = delta_to_microseconds(left);
1698 if (pyus_left == NULL)
1699 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 pyus_right = delta_to_microseconds(right);
1702 if (pyus_right == NULL) {
1703 Py_DECREF(pyus_left);
1704 return NULL;
1705 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001707 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1708 Py_DECREF(pyus_left);
1709 Py_DECREF(pyus_right);
1710 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001711}
1712
1713static PyObject *
1714truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 PyObject *pyus_left;
1717 PyObject *pyus_right;
1718 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 pyus_left = delta_to_microseconds(left);
1721 if (pyus_left == NULL)
1722 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001723
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 pyus_right = delta_to_microseconds(right);
1725 if (pyus_right == NULL) {
1726 Py_DECREF(pyus_left);
1727 return NULL;
1728 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001729
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1731 Py_DECREF(pyus_left);
1732 Py_DECREF(pyus_right);
1733 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001734}
1735
1736static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001737truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1738{
1739 PyObject *result = NULL;
1740 PyObject *pyus_in = NULL, *temp, *pyus_out;
1741 PyObject *ratio = NULL;
1742
1743 pyus_in = delta_to_microseconds(delta);
1744 if (pyus_in == NULL)
1745 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001746 ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001747 if (ratio == NULL)
1748 goto error;
1749 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1750 Py_DECREF(pyus_in);
1751 pyus_in = NULL;
1752 if (temp == NULL)
1753 goto error;
1754 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1755 Py_DECREF(temp);
1756 if (pyus_out == NULL)
1757 goto error;
1758 result = microseconds_to_delta(pyus_out);
1759 Py_DECREF(pyus_out);
1760 error:
1761 Py_XDECREF(pyus_in);
1762 Py_XDECREF(ratio);
1763
1764 return result;
1765}
1766
1767static PyObject *
1768truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1769{
1770 PyObject *result;
1771 PyObject *pyus_in, *pyus_out;
1772 pyus_in = delta_to_microseconds(delta);
1773 if (pyus_in == NULL)
1774 return NULL;
1775 pyus_out = divide_nearest(pyus_in, i);
1776 Py_DECREF(pyus_in);
1777 if (pyus_out == NULL)
1778 return NULL;
1779 result = microseconds_to_delta(pyus_out);
1780 Py_DECREF(pyus_out);
1781
1782 return result;
1783}
1784
1785static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001786delta_add(PyObject *left, PyObject *right)
1787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1791 /* delta + delta */
1792 /* The C-level additions can't overflow because of the
1793 * invariant bounds.
1794 */
1795 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1796 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1797 int microseconds = GET_TD_MICROSECONDS(left) +
1798 GET_TD_MICROSECONDS(right);
1799 result = new_delta(days, seconds, microseconds, 1);
1800 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 if (result == Py_NotImplemented)
1803 Py_INCREF(result);
1804 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001805}
1806
1807static PyObject *
1808delta_negative(PyDateTime_Delta *self)
1809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 return new_delta(-GET_TD_DAYS(self),
1811 -GET_TD_SECONDS(self),
1812 -GET_TD_MICROSECONDS(self),
1813 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001814}
1815
1816static PyObject *
1817delta_positive(PyDateTime_Delta *self)
1818{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 /* Could optimize this (by returning self) if this isn't a
1820 * subclass -- but who uses unary + ? Approximately nobody.
1821 */
1822 return new_delta(GET_TD_DAYS(self),
1823 GET_TD_SECONDS(self),
1824 GET_TD_MICROSECONDS(self),
1825 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001826}
1827
1828static PyObject *
1829delta_abs(PyDateTime_Delta *self)
1830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001831 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 assert(GET_TD_MICROSECONDS(self) >= 0);
1834 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 if (GET_TD_DAYS(self) < 0)
1837 result = delta_negative(self);
1838 else
1839 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001842}
1843
1844static PyObject *
1845delta_subtract(PyObject *left, PyObject *right)
1846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1850 /* delta - delta */
Alexander Belopolskyb6f5ec72011-04-05 20:07:38 -04001851 /* The C-level additions can't overflow because of the
1852 * invariant bounds.
1853 */
1854 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1855 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1856 int microseconds = GET_TD_MICROSECONDS(left) -
1857 GET_TD_MICROSECONDS(right);
1858 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 if (result == Py_NotImplemented)
1862 Py_INCREF(result);
1863 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001864}
1865
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001866static int
1867delta_cmp(PyObject *self, PyObject *other)
1868{
1869 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1870 if (diff == 0) {
1871 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1872 if (diff == 0)
1873 diff = GET_TD_MICROSECONDS(self) -
1874 GET_TD_MICROSECONDS(other);
1875 }
1876 return diff;
1877}
1878
Tim Peters2a799bf2002-12-16 20:18:38 +00001879static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001880delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001881{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001882 if (PyDelta_Check(other)) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00001883 int diff = delta_cmp(self, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 return diff_to_bool(diff, op);
1885 }
1886 else {
Brian Curtindfc80e32011-08-10 20:28:54 -05001887 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001889}
1890
1891static PyObject *delta_getstate(PyDateTime_Delta *self);
1892
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001893static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00001894delta_hash(PyDateTime_Delta *self)
1895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 if (self->hashcode == -1) {
1897 PyObject *temp = delta_getstate(self);
1898 if (temp != NULL) {
1899 self->hashcode = PyObject_Hash(temp);
1900 Py_DECREF(temp);
1901 }
1902 }
1903 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001904}
1905
1906static PyObject *
1907delta_multiply(PyObject *left, PyObject *right)
1908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (PyDelta_Check(left)) {
1912 /* delta * ??? */
1913 if (PyLong_Check(right))
1914 result = multiply_int_timedelta(right,
1915 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001916 else if (PyFloat_Check(right))
1917 result = multiply_float_timedelta(right,
1918 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 }
1920 else if (PyLong_Check(left))
1921 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001922 (PyDateTime_Delta *) right);
1923 else if (PyFloat_Check(left))
1924 result = multiply_float_timedelta(left,
1925 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 if (result == Py_NotImplemented)
1928 Py_INCREF(result);
1929 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001930}
1931
1932static PyObject *
1933delta_divide(PyObject *left, PyObject *right)
1934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 if (PyDelta_Check(left)) {
1938 /* delta * ??? */
1939 if (PyLong_Check(right))
1940 result = divide_timedelta_int(
1941 (PyDateTime_Delta *)left,
1942 right);
1943 else if (PyDelta_Check(right))
1944 result = divide_timedelta_timedelta(
1945 (PyDateTime_Delta *)left,
1946 (PyDateTime_Delta *)right);
1947 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 if (result == Py_NotImplemented)
1950 Py_INCREF(result);
1951 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001952}
1953
Mark Dickinson7c186e22010-04-20 22:32:49 +00001954static PyObject *
1955delta_truedivide(PyObject *left, PyObject *right)
1956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 if (PyDelta_Check(left)) {
1960 if (PyDelta_Check(right))
1961 result = truedivide_timedelta_timedelta(
1962 (PyDateTime_Delta *)left,
1963 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001964 else if (PyFloat_Check(right))
1965 result = truedivide_timedelta_float(
1966 (PyDateTime_Delta *)left, right);
1967 else if (PyLong_Check(right))
1968 result = truedivide_timedelta_int(
1969 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 if (result == Py_NotImplemented)
1973 Py_INCREF(result);
1974 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001975}
1976
1977static PyObject *
1978delta_remainder(PyObject *left, PyObject *right)
1979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 PyObject *pyus_left;
1981 PyObject *pyus_right;
1982 PyObject *pyus_remainder;
1983 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001984
Brian Curtindfc80e32011-08-10 20:28:54 -05001985 if (!PyDelta_Check(left) || !PyDelta_Check(right))
1986 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
1989 if (pyus_left == NULL)
1990 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
1993 if (pyus_right == NULL) {
1994 Py_DECREF(pyus_left);
1995 return NULL;
1996 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
1999 Py_DECREF(pyus_left);
2000 Py_DECREF(pyus_right);
2001 if (pyus_remainder == NULL)
2002 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 remainder = microseconds_to_delta(pyus_remainder);
2005 Py_DECREF(pyus_remainder);
2006 if (remainder == NULL)
2007 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002010}
2011
2012static PyObject *
2013delta_divmod(PyObject *left, PyObject *right)
2014{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 PyObject *pyus_left;
2016 PyObject *pyus_right;
2017 PyObject *divmod;
2018 PyObject *delta;
2019 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002020
Brian Curtindfc80e32011-08-10 20:28:54 -05002021 if (!PyDelta_Check(left) || !PyDelta_Check(right))
2022 Py_RETURN_NOTIMPLEMENTED;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2025 if (pyus_left == NULL)
2026 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2029 if (pyus_right == NULL) {
2030 Py_DECREF(pyus_left);
2031 return NULL;
2032 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2035 Py_DECREF(pyus_left);
2036 Py_DECREF(pyus_right);
2037 if (divmod == NULL)
2038 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 assert(PyTuple_Size(divmod) == 2);
2041 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2042 if (delta == NULL) {
2043 Py_DECREF(divmod);
2044 return NULL;
2045 }
2046 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2047 Py_DECREF(delta);
2048 Py_DECREF(divmod);
2049 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002050}
2051
Tim Peters2a799bf2002-12-16 20:18:38 +00002052/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2053 * timedelta constructor. sofar is the # of microseconds accounted for
2054 * so far, and there are factor microseconds per current unit, the number
2055 * of which is given by num. num * factor is added to sofar in a
2056 * numerically careful way, and that's the result. Any fractional
2057 * microseconds left over (this can happen if num is a float type) are
2058 * added into *leftover.
2059 * Note that there are many ways this can give an error (NULL) return.
2060 */
2061static PyObject *
2062accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2063 double *leftover)
2064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 PyObject *prod;
2066 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 if (PyLong_Check(num)) {
2071 prod = PyNumber_Multiply(num, factor);
2072 if (prod == NULL)
2073 return NULL;
2074 sum = PyNumber_Add(sofar, prod);
2075 Py_DECREF(prod);
2076 return sum;
2077 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002079 if (PyFloat_Check(num)) {
2080 double dnum;
2081 double fracpart;
2082 double intpart;
2083 PyObject *x;
2084 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002086 /* The Plan: decompose num into an integer part and a
2087 * fractional part, num = intpart + fracpart.
2088 * Then num * factor ==
2089 * intpart * factor + fracpart * factor
2090 * and the LHS can be computed exactly in long arithmetic.
2091 * The RHS is again broken into an int part and frac part.
2092 * and the frac part is added into *leftover.
2093 */
2094 dnum = PyFloat_AsDouble(num);
2095 if (dnum == -1.0 && PyErr_Occurred())
2096 return NULL;
2097 fracpart = modf(dnum, &intpart);
2098 x = PyLong_FromDouble(intpart);
2099 if (x == NULL)
2100 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002102 prod = PyNumber_Multiply(x, factor);
2103 Py_DECREF(x);
2104 if (prod == NULL)
2105 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002106
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 sum = PyNumber_Add(sofar, prod);
2108 Py_DECREF(prod);
2109 if (sum == NULL)
2110 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 if (fracpart == 0.0)
2113 return sum;
2114 /* So far we've lost no information. Dealing with the
2115 * fractional part requires float arithmetic, and may
2116 * lose a little info.
2117 */
2118 assert(PyLong_Check(factor));
2119 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 dnum *= fracpart;
2122 fracpart = modf(dnum, &intpart);
2123 x = PyLong_FromDouble(intpart);
2124 if (x == NULL) {
2125 Py_DECREF(sum);
2126 return NULL;
2127 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 y = PyNumber_Add(sum, x);
2130 Py_DECREF(sum);
2131 Py_DECREF(x);
2132 *leftover += fracpart;
2133 return y;
2134 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 PyErr_Format(PyExc_TypeError,
2137 "unsupported type for timedelta %s component: %s",
2138 tag, Py_TYPE(num)->tp_name);
2139 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002140}
2141
2142static PyObject *
2143delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002145 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002147 /* Argument objects. */
2148 PyObject *day = NULL;
2149 PyObject *second = NULL;
2150 PyObject *us = NULL;
2151 PyObject *ms = NULL;
2152 PyObject *minute = NULL;
2153 PyObject *hour = NULL;
2154 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 PyObject *x = NULL; /* running sum of microseconds */
2157 PyObject *y = NULL; /* temp sum of microseconds */
2158 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 static char *keywords[] = {
2161 "days", "seconds", "microseconds", "milliseconds",
2162 "minutes", "hours", "weeks", NULL
2163 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2166 keywords,
2167 &day, &second, &us,
2168 &ms, &minute, &hour, &week) == 0)
2169 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 x = PyLong_FromLong(0);
2172 if (x == NULL)
2173 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175#define CLEANUP \
2176 Py_DECREF(x); \
2177 x = y; \
2178 if (x == NULL) \
2179 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 if (us) {
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002182 y = accum("microseconds", x, us, one, &leftover_us);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 CLEANUP;
2184 }
2185 if (ms) {
2186 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2187 CLEANUP;
2188 }
2189 if (second) {
2190 y = accum("seconds", x, second, us_per_second, &leftover_us);
2191 CLEANUP;
2192 }
2193 if (minute) {
2194 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2195 CLEANUP;
2196 }
2197 if (hour) {
2198 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2199 CLEANUP;
2200 }
2201 if (day) {
2202 y = accum("days", x, day, us_per_day, &leftover_us);
2203 CLEANUP;
2204 }
2205 if (week) {
2206 y = accum("weeks", x, week, us_per_week, &leftover_us);
2207 CLEANUP;
2208 }
2209 if (leftover_us) {
2210 /* Round to nearest whole # of us, and add into x. */
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002211 double whole_us = round(leftover_us);
Victor Stinner69cc4872015-09-08 23:58:54 +02002212 int x_is_odd;
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002213 PyObject *temp;
2214
Victor Stinner69cc4872015-09-08 23:58:54 +02002215 whole_us = round(leftover_us);
2216 if (fabs(whole_us - leftover_us) == 0.5) {
2217 /* We're exactly halfway between two integers. In order
2218 * to do round-half-to-even, we must determine whether x
2219 * is odd. Note that x is odd when it's last bit is 1. The
2220 * code below uses bitwise and operation to check the last
2221 * bit. */
2222 temp = PyNumber_And(x, one); /* temp <- x & 1 */
2223 if (temp == NULL) {
2224 Py_DECREF(x);
2225 goto Done;
2226 }
2227 x_is_odd = PyObject_IsTrue(temp);
2228 Py_DECREF(temp);
2229 if (x_is_odd == -1) {
2230 Py_DECREF(x);
2231 goto Done;
2232 }
2233 whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2234 }
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002235
Victor Stinner36a5a062013-08-28 01:53:39 +02002236 temp = PyLong_FromLong((long)whole_us);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04002237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002238 if (temp == NULL) {
2239 Py_DECREF(x);
2240 goto Done;
2241 }
2242 y = PyNumber_Add(x, temp);
2243 Py_DECREF(temp);
2244 CLEANUP;
2245 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 self = microseconds_to_delta_ex(x, type);
2248 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002249Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002251
2252#undef CLEANUP
2253}
2254
2255static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002256delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 return (GET_TD_DAYS(self) != 0
2259 || GET_TD_SECONDS(self) != 0
2260 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002261}
2262
2263static PyObject *
2264delta_repr(PyDateTime_Delta *self)
2265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 if (GET_TD_MICROSECONDS(self) != 0)
2267 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2268 Py_TYPE(self)->tp_name,
2269 GET_TD_DAYS(self),
2270 GET_TD_SECONDS(self),
2271 GET_TD_MICROSECONDS(self));
2272 if (GET_TD_SECONDS(self) != 0)
2273 return PyUnicode_FromFormat("%s(%d, %d)",
2274 Py_TYPE(self)->tp_name,
2275 GET_TD_DAYS(self),
2276 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 return PyUnicode_FromFormat("%s(%d)",
2279 Py_TYPE(self)->tp_name,
2280 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002281}
2282
2283static PyObject *
2284delta_str(PyDateTime_Delta *self)
2285{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 int us = GET_TD_MICROSECONDS(self);
2287 int seconds = GET_TD_SECONDS(self);
2288 int minutes = divmod(seconds, 60, &seconds);
2289 int hours = divmod(minutes, 60, &minutes);
2290 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 if (days) {
2293 if (us)
2294 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2295 days, (days == 1 || days == -1) ? "" : "s",
2296 hours, minutes, seconds, us);
2297 else
2298 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2299 days, (days == 1 || days == -1) ? "" : "s",
2300 hours, minutes, seconds);
2301 } else {
2302 if (us)
2303 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2304 hours, minutes, seconds, us);
2305 else
2306 return PyUnicode_FromFormat("%d:%02d:%02d",
2307 hours, minutes, seconds);
2308 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002309
Tim Peters2a799bf2002-12-16 20:18:38 +00002310}
2311
Tim Peters371935f2003-02-01 01:52:50 +00002312/* Pickle support, a simple use of __reduce__. */
2313
Tim Petersb57f8f02003-02-01 02:54:15 +00002314/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002315static PyObject *
2316delta_getstate(PyDateTime_Delta *self)
2317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 return Py_BuildValue("iii", GET_TD_DAYS(self),
2319 GET_TD_SECONDS(self),
2320 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002321}
2322
Tim Peters2a799bf2002-12-16 20:18:38 +00002323static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002324delta_total_seconds(PyObject *self)
2325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002326 PyObject *total_seconds;
2327 PyObject *total_microseconds;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002329 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2330 if (total_microseconds == NULL)
2331 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002332
Alexander Belopolskydf7027b2013-08-04 15:18:58 -04002333 total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 Py_DECREF(total_microseconds);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002337}
2338
2339static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002340delta_reduce(PyDateTime_Delta* self)
2341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002342 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002343}
2344
2345#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2346
2347static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 {"days", T_INT, OFFSET(days), READONLY,
2350 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002352 {"seconds", T_INT, OFFSET(seconds), READONLY,
2353 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002355 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2356 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2357 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002358};
2359
2360static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2362 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2365 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002367 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002368};
2369
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002370static const char delta_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00002371PyDoc_STR("Difference between two datetime values.");
2372
2373static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 delta_add, /* nb_add */
2375 delta_subtract, /* nb_subtract */
2376 delta_multiply, /* nb_multiply */
2377 delta_remainder, /* nb_remainder */
2378 delta_divmod, /* nb_divmod */
2379 0, /* nb_power */
2380 (unaryfunc)delta_negative, /* nb_negative */
2381 (unaryfunc)delta_positive, /* nb_positive */
2382 (unaryfunc)delta_abs, /* nb_absolute */
2383 (inquiry)delta_bool, /* nb_bool */
2384 0, /*nb_invert*/
2385 0, /*nb_lshift*/
2386 0, /*nb_rshift*/
2387 0, /*nb_and*/
2388 0, /*nb_xor*/
2389 0, /*nb_or*/
2390 0, /*nb_int*/
2391 0, /*nb_reserved*/
2392 0, /*nb_float*/
2393 0, /*nb_inplace_add*/
2394 0, /*nb_inplace_subtract*/
2395 0, /*nb_inplace_multiply*/
2396 0, /*nb_inplace_remainder*/
2397 0, /*nb_inplace_power*/
2398 0, /*nb_inplace_lshift*/
2399 0, /*nb_inplace_rshift*/
2400 0, /*nb_inplace_and*/
2401 0, /*nb_inplace_xor*/
2402 0, /*nb_inplace_or*/
2403 delta_divide, /* nb_floor_divide */
2404 delta_truedivide, /* nb_true_divide */
2405 0, /* nb_inplace_floor_divide */
2406 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002407};
2408
2409static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 PyVarObject_HEAD_INIT(NULL, 0)
2411 "datetime.timedelta", /* tp_name */
2412 sizeof(PyDateTime_Delta), /* tp_basicsize */
2413 0, /* tp_itemsize */
2414 0, /* tp_dealloc */
2415 0, /* tp_print */
2416 0, /* tp_getattr */
2417 0, /* tp_setattr */
2418 0, /* tp_reserved */
2419 (reprfunc)delta_repr, /* tp_repr */
2420 &delta_as_number, /* tp_as_number */
2421 0, /* tp_as_sequence */
2422 0, /* tp_as_mapping */
2423 (hashfunc)delta_hash, /* tp_hash */
2424 0, /* tp_call */
2425 (reprfunc)delta_str, /* tp_str */
2426 PyObject_GenericGetAttr, /* tp_getattro */
2427 0, /* tp_setattro */
2428 0, /* tp_as_buffer */
2429 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2430 delta_doc, /* tp_doc */
2431 0, /* tp_traverse */
2432 0, /* tp_clear */
2433 delta_richcompare, /* tp_richcompare */
2434 0, /* tp_weaklistoffset */
2435 0, /* tp_iter */
2436 0, /* tp_iternext */
2437 delta_methods, /* tp_methods */
2438 delta_members, /* tp_members */
2439 0, /* tp_getset */
2440 0, /* tp_base */
2441 0, /* tp_dict */
2442 0, /* tp_descr_get */
2443 0, /* tp_descr_set */
2444 0, /* tp_dictoffset */
2445 0, /* tp_init */
2446 0, /* tp_alloc */
2447 delta_new, /* tp_new */
2448 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002449};
2450
2451/*
2452 * PyDateTime_Date implementation.
2453 */
2454
2455/* Accessor properties. */
2456
2457static PyObject *
2458date_year(PyDateTime_Date *self, void *unused)
2459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002461}
2462
2463static PyObject *
2464date_month(PyDateTime_Date *self, void *unused)
2465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002467}
2468
2469static PyObject *
2470date_day(PyDateTime_Date *self, void *unused)
2471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002473}
2474
2475static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 {"year", (getter)date_year},
2477 {"month", (getter)date_month},
2478 {"day", (getter)date_day},
2479 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002480};
2481
2482/* Constructors. */
2483
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002484static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002485
Tim Peters2a799bf2002-12-16 20:18:38 +00002486static PyObject *
2487date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 PyObject *self = NULL;
2490 PyObject *state;
2491 int year;
2492 int month;
2493 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002495 /* Check for invocation from pickle with __getstate__ state */
2496 if (PyTuple_GET_SIZE(args) == 1 &&
2497 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2498 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2499 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2500 {
2501 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002503 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2504 if (me != NULL) {
2505 char *pdata = PyBytes_AS_STRING(state);
2506 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2507 me->hashcode = -1;
2508 }
2509 return (PyObject *)me;
2510 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002512 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2513 &year, &month, &day)) {
2514 if (check_date_args(year, month, day) < 0)
2515 return NULL;
2516 self = new_date_ex(year, month, day, type);
2517 }
2518 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002519}
2520
2521/* Return new date from localtime(t). */
2522static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01002523date_local_from_object(PyObject *cls, PyObject *obj)
Tim Peters2a799bf2002-12-16 20:18:38 +00002524{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002525 struct tm tm;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002526 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002527
Victor Stinnere4a994d2015-03-30 01:10:14 +02002528 if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 return NULL;
Victor Stinner5d272cc2012-03-13 13:35:55 +01002530
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04002531 if (_PyTime_localtime(t, &tm) != 0)
Victor Stinner21f58932012-03-14 00:15:40 +01002532 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01002533
2534 return PyObject_CallFunction(cls, "iii",
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04002535 tm.tm_year + 1900,
2536 tm.tm_mon + 1,
2537 tm.tm_mday);
Tim Peters2a799bf2002-12-16 20:18:38 +00002538}
2539
2540/* Return new date from current time.
2541 * We say this is equivalent to fromtimestamp(time.time()), and the
2542 * only way to be sure of that is to *call* time.time(). That's not
2543 * generally the same as calling C's time.
2544 */
2545static PyObject *
2546date_today(PyObject *cls, PyObject *dummy)
2547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002548 PyObject *time;
2549 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002550 _Py_IDENTIFIER(fromtimestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002552 time = time_time();
2553 if (time == NULL)
2554 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 /* Note well: today() is a class method, so this may not call
2557 * date.fromtimestamp. For example, it may call
2558 * datetime.fromtimestamp. That's why we need all the accuracy
2559 * time.time() delivers; if someone were gonzo about optimization,
2560 * date.today() could get away with plain C time().
2561 */
Victor Stinner20401de2016-12-09 15:24:31 +01002562 result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2563 time, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 Py_DECREF(time);
2565 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002566}
2567
2568/* Return new date from given timestamp (Python timestamp -- a double). */
2569static PyObject *
2570date_fromtimestamp(PyObject *cls, PyObject *args)
2571{
Victor Stinner5d272cc2012-03-13 13:35:55 +01002572 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002573 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002574
Victor Stinner5d272cc2012-03-13 13:35:55 +01002575 if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2576 result = date_local_from_object(cls, timestamp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002577 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002578}
2579
2580/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2581 * the ordinal is out of range.
2582 */
2583static PyObject *
2584date_fromordinal(PyObject *cls, PyObject *args)
2585{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 PyObject *result = NULL;
2587 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002589 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2590 int year;
2591 int month;
2592 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002594 if (ordinal < 1)
2595 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2596 ">= 1");
2597 else {
2598 ord_to_ymd(ordinal, &year, &month, &day);
2599 result = PyObject_CallFunction(cls, "iii",
2600 year, month, day);
2601 }
2602 }
2603 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002604}
2605
2606/*
2607 * Date arithmetic.
2608 */
2609
2610/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2611 * instead.
2612 */
2613static PyObject *
2614add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002616 PyObject *result = NULL;
2617 int year = GET_YEAR(date);
2618 int month = GET_MONTH(date);
2619 int deltadays = GET_TD_DAYS(delta);
2620 /* C-level overflow is impossible because |deltadays| < 1e9. */
2621 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002623 if (normalize_date(&year, &month, &day) >= 0)
2624 result = new_date(year, month, day);
2625 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002626}
2627
2628static PyObject *
2629date_add(PyObject *left, PyObject *right)
2630{
Brian Curtindfc80e32011-08-10 20:28:54 -05002631 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2632 Py_RETURN_NOTIMPLEMENTED;
2633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002634 if (PyDate_Check(left)) {
2635 /* date + ??? */
2636 if (PyDelta_Check(right))
2637 /* date + delta */
2638 return add_date_timedelta((PyDateTime_Date *) left,
2639 (PyDateTime_Delta *) right,
2640 0);
2641 }
2642 else {
2643 /* ??? + date
2644 * 'right' must be one of us, or we wouldn't have been called
2645 */
2646 if (PyDelta_Check(left))
2647 /* delta + date */
2648 return add_date_timedelta((PyDateTime_Date *) right,
2649 (PyDateTime_Delta *) left,
2650 0);
2651 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002652 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002653}
2654
2655static PyObject *
2656date_subtract(PyObject *left, PyObject *right)
2657{
Brian Curtindfc80e32011-08-10 20:28:54 -05002658 if (PyDateTime_Check(left) || PyDateTime_Check(right))
2659 Py_RETURN_NOTIMPLEMENTED;
2660
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002661 if (PyDate_Check(left)) {
2662 if (PyDate_Check(right)) {
2663 /* date - date */
2664 int left_ord = ymd_to_ord(GET_YEAR(left),
2665 GET_MONTH(left),
2666 GET_DAY(left));
2667 int right_ord = ymd_to_ord(GET_YEAR(right),
2668 GET_MONTH(right),
2669 GET_DAY(right));
2670 return new_delta(left_ord - right_ord, 0, 0, 0);
2671 }
2672 if (PyDelta_Check(right)) {
2673 /* date - delta */
2674 return add_date_timedelta((PyDateTime_Date *) left,
2675 (PyDateTime_Delta *) right,
2676 1);
2677 }
2678 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002679 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002680}
2681
2682
2683/* Various ways to turn a date into a string. */
2684
2685static PyObject *
2686date_repr(PyDateTime_Date *self)
2687{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002688 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2689 Py_TYPE(self)->tp_name,
2690 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002691}
2692
2693static PyObject *
2694date_isoformat(PyDateTime_Date *self)
2695{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002696 return PyUnicode_FromFormat("%04d-%02d-%02d",
2697 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002698}
2699
Tim Peterse2df5ff2003-05-02 18:39:55 +00002700/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002701static PyObject *
2702date_str(PyDateTime_Date *self)
2703{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002704 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002705}
2706
2707
2708static PyObject *
2709date_ctime(PyDateTime_Date *self)
2710{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002711 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002712}
2713
2714static PyObject *
2715date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002717 /* This method can be inherited, and needs to call the
2718 * timetuple() method appropriate to self's class.
2719 */
2720 PyObject *result;
2721 PyObject *tuple;
2722 PyObject *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002723 _Py_IDENTIFIER(timetuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002724 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002726 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2727 &format))
2728 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002729
Victor Stinnerad8c83a2016-09-05 17:53:15 -07002730 tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002731 if (tuple == NULL)
2732 return NULL;
2733 result = wrap_strftime((PyObject *)self, format, tuple,
2734 (PyObject *)self);
2735 Py_DECREF(tuple);
2736 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002737}
2738
Eric Smith1ba31142007-09-11 18:06:02 +00002739static PyObject *
2740date_format(PyDateTime_Date *self, PyObject *args)
2741{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002742 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002743
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002744 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2745 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002746
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002747 /* if the format is zero length, return str(self) */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002748 if (PyUnicode_GetLength(format) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002749 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002750
Victor Stinner20401de2016-12-09 15:24:31 +01002751 return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
2752 format, NULL);
Eric Smith1ba31142007-09-11 18:06:02 +00002753}
2754
Tim Peters2a799bf2002-12-16 20:18:38 +00002755/* ISO methods. */
2756
2757static PyObject *
2758date_isoweekday(PyDateTime_Date *self)
2759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002760 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002762 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002763}
2764
2765static PyObject *
2766date_isocalendar(PyDateTime_Date *self)
2767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002768 int year = GET_YEAR(self);
2769 int week1_monday = iso_week1_monday(year);
2770 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2771 int week;
2772 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002774 week = divmod(today - week1_monday, 7, &day);
2775 if (week < 0) {
2776 --year;
2777 week1_monday = iso_week1_monday(year);
2778 week = divmod(today - week1_monday, 7, &day);
2779 }
2780 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2781 ++year;
2782 week = 0;
2783 }
2784 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002785}
2786
2787/* Miscellaneous methods. */
2788
Tim Peters2a799bf2002-12-16 20:18:38 +00002789static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002790date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002791{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002792 if (PyDate_Check(other)) {
2793 int diff = memcmp(((PyDateTime_Date *)self)->data,
2794 ((PyDateTime_Date *)other)->data,
2795 _PyDateTime_DATE_DATASIZE);
2796 return diff_to_bool(diff, op);
2797 }
Brian Curtindfc80e32011-08-10 20:28:54 -05002798 else
2799 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00002800}
2801
2802static PyObject *
2803date_timetuple(PyDateTime_Date *self)
2804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 return build_struct_time(GET_YEAR(self),
2806 GET_MONTH(self),
2807 GET_DAY(self),
2808 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002809}
2810
Tim Peters12bf3392002-12-24 05:41:27 +00002811static PyObject *
2812date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2813{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 PyObject *clone;
2815 PyObject *tuple;
2816 int year = GET_YEAR(self);
2817 int month = GET_MONTH(self);
2818 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002820 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2821 &year, &month, &day))
2822 return NULL;
2823 tuple = Py_BuildValue("iii", year, month, day);
2824 if (tuple == NULL)
2825 return NULL;
2826 clone = date_new(Py_TYPE(self), tuple, NULL);
2827 Py_DECREF(tuple);
2828 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002829}
2830
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002831static Py_hash_t
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002832generic_hash(unsigned char *data, int len)
2833{
Gregory P. Smith5831bd22012-01-14 14:31:13 -08002834 return _Py_HashBytes(data, len);
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002835}
2836
2837
2838static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002839
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002840static Py_hash_t
Tim Peters2a799bf2002-12-16 20:18:38 +00002841date_hash(PyDateTime_Date *self)
2842{
Benjamin Petersondec2df32016-09-09 17:46:24 -07002843 if (self->hashcode == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 self->hashcode = generic_hash(
2845 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Benjamin Petersondec2df32016-09-09 17:46:24 -07002846 }
Guido van Rossum254348e2007-11-21 19:29:53 +00002847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002848 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002849}
2850
2851static PyObject *
2852date_toordinal(PyDateTime_Date *self)
2853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2855 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002856}
2857
2858static PyObject *
2859date_weekday(PyDateTime_Date *self)
2860{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002861 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002863 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002864}
2865
Tim Peters371935f2003-02-01 01:52:50 +00002866/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002867
Tim Petersb57f8f02003-02-01 02:54:15 +00002868/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002869static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002870date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002871{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002872 PyObject* field;
2873 field = PyBytes_FromStringAndSize((char*)self->data,
2874 _PyDateTime_DATE_DATASIZE);
2875 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002876}
2877
2878static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002879date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002881 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002882}
2883
2884static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002886 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002888 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2889 METH_CLASS,
2890 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2891 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2894 METH_CLASS,
2895 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2896 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002898 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2899 PyDoc_STR("Current date or datetime: same as "
2900 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002902 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002904 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2905 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002907 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2908 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002909
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002910 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2911 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002913 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2914 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002916 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2917 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2918 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002920 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2921 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002923 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2924 PyDoc_STR("Return the day of the week represented by the date.\n"
2925 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002927 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2928 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2929 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002931 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2932 PyDoc_STR("Return the day of the week represented by the date.\n"
2933 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002935 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2936 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002938 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2939 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002941 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002942};
2943
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002944static const char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002945PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002946
2947static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002948 date_add, /* nb_add */
2949 date_subtract, /* nb_subtract */
2950 0, /* nb_multiply */
2951 0, /* nb_remainder */
2952 0, /* nb_divmod */
2953 0, /* nb_power */
2954 0, /* nb_negative */
2955 0, /* nb_positive */
2956 0, /* nb_absolute */
2957 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002958};
2959
2960static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002961 PyVarObject_HEAD_INIT(NULL, 0)
2962 "datetime.date", /* tp_name */
2963 sizeof(PyDateTime_Date), /* tp_basicsize */
2964 0, /* tp_itemsize */
2965 0, /* tp_dealloc */
2966 0, /* tp_print */
2967 0, /* tp_getattr */
2968 0, /* tp_setattr */
2969 0, /* tp_reserved */
2970 (reprfunc)date_repr, /* tp_repr */
2971 &date_as_number, /* tp_as_number */
2972 0, /* tp_as_sequence */
2973 0, /* tp_as_mapping */
2974 (hashfunc)date_hash, /* tp_hash */
2975 0, /* tp_call */
2976 (reprfunc)date_str, /* tp_str */
2977 PyObject_GenericGetAttr, /* tp_getattro */
2978 0, /* tp_setattro */
2979 0, /* tp_as_buffer */
2980 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2981 date_doc, /* tp_doc */
2982 0, /* tp_traverse */
2983 0, /* tp_clear */
2984 date_richcompare, /* tp_richcompare */
2985 0, /* tp_weaklistoffset */
2986 0, /* tp_iter */
2987 0, /* tp_iternext */
2988 date_methods, /* tp_methods */
2989 0, /* tp_members */
2990 date_getset, /* tp_getset */
2991 0, /* tp_base */
2992 0, /* tp_dict */
2993 0, /* tp_descr_get */
2994 0, /* tp_descr_set */
2995 0, /* tp_dictoffset */
2996 0, /* tp_init */
2997 0, /* tp_alloc */
2998 date_new, /* tp_new */
2999 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003000};
3001
3002/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003003 * PyDateTime_TZInfo implementation.
3004 */
3005
3006/* This is a pure abstract base class, so doesn't do anything beyond
3007 * raising NotImplemented exceptions. Real tzinfo classes need
3008 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003009 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003010 * be subclasses of this tzinfo class, which is easy and quick to check).
3011 *
3012 * Note: For reasons having to do with pickling of subclasses, we have
3013 * to allow tzinfo objects to be instantiated. This wasn't an issue
3014 * in the Python implementation (__init__() could raise NotImplementedError
3015 * there without ill effect), but doing so in the C implementation hit a
3016 * brick wall.
3017 */
3018
3019static PyObject *
3020tzinfo_nogo(const char* methodname)
3021{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003022 PyErr_Format(PyExc_NotImplementedError,
3023 "a tzinfo subclass must implement %s()",
3024 methodname);
3025 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003026}
3027
3028/* Methods. A subclass must implement these. */
3029
Tim Peters52dcce22003-01-23 16:36:11 +00003030static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003031tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3032{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003033 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003034}
3035
Tim Peters52dcce22003-01-23 16:36:11 +00003036static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003037tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3038{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003039 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003040}
3041
Tim Peters52dcce22003-01-23 16:36:11 +00003042static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003043tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003045 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003046}
3047
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003048
3049static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3050 PyDateTime_Delta *delta,
3051 int factor);
3052static PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3053static PyObject *datetime_dst(PyObject *self, PyObject *);
3054
Tim Peters52dcce22003-01-23 16:36:11 +00003055static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003056tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
Tim Peters52dcce22003-01-23 16:36:11 +00003057{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003058 PyObject *result = NULL;
3059 PyObject *off = NULL, *dst = NULL;
3060 PyDateTime_Delta *delta = NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003061
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003062 if (!PyDateTime_Check(dt)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003063 PyErr_SetString(PyExc_TypeError,
3064 "fromutc: argument must be a datetime");
3065 return NULL;
3066 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003067 if (GET_DT_TZINFO(dt) != (PyObject *)self) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003068 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3069 "is not self");
3070 return NULL;
3071 }
Tim Peters52dcce22003-01-23 16:36:11 +00003072
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003073 off = datetime_utcoffset(dt, NULL);
3074 if (off == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003075 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003076 if (off == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003077 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3078 "utcoffset() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003079 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003080 }
Tim Peters52dcce22003-01-23 16:36:11 +00003081
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003082 dst = datetime_dst(dt, NULL);
3083 if (dst == NULL)
3084 goto Fail;
3085 if (dst == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003086 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3087 "dst() result required");
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003088 goto Fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003089 }
Tim Peters52dcce22003-01-23 16:36:11 +00003090
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003091 delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3092 if (delta == NULL)
3093 goto Fail;
3094 result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003095 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003096 goto Fail;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003097
3098 Py_DECREF(dst);
3099 dst = call_dst(GET_DT_TZINFO(dt), result);
3100 if (dst == NULL)
3101 goto Fail;
3102 if (dst == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003103 goto Inconsistent;
Alexander Belopolskyc79447b2015-09-27 21:41:55 -04003104 if (delta_bool((PyDateTime_Delta *)dst) != 0) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03003105 Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
Serhiy Storchaka576f1322016-01-05 21:27:54 +02003106 (PyDateTime_Delta *)dst, 1));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003107 if (result == NULL)
3108 goto Fail;
3109 }
3110 Py_DECREF(delta);
3111 Py_DECREF(dst);
3112 Py_DECREF(off);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003113 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003114
3115Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003116 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3117 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003119 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003120Fail:
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003121 Py_XDECREF(off);
3122 Py_XDECREF(dst);
3123 Py_XDECREF(delta);
3124 Py_XDECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003126}
3127
Tim Peters2a799bf2002-12-16 20:18:38 +00003128/*
3129 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003130 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003131 */
3132
Guido van Rossum177e41a2003-01-30 22:06:23 +00003133static PyObject *
3134tzinfo_reduce(PyObject *self)
3135{
Victor Stinnerd1584d32016-08-23 00:11:04 +02003136 PyObject *args, *state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003137 PyObject *getinitargs, *getstate;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003138 _Py_IDENTIFIER(__getinitargs__);
3139 _Py_IDENTIFIER(__getstate__);
Tim Peters2a799bf2002-12-16 20:18:38 +00003140
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003141 getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003142 if (getinitargs != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003143 args = _PyObject_CallNoArg(getinitargs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003144 Py_DECREF(getinitargs);
3145 if (args == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003146 return NULL;
3147 }
3148 }
3149 else {
3150 PyErr_Clear();
Victor Stinnerd1584d32016-08-23 00:11:04 +02003151
3152 args = PyTuple_New(0);
3153 if (args == NULL) {
3154 return NULL;
3155 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003156 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003157
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003158 getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003159 if (getstate != NULL) {
Victor Stinnerd1584d32016-08-23 00:11:04 +02003160 state = _PyObject_CallNoArg(getstate);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003161 Py_DECREF(getstate);
3162 if (state == NULL) {
3163 Py_DECREF(args);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003164 return NULL;
3165 }
3166 }
3167 else {
3168 PyObject **dictptr;
3169 PyErr_Clear();
3170 state = Py_None;
3171 dictptr = _PyObject_GetDictPtr(self);
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02003172 if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003173 state = *dictptr;
Victor Stinnerd1584d32016-08-23 00:11:04 +02003174 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003175 Py_INCREF(state);
3176 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003178 if (state == Py_None) {
3179 Py_DECREF(state);
3180 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3181 }
3182 else
3183 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003184}
Tim Peters2a799bf2002-12-16 20:18:38 +00003185
3186static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003188 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3189 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003191 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003192 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3193 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003195 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3196 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003199 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003201 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3202 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003204 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003205};
3206
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003207static const char tzinfo_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003208PyDoc_STR("Abstract base class for time zone info objects.");
3209
Neal Norwitz227b5332006-03-22 09:28:35 +00003210static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003211 PyVarObject_HEAD_INIT(NULL, 0)
3212 "datetime.tzinfo", /* tp_name */
3213 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3214 0, /* tp_itemsize */
3215 0, /* tp_dealloc */
3216 0, /* tp_print */
3217 0, /* tp_getattr */
3218 0, /* tp_setattr */
3219 0, /* tp_reserved */
3220 0, /* tp_repr */
3221 0, /* tp_as_number */
3222 0, /* tp_as_sequence */
3223 0, /* tp_as_mapping */
3224 0, /* tp_hash */
3225 0, /* tp_call */
3226 0, /* tp_str */
3227 PyObject_GenericGetAttr, /* tp_getattro */
3228 0, /* tp_setattro */
3229 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003230 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003231 tzinfo_doc, /* tp_doc */
3232 0, /* tp_traverse */
3233 0, /* tp_clear */
3234 0, /* tp_richcompare */
3235 0, /* tp_weaklistoffset */
3236 0, /* tp_iter */
3237 0, /* tp_iternext */
3238 tzinfo_methods, /* tp_methods */
3239 0, /* tp_members */
3240 0, /* tp_getset */
3241 0, /* tp_base */
3242 0, /* tp_dict */
3243 0, /* tp_descr_get */
3244 0, /* tp_descr_set */
3245 0, /* tp_dictoffset */
3246 0, /* tp_init */
3247 0, /* tp_alloc */
3248 PyType_GenericNew, /* tp_new */
3249 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003250};
3251
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003252static char *timezone_kws[] = {"offset", "name", NULL};
3253
3254static PyObject *
3255timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3256{
3257 PyObject *offset;
3258 PyObject *name = NULL;
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03003259 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3260 &PyDateTime_DeltaType, &offset, &name))
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003261 return new_timezone(offset, name);
3262
3263 return NULL;
3264}
3265
3266static void
3267timezone_dealloc(PyDateTime_TimeZone *self)
3268{
3269 Py_CLEAR(self->offset);
3270 Py_CLEAR(self->name);
3271 Py_TYPE(self)->tp_free((PyObject *)self);
3272}
3273
3274static PyObject *
3275timezone_richcompare(PyDateTime_TimeZone *self,
3276 PyDateTime_TimeZone *other, int op)
3277{
Brian Curtindfc80e32011-08-10 20:28:54 -05003278 if (op != Py_EQ && op != Py_NE)
3279 Py_RETURN_NOTIMPLEMENTED;
Georg Brandl0085a242012-09-22 09:23:12 +02003280 if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07003281 if (op == Py_EQ)
3282 Py_RETURN_FALSE;
3283 else
3284 Py_RETURN_TRUE;
Georg Brandl0085a242012-09-22 09:23:12 +02003285 }
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003286 return delta_richcompare(self->offset, other->offset, op);
3287}
3288
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003289static Py_hash_t
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003290timezone_hash(PyDateTime_TimeZone *self)
3291{
3292 return delta_hash((PyDateTime_Delta *)self->offset);
3293}
3294
3295/* Check argument type passed to tzname, utcoffset, or dst methods.
3296 Returns 0 for good argument. Returns -1 and sets exception info
3297 otherwise.
3298 */
3299static int
3300_timezone_check_argument(PyObject *dt, const char *meth)
3301{
3302 if (dt == Py_None || PyDateTime_Check(dt))
3303 return 0;
3304 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3305 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3306 return -1;
3307}
3308
3309static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003310timezone_repr(PyDateTime_TimeZone *self)
3311{
3312 /* Note that although timezone is not subclassable, it is convenient
3313 to use Py_TYPE(self)->tp_name here. */
3314 const char *type_name = Py_TYPE(self)->tp_name;
3315
3316 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3317 return PyUnicode_FromFormat("%s.utc", type_name);
3318
3319 if (self->name == NULL)
3320 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3321
3322 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3323 self->name);
3324}
3325
3326
3327static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003328timezone_str(PyDateTime_TimeZone *self)
3329{
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003330 int hours, minutes, seconds;
3331 PyObject *offset;
3332 char sign;
3333
3334 if (self->name != NULL) {
3335 Py_INCREF(self->name);
3336 return self->name;
3337 }
Victor Stinner90fd8952015-09-08 00:12:49 +02003338 if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
Alexander Belopolsky7827a5b2015-09-06 13:07:21 -04003339 (GET_TD_DAYS(self->offset) == 0 &&
3340 GET_TD_SECONDS(self->offset) == 0 &&
3341 GET_TD_MICROSECONDS(self->offset) == 0))
3342 return PyUnicode_FromString("UTC");
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003343 /* Offset is normalized, so it is negative if days < 0 */
3344 if (GET_TD_DAYS(self->offset) < 0) {
3345 sign = '-';
3346 offset = delta_negative((PyDateTime_Delta *)self->offset);
3347 if (offset == NULL)
3348 return NULL;
3349 }
3350 else {
3351 sign = '+';
3352 offset = self->offset;
3353 Py_INCREF(offset);
3354 }
3355 /* Offset is not negative here. */
3356 seconds = GET_TD_SECONDS(offset);
3357 Py_DECREF(offset);
3358 minutes = divmod(seconds, 60, &seconds);
3359 hours = divmod(minutes, 60, &minutes);
Martin Pantere26da7c2016-06-02 10:07:09 +00003360 /* XXX ignore sub-minute data, currently not allowed. */
Victor Stinner6ced7c42011-03-21 18:15:42 +01003361 assert(seconds == 0);
3362 return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003363}
3364
3365static PyObject *
3366timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3367{
3368 if (_timezone_check_argument(dt, "tzname") == -1)
3369 return NULL;
3370
3371 return timezone_str(self);
3372}
3373
3374static PyObject *
3375timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3376{
3377 if (_timezone_check_argument(dt, "utcoffset") == -1)
3378 return NULL;
3379
3380 Py_INCREF(self->offset);
3381 return self->offset;
3382}
3383
3384static PyObject *
3385timezone_dst(PyObject *self, PyObject *dt)
3386{
3387 if (_timezone_check_argument(dt, "dst") == -1)
3388 return NULL;
3389
3390 Py_RETURN_NONE;
3391}
3392
3393static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003394timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3395{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003396 if (!PyDateTime_Check(dt)) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003397 PyErr_SetString(PyExc_TypeError,
3398 "fromutc: argument must be a datetime");
3399 return NULL;
3400 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003401 if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003402 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3403 "is not self");
3404 return NULL;
3405 }
3406
3407 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3408}
3409
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003410static PyObject *
3411timezone_getinitargs(PyDateTime_TimeZone *self)
3412{
3413 if (self->name == NULL)
3414 return Py_BuildValue("(O)", self->offset);
3415 return Py_BuildValue("(OO)", self->offset, self->name);
3416}
3417
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003418static PyMethodDef timezone_methods[] = {
3419 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3420 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003421 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003422
3423 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003424 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003425
3426 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003427 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003428
3429 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3430 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3431
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003432 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3433 PyDoc_STR("pickle support")},
3434
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003435 {NULL, NULL}
3436};
3437
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003438static const char timezone_doc[] =
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003439PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3440
3441static PyTypeObject PyDateTime_TimeZoneType = {
3442 PyVarObject_HEAD_INIT(NULL, 0)
3443 "datetime.timezone", /* tp_name */
3444 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3445 0, /* tp_itemsize */
3446 (destructor)timezone_dealloc, /* tp_dealloc */
3447 0, /* tp_print */
3448 0, /* tp_getattr */
3449 0, /* tp_setattr */
3450 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003451 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003452 0, /* tp_as_number */
3453 0, /* tp_as_sequence */
3454 0, /* tp_as_mapping */
3455 (hashfunc)timezone_hash, /* tp_hash */
3456 0, /* tp_call */
3457 (reprfunc)timezone_str, /* tp_str */
3458 0, /* tp_getattro */
3459 0, /* tp_setattro */
3460 0, /* tp_as_buffer */
3461 Py_TPFLAGS_DEFAULT, /* tp_flags */
3462 timezone_doc, /* tp_doc */
3463 0, /* tp_traverse */
3464 0, /* tp_clear */
3465 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3466 0, /* tp_weaklistoffset */
3467 0, /* tp_iter */
3468 0, /* tp_iternext */
3469 timezone_methods, /* tp_methods */
3470 0, /* tp_members */
3471 0, /* tp_getset */
3472 &PyDateTime_TZInfoType, /* tp_base */
3473 0, /* tp_dict */
3474 0, /* tp_descr_get */
3475 0, /* tp_descr_set */
3476 0, /* tp_dictoffset */
3477 0, /* tp_init */
3478 0, /* tp_alloc */
3479 timezone_new, /* tp_new */
3480};
3481
Tim Peters2a799bf2002-12-16 20:18:38 +00003482/*
Tim Peters37f39822003-01-10 03:49:02 +00003483 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003484 */
3485
Tim Peters37f39822003-01-10 03:49:02 +00003486/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003487 */
3488
3489static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003490time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003491{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003492 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003493}
3494
Tim Peters37f39822003-01-10 03:49:02 +00003495static PyObject *
3496time_minute(PyDateTime_Time *self, void *unused)
3497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003498 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003499}
3500
3501/* The name time_second conflicted with some platform header file. */
3502static PyObject *
3503py_time_second(PyDateTime_Time *self, void *unused)
3504{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003505 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003506}
3507
3508static PyObject *
3509time_microsecond(PyDateTime_Time *self, void *unused)
3510{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003511 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003512}
3513
3514static PyObject *
3515time_tzinfo(PyDateTime_Time *self, void *unused)
3516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003517 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3518 Py_INCREF(result);
3519 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003520}
3521
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003522static PyObject *
3523time_fold(PyDateTime_Time *self, void *unused)
3524{
3525 return PyLong_FromLong(TIME_GET_FOLD(self));
3526}
3527
Tim Peters37f39822003-01-10 03:49:02 +00003528static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003529 {"hour", (getter)time_hour},
3530 {"minute", (getter)time_minute},
3531 {"second", (getter)py_time_second},
3532 {"microsecond", (getter)time_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003533 {"tzinfo", (getter)time_tzinfo},
3534 {"fold", (getter)time_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003535 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003536};
3537
3538/*
3539 * Constructors.
3540 */
3541
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003542static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003543 "tzinfo", "fold", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003544
Tim Peters2a799bf2002-12-16 20:18:38 +00003545static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003546time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003548 PyObject *self = NULL;
3549 PyObject *state;
3550 int hour = 0;
3551 int minute = 0;
3552 int second = 0;
3553 int usecond = 0;
3554 PyObject *tzinfo = Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003555 int fold = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003557 /* Check for invocation from pickle with __getstate__ state */
3558 if (PyTuple_GET_SIZE(args) >= 1 &&
3559 PyTuple_GET_SIZE(args) <= 2 &&
3560 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3561 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003562 (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003563 {
3564 PyDateTime_Time *me;
3565 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003567 if (PyTuple_GET_SIZE(args) == 2) {
3568 tzinfo = PyTuple_GET_ITEM(args, 1);
3569 if (check_tzinfo_subclass(tzinfo) < 0) {
3570 PyErr_SetString(PyExc_TypeError, "bad "
3571 "tzinfo state arg");
3572 return NULL;
3573 }
3574 }
3575 aware = (char)(tzinfo != Py_None);
3576 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3577 if (me != NULL) {
3578 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003580 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3581 me->hashcode = -1;
3582 me->hastzinfo = aware;
3583 if (aware) {
3584 Py_INCREF(tzinfo);
3585 me->tzinfo = tzinfo;
3586 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003587 if (pdata[0] & (1 << 7)) {
3588 me->data[0] -= 128;
3589 me->fold = 1;
3590 }
3591 else {
3592 me->fold = 0;
3593 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003594 }
3595 return (PyObject *)me;
3596 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003597
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003598 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003599 &hour, &minute, &second, &usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003600 &tzinfo, &fold)) {
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003601 if (check_time_args(hour, minute, second, usecond, fold) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003602 return NULL;
3603 if (check_tzinfo_subclass(tzinfo) < 0)
3604 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003605 self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3606 type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003607 }
3608 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003609}
3610
3611/*
3612 * Destructor.
3613 */
3614
3615static void
Tim Peters37f39822003-01-10 03:49:02 +00003616time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003617{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003618 if (HASTZINFO(self)) {
3619 Py_XDECREF(self->tzinfo);
3620 }
3621 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003622}
3623
3624/*
Tim Peters855fe882002-12-22 03:43:39 +00003625 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003626 */
3627
Tim Peters2a799bf2002-12-16 20:18:38 +00003628/* These are all METH_NOARGS, so don't need to check the arglist. */
3629static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003630time_utcoffset(PyObject *self, PyObject *unused) {
3631 return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003632}
3633
3634static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003635time_dst(PyObject *self, PyObject *unused) {
3636 return call_dst(GET_TIME_TZINFO(self), Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003637}
3638
3639static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003640time_tzname(PyDateTime_Time *self, PyObject *unused) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003641 return call_tzname(GET_TIME_TZINFO(self), Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003642}
3643
3644/*
Tim Peters37f39822003-01-10 03:49:02 +00003645 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003646 */
3647
3648static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003649time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003650{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003651 const char *type_name = Py_TYPE(self)->tp_name;
3652 int h = TIME_GET_HOUR(self);
3653 int m = TIME_GET_MINUTE(self);
3654 int s = TIME_GET_SECOND(self);
3655 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003656 int fold = TIME_GET_FOLD(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003657 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003659 if (us)
3660 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3661 type_name, h, m, s, us);
3662 else if (s)
3663 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3664 type_name, h, m, s);
3665 else
3666 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3667 if (result != NULL && HASTZINFO(self))
3668 result = append_keyword_tzinfo(result, self->tzinfo);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003669 if (result != NULL && fold)
3670 result = append_keyword_fold(result, fold);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003671 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003672}
3673
Tim Peters37f39822003-01-10 03:49:02 +00003674static PyObject *
3675time_str(PyDateTime_Time *self)
3676{
Victor Stinnerad8c83a2016-09-05 17:53:15 -07003677 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003678}
Tim Peters2a799bf2002-12-16 20:18:38 +00003679
3680static PyObject *
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003681time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003682{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003683 char buf[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003684 char *timespec = NULL;
3685 static char *keywords[] = {"timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003686 PyObject *result;
Ezio Melotti3f5db392013-01-27 06:20:14 +02003687 int us = TIME_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003688 static char *specs[][2] = {
3689 {"hours", "%02d"},
3690 {"minutes", "%02d:%02d"},
3691 {"seconds", "%02d:%02d:%02d"},
3692 {"milliseconds", "%02d:%02d:%02d.%03d"},
3693 {"microseconds", "%02d:%02d:%02d.%06d"},
3694 };
3695 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00003696
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003697 if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3698 return NULL;
3699
3700 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3701 if (us == 0) {
3702 /* seconds */
3703 given_spec = 2;
3704 }
3705 else {
3706 /* microseconds */
3707 given_spec = 4;
3708 }
3709 }
3710 else {
3711 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3712 if (strcmp(timespec, specs[given_spec][0]) == 0) {
3713 if (given_spec == 3) {
3714 /* milliseconds */
3715 us = us / 1000;
3716 }
3717 break;
3718 }
3719 }
3720 }
3721
3722 if (given_spec == Py_ARRAY_LENGTH(specs)) {
3723 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3724 return NULL;
3725 }
3726 else {
3727 result = PyUnicode_FromFormat(specs[given_spec][1],
3728 TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3729 TIME_GET_SECOND(self), us);
3730 }
Tim Peters37f39822003-01-10 03:49:02 +00003731
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003732 if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003733 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003735 /* We need to append the UTC offset. */
3736 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3737 Py_None) < 0) {
3738 Py_DECREF(result);
3739 return NULL;
3740 }
3741 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3742 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003743}
3744
Tim Peters37f39822003-01-10 03:49:02 +00003745static PyObject *
3746time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003748 PyObject *result;
3749 PyObject *tuple;
3750 PyObject *format;
3751 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003752
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003753 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3754 &format))
3755 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003757 /* Python's strftime does insane things with the year part of the
3758 * timetuple. The year is forced to (the otherwise nonsensical)
Alexander Belopolskyb8bb4662011-01-08 00:13:34 +00003759 * 1900 to work around that.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003760 */
3761 tuple = Py_BuildValue("iiiiiiiii",
3762 1900, 1, 1, /* year, month, day */
3763 TIME_GET_HOUR(self),
3764 TIME_GET_MINUTE(self),
3765 TIME_GET_SECOND(self),
3766 0, 1, -1); /* weekday, daynum, dst */
3767 if (tuple == NULL)
3768 return NULL;
3769 assert(PyTuple_Size(tuple) == 9);
3770 result = wrap_strftime((PyObject *)self, format, tuple,
3771 Py_None);
3772 Py_DECREF(tuple);
3773 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003774}
Tim Peters2a799bf2002-12-16 20:18:38 +00003775
3776/*
3777 * Miscellaneous methods.
3778 */
3779
Tim Peters37f39822003-01-10 03:49:02 +00003780static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003781time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003782{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003783 PyObject *result = NULL;
3784 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003785 int diff;
Tim Peters37f39822003-01-10 03:49:02 +00003786
Brian Curtindfc80e32011-08-10 20:28:54 -05003787 if (! PyTime_Check(other))
3788 Py_RETURN_NOTIMPLEMENTED;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003789
3790 if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003791 diff = memcmp(((PyDateTime_Time *)self)->data,
3792 ((PyDateTime_Time *)other)->data,
3793 _PyDateTime_TIME_DATASIZE);
3794 return diff_to_bool(diff, op);
3795 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003796 offset1 = time_utcoffset(self, NULL);
3797 if (offset1 == NULL)
3798 return NULL;
3799 offset2 = time_utcoffset(other, NULL);
3800 if (offset2 == NULL)
3801 goto done;
3802 /* If they're both naive, or both aware and have the same offsets,
3803 * we get off cheap. Note that if they're both naive, offset1 ==
3804 * offset2 == Py_None at this point.
3805 */
3806 if ((offset1 == offset2) ||
3807 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3808 delta_cmp(offset1, offset2) == 0)) {
3809 diff = memcmp(((PyDateTime_Time *)self)->data,
3810 ((PyDateTime_Time *)other)->data,
3811 _PyDateTime_TIME_DATASIZE);
3812 result = diff_to_bool(diff, op);
3813 }
3814 /* The hard case: both aware with different UTC offsets */
3815 else if (offset1 != Py_None && offset2 != Py_None) {
3816 int offsecs1, offsecs2;
3817 assert(offset1 != offset2); /* else last "if" handled it */
3818 offsecs1 = TIME_GET_HOUR(self) * 3600 +
3819 TIME_GET_MINUTE(self) * 60 +
3820 TIME_GET_SECOND(self) -
3821 GET_TD_DAYS(offset1) * 86400 -
3822 GET_TD_SECONDS(offset1);
3823 offsecs2 = TIME_GET_HOUR(other) * 3600 +
3824 TIME_GET_MINUTE(other) * 60 +
3825 TIME_GET_SECOND(other) -
3826 GET_TD_DAYS(offset2) * 86400 -
3827 GET_TD_SECONDS(offset2);
3828 diff = offsecs1 - offsecs2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003829 if (diff == 0)
3830 diff = TIME_GET_MICROSECOND(self) -
3831 TIME_GET_MICROSECOND(other);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003832 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003833 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04003834 else if (op == Py_EQ) {
3835 result = Py_False;
3836 Py_INCREF(result);
3837 }
3838 else if (op == Py_NE) {
3839 result = Py_True;
3840 Py_INCREF(result);
3841 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003842 else {
3843 PyErr_SetString(PyExc_TypeError,
3844 "can't compare offset-naive and "
3845 "offset-aware times");
3846 }
3847 done:
3848 Py_DECREF(offset1);
3849 Py_XDECREF(offset2);
3850 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003851}
3852
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003853static Py_hash_t
Tim Peters37f39822003-01-10 03:49:02 +00003854time_hash(PyDateTime_Time *self)
3855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003856 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003857 PyObject *offset, *self0;
Victor Stinner423c16b2017-01-03 23:47:12 +01003858 if (TIME_GET_FOLD(self)) {
3859 self0 = new_time_ex2(TIME_GET_HOUR(self),
3860 TIME_GET_MINUTE(self),
3861 TIME_GET_SECOND(self),
3862 TIME_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003863 HASTZINFO(self) ? self->tzinfo : Py_None,
3864 0, Py_TYPE(self));
3865 if (self0 == NULL)
3866 return -1;
3867 }
3868 else {
3869 self0 = (PyObject *)self;
3870 Py_INCREF(self0);
3871 }
3872 offset = time_utcoffset(self0, NULL);
3873 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003874
3875 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003876 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003878 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003879 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003880 self->hashcode = generic_hash(
3881 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003882 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003883 PyObject *temp1, *temp2;
3884 int seconds, microseconds;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003885 assert(HASTZINFO(self));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003886 seconds = TIME_GET_HOUR(self) * 3600 +
3887 TIME_GET_MINUTE(self) * 60 +
3888 TIME_GET_SECOND(self);
3889 microseconds = TIME_GET_MICROSECOND(self);
3890 temp1 = new_delta(0, seconds, microseconds, 1);
3891 if (temp1 == NULL) {
3892 Py_DECREF(offset);
3893 return -1;
3894 }
3895 temp2 = delta_subtract(temp1, offset);
3896 Py_DECREF(temp1);
3897 if (temp2 == NULL) {
3898 Py_DECREF(offset);
3899 return -1;
3900 }
3901 self->hashcode = PyObject_Hash(temp2);
3902 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003903 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00003904 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003905 }
3906 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003907}
Tim Peters2a799bf2002-12-16 20:18:38 +00003908
Tim Peters12bf3392002-12-24 05:41:27 +00003909static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003910time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003911{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003912 PyObject *clone;
3913 PyObject *tuple;
3914 int hh = TIME_GET_HOUR(self);
3915 int mm = TIME_GET_MINUTE(self);
3916 int ss = TIME_GET_SECOND(self);
3917 int us = TIME_GET_MICROSECOND(self);
3918 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003919 int fold = TIME_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00003920
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003921 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003922 time_kws,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003923 &hh, &mm, &ss, &us, &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003924 return NULL;
3925 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3926 if (tuple == NULL)
3927 return NULL;
3928 clone = time_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003929 if (clone != NULL) {
3930 if (fold != 0 && fold != 1) {
3931 PyErr_SetString(PyExc_ValueError,
3932 "fold must be either 0 or 1");
3933 return NULL;
3934 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003935 TIME_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04003936 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003937 Py_DECREF(tuple);
3938 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003939}
3940
Tim Peters371935f2003-02-01 01:52:50 +00003941/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003942
Tim Peters33e0f382003-01-10 02:05:14 +00003943/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003944 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3945 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003946 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003947 */
3948static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003949time_getstate(PyDateTime_Time *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00003950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003951 PyObject *basestate;
3952 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003954 basestate = PyBytes_FromStringAndSize((char *)self->data,
3955 _PyDateTime_TIME_DATASIZE);
3956 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003957 if (proto > 3 && TIME_GET_FOLD(self))
3958 /* Set the first bit of the first byte */
3959 PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003960 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3961 result = PyTuple_Pack(1, basestate);
3962 else
3963 result = PyTuple_Pack(2, basestate, self->tzinfo);
3964 Py_DECREF(basestate);
3965 }
3966 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003967}
3968
3969static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003970time_reduce_ex(PyDateTime_Time *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00003971{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003972 int proto;
3973 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04003974 return NULL;
3975
3976 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00003977}
3978
Serhiy Storchaka546ce652016-11-22 00:29:42 +02003979static PyObject *
3980time_reduce(PyDateTime_Time *self, PyObject *arg)
3981{
3982 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
3983}
3984
Tim Peters37f39822003-01-10 03:49:02 +00003985static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003986
Alexander Belopolskya2998a62016-03-06 14:58:43 -05003987 {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
3988 PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
3989 "[+HH:MM].\n\n"
3990 "timespec specifies what components of the time to include.\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003992 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3993 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003995 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3996 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003998 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3999 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4002 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4005 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004007 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4008 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004009
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004010 {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004011 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004012
Serhiy Storchaka546ce652016-11-22 00:29:42 +02004013 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4014 PyDoc_STR("__reduce__() -> (cls, state)")},
4015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004016 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004017};
4018
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02004019static const char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004020PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4021\n\
4022All arguments are optional. tzinfo may be None, or an instance of\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03004023a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004024
Neal Norwitz227b5332006-03-22 09:28:35 +00004025static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004026 PyVarObject_HEAD_INIT(NULL, 0)
4027 "datetime.time", /* tp_name */
4028 sizeof(PyDateTime_Time), /* tp_basicsize */
4029 0, /* tp_itemsize */
4030 (destructor)time_dealloc, /* tp_dealloc */
4031 0, /* tp_print */
4032 0, /* tp_getattr */
4033 0, /* tp_setattr */
4034 0, /* tp_reserved */
4035 (reprfunc)time_repr, /* tp_repr */
Benjamin Petersonee6bdc02014-03-20 18:00:35 -05004036 0, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004037 0, /* tp_as_sequence */
4038 0, /* tp_as_mapping */
4039 (hashfunc)time_hash, /* tp_hash */
4040 0, /* tp_call */
4041 (reprfunc)time_str, /* tp_str */
4042 PyObject_GenericGetAttr, /* tp_getattro */
4043 0, /* tp_setattro */
4044 0, /* tp_as_buffer */
4045 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4046 time_doc, /* tp_doc */
4047 0, /* tp_traverse */
4048 0, /* tp_clear */
4049 time_richcompare, /* tp_richcompare */
4050 0, /* tp_weaklistoffset */
4051 0, /* tp_iter */
4052 0, /* tp_iternext */
4053 time_methods, /* tp_methods */
4054 0, /* tp_members */
4055 time_getset, /* tp_getset */
4056 0, /* tp_base */
4057 0, /* tp_dict */
4058 0, /* tp_descr_get */
4059 0, /* tp_descr_set */
4060 0, /* tp_dictoffset */
4061 0, /* tp_init */
4062 time_alloc, /* tp_alloc */
4063 time_new, /* tp_new */
4064 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004065};
4066
4067/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004068 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004069 */
4070
Tim Petersa9bc1682003-01-11 03:39:11 +00004071/* Accessor properties. Properties for day, month, and year are inherited
4072 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004073 */
4074
4075static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004076datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004077{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004078 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004079}
4080
Tim Petersa9bc1682003-01-11 03:39:11 +00004081static PyObject *
4082datetime_minute(PyDateTime_DateTime *self, void *unused)
4083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004084 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004085}
4086
4087static PyObject *
4088datetime_second(PyDateTime_DateTime *self, void *unused)
4089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004090 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004091}
4092
4093static PyObject *
4094datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004096 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004097}
4098
4099static PyObject *
4100datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4103 Py_INCREF(result);
4104 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004105}
4106
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004107static PyObject *
4108datetime_fold(PyDateTime_DateTime *self, void *unused)
4109{
4110 return PyLong_FromLong(DATE_GET_FOLD(self));
4111}
4112
Tim Petersa9bc1682003-01-11 03:39:11 +00004113static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004114 {"hour", (getter)datetime_hour},
4115 {"minute", (getter)datetime_minute},
4116 {"second", (getter)datetime_second},
4117 {"microsecond", (getter)datetime_microsecond},
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004118 {"tzinfo", (getter)datetime_tzinfo},
4119 {"fold", (getter)datetime_fold},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004120 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004121};
4122
4123/*
4124 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004125 */
4126
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004127static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004128 "year", "month", "day", "hour", "minute", "second",
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004129 "microsecond", "tzinfo", "fold", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004130};
4131
Tim Peters2a799bf2002-12-16 20:18:38 +00004132static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004133datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004135 PyObject *self = NULL;
4136 PyObject *state;
4137 int year;
4138 int month;
4139 int day;
4140 int hour = 0;
4141 int minute = 0;
4142 int second = 0;
4143 int usecond = 0;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004144 int fold = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004145 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004147 /* Check for invocation from pickle with __getstate__ state */
4148 if (PyTuple_GET_SIZE(args) >= 1 &&
4149 PyTuple_GET_SIZE(args) <= 2 &&
4150 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4151 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004152 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004153 {
4154 PyDateTime_DateTime *me;
4155 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004157 if (PyTuple_GET_SIZE(args) == 2) {
4158 tzinfo = PyTuple_GET_ITEM(args, 1);
4159 if (check_tzinfo_subclass(tzinfo) < 0) {
4160 PyErr_SetString(PyExc_TypeError, "bad "
4161 "tzinfo state arg");
4162 return NULL;
4163 }
4164 }
4165 aware = (char)(tzinfo != Py_None);
4166 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4167 if (me != NULL) {
4168 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004170 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4171 me->hashcode = -1;
4172 me->hastzinfo = aware;
4173 if (aware) {
4174 Py_INCREF(tzinfo);
4175 me->tzinfo = tzinfo;
4176 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004177 if (pdata[2] & (1 << 7)) {
4178 me->data[2] -= 128;
4179 me->fold = 1;
4180 }
4181 else {
4182 me->fold = 0;
4183 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004184 }
4185 return (PyObject *)me;
4186 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004187
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004188 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004189 &year, &month, &day, &hour, &minute,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004190 &second, &usecond, &tzinfo, &fold)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 if (check_date_args(year, month, day) < 0)
4192 return NULL;
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04004193 if (check_time_args(hour, minute, second, usecond, fold) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004194 return NULL;
4195 if (check_tzinfo_subclass(tzinfo) < 0)
4196 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004197 self = new_datetime_ex2(year, month, day,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004198 hour, minute, second, usecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004199 tzinfo, fold, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004200 }
4201 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004202}
4203
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004204/* TM_FUNC is the shared type of _PyTime_localtime() and
4205 * _PyTime_gmtime(). */
4206typedef int (*TM_FUNC)(time_t timer, struct tm*);
Tim Petersa9bc1682003-01-11 03:39:11 +00004207
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004208/* As of version 2015f max fold in IANA database is
4209 * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004210static long long max_fold_seconds = 24 * 3600;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004211/* NB: date(1970,1,1).toordinal() == 719163 */
Benjamin Petersonac965ca2016-09-18 18:12:21 -07004212static long long epoch = 719163LL * 24 * 60 * 60;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004213
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004214static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004215utc_to_seconds(int year, int month, int day,
4216 int hour, int minute, int second)
4217{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004218 long long ordinal = ymd_to_ord(year, month, day);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004219 return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4220}
4221
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004222static long long
4223local(long long u)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004224{
4225 struct tm local_time;
Alexander Belopolsky8e1d3a22016-07-25 13:54:51 -04004226 time_t t;
4227 u -= epoch;
4228 t = u;
4229 if (t != u) {
4230 PyErr_SetString(PyExc_OverflowError,
4231 "timestamp out of range for platform time_t");
4232 return -1;
4233 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004234 /* XXX: add bounds checking */
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004235 if (_PyTime_localtime(t, &local_time) != 0)
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004236 return -1;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004237 return utc_to_seconds(local_time.tm_year + 1900,
4238 local_time.tm_mon + 1,
4239 local_time.tm_mday,
4240 local_time.tm_hour,
4241 local_time.tm_min,
4242 local_time.tm_sec);
4243}
4244
Tim Petersa9bc1682003-01-11 03:39:11 +00004245/* Internal helper.
4246 * Build datetime from a time_t and a distinct count of microseconds.
4247 * Pass localtime or gmtime for f, to control the interpretation of timet.
4248 */
4249static PyObject *
4250datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004251 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004252{
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004253 struct tm tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004254 int year, month, day, hour, minute, second, fold = 0;
Tim Petersa9bc1682003-01-11 03:39:11 +00004255
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004256 if (f(timet, &tm) != 0)
4257 return NULL;
Victor Stinner21f58932012-03-14 00:15:40 +01004258
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004259 year = tm.tm_year + 1900;
4260 month = tm.tm_mon + 1;
4261 day = tm.tm_mday;
4262 hour = tm.tm_hour;
4263 minute = tm.tm_min;
Victor Stinner21f58932012-03-14 00:15:40 +01004264 /* The platform localtime/gmtime may insert leap seconds,
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004265 * indicated by tm.tm_sec > 59. We don't care about them,
Victor Stinner21f58932012-03-14 00:15:40 +01004266 * except to the extent that passing them on to the datetime
4267 * constructor would raise ValueError for a reason that
4268 * made no sense to the user.
4269 */
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04004270 second = Py_MIN(59, tm.tm_sec);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004271
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004272 if (tzinfo == Py_None && f == _PyTime_localtime) {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07004273 long long probe_seconds, result_seconds, transition;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004274
4275 result_seconds = utc_to_seconds(year, month, day,
4276 hour, minute, second);
4277 /* Probe max_fold_seconds to detect a fold. */
4278 probe_seconds = local(epoch + timet - max_fold_seconds);
4279 if (probe_seconds == -1)
4280 return NULL;
4281 transition = result_seconds - probe_seconds - max_fold_seconds;
4282 if (transition < 0) {
4283 probe_seconds = local(epoch + timet + transition);
4284 if (probe_seconds == -1)
4285 return NULL;
4286 if (probe_seconds == result_seconds)
4287 fold = 1;
4288 }
4289 }
4290 return new_datetime_ex2(year, month, day, hour,
4291 minute, second, us, tzinfo, fold,
4292 (PyTypeObject *)cls);
Tim Petersa9bc1682003-01-11 03:39:11 +00004293}
4294
4295/* Internal helper.
4296 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4297 * to control the interpretation of the timestamp. Since a double doesn't
4298 * have enough bits to cover a datetime's full range of precision, it's
4299 * better to call datetime_from_timet_and_us provided you have a way
4300 * to get that much precision (e.g., C time() isn't good enough).
4301 */
4302static PyObject *
Victor Stinner5d272cc2012-03-13 13:35:55 +01004303datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004304 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004306 time_t timet;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004307 long us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004308
Victor Stinnere4a994d2015-03-30 01:10:14 +02004309 if (_PyTime_ObjectToTimeval(timestamp,
Victor Stinner7667f582015-09-09 01:02:23 +02004310 &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004311 return NULL;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004312
Victor Stinner21f58932012-03-14 00:15:40 +01004313 return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004314}
4315
4316/* Internal helper.
4317 * Build most accurate possible datetime for current time. Pass localtime or
4318 * gmtime for f as appropriate.
4319 */
4320static PyObject *
4321datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4322{
Victor Stinner09e5cf22015-03-30 00:09:18 +02004323 _PyTime_t ts = _PyTime_GetSystemClock();
Victor Stinner1e2b6882015-09-18 13:23:02 +02004324 time_t secs;
4325 int us;
Victor Stinner09e5cf22015-03-30 00:09:18 +02004326
Victor Stinner1e2b6882015-09-18 13:23:02 +02004327 if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
Victor Stinner09e5cf22015-03-30 00:09:18 +02004328 return NULL;
Victor Stinner1e2b6882015-09-18 13:23:02 +02004329 assert(0 <= us && us <= 999999);
Victor Stinner09e5cf22015-03-30 00:09:18 +02004330
Victor Stinner1e2b6882015-09-18 13:23:02 +02004331 return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004332}
4333
Larry Hastings61272b72014-01-07 12:41:53 -08004334/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07004335
4336@classmethod
Larry Hastingsed4a1c52013-11-18 09:32:13 -08004337datetime.datetime.now
Larry Hastings31826802013-10-19 00:09:25 -07004338
4339 tz: object = None
4340 Timezone object.
4341
4342Returns new datetime object representing current time local to tz.
4343
4344If no tz is specified, uses local timezone.
Larry Hastings61272b72014-01-07 12:41:53 -08004345[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07004346
Larry Hastings31826802013-10-19 00:09:25 -07004347static PyObject *
Larry Hastings5c661892014-01-24 06:17:25 -08004348datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004349/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
Tim Peters2a799bf2002-12-16 20:18:38 +00004350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004351 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004352
Larry Hastings31826802013-10-19 00:09:25 -07004353 /* Return best possible local time -- this isn't constrained by the
4354 * precision of a timestamp.
4355 */
4356 if (check_tzinfo_subclass(tz) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004357 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004358
Larry Hastings5c661892014-01-24 06:17:25 -08004359 self = datetime_best_possible((PyObject *)type,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004360 tz == Py_None ? _PyTime_localtime :
4361 _PyTime_gmtime,
Larry Hastings31826802013-10-19 00:09:25 -07004362 tz);
4363 if (self != NULL && tz != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004364 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004365 self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004366 }
4367 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004368}
4369
Tim Petersa9bc1682003-01-11 03:39:11 +00004370/* Return best possible UTC time -- this isn't constrained by the
4371 * precision of a timestamp.
4372 */
4373static PyObject *
4374datetime_utcnow(PyObject *cls, PyObject *dummy)
4375{
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004376 return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004377}
4378
Tim Peters2a799bf2002-12-16 20:18:38 +00004379/* Return new local datetime from timestamp (Python timestamp -- a double). */
4380static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004381datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004383 PyObject *self;
Victor Stinner5d272cc2012-03-13 13:35:55 +01004384 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004385 PyObject *tzinfo = Py_None;
4386 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004387
Victor Stinner5d272cc2012-03-13 13:35:55 +01004388 if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004389 keywords, &timestamp, &tzinfo))
4390 return NULL;
4391 if (check_tzinfo_subclass(tzinfo) < 0)
4392 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004394 self = datetime_from_timestamp(cls,
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004395 tzinfo == Py_None ? _PyTime_localtime :
4396 _PyTime_gmtime,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004397 timestamp,
4398 tzinfo);
4399 if (self != NULL && tzinfo != Py_None) {
4400 /* Convert UTC to tzinfo's zone. */
Serhiy Storchaka576f1322016-01-05 21:27:54 +02004401 self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004402 }
4403 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004404}
4405
Tim Petersa9bc1682003-01-11 03:39:11 +00004406/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4407static PyObject *
4408datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4409{
Victor Stinner5d272cc2012-03-13 13:35:55 +01004410 PyObject *timestamp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004412
Victor Stinner5d272cc2012-03-13 13:35:55 +01004413 if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04004414 result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004415 Py_None);
4416 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004417}
4418
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004419/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004420static PyObject *
4421datetime_strptime(PyObject *cls, PyObject *args)
4422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004423 static PyObject *module = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004424 PyObject *string, *format;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02004425 _Py_IDENTIFIER(_strptime_datetime);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004426
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02004427 if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004428 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004429
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004430 if (module == NULL) {
4431 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004432 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004433 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004434 }
Victor Stinner20401de2016-12-09 15:24:31 +01004435 return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4436 cls, string, format, NULL);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004437}
4438
Tim Petersa9bc1682003-01-11 03:39:11 +00004439/* Return new datetime from date/datetime and time arguments. */
4440static PyObject *
4441datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4442{
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004443 static char *keywords[] = {"date", "time", "tzinfo", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004444 PyObject *date;
4445 PyObject *time;
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004446 PyObject *tzinfo = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004447 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004448
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004449 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004450 &PyDateTime_DateType, &date,
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004451 &PyDateTime_TimeType, &time, &tzinfo)) {
4452 if (tzinfo == NULL) {
4453 if (HASTZINFO(time))
4454 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4455 else
4456 tzinfo = Py_None;
4457 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004458 result = PyObject_CallFunction(cls, "iiiiiiiO",
Alexander Belopolsky43746c32016-08-02 17:49:30 -04004459 GET_YEAR(date),
4460 GET_MONTH(date),
4461 GET_DAY(date),
4462 TIME_GET_HOUR(time),
4463 TIME_GET_MINUTE(time),
4464 TIME_GET_SECOND(time),
4465 TIME_GET_MICROSECOND(time),
4466 tzinfo);
4467 if (result)
4468 DATE_SET_FOLD(result, TIME_GET_FOLD(time));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004469 }
4470 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004471}
Tim Peters2a799bf2002-12-16 20:18:38 +00004472
4473/*
4474 * Destructor.
4475 */
4476
4477static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004478datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004479{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004480 if (HASTZINFO(self)) {
4481 Py_XDECREF(self->tzinfo);
4482 }
4483 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004484}
4485
4486/*
4487 * Indirect access to tzinfo methods.
4488 */
4489
Tim Peters2a799bf2002-12-16 20:18:38 +00004490/* These are all METH_NOARGS, so don't need to check the arglist. */
4491static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004492datetime_utcoffset(PyObject *self, PyObject *unused) {
4493 return call_utcoffset(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004494}
4495
4496static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004497datetime_dst(PyObject *self, PyObject *unused) {
4498 return call_dst(GET_DT_TZINFO(self), self);
Tim Peters855fe882002-12-22 03:43:39 +00004499}
4500
4501static PyObject *
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004502datetime_tzname(PyObject *self, PyObject *unused) {
4503 return call_tzname(GET_DT_TZINFO(self), self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004504}
4505
4506/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004507 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004508 */
4509
Tim Petersa9bc1682003-01-11 03:39:11 +00004510/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4511 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004512 */
4513static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004514add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004515 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004517 /* Note that the C-level additions can't overflow, because of
4518 * invariant bounds on the member values.
4519 */
4520 int year = GET_YEAR(date);
4521 int month = GET_MONTH(date);
4522 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4523 int hour = DATE_GET_HOUR(date);
4524 int minute = DATE_GET_MINUTE(date);
4525 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4526 int microsecond = DATE_GET_MICROSECOND(date) +
4527 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004529 assert(factor == 1 || factor == -1);
4530 if (normalize_datetime(&year, &month, &day,
4531 &hour, &minute, &second, &microsecond) < 0)
4532 return NULL;
4533 else
4534 return new_datetime(year, month, day,
4535 hour, minute, second, microsecond,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004536 HASTZINFO(date) ? date->tzinfo : Py_None, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004537}
4538
4539static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004540datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004541{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004542 if (PyDateTime_Check(left)) {
4543 /* datetime + ??? */
4544 if (PyDelta_Check(right))
4545 /* datetime + delta */
4546 return add_datetime_timedelta(
4547 (PyDateTime_DateTime *)left,
4548 (PyDateTime_Delta *)right,
4549 1);
4550 }
4551 else if (PyDelta_Check(left)) {
4552 /* delta + datetime */
4553 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4554 (PyDateTime_Delta *) left,
4555 1);
4556 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004557 Py_RETURN_NOTIMPLEMENTED;
Tim Peters2a799bf2002-12-16 20:18:38 +00004558}
4559
4560static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004561datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004562{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004563 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004565 if (PyDateTime_Check(left)) {
4566 /* datetime - ??? */
4567 if (PyDateTime_Check(right)) {
4568 /* datetime - datetime */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004569 PyObject *offset1, *offset2, *offdiff = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004570 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004571
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004572 if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4573 offset2 = offset1 = Py_None;
4574 Py_INCREF(offset1);
4575 Py_INCREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004576 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004577 else {
4578 offset1 = datetime_utcoffset(left, NULL);
4579 if (offset1 == NULL)
4580 return NULL;
4581 offset2 = datetime_utcoffset(right, NULL);
4582 if (offset2 == NULL) {
4583 Py_DECREF(offset1);
4584 return NULL;
4585 }
4586 if ((offset1 != Py_None) != (offset2 != Py_None)) {
4587 PyErr_SetString(PyExc_TypeError,
4588 "can't subtract offset-naive and "
4589 "offset-aware datetimes");
4590 Py_DECREF(offset1);
4591 Py_DECREF(offset2);
4592 return NULL;
4593 }
4594 }
4595 if ((offset1 != offset2) &&
4596 delta_cmp(offset1, offset2) != 0) {
4597 offdiff = delta_subtract(offset1, offset2);
4598 if (offdiff == NULL) {
4599 Py_DECREF(offset1);
4600 Py_DECREF(offset2);
4601 return NULL;
4602 }
4603 }
4604 Py_DECREF(offset1);
4605 Py_DECREF(offset2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004606 delta_d = ymd_to_ord(GET_YEAR(left),
4607 GET_MONTH(left),
4608 GET_DAY(left)) -
4609 ymd_to_ord(GET_YEAR(right),
4610 GET_MONTH(right),
4611 GET_DAY(right));
4612 /* These can't overflow, since the values are
4613 * normalized. At most this gives the number of
4614 * seconds in one day.
4615 */
4616 delta_s = (DATE_GET_HOUR(left) -
4617 DATE_GET_HOUR(right)) * 3600 +
4618 (DATE_GET_MINUTE(left) -
4619 DATE_GET_MINUTE(right)) * 60 +
4620 (DATE_GET_SECOND(left) -
4621 DATE_GET_SECOND(right));
4622 delta_us = DATE_GET_MICROSECOND(left) -
4623 DATE_GET_MICROSECOND(right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004624 result = new_delta(delta_d, delta_s, delta_us, 1);
Victor Stinner70e11ac2013-11-08 00:50:58 +01004625 if (result == NULL)
4626 return NULL;
4627
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004628 if (offdiff != NULL) {
Serhiy Storchakaf01e4082016-04-10 18:12:01 +03004629 Py_SETREF(result, delta_subtract(result, offdiff));
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004630 Py_DECREF(offdiff);
4631 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004632 }
4633 else if (PyDelta_Check(right)) {
4634 /* datetime - delta */
4635 result = add_datetime_timedelta(
4636 (PyDateTime_DateTime *)left,
4637 (PyDateTime_Delta *)right,
4638 -1);
4639 }
4640 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004642 if (result == Py_NotImplemented)
4643 Py_INCREF(result);
4644 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004645}
4646
4647/* Various ways to turn a datetime into a string. */
4648
4649static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004650datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004651{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004652 const char *type_name = Py_TYPE(self)->tp_name;
4653 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004655 if (DATE_GET_MICROSECOND(self)) {
4656 baserepr = PyUnicode_FromFormat(
4657 "%s(%d, %d, %d, %d, %d, %d, %d)",
4658 type_name,
4659 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4660 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4661 DATE_GET_SECOND(self),
4662 DATE_GET_MICROSECOND(self));
4663 }
4664 else if (DATE_GET_SECOND(self)) {
4665 baserepr = PyUnicode_FromFormat(
4666 "%s(%d, %d, %d, %d, %d, %d)",
4667 type_name,
4668 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4669 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4670 DATE_GET_SECOND(self));
4671 }
4672 else {
4673 baserepr = PyUnicode_FromFormat(
4674 "%s(%d, %d, %d, %d, %d)",
4675 type_name,
4676 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4677 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4678 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004679 if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4680 baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004681 if (baserepr == NULL || ! HASTZINFO(self))
4682 return baserepr;
4683 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004684}
4685
Tim Petersa9bc1682003-01-11 03:39:11 +00004686static PyObject *
4687datetime_str(PyDateTime_DateTime *self)
4688{
Victor Stinner4c381542016-12-09 00:33:39 +01004689 return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004690}
Tim Peters2a799bf2002-12-16 20:18:38 +00004691
4692static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004693datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004695 int sep = 'T';
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004696 char *timespec = NULL;
4697 static char *keywords[] = {"sep", "timespec", NULL};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004698 char buffer[100];
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004699 PyObject *result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004700 int us = DATE_GET_MICROSECOND(self);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004701 static char *specs[][2] = {
4702 {"hours", "%04d-%02d-%02d%c%02d"},
4703 {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4704 {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4705 {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4706 {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4707 };
4708 size_t given_spec;
Tim Peters2a799bf2002-12-16 20:18:38 +00004709
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004710 if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004711 return NULL;
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004712
4713 if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4714 if (us == 0) {
4715 /* seconds */
4716 given_spec = 2;
4717 }
4718 else {
4719 /* microseconds */
4720 given_spec = 4;
4721 }
4722 }
4723 else {
4724 for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4725 if (strcmp(timespec, specs[given_spec][0]) == 0) {
4726 if (given_spec == 3) {
4727 us = us / 1000;
4728 }
4729 break;
4730 }
4731 }
4732 }
4733
4734 if (given_spec == Py_ARRAY_LENGTH(specs)) {
4735 PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4736 return NULL;
4737 }
4738 else {
4739 result = PyUnicode_FromFormat(specs[given_spec][1],
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004740 GET_YEAR(self), GET_MONTH(self),
4741 GET_DAY(self), (int)sep,
4742 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4743 DATE_GET_SECOND(self), us);
Alexander Belopolskya2998a62016-03-06 14:58:43 -05004744 }
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004746 if (!result || !HASTZINFO(self))
4747 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004749 /* We need to append the UTC offset. */
4750 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4751 (PyObject *)self) < 0) {
4752 Py_DECREF(result);
4753 return NULL;
4754 }
4755 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4756 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004757}
4758
Tim Petersa9bc1682003-01-11 03:39:11 +00004759static PyObject *
4760datetime_ctime(PyDateTime_DateTime *self)
4761{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004762 return format_ctime((PyDateTime_Date *)self,
4763 DATE_GET_HOUR(self),
4764 DATE_GET_MINUTE(self),
4765 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004766}
4767
Tim Peters2a799bf2002-12-16 20:18:38 +00004768/* Miscellaneous methods. */
4769
Tim Petersa9bc1682003-01-11 03:39:11 +00004770static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004771flip_fold(PyObject *dt)
4772{
4773 return new_datetime_ex2(GET_YEAR(dt),
4774 GET_MONTH(dt),
4775 GET_DAY(dt),
4776 DATE_GET_HOUR(dt),
4777 DATE_GET_MINUTE(dt),
4778 DATE_GET_SECOND(dt),
4779 DATE_GET_MICROSECOND(dt),
4780 HASTZINFO(dt) ?
4781 ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4782 !DATE_GET_FOLD(dt),
4783 Py_TYPE(dt));
4784}
4785
4786static PyObject *
4787get_flip_fold_offset(PyObject *dt)
4788{
4789 PyObject *result, *flip_dt;
4790
4791 flip_dt = flip_fold(dt);
4792 if (flip_dt == NULL)
4793 return NULL;
4794 result = datetime_utcoffset(flip_dt, NULL);
4795 Py_DECREF(flip_dt);
4796 return result;
4797}
4798
4799/* PEP 495 exception: Whenever one or both of the operands in
4800 * inter-zone comparison is such that its utcoffset() depends
4801 * on the value of its fold fold attribute, the result is False.
4802 *
4803 * Return 1 if exception applies, 0 if not, and -1 on error.
4804 */
4805static int
4806pep495_eq_exception(PyObject *self, PyObject *other,
4807 PyObject *offset_self, PyObject *offset_other)
4808{
4809 int result = 0;
4810 PyObject *flip_offset;
4811
4812 flip_offset = get_flip_fold_offset(self);
4813 if (flip_offset == NULL)
4814 return -1;
4815 if (flip_offset != offset_self &&
4816 delta_cmp(flip_offset, offset_self))
4817 {
4818 result = 1;
4819 goto done;
4820 }
4821 Py_DECREF(flip_offset);
4822
4823 flip_offset = get_flip_fold_offset(other);
4824 if (flip_offset == NULL)
4825 return -1;
4826 if (flip_offset != offset_other &&
4827 delta_cmp(flip_offset, offset_other))
4828 result = 1;
4829 done:
4830 Py_DECREF(flip_offset);
4831 return result;
4832}
4833
4834static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004835datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004836{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004837 PyObject *result = NULL;
4838 PyObject *offset1, *offset2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004839 int diff;
Tim Petersa9bc1682003-01-11 03:39:11 +00004840
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004841 if (! PyDateTime_Check(other)) {
4842 if (PyDate_Check(other)) {
4843 /* Prevent invocation of date_richcompare. We want to
4844 return NotImplemented here to give the other object
4845 a chance. But since DateTime is a subclass of
4846 Date, if the other object is a Date, it would
4847 compute an ordering based on the date part alone,
4848 and we don't want that. So force unequal or
4849 uncomparable here in that case. */
4850 if (op == Py_EQ)
4851 Py_RETURN_FALSE;
4852 if (op == Py_NE)
4853 Py_RETURN_TRUE;
4854 return cmperror(self, other);
4855 }
Brian Curtindfc80e32011-08-10 20:28:54 -05004856 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004857 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004858
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004859 if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004860 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4861 ((PyDateTime_DateTime *)other)->data,
4862 _PyDateTime_DATETIME_DATASIZE);
4863 return diff_to_bool(diff, op);
4864 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004865 offset1 = datetime_utcoffset(self, NULL);
4866 if (offset1 == NULL)
4867 return NULL;
4868 offset2 = datetime_utcoffset(other, NULL);
4869 if (offset2 == NULL)
4870 goto done;
4871 /* If they're both naive, or both aware and have the same offsets,
4872 * we get off cheap. Note that if they're both naive, offset1 ==
4873 * offset2 == Py_None at this point.
4874 */
4875 if ((offset1 == offset2) ||
4876 (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4877 delta_cmp(offset1, offset2) == 0)) {
4878 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4879 ((PyDateTime_DateTime *)other)->data,
4880 _PyDateTime_DATETIME_DATASIZE);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004881 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4882 int ex = pep495_eq_exception(self, other, offset1, offset2);
4883 if (ex == -1)
4884 goto done;
4885 if (ex)
4886 diff = 1;
4887 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004888 result = diff_to_bool(diff, op);
4889 }
4890 else if (offset1 != Py_None && offset2 != Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004891 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004892
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004893 assert(offset1 != offset2); /* else last "if" handled it */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004894 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4895 other);
4896 if (delta == NULL)
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004897 goto done;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004898 diff = GET_TD_DAYS(delta);
4899 if (diff == 0)
4900 diff = GET_TD_SECONDS(delta) |
4901 GET_TD_MICROSECONDS(delta);
4902 Py_DECREF(delta);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004903 if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4904 int ex = pep495_eq_exception(self, other, offset1, offset2);
4905 if (ex == -1)
4906 goto done;
4907 if (ex)
4908 diff = 1;
4909 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004910 result = diff_to_bool(diff, op);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004911 }
Alexander Belopolsky08313822012-06-15 20:19:47 -04004912 else if (op == Py_EQ) {
4913 result = Py_False;
4914 Py_INCREF(result);
4915 }
4916 else if (op == Py_NE) {
4917 result = Py_True;
4918 Py_INCREF(result);
4919 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004920 else {
4921 PyErr_SetString(PyExc_TypeError,
4922 "can't compare offset-naive and "
4923 "offset-aware datetimes");
4924 }
4925 done:
4926 Py_DECREF(offset1);
4927 Py_XDECREF(offset2);
4928 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004929}
4930
Benjamin Peterson8f67d082010-10-17 20:54:53 +00004931static Py_hash_t
Tim Petersa9bc1682003-01-11 03:39:11 +00004932datetime_hash(PyDateTime_DateTime *self)
4933{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 if (self->hashcode == -1) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04004935 PyObject *offset, *self0;
4936 if (DATE_GET_FOLD(self)) {
4937 self0 = new_datetime_ex2(GET_YEAR(self),
4938 GET_MONTH(self),
4939 GET_DAY(self),
4940 DATE_GET_HOUR(self),
4941 DATE_GET_MINUTE(self),
4942 DATE_GET_SECOND(self),
4943 DATE_GET_MICROSECOND(self),
4944 HASTZINFO(self) ? self->tzinfo : Py_None,
4945 0, Py_TYPE(self));
4946 if (self0 == NULL)
4947 return -1;
4948 }
4949 else {
4950 self0 = (PyObject *)self;
4951 Py_INCREF(self0);
4952 }
4953 offset = datetime_utcoffset(self0, NULL);
4954 Py_DECREF(self0);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004955
4956 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004957 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004959 /* Reduce this to a hash of another object. */
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004960 if (offset == Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004961 self->hashcode = generic_hash(
4962 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004963 else {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004964 PyObject *temp1, *temp2;
4965 int days, seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004967 assert(HASTZINFO(self));
4968 days = ymd_to_ord(GET_YEAR(self),
4969 GET_MONTH(self),
4970 GET_DAY(self));
4971 seconds = DATE_GET_HOUR(self) * 3600 +
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004972 DATE_GET_MINUTE(self) * 60 +
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004973 DATE_GET_SECOND(self);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004974 temp1 = new_delta(days, seconds,
4975 DATE_GET_MICROSECOND(self),
4976 1);
4977 if (temp1 == NULL) {
4978 Py_DECREF(offset);
4979 return -1;
4980 }
4981 temp2 = delta_subtract(temp1, offset);
4982 Py_DECREF(temp1);
4983 if (temp2 == NULL) {
4984 Py_DECREF(offset);
4985 return -1;
4986 }
4987 self->hashcode = PyObject_Hash(temp2);
4988 Py_DECREF(temp2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004989 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00004990 Py_DECREF(offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004991 }
4992 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004993}
Tim Peters2a799bf2002-12-16 20:18:38 +00004994
4995static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004996datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004997{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004998 PyObject *clone;
4999 PyObject *tuple;
5000 int y = GET_YEAR(self);
5001 int m = GET_MONTH(self);
5002 int d = GET_DAY(self);
5003 int hh = DATE_GET_HOUR(self);
5004 int mm = DATE_GET_MINUTE(self);
5005 int ss = DATE_GET_SECOND(self);
5006 int us = DATE_GET_MICROSECOND(self);
5007 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005008 int fold = DATE_GET_FOLD(self);
Tim Peters12bf3392002-12-24 05:41:27 +00005009
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005010 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005011 datetime_kws,
5012 &y, &m, &d, &hh, &mm, &ss, &us,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005013 &tzinfo, &fold))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005014 return NULL;
5015 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5016 if (tuple == NULL)
5017 return NULL;
5018 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005019
5020 if (clone != NULL) {
5021 if (fold != 0 && fold != 1) {
5022 PyErr_SetString(PyExc_ValueError,
5023 "fold must be either 0 or 1");
5024 return NULL;
5025 }
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005026 DATE_SET_FOLD(clone, fold);
Alexander Belopolsky47649ab2016-08-08 17:05:40 -04005027 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005028 Py_DECREF(tuple);
5029 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00005030}
5031
5032static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005033local_timezone_from_timestamp(time_t timestamp)
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005034{
5035 PyObject *result = NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005036 PyObject *delta;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005037 struct tm local_time_tm;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005038 PyObject *nameo = NULL;
5039 const char *zone = NULL;
5040
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005041 if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005042 return NULL;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005043#ifdef HAVE_STRUCT_TM_TM_ZONE
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005044 zone = local_time_tm.tm_zone;
5045 delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005046#else /* HAVE_STRUCT_TM_TM_ZONE */
5047 {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005048 PyObject *local_time, *utc_time;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005049 struct tm utc_time_tm;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005050 char buf[100];
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005051 strftime(buf, sizeof(buf), "%Z", &local_time_tm);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005052 zone = buf;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005053 local_time = new_datetime(local_time_tm.tm_year + 1900,
5054 local_time_tm.tm_mon + 1,
5055 local_time_tm.tm_mday,
5056 local_time_tm.tm_hour,
5057 local_time_tm.tm_min,
5058 local_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005059 if (local_time == NULL) {
5060 return NULL;
5061 }
Alexander Belopolsky3e7a3cb2016-09-28 17:31:35 -04005062 if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005063 return NULL;
Alexander Belopolsky6d88fa52016-09-10 15:58:31 -04005064 utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5065 utc_time_tm.tm_mon + 1,
5066 utc_time_tm.tm_mday,
5067 utc_time_tm.tm_hour,
5068 utc_time_tm.tm_min,
5069 utc_time_tm.tm_sec, 0, Py_None, 0);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005070 if (utc_time == NULL) {
5071 Py_DECREF(local_time);
5072 return NULL;
5073 }
5074 delta = datetime_subtract(local_time, utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005075 Py_DECREF(local_time);
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005076 Py_DECREF(utc_time);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005077 }
5078#endif /* HAVE_STRUCT_TM_TM_ZONE */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005079 if (delta == NULL) {
5080 return NULL;
5081 }
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005082 if (zone != NULL) {
5083 nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5084 if (nameo == NULL)
5085 goto error;
5086 }
5087 result = new_timezone(delta, nameo);
Christian Heimesb91ffaa2013-06-29 20:52:33 +02005088 Py_XDECREF(nameo);
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005089 error:
5090 Py_DECREF(delta);
5091 return result;
5092}
5093
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005094static PyObject *
5095local_timezone(PyDateTime_DateTime *utc_time)
5096{
5097 time_t timestamp;
5098 PyObject *delta;
5099 PyObject *one_second;
5100 PyObject *seconds;
5101
5102 delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5103 if (delta == NULL)
5104 return NULL;
5105 one_second = new_delta(0, 1, 0, 0);
5106 if (one_second == NULL) {
5107 Py_DECREF(delta);
5108 return NULL;
5109 }
5110 seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5111 (PyDateTime_Delta *)one_second);
5112 Py_DECREF(one_second);
5113 Py_DECREF(delta);
5114 if (seconds == NULL)
5115 return NULL;
5116 timestamp = _PyLong_AsTime_t(seconds);
5117 Py_DECREF(seconds);
5118 if (timestamp == -1 && PyErr_Occurred())
5119 return NULL;
5120 return local_timezone_from_timestamp(timestamp);
5121}
5122
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005123static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005124local_to_seconds(int year, int month, int day,
5125 int hour, int minute, int second, int fold);
5126
5127static PyObject *
5128local_timezone_from_local(PyDateTime_DateTime *local_dt)
5129{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005130 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005131 time_t timestamp;
5132 seconds = local_to_seconds(GET_YEAR(local_dt),
5133 GET_MONTH(local_dt),
5134 GET_DAY(local_dt),
5135 DATE_GET_HOUR(local_dt),
5136 DATE_GET_MINUTE(local_dt),
5137 DATE_GET_SECOND(local_dt),
5138 DATE_GET_FOLD(local_dt));
5139 if (seconds == -1)
5140 return NULL;
5141 /* XXX: add bounds check */
5142 timestamp = seconds - epoch;
5143 return local_timezone_from_timestamp(timestamp);
5144}
5145
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005146static PyDateTime_DateTime *
Tim Petersa9bc1682003-01-11 03:39:11 +00005147datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00005148{
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005149 PyDateTime_DateTime *result;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005150 PyObject *offset;
5151 PyObject *temp;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005152 PyObject *self_tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005153 PyObject *tzinfo = Py_None;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005154 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00005155
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005156 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
Raymond Hettinger5a2146a2014-07-25 14:59:48 -07005157 &tzinfo))
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005158 return NULL;
5159
5160 if (check_tzinfo_subclass(tzinfo) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005161 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00005162
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005163 if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5164 self_tzinfo = local_timezone_from_local(self);
5165 if (self_tzinfo == NULL)
5166 return NULL;
5167 } else {
5168 self_tzinfo = self->tzinfo;
5169 Py_INCREF(self_tzinfo);
5170 }
Tim Peters521fc152002-12-31 17:36:56 +00005171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005172 /* Conversion to self's own time zone is a NOP. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005173 if (self_tzinfo == tzinfo) {
5174 Py_DECREF(self_tzinfo);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005175 Py_INCREF(self);
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005176 return self;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005177 }
Tim Peters521fc152002-12-31 17:36:56 +00005178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005179 /* Convert self to UTC. */
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005180 offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5181 Py_DECREF(self_tzinfo);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005182 if (offset == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005183 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005184 /* result = self - offset */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005185 result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5186 (PyDateTime_Delta *)offset, -1);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005187 Py_DECREF(offset);
5188 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005189 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00005190
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005191 /* Make sure result is aware and UTC. */
5192 if (!HASTZINFO(result)) {
5193 temp = (PyObject *)result;
5194 result = (PyDateTime_DateTime *)
5195 new_datetime_ex2(GET_YEAR(result),
5196 GET_MONTH(result),
5197 GET_DAY(result),
5198 DATE_GET_HOUR(result),
5199 DATE_GET_MINUTE(result),
5200 DATE_GET_SECOND(result),
5201 DATE_GET_MICROSECOND(result),
5202 PyDateTime_TimeZone_UTC,
5203 DATE_GET_FOLD(result),
5204 Py_TYPE(result));
5205 Py_DECREF(temp);
5206 if (result == NULL)
5207 return NULL;
5208 }
5209 else {
5210 /* Result is already aware - just replace tzinfo. */
5211 temp = result->tzinfo;
5212 result->tzinfo = PyDateTime_TimeZone_UTC;
5213 Py_INCREF(result->tzinfo);
5214 Py_DECREF(temp);
5215 }
5216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005217 /* Attach new tzinfo and let fromutc() do the rest. */
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005218 temp = result->tzinfo;
Alexander Belopolskyfdc860f2012-06-22 12:23:23 -04005219 if (tzinfo == Py_None) {
5220 tzinfo = local_timezone(result);
5221 if (tzinfo == NULL) {
5222 Py_DECREF(result);
5223 return NULL;
5224 }
5225 }
5226 else
5227 Py_INCREF(tzinfo);
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005228 result->tzinfo = tzinfo;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005229 Py_DECREF(temp);
Tim Peters52dcce22003-01-23 16:36:11 +00005230
Alexander Belopolsky31227ca2012-06-22 13:23:21 -04005231 temp = (PyObject *)result;
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005232 result = (PyDateTime_DateTime *)
Victor Stinner20401de2016-12-09 15:24:31 +01005233 _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005234 Py_DECREF(temp);
5235
Alexander Belopolsky878054e2012-06-22 14:11:58 -04005236 return result;
Tim Peters80475bb2002-12-25 07:40:55 +00005237}
5238
5239static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005240datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005242 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00005243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005244 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005245 PyObject * dst;
Tim Peters2a799bf2002-12-16 20:18:38 +00005246
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005247 dst = call_dst(self->tzinfo, (PyObject *)self);
5248 if (dst == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005249 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005250
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005251 if (dst != Py_None)
5252 dstflag = delta_bool((PyDateTime_Delta *)dst);
5253 Py_DECREF(dst);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005254 }
5255 return build_struct_time(GET_YEAR(self),
5256 GET_MONTH(self),
5257 GET_DAY(self),
5258 DATE_GET_HOUR(self),
5259 DATE_GET_MINUTE(self),
5260 DATE_GET_SECOND(self),
5261 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00005262}
5263
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005264static long long
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005265local_to_seconds(int year, int month, int day,
5266 int hour, int minute, int second, int fold)
5267{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005268 long long t, a, b, u1, u2, t1, t2, lt;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005269 t = utc_to_seconds(year, month, day, hour, minute, second);
5270 /* Our goal is to solve t = local(u) for u. */
5271 lt = local(t);
5272 if (lt == -1)
5273 return -1;
5274 a = lt - t;
5275 u1 = t - a;
5276 t1 = local(u1);
5277 if (t1 == -1)
5278 return -1;
5279 if (t1 == t) {
5280 /* We found one solution, but it may not be the one we need.
5281 * Look for an earlier solution (if `fold` is 0), or a
5282 * later one (if `fold` is 1). */
5283 if (fold)
5284 u2 = u1 + max_fold_seconds;
5285 else
5286 u2 = u1 - max_fold_seconds;
5287 lt = local(u2);
5288 if (lt == -1)
5289 return -1;
5290 b = lt - u2;
5291 if (a == b)
5292 return u1;
5293 }
5294 else {
5295 b = t1 - u1;
5296 assert(a != b);
5297 }
5298 u2 = t - b;
5299 t2 = local(u2);
5300 if (t2 == -1)
5301 return -1;
5302 if (t2 == t)
5303 return u2;
5304 if (t1 == t)
5305 return u1;
5306 /* We have found both offsets a and b, but neither t - a nor t - b is
5307 * a solution. This means t is in the gap. */
5308 return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5309}
5310
5311/* date(1970,1,1).toordinal() == 719163 */
5312#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5313
Tim Peters2a799bf2002-12-16 20:18:38 +00005314static PyObject *
Alexander Belopolskya4415142012-06-08 12:33:09 -04005315datetime_timestamp(PyDateTime_DateTime *self)
5316{
5317 PyObject *result;
5318
5319 if (HASTZINFO(self) && self->tzinfo != Py_None) {
5320 PyObject *delta;
5321 delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5322 if (delta == NULL)
5323 return NULL;
5324 result = delta_total_seconds(delta);
5325 Py_DECREF(delta);
5326 }
5327 else {
Benjamin Petersonaf580df2016-09-06 10:46:49 -07005328 long long seconds;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005329 seconds = local_to_seconds(GET_YEAR(self),
5330 GET_MONTH(self),
5331 GET_DAY(self),
5332 DATE_GET_HOUR(self),
5333 DATE_GET_MINUTE(self),
5334 DATE_GET_SECOND(self),
5335 DATE_GET_FOLD(self));
5336 if (seconds == -1)
Alexander Belopolskya4415142012-06-08 12:33:09 -04005337 return NULL;
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005338 result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5339 DATE_GET_MICROSECOND(self) / 1e6);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005340 }
5341 return result;
5342}
5343
5344static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005345datetime_getdate(PyDateTime_DateTime *self)
5346{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005347 return new_date(GET_YEAR(self),
5348 GET_MONTH(self),
5349 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005350}
5351
5352static PyObject *
5353datetime_gettime(PyDateTime_DateTime *self)
5354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005355 return new_time(DATE_GET_HOUR(self),
5356 DATE_GET_MINUTE(self),
5357 DATE_GET_SECOND(self),
5358 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005359 Py_None,
5360 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005361}
5362
5363static PyObject *
5364datetime_gettimetz(PyDateTime_DateTime *self)
5365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005366 return new_time(DATE_GET_HOUR(self),
5367 DATE_GET_MINUTE(self),
5368 DATE_GET_SECOND(self),
5369 DATE_GET_MICROSECOND(self),
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005370 GET_DT_TZINFO(self),
5371 DATE_GET_FOLD(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00005372}
5373
5374static PyObject *
5375datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005376{
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005377 int y, m, d, hh, mm, ss;
5378 PyObject *tzinfo;
5379 PyDateTime_DateTime *utcself;
Tim Peters2a799bf2002-12-16 20:18:38 +00005380
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005381 tzinfo = GET_DT_TZINFO(self);
5382 if (tzinfo == Py_None) {
5383 utcself = self;
5384 Py_INCREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005385 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005386 else {
5387 PyObject *offset;
5388 offset = call_utcoffset(tzinfo, (PyObject *)self);
5389 if (offset == NULL)
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00005390 return NULL;
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005391 if (offset == Py_None) {
5392 Py_DECREF(offset);
5393 utcself = self;
5394 Py_INCREF(utcself);
5395 }
5396 else {
5397 utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5398 (PyDateTime_Delta *)offset, -1);
5399 Py_DECREF(offset);
5400 if (utcself == NULL)
5401 return NULL;
5402 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005403 }
Alexander Belopolsky73ca4402010-07-07 23:56:38 +00005404 y = GET_YEAR(utcself);
5405 m = GET_MONTH(utcself);
5406 d = GET_DAY(utcself);
5407 hh = DATE_GET_HOUR(utcself);
5408 mm = DATE_GET_MINUTE(utcself);
5409 ss = DATE_GET_SECOND(utcself);
5410
5411 Py_DECREF(utcself);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005412 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005413}
5414
Tim Peters371935f2003-02-01 01:52:50 +00005415/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005416
Tim Petersa9bc1682003-01-11 03:39:11 +00005417/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005418 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5419 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005420 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005421 */
5422static PyObject *
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005423datetime_getstate(PyDateTime_DateTime *self, int proto)
Tim Peters2a799bf2002-12-16 20:18:38 +00005424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005425 PyObject *basestate;
5426 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005428 basestate = PyBytes_FromStringAndSize((char *)self->data,
5429 _PyDateTime_DATETIME_DATASIZE);
5430 if (basestate != NULL) {
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005431 if (proto > 3 && DATE_GET_FOLD(self))
5432 /* Set the first bit of the third byte */
5433 PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005434 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5435 result = PyTuple_Pack(1, basestate);
5436 else
5437 result = PyTuple_Pack(2, basestate, self->tzinfo);
5438 Py_DECREF(basestate);
5439 }
5440 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005441}
5442
5443static PyObject *
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005444datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
Tim Peters2a799bf2002-12-16 20:18:38 +00005445{
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005446 int proto;
5447 if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005448 return NULL;
5449
5450 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
Tim Peters2a799bf2002-12-16 20:18:38 +00005451}
5452
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005453static PyObject *
5454datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5455{
5456 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5457}
5458
Tim Petersa9bc1682003-01-11 03:39:11 +00005459static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005461 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005462
Larry Hastingsed4a1c52013-11-18 09:32:13 -08005463 DATETIME_DATETIME_NOW_METHODDEF
Tim Peters2a799bf2002-12-16 20:18:38 +00005464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005465 {"utcnow", (PyCFunction)datetime_utcnow,
5466 METH_NOARGS | METH_CLASS,
5467 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005469 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5470 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5471 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005473 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5474 METH_VARARGS | METH_CLASS,
Alexander Belopolskye2e178e2015-03-01 14:52:07 -05005475 PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005477 {"strptime", (PyCFunction)datetime_strptime,
5478 METH_VARARGS | METH_CLASS,
5479 PyDoc_STR("string, format -> new datetime parsed from a string "
5480 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005482 {"combine", (PyCFunction)datetime_combine,
5483 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5484 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005486 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005488 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5489 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005491 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5492 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005494 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5495 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005497 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5498 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005500 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5501 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005502
Alexander Belopolskya4415142012-06-08 12:33:09 -04005503 {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5504 PyDoc_STR("Return POSIX timestamp as float.")},
5505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005506 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5507 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005509 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5510 PyDoc_STR("[sep] -> string in ISO 8601 format, "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005511 "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005512 "sep is used to separate the year from the time, and "
Alexander Belopolskya2998a62016-03-06 14:58:43 -05005513 "defaults to 'T'.\n"
5514 "timespec specifies what components of the time to include"
5515 " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5516 " 'milliseconds', and 'microseconds').\n")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005518 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5519 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005521 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5522 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005524 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5525 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005527 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5528 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005529
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005530 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5531 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005532
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005533 {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005534 PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005535
Serhiy Storchaka546ce652016-11-22 00:29:42 +02005536 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5537 PyDoc_STR("__reduce__() -> (cls, state)")},
5538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005539 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005540};
5541
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02005542static const char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005543PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5544\n\
5545The year, month and day arguments are required. tzinfo may be None, or an\n\
Serhiy Storchaka95949422013-08-27 19:40:23 +03005546instance of a tzinfo subclass. The remaining arguments may be ints.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005547
Tim Petersa9bc1682003-01-11 03:39:11 +00005548static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005549 datetime_add, /* nb_add */
5550 datetime_subtract, /* nb_subtract */
5551 0, /* nb_multiply */
5552 0, /* nb_remainder */
5553 0, /* nb_divmod */
5554 0, /* nb_power */
5555 0, /* nb_negative */
5556 0, /* nb_positive */
5557 0, /* nb_absolute */
5558 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005559};
5560
Neal Norwitz227b5332006-03-22 09:28:35 +00005561static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005562 PyVarObject_HEAD_INIT(NULL, 0)
5563 "datetime.datetime", /* tp_name */
5564 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5565 0, /* tp_itemsize */
5566 (destructor)datetime_dealloc, /* tp_dealloc */
5567 0, /* tp_print */
5568 0, /* tp_getattr */
5569 0, /* tp_setattr */
5570 0, /* tp_reserved */
5571 (reprfunc)datetime_repr, /* tp_repr */
5572 &datetime_as_number, /* tp_as_number */
5573 0, /* tp_as_sequence */
5574 0, /* tp_as_mapping */
5575 (hashfunc)datetime_hash, /* tp_hash */
5576 0, /* tp_call */
5577 (reprfunc)datetime_str, /* tp_str */
5578 PyObject_GenericGetAttr, /* tp_getattro */
5579 0, /* tp_setattro */
5580 0, /* tp_as_buffer */
5581 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5582 datetime_doc, /* tp_doc */
5583 0, /* tp_traverse */
5584 0, /* tp_clear */
5585 datetime_richcompare, /* tp_richcompare */
5586 0, /* tp_weaklistoffset */
5587 0, /* tp_iter */
5588 0, /* tp_iternext */
5589 datetime_methods, /* tp_methods */
5590 0, /* tp_members */
5591 datetime_getset, /* tp_getset */
5592 &PyDateTime_DateType, /* tp_base */
5593 0, /* tp_dict */
5594 0, /* tp_descr_get */
5595 0, /* tp_descr_set */
5596 0, /* tp_dictoffset */
5597 0, /* tp_init */
5598 datetime_alloc, /* tp_alloc */
5599 datetime_new, /* tp_new */
5600 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005601};
5602
5603/* ---------------------------------------------------------------------------
5604 * Module methods and initialization.
5605 */
5606
5607static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005608 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005609};
5610
Tim Peters9ddf40b2004-06-20 22:41:32 +00005611/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5612 * datetime.h.
5613 */
5614static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005615 &PyDateTime_DateType,
5616 &PyDateTime_DateTimeType,
5617 &PyDateTime_TimeType,
5618 &PyDateTime_DeltaType,
5619 &PyDateTime_TZInfoType,
5620 new_date_ex,
5621 new_datetime_ex,
5622 new_time_ex,
5623 new_delta_ex,
5624 datetime_fromtimestamp,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005625 date_fromtimestamp,
5626 new_datetime_ex2,
5627 new_time_ex2
Tim Peters9ddf40b2004-06-20 22:41:32 +00005628};
5629
5630
Martin v. Löwis1a214512008-06-11 05:26:20 +00005631
5632static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005633 PyModuleDef_HEAD_INIT,
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005634 "_datetime",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005635 "Fast implementation of the datetime type.",
5636 -1,
5637 module_methods,
5638 NULL,
5639 NULL,
5640 NULL,
5641 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005642};
5643
Tim Peters2a799bf2002-12-16 20:18:38 +00005644PyMODINIT_FUNC
Alexander Belopolskycf86e362010-07-23 19:25:47 +00005645PyInit__datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005646{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005647 PyObject *m; /* a module object */
5648 PyObject *d; /* its dict */
5649 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005650 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005652 m = PyModule_Create(&datetimemodule);
5653 if (m == NULL)
5654 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005656 if (PyType_Ready(&PyDateTime_DateType) < 0)
5657 return NULL;
5658 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5659 return NULL;
5660 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5661 return NULL;
5662 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5663 return NULL;
5664 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5665 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005666 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5667 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005669 /* timedelta values */
5670 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005672 x = new_delta(0, 0, 1, 0);
5673 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5674 return NULL;
5675 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005677 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5678 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5679 return NULL;
5680 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005682 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5683 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5684 return NULL;
5685 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005687 /* date values */
5688 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005690 x = new_date(1, 1, 1);
5691 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5692 return NULL;
5693 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005695 x = new_date(MAXYEAR, 12, 31);
5696 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5697 return NULL;
5698 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005700 x = new_delta(1, 0, 0, 0);
5701 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5702 return NULL;
5703 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005705 /* time values */
5706 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005707
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005708 x = new_time(0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005709 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5710 return NULL;
5711 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005712
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005713 x = new_time(23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005714 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5715 return NULL;
5716 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005718 x = new_delta(0, 0, 1, 0);
5719 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5720 return NULL;
5721 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005723 /* datetime values */
5724 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005725
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005726 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005727 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5728 return NULL;
5729 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005730
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005731 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005732 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5733 return NULL;
5734 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005736 x = new_delta(0, 0, 1, 0);
5737 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5738 return NULL;
5739 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005740
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005741 /* timezone values */
5742 d = PyDateTime_TimeZoneType.tp_dict;
5743
5744 delta = new_delta(0, 0, 0, 0);
5745 if (delta == NULL)
5746 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005747 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005748 Py_DECREF(delta);
5749 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5750 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005751 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005752
5753 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5754 if (delta == NULL)
5755 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005756 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005757 Py_DECREF(delta);
5758 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5759 return NULL;
5760 Py_DECREF(x);
5761
5762 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5763 if (delta == NULL)
5764 return NULL;
Alexander Belopolsky1bcbaab2010-10-14 17:03:51 +00005765 x = create_timezone(delta, NULL);
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005766 Py_DECREF(delta);
5767 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5768 return NULL;
5769 Py_DECREF(x);
5770
Alexander Belopolskya4415142012-06-08 12:33:09 -04005771 /* Epoch */
5772 PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
Alexander Belopolsky5d0c5982016-07-22 18:47:04 -04005773 PyDateTime_TimeZone_UTC, 0);
Alexander Belopolskya4415142012-06-08 12:33:09 -04005774 if (PyDateTime_Epoch == NULL)
5775 return NULL;
5776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005777 /* module initialization */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +02005778 PyModule_AddIntMacro(m, MINYEAR);
5779 PyModule_AddIntMacro(m, MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005781 Py_INCREF(&PyDateTime_DateType);
5782 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005784 Py_INCREF(&PyDateTime_DateTimeType);
5785 PyModule_AddObject(m, "datetime",
5786 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005788 Py_INCREF(&PyDateTime_TimeType);
5789 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005790
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005791 Py_INCREF(&PyDateTime_DeltaType);
5792 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005794 Py_INCREF(&PyDateTime_TZInfoType);
5795 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005796
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005797 Py_INCREF(&PyDateTime_TimeZoneType);
5798 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005800 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5801 if (x == NULL)
5802 return NULL;
5803 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005805 /* A 4-year cycle has an extra leap day over what we'd get from
5806 * pasting together 4 single years.
5807 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005808 Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005809 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005810
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005811 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5812 * get from pasting together 4 100-year cycles.
5813 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005814 Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005815 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005817 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5818 * pasting together 25 4-year cycles.
5819 */
Serhiy Storchakafad85aa2015-11-07 15:42:38 +02005820 Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005821 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005822
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005823 one = PyLong_FromLong(1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005824 us_per_ms = PyLong_FromLong(1000);
5825 us_per_second = PyLong_FromLong(1000000);
5826 us_per_minute = PyLong_FromLong(60000000);
5827 seconds_per_day = PyLong_FromLong(24 * 3600);
Alexander Belopolsky790d2692013-08-04 14:51:35 -04005828 if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005829 us_per_minute == NULL || seconds_per_day == NULL)
5830 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005832 /* The rest are too big for 32-bit ints, but even
5833 * us_per_week fits in 40 bits, so doubles should be exact.
5834 */
5835 us_per_hour = PyLong_FromDouble(3600000000.0);
5836 us_per_day = PyLong_FromDouble(86400000000.0);
5837 us_per_week = PyLong_FromDouble(604800000000.0);
5838 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5839 return NULL;
5840 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005841}
Tim Petersf3615152003-01-01 21:51:37 +00005842
5843/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005844Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005845 x.n = x stripped of its timezone -- its naive time.
5846 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005847 return None
Tim Petersf3615152003-01-01 21:51:37 +00005848 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005849 return None
Tim Petersf3615152003-01-01 21:51:37 +00005850 x.s = x's standard offset, x.o - x.d
5851
5852Now some derived rules, where k is a duration (timedelta).
5853
58541. x.o = x.s + x.d
5855 This follows from the definition of x.s.
5856
Tim Petersc5dc4da2003-01-02 17:55:03 +000058572. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005858 This is actually a requirement, an assumption we need to make about
5859 sane tzinfo classes.
5860
58613. The naive UTC time corresponding to x is x.n - x.o.
5862 This is again a requirement for a sane tzinfo class.
5863
58644. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005865 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005866
Tim Petersc5dc4da2003-01-02 17:55:03 +000058675. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005868 Again follows from how arithmetic is defined.
5869
Tim Peters8bb5ad22003-01-24 02:44:45 +00005870Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005871(meaning that the various tzinfo methods exist, and don't blow up or return
5872None when called).
5873
Tim Petersa9bc1682003-01-11 03:39:11 +00005874The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005875x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005876
5877By #3, we want
5878
Tim Peters8bb5ad22003-01-24 02:44:45 +00005879 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005880
5881The algorithm starts by attaching tz to x.n, and calling that y. So
5882x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5883becomes true; in effect, we want to solve [2] for k:
5884
Tim Peters8bb5ad22003-01-24 02:44:45 +00005885 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005886
5887By #1, this is the same as
5888
Tim Peters8bb5ad22003-01-24 02:44:45 +00005889 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005890
5891By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5892Substituting that into [3],
5893
Tim Peters8bb5ad22003-01-24 02:44:45 +00005894 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5895 k - (y+k).s - (y+k).d = 0; rearranging,
5896 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5897 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005898
Tim Peters8bb5ad22003-01-24 02:44:45 +00005899On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5900approximate k by ignoring the (y+k).d term at first. Note that k can't be
5901very large, since all offset-returning methods return a duration of magnitude
5902less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5903be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005904
5905In any case, the new value is
5906
Tim Peters8bb5ad22003-01-24 02:44:45 +00005907 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005908
Tim Peters8bb5ad22003-01-24 02:44:45 +00005909It's helpful to step back at look at [4] from a higher level: it's simply
5910mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005911
5912At this point, if
5913
Tim Peters8bb5ad22003-01-24 02:44:45 +00005914 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005915
5916we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005917at the start of daylight time. Picture US Eastern for concreteness. The wall
5918time 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 +00005919sense then. The docs ask that an Eastern tzinfo class consider such a time to
5920be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5921on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005922the only spelling that makes sense on the local wall clock.
5923
Tim Petersc5dc4da2003-01-02 17:55:03 +00005924In fact, if [5] holds at this point, we do have the standard-time spelling,
5925but that takes a bit of proof. We first prove a stronger result. What's the
5926difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005927
Tim Peters8bb5ad22003-01-24 02:44:45 +00005928 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005929
Tim Petersc5dc4da2003-01-02 17:55:03 +00005930Now
5931 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005932 (y + y.s).n = by #5
5933 y.n + y.s = since y.n = x.n
5934 x.n + y.s = since z and y are have the same tzinfo member,
5935 y.s = z.s by #2
5936 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005937
Tim Petersc5dc4da2003-01-02 17:55:03 +00005938Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005939
Tim Petersc5dc4da2003-01-02 17:55:03 +00005940 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005941 x.n - ((x.n + z.s) - z.o) = expanding
5942 x.n - x.n - z.s + z.o = cancelling
5943 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005944 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005945
Tim Petersc5dc4da2003-01-02 17:55:03 +00005946So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005947
Tim Petersc5dc4da2003-01-02 17:55:03 +00005948If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005949spelling we wanted in the endcase described above. We're done. Contrarily,
5950if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005951
Tim Petersc5dc4da2003-01-02 17:55:03 +00005952If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5953add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005954local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005955
Tim Petersc5dc4da2003-01-02 17:55:03 +00005956Let
Tim Petersf3615152003-01-01 21:51:37 +00005957
Tim Peters4fede1a2003-01-04 00:26:59 +00005958 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005959
Tim Peters4fede1a2003-01-04 00:26:59 +00005960and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005961
Tim Peters8bb5ad22003-01-24 02:44:45 +00005962 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005963
Tim Peters8bb5ad22003-01-24 02:44:45 +00005964If so, we're done. If not, the tzinfo class is insane, according to the
5965assumptions we've made. This also requires a bit of proof. As before, let's
5966compute the difference between the LHS and RHS of [8] (and skipping some of
5967the justifications for the kinds of substitutions we've done several times
5968already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005969
Tim Peters8bb5ad22003-01-24 02:44:45 +00005970 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005971 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5972 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5973 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5974 - z.n + z.n - z.o + z'.o = cancel z.n
5975 - z.o + z'.o = #1 twice
5976 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5977 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005978
5979So 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 +00005980we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5981return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005982
Tim Peters8bb5ad22003-01-24 02:44:45 +00005983How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5984a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5985would have to change the result dst() returns: we start in DST, and moving
5986a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005987
Tim Peters8bb5ad22003-01-24 02:44:45 +00005988There isn't a sane case where this can happen. The closest it gets is at
5989the end of DST, where there's an hour in UTC with no spelling in a hybrid
5990tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5991that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5992UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5993time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5994clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5995standard time. Since that's what the local clock *does*, we want to map both
5996UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005997in local time, but so it goes -- it's the way the local clock works.
5998
Tim Peters8bb5ad22003-01-24 02:44:45 +00005999When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6000so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6001z' = 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 +00006002(correctly) concludes that z' is not UTC-equivalent to x.
6003
6004Because we know z.d said z was in daylight time (else [5] would have held and
6005we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00006006and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00006007return in Eastern, it follows that z'.d must be 0 (which it is in the example,
6008but the reasoning doesn't depend on the example -- it depends on there being
6009two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00006010z' must be in standard time, and is the spelling we want in this case.
6011
6012Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6013concerned (because it takes z' as being in standard time rather than the
6014daylight time we intend here), but returning it gives the real-life "local
6015clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6016tz.
6017
6018When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6019the 1:MM standard time spelling we want.
6020
6021So how can this break? One of the assumptions must be violated. Two
6022possibilities:
6023
60241) [2] effectively says that y.s is invariant across all y belong to a given
6025 time zone. This isn't true if, for political reasons or continental drift,
6026 a region decides to change its base offset from UTC.
6027
60282) There may be versions of "double daylight" time where the tail end of
6029 the analysis gives up a step too early. I haven't thought about that
6030 enough to say.
6031
6032In any case, it's clear that the default fromutc() is strong enough to handle
6033"almost all" time zones: so long as the standard offset is invariant, it
6034doesn't matter if daylight time transition points change from year to year, or
6035if daylight time is skipped in some years; it doesn't matter how large or
6036small dst() may get within its bounds; and it doesn't even matter if some
6037perverse time zone returns a negative dst()). So a breaking case must be
6038pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00006039--------------------------------------------------------------------------- */