blob: 34b8ed41b8dee459b378f66e5a741d056baa3c4d [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
Gregory P. Smith137d8242008-06-02 04:05:52 +00005#define PY_SSIZE_T_CLEAN
6
Tim Peters2a799bf2002-12-16 20:18:38 +00007#include "Python.h"
8#include "modsupport.h"
9#include "structmember.h"
10
11#include <time.h>
12
Tim Peters1b6f7a92004-06-20 02:50:16 +000013#include "timefuncs.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000014
15/* Differentiate between building the core module and building extension
16 * modules.
17 */
Kristján Valur Jónsson7a0da192007-04-30 15:17:46 +000018#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000019#define Py_BUILD_CORE
Kristján Valur Jónsson7a0da192007-04-30 15:17:46 +000020#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000021#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000022#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000023
24/* We require that C int be at least 32 bits, and use int virtually
25 * everywhere. In just a few cases we use a temp long, where a Python
26 * API returns a C long. In such cases, we have to ensure that the
27 * final result fits in a C int (this can be an issue on 64-bit boxes).
28 */
29#if SIZEOF_INT < 4
Antoine Pitrouc83ea132010-05-09 14:46:46 +000030# error "datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000031#endif
32
33#define MINYEAR 1
34#define MAXYEAR 9999
Alexander Belopolsky9292ee02010-05-27 20:55:27 +000035#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000036
37/* Nine decimal digits is easy to communicate, and leaves enough room
38 * so that two delta days can be added w/o fear of overflowing a signed
39 * 32-bit int, and with plenty of room left over to absorb any possible
40 * carries from adding seconds.
41 */
42#define MAX_DELTA_DAYS 999999999
43
44/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000045#define GET_YEAR PyDateTime_GET_YEAR
46#define GET_MONTH PyDateTime_GET_MONTH
47#define GET_DAY PyDateTime_GET_DAY
48#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
49#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
50#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
51#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000052
53/* Date accessors for date and datetime. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000054#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
55 ((o)->data[1] = ((v) & 0x00ff)))
56#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
57#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000058
59/* Date/Time accessors for datetime. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000060#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
61#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
62#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
63#define DATE_SET_MICROSECOND(o, v) \
64 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
65 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
66 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000067
68/* Time accessors for time. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000069#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
70#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
71#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
72#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
73#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
74#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
75#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
76#define TIME_SET_MICROSECOND(o, v) \
77 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
78 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
79 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000080
81/* Delta accessors for timedelta. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000082#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
83#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
84#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000085
Antoine Pitrouc83ea132010-05-09 14:46:46 +000086#define SET_TD_DAYS(o, v) ((o)->days = (v))
87#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000088#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
89
Tim Petersa032d2e2003-01-11 00:15:54 +000090/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
91 * p->hastzinfo.
92 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +000093#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
Tim Petersa032d2e2003-01-11 00:15:54 +000094
Tim Peters3f606292004-03-21 23:38:41 +000095/* M is a char or int claiming to be a valid month. The macro is equivalent
96 * to the two-sided Python test
Antoine Pitrouc83ea132010-05-09 14:46:46 +000097 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +000098 */
99#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
100
Tim Peters2a799bf2002-12-16 20:18:38 +0000101/* Forward declarations. */
102static PyTypeObject PyDateTime_DateType;
103static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000104static PyTypeObject PyDateTime_DeltaType;
105static PyTypeObject PyDateTime_TimeType;
106static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000107
108/* ---------------------------------------------------------------------------
109 * Math utilities.
110 */
111
112/* k = i+j overflows iff k differs in sign from both inputs,
113 * iff k^i has sign bit set and k^j has sign bit set,
114 * iff (k^i)&(k^j) has sign bit set.
115 */
116#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000117 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000118
119/* Compute Python divmod(x, y), returning the quotient and storing the
120 * remainder into *r. The quotient is the floor of x/y, and that's
121 * the real point of this. C will probably truncate instead (C99
122 * requires truncation; C89 left it implementation-defined).
123 * Simplification: we *require* that y > 0 here. That's appropriate
124 * for all the uses made of it. This simplifies the code and makes
125 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
126 * overflow case).
127 */
128static int
129divmod(int x, int y, int *r)
130{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000131 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000132
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000133 assert(y > 0);
134 quo = x / y;
135 *r = x - quo * y;
136 if (*r < 0) {
137 --quo;
138 *r += y;
139 }
140 assert(0 <= *r && *r < y);
141 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000142}
143
Tim Peters5d644dd2003-01-02 16:32:54 +0000144/* Round a double to the nearest long. |x| must be small enough to fit
145 * in a C long; this is not checked.
146 */
147static long
148round_to_long(double x)
149{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000150 if (x >= 0.0)
151 x = floor(x + 0.5);
152 else
153 x = ceil(x - 0.5);
154 return (long)x;
Tim Peters5d644dd2003-01-02 16:32:54 +0000155}
156
Tim Peters2a799bf2002-12-16 20:18:38 +0000157/* ---------------------------------------------------------------------------
158 * General calendrical helper functions
159 */
160
161/* For each month ordinal in 1..12, the number of days in that month,
162 * and the number of days before that month in the same year. These
163 * are correct for non-leap years only.
164 */
165static int _days_in_month[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000166 0, /* unused; this vector uses 1-based indexing */
167 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000168};
169
170static int _days_before_month[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000171 0, /* unused; this vector uses 1-based indexing */
172 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000173};
174
175/* year -> 1 if leap year, else 0. */
176static int
177is_leap(int year)
178{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000179 /* Cast year to unsigned. The result is the same either way, but
180 * C can generate faster code for unsigned mod than for signed
181 * mod (especially for % 4 -- a good compiler should just grab
182 * the last 2 bits when the LHS is unsigned).
183 */
184 const unsigned int ayear = (unsigned int)year;
185 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000186}
187
188/* year, month -> number of days in that month in that year */
189static int
190days_in_month(int year, int month)
191{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000192 assert(month >= 1);
193 assert(month <= 12);
194 if (month == 2 && is_leap(year))
195 return 29;
196 else
197 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000198}
199
Martin Panterb1d867f2016-05-26 05:28:50 +0000200/* year, month -> number of days in year preceding first day of month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000201static int
202days_before_month(int year, int month)
203{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000204 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000205
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000206 assert(month >= 1);
207 assert(month <= 12);
208 days = _days_before_month[month];
209 if (month > 2 && is_leap(year))
210 ++days;
211 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000212}
213
214/* year -> number of days before January 1st of year. Remember that we
215 * start with year 1, so days_before_year(1) == 0.
216 */
217static int
218days_before_year(int year)
219{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000220 int y = year - 1;
221 /* This is incorrect if year <= 0; we really want the floor
222 * here. But so long as MINYEAR is 1, the smallest year this
223 * can see is 0 (this can happen in some normalization endcases),
224 * so we'll just special-case that.
225 */
226 assert (year >= 0);
227 if (y >= 0)
228 return y*365 + y/4 - y/100 + y/400;
229 else {
230 assert(y == -1);
231 return -366;
232 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000233}
234
235/* Number of days in 4, 100, and 400 year cycles. That these have
236 * the correct values is asserted in the module init function.
237 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000238#define DI4Y 1461 /* days_before_year(5); days in 4 years */
239#define DI100Y 36524 /* days_before_year(101); days in 100 years */
240#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000241
242/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
243static void
244ord_to_ymd(int ordinal, int *year, int *month, int *day)
245{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000246 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000247
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000248 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
249 * leap years repeats exactly every 400 years. The basic strategy is
250 * to find the closest 400-year boundary at or before ordinal, then
251 * work with the offset from that boundary to ordinal. Life is much
252 * clearer if we subtract 1 from ordinal first -- then the values
253 * of ordinal at 400-year boundaries are exactly those divisible
254 * by DI400Y:
255 *
256 * D M Y n n-1
257 * -- --- ---- ---------- ----------------
258 * 31 Dec -400 -DI400Y -DI400Y -1
259 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
260 * ...
261 * 30 Dec 000 -1 -2
262 * 31 Dec 000 0 -1
263 * 1 Jan 001 1 0 400-year boundary
264 * 2 Jan 001 2 1
265 * 3 Jan 001 3 2
266 * ...
267 * 31 Dec 400 DI400Y DI400Y -1
268 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
269 */
270 assert(ordinal >= 1);
271 --ordinal;
272 n400 = ordinal / DI400Y;
273 n = ordinal % DI400Y;
274 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000275
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000276 /* Now n is the (non-negative) offset, in days, from January 1 of
277 * year, to the desired date. Now compute how many 100-year cycles
278 * precede n.
279 * Note that it's possible for n100 to equal 4! In that case 4 full
280 * 100-year cycles precede the desired day, which implies the
281 * desired day is December 31 at the end of a 400-year cycle.
282 */
283 n100 = n / DI100Y;
284 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000285
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000286 /* Now compute how many 4-year cycles precede it. */
287 n4 = n / DI4Y;
288 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000289
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000290 /* And now how many single years. Again n1 can be 4, and again
291 * meaning that the desired day is December 31 at the end of the
292 * 4-year cycle.
293 */
294 n1 = n / 365;
295 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000296
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000297 *year += n100 * 100 + n4 * 4 + n1;
298 if (n1 == 4 || n100 == 4) {
299 assert(n == 0);
300 *year -= 1;
301 *month = 12;
302 *day = 31;
303 return;
304 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000305
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000306 /* Now the year is correct, and n is the offset from January 1. We
307 * find the month via an estimate that's either exact or one too
308 * large.
309 */
310 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
311 assert(leapyear == is_leap(*year));
312 *month = (n + 50) >> 5;
313 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
314 if (preceding > n) {
315 /* estimate is too large */
316 *month -= 1;
317 preceding -= days_in_month(*year, *month);
318 }
319 n -= preceding;
320 assert(0 <= n);
321 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000322
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000323 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000324}
325
326/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
327static int
328ymd_to_ord(int year, int month, int day)
329{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000330 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000331}
332
333/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
334static int
335weekday(int year, int month, int day)
336{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000337 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000338}
339
340/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
341 * first calendar week containing a Thursday.
342 */
343static int
344iso_week1_monday(int year)
345{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000346 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
347 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
348 int first_weekday = (first_day + 6) % 7;
349 /* ordinal of closest Monday at or before 1/1 */
350 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000351
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000352 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
353 week1_monday += 7;
354 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000355}
356
357/* ---------------------------------------------------------------------------
358 * Range checkers.
359 */
360
361/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
362 * If not, raise OverflowError and return -1.
363 */
364static int
365check_delta_day_range(int days)
366{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000367 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
368 return 0;
369 PyErr_Format(PyExc_OverflowError,
370 "days=%d; must have magnitude <= %d",
371 days, MAX_DELTA_DAYS);
372 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000373}
374
375/* Check that date arguments are in range. Return 0 if they are. If they
376 * aren't, raise ValueError and return -1.
377 */
378static int
379check_date_args(int year, int month, int day)
380{
381
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000382 if (year < MINYEAR || year > MAXYEAR) {
383 PyErr_SetString(PyExc_ValueError,
384 "year is out of range");
385 return -1;
386 }
387 if (month < 1 || month > 12) {
388 PyErr_SetString(PyExc_ValueError,
389 "month must be in 1..12");
390 return -1;
391 }
392 if (day < 1 || day > days_in_month(year, month)) {
393 PyErr_SetString(PyExc_ValueError,
394 "day is out of range for month");
395 return -1;
396 }
397 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000398}
399
400/* Check that time arguments are in range. Return 0 if they are. If they
401 * aren't, raise ValueError and return -1.
402 */
403static int
404check_time_args(int h, int m, int s, int us)
405{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000406 if (h < 0 || h > 23) {
407 PyErr_SetString(PyExc_ValueError,
408 "hour must be in 0..23");
409 return -1;
410 }
411 if (m < 0 || m > 59) {
412 PyErr_SetString(PyExc_ValueError,
413 "minute must be in 0..59");
414 return -1;
415 }
416 if (s < 0 || s > 59) {
417 PyErr_SetString(PyExc_ValueError,
418 "second must be in 0..59");
419 return -1;
420 }
421 if (us < 0 || us > 999999) {
422 PyErr_SetString(PyExc_ValueError,
423 "microsecond must be in 0..999999");
424 return -1;
425 }
426 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000427}
428
429/* ---------------------------------------------------------------------------
430 * Normalization utilities.
431 */
432
433/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
434 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
435 * at least factor, enough of *lo is converted into "hi" units so that
436 * 0 <= *lo < factor. The input values must be such that int overflow
437 * is impossible.
438 */
439static void
440normalize_pair(int *hi, int *lo, int factor)
441{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000442 assert(factor > 0);
443 assert(lo != hi);
444 if (*lo < 0 || *lo >= factor) {
445 const int num_hi = divmod(*lo, factor, lo);
446 const int new_hi = *hi + num_hi;
447 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
448 *hi = new_hi;
449 }
450 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000451}
452
453/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000454 * 0 <= *s < 24*3600
455 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000456 * The input values must be such that the internals don't overflow.
457 * The way this routine is used, we don't get close.
458 */
459static void
460normalize_d_s_us(int *d, int *s, int *us)
461{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000462 if (*us < 0 || *us >= 1000000) {
463 normalize_pair(s, us, 1000000);
464 /* |s| can't be bigger than about
465 * |original s| + |original us|/1000000 now.
466 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000467
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000468 }
469 if (*s < 0 || *s >= 24*3600) {
470 normalize_pair(d, s, 24*3600);
471 /* |d| can't be bigger than about
472 * |original d| +
473 * (|original s| + |original us|/1000000) / (24*3600) now.
474 */
475 }
476 assert(0 <= *s && *s < 24*3600);
477 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000478}
479
480/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000481 * 1 <= *m <= 12
482 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000483 * The input values must be such that the internals don't overflow.
484 * The way this routine is used, we don't get close.
485 */
Alexander Belopolsky9292ee02010-05-27 20:55:27 +0000486static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000487normalize_y_m_d(int *y, int *m, int *d)
488{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000489 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000490
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000491 /* This gets muddy: the proper range for day can't be determined
492 * without knowing the correct month and year, but if day is, e.g.,
493 * plus or minus a million, the current month and year values make
494 * no sense (and may also be out of bounds themselves).
495 * Saying 12 months == 1 year should be non-controversial.
496 */
497 if (*m < 1 || *m > 12) {
498 --*m;
499 normalize_pair(y, m, 12);
500 ++*m;
501 /* |y| can't be bigger than about
502 * |original y| + |original m|/12 now.
503 */
504 }
505 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000506
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000507 /* Now only day can be out of bounds (year may also be out of bounds
508 * for a datetime object, but we don't care about that here).
509 * If day is out of bounds, what to do is arguable, but at least the
510 * method here is principled and explainable.
511 */
512 dim = days_in_month(*y, *m);
513 if (*d < 1 || *d > dim) {
514 /* Move day-1 days from the first of the month. First try to
515 * get off cheap if we're only one day out of range
516 * (adjustments for timezone alone can't be worse than that).
517 */
518 if (*d == 0) {
519 --*m;
520 if (*m > 0)
521 *d = days_in_month(*y, *m);
522 else {
523 --*y;
524 *m = 12;
525 *d = 31;
526 }
527 }
528 else if (*d == dim + 1) {
529 /* move forward a day */
530 ++*m;
531 *d = 1;
532 if (*m > 12) {
533 *m = 1;
534 ++*y;
535 }
536 }
537 else {
538 int ordinal = ymd_to_ord(*y, *m, 1) +
539 *d - 1;
Alexander Belopolsky9292ee02010-05-27 20:55:27 +0000540 if (ordinal < 1 || ordinal > MAXORDINAL) {
541 goto error;
542 } else {
543 ord_to_ymd(ordinal, y, m, d);
544 return 0;
545 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000546 }
547 }
548 assert(*m > 0);
549 assert(*d > 0);
Alexander Belopolsky9292ee02010-05-27 20:55:27 +0000550 if (MINYEAR <= *y && *y <= MAXYEAR)
551 return 0;
552 error:
553 PyErr_SetString(PyExc_OverflowError,
554 "date value out of range");
555 return -1;
556
Tim Peters2a799bf2002-12-16 20:18:38 +0000557}
558
559/* Fiddle out-of-bounds months and days so that the result makes some kind
560 * of sense. The parameters are both inputs and outputs. Returns < 0 on
561 * failure, where failure means the adjusted year is out of bounds.
562 */
563static int
564normalize_date(int *year, int *month, int *day)
565{
Alexander Belopolsky9292ee02010-05-27 20:55:27 +0000566 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000567}
568
569/* Force all the datetime fields into range. The parameters are both
570 * inputs and outputs. Returns < 0 on error.
571 */
572static int
573normalize_datetime(int *year, int *month, int *day,
574 int *hour, int *minute, int *second,
575 int *microsecond)
576{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000577 normalize_pair(second, microsecond, 1000000);
578 normalize_pair(minute, second, 60);
579 normalize_pair(hour, minute, 60);
580 normalize_pair(day, hour, 24);
581 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000582}
583
584/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000585 * Basic object allocation: tp_alloc implementations. These allocate
586 * Python objects of the right size and type, and do the Python object-
587 * initialization bit. If there's not enough memory, they return NULL after
588 * setting MemoryError. All data members remain uninitialized trash.
589 *
590 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000591 * member is needed. This is ugly, imprecise, and possibly insecure.
592 * tp_basicsize for the time and datetime types is set to the size of the
593 * struct that has room for the tzinfo member, so subclasses in Python will
594 * allocate enough space for a tzinfo member whether or not one is actually
595 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
596 * part is that PyType_GenericAlloc() (which subclasses in Python end up
597 * using) just happens today to effectively ignore the nitems argument
598 * when tp_itemsize is 0, which it is for these type objects. If that
599 * changes, perhaps the callers of tp_alloc slots in this file should
600 * be changed to force a 0 nitems argument unless the type being allocated
601 * is a base type implemented in this file (so that tp_alloc is time_alloc
602 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000603 */
604
605static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000606time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000607{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000608 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000609
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000610 self = (PyObject *)
611 PyObject_MALLOC(aware ?
612 sizeof(PyDateTime_Time) :
613 sizeof(_PyDateTime_BaseTime));
614 if (self == NULL)
615 return (PyObject *)PyErr_NoMemory();
Martin Panter646b5282016-06-21 23:58:05 +0000616 (void)PyObject_INIT(self, type);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000617 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000618}
619
620static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000621datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000622{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000623 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000624
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000625 self = (PyObject *)
626 PyObject_MALLOC(aware ?
627 sizeof(PyDateTime_DateTime) :
628 sizeof(_PyDateTime_BaseDateTime));
629 if (self == NULL)
630 return (PyObject *)PyErr_NoMemory();
Martin Panter646b5282016-06-21 23:58:05 +0000631 (void)PyObject_INIT(self, type);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000632 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000633}
634
635/* ---------------------------------------------------------------------------
636 * Helpers for setting object fields. These work on pointers to the
637 * appropriate base class.
638 */
639
640/* For date and datetime. */
641static void
642set_date_fields(PyDateTime_Date *self, int y, int m, int d)
643{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000644 self->hashcode = -1;
645 SET_YEAR(self, y);
646 SET_MONTH(self, m);
647 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000648}
649
650/* ---------------------------------------------------------------------------
651 * Create various objects, mostly without range checking.
652 */
653
654/* Create a date instance with no range checking. */
655static PyObject *
656new_date_ex(int year, int month, int day, PyTypeObject *type)
657{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000658 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000659
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000660 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
661 if (self != NULL)
662 set_date_fields(self, year, month, day);
663 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000664}
665
666#define new_date(year, month, day) \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000667 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000668
669/* Create a datetime instance with no range checking. */
670static PyObject *
671new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000672 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000673{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000674 PyDateTime_DateTime *self;
675 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000676
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000677 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
678 if (self != NULL) {
679 self->hastzinfo = aware;
680 set_date_fields((PyDateTime_Date *)self, year, month, day);
681 DATE_SET_HOUR(self, hour);
682 DATE_SET_MINUTE(self, minute);
683 DATE_SET_SECOND(self, second);
684 DATE_SET_MICROSECOND(self, usecond);
685 if (aware) {
686 Py_INCREF(tzinfo);
687 self->tzinfo = tzinfo;
688 }
689 }
690 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000691}
692
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000693#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
694 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
695 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000696
697/* Create a time instance with no range checking. */
698static PyObject *
699new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000700 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000701{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000702 PyDateTime_Time *self;
703 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000704
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000705 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
706 if (self != NULL) {
707 self->hastzinfo = aware;
708 self->hashcode = -1;
709 TIME_SET_HOUR(self, hour);
710 TIME_SET_MINUTE(self, minute);
711 TIME_SET_SECOND(self, second);
712 TIME_SET_MICROSECOND(self, usecond);
713 if (aware) {
714 Py_INCREF(tzinfo);
715 self->tzinfo = tzinfo;
716 }
717 }
718 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000719}
720
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000721#define new_time(hh, mm, ss, us, tzinfo) \
722 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000723
724/* Create a timedelta instance. Normalize the members iff normalize is
725 * true. Passing false is a speed optimization, if you know for sure
726 * that seconds and microseconds are already in their proper ranges. In any
727 * case, raises OverflowError and returns NULL if the normalized days is out
728 * of range).
729 */
730static PyObject *
731new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000732 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000733{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000734 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000735
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000736 if (normalize)
737 normalize_d_s_us(&days, &seconds, &microseconds);
738 assert(0 <= seconds && seconds < 24*3600);
739 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000740
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000741 if (check_delta_day_range(days) < 0)
742 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000743
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000744 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
745 if (self != NULL) {
746 self->hashcode = -1;
747 SET_TD_DAYS(self, days);
748 SET_TD_SECONDS(self, seconds);
749 SET_TD_MICROSECONDS(self, microseconds);
750 }
751 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000752}
753
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000754#define new_delta(d, s, us, normalize) \
755 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000756
757/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000758 * tzinfo helpers.
759 */
760
Tim Peters855fe882002-12-22 03:43:39 +0000761/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
762 * raise TypeError and return -1.
763 */
764static int
765check_tzinfo_subclass(PyObject *p)
766{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000767 if (p == Py_None || PyTZInfo_Check(p))
768 return 0;
769 PyErr_Format(PyExc_TypeError,
770 "tzinfo argument must be None or of a tzinfo subclass, "
771 "not type '%s'",
772 Py_TYPE(p)->tp_name);
773 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000774}
775
Tim Petersbad8ff02002-12-30 20:52:32 +0000776/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000777 * If tzinfo is None, returns None.
778 */
779static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000780call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000781{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000782 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000783
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000784 assert(tzinfo && methname && tzinfoarg);
785 assert(check_tzinfo_subclass(tzinfo) >= 0);
786 if (tzinfo == Py_None) {
787 result = Py_None;
788 Py_INCREF(result);
789 }
790 else
791 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
792 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000793}
794
Tim Peters2a799bf2002-12-16 20:18:38 +0000795/* If self has a tzinfo member, return a BORROWED reference to it. Else
796 * return NULL, which is NOT AN ERROR. There are no error returns here,
797 * and the caller must not decref the result.
798 */
799static PyObject *
800get_tzinfo_member(PyObject *self)
801{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000802 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000803
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000804 if (PyDateTime_Check(self) && HASTZINFO(self))
805 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
806 else if (PyTime_Check(self) && HASTZINFO(self))
807 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000808
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000809 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000810}
811
Tim Petersbad8ff02002-12-30 20:52:32 +0000812/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000813 * result. tzinfo must be an instance of the tzinfo class. If the method
814 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000815 * return None or timedelta, TypeError is raised and this returns -1. If it
816 * returnsa timedelta and the value is out of range or isn't a whole number
817 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000818 * Else *none is set to 0 and the integer method result is returned.
819 */
820static int
821call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000822 int *none)
Tim Peters2a799bf2002-12-16 20:18:38 +0000823{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000824 PyObject *u;
825 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000826
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000827 assert(tzinfo != NULL);
828 assert(PyTZInfo_Check(tzinfo));
829 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000830
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000831 *none = 0;
832 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
833 if (u == NULL)
834 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000835
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000836 else if (u == Py_None) {
837 result = 0;
838 *none = 1;
839 }
840 else if (PyDelta_Check(u)) {
841 const int days = GET_TD_DAYS(u);
842 if (days < -1 || days > 0)
843 result = 24*60; /* trigger ValueError below */
844 else {
845 /* next line can't overflow because we know days
846 * is -1 or 0 now
847 */
848 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
849 result = divmod(ss, 60, &ss);
850 if (ss || GET_TD_MICROSECONDS(u)) {
851 PyErr_Format(PyExc_ValueError,
852 "tzinfo.%s() must return a "
853 "whole number of minutes",
854 name);
855 result = -1;
856 }
857 }
858 }
859 else {
860 PyErr_Format(PyExc_TypeError,
861 "tzinfo.%s() must return None or "
862 "timedelta, not '%s'",
863 name, Py_TYPE(u)->tp_name);
864 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000865
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000866 Py_DECREF(u);
867 if (result < -1439 || result > 1439) {
868 PyErr_Format(PyExc_ValueError,
869 "tzinfo.%s() returned %d; must be in "
870 "-1439 .. 1439",
871 name, result);
872 result = -1;
873 }
874 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000875}
876
877/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
878 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
879 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000880 * doesn't return None or timedelta, TypeError is raised and this returns -1.
881 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
882 * # of minutes), ValueError is raised and this returns -1. Else *none is
883 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000884 */
885static int
886call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
887{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000888 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000889}
890
Tim Petersbad8ff02002-12-30 20:52:32 +0000891/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
892 */
Tim Peters855fe882002-12-22 03:43:39 +0000893static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000894offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000895 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000896
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000897 assert(tzinfo && name && tzinfoarg);
898 if (tzinfo == Py_None) {
899 result = Py_None;
900 Py_INCREF(result);
901 }
902 else {
903 int none;
904 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
905 &none);
906 if (offset < 0 && PyErr_Occurred())
907 return NULL;
908 if (none) {
909 result = Py_None;
910 Py_INCREF(result);
911 }
912 else
913 result = new_delta(0, offset * 60, 0, 1);
914 }
915 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000916}
917
Tim Peters2a799bf2002-12-16 20:18:38 +0000918/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
919 * result. tzinfo must be an instance of the tzinfo class. If dst()
920 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000921 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000922 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000923 * ValueError is raised and this returns -1. Else *none is set to 0 and
924 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000925 */
926static int
927call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
928{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000929 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000930}
931
Tim Petersbad8ff02002-12-30 20:52:32 +0000932/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000933 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000934 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000935 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000936 */
937static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000938call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000939{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000940 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000941
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000942 assert(tzinfo != NULL);
943 assert(check_tzinfo_subclass(tzinfo) >= 0);
944 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000945
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000946 if (tzinfo == Py_None) {
947 result = Py_None;
948 Py_INCREF(result);
949 }
950 else
951 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000952
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000953 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
954 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
955 "return None or a string, not '%s'",
956 Py_TYPE(result)->tp_name);
957 Py_DECREF(result);
958 result = NULL;
959 }
960 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000961}
962
963typedef enum {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000964 /* an exception has been set; the caller should pass it on */
965 OFFSET_ERROR,
Tim Peters2a799bf2002-12-16 20:18:38 +0000966
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000967 /* type isn't date, datetime, or time subclass */
968 OFFSET_UNKNOWN,
Tim Peters2a799bf2002-12-16 20:18:38 +0000969
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000970 /* date,
971 * datetime with !hastzinfo
972 * datetime with None tzinfo,
973 * datetime where utcoffset() returns None
974 * time with !hastzinfo
975 * time with None tzinfo,
976 * time where utcoffset() returns None
977 */
978 OFFSET_NAIVE,
Tim Peters2a799bf2002-12-16 20:18:38 +0000979
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000980 /* time or datetime where utcoffset() doesn't return None */
981 OFFSET_AWARE
Tim Peters2a799bf2002-12-16 20:18:38 +0000982} naivety;
983
Tim Peters14b69412002-12-22 18:10:22 +0000984/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000985 * the "naivety" typedef for details. If the type is aware, *offset is set
986 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000987 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000988 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000989 */
990static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000991classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000992{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000993 int none;
994 PyObject *tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000995
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000996 assert(tzinfoarg != NULL);
997 *offset = 0;
998 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
999 if (tzinfo == Py_None)
1000 return OFFSET_NAIVE;
1001 if (tzinfo == NULL) {
1002 /* note that a datetime passes the PyDate_Check test */
1003 return (PyTime_Check(op) || PyDate_Check(op)) ?
1004 OFFSET_NAIVE : OFFSET_UNKNOWN;
1005 }
1006 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1007 if (*offset == -1 && PyErr_Occurred())
1008 return OFFSET_ERROR;
1009 return none ? OFFSET_NAIVE : OFFSET_AWARE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001010}
1011
Tim Peters00237032002-12-27 02:21:51 +00001012/* Classify two objects as to whether they're naive or offset-aware.
1013 * This isn't quite the same as calling classify_utcoffset() twice: for
1014 * binary operations (comparison and subtraction), we generally want to
1015 * ignore the tzinfo members if they're identical. This is by design,
1016 * so that results match "naive" expectations when mixing objects from a
1017 * single timezone. So in that case, this sets both offsets to 0 and
1018 * both naiveties to OFFSET_NAIVE.
1019 * The function returns 0 if everything's OK, and -1 on error.
1020 */
1021static int
1022classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001023 PyObject *tzinfoarg1,
1024 PyObject *o2, int *offset2, naivety *n2,
1025 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001026{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001027 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1028 *offset1 = *offset2 = 0;
1029 *n1 = *n2 = OFFSET_NAIVE;
1030 }
1031 else {
1032 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1033 if (*n1 == OFFSET_ERROR)
1034 return -1;
1035 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1036 if (*n2 == OFFSET_ERROR)
1037 return -1;
1038 }
1039 return 0;
Tim Peters00237032002-12-27 02:21:51 +00001040}
1041
Tim Peters2a799bf2002-12-16 20:18:38 +00001042/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1043 * stuff
1044 * ", tzinfo=" + repr(tzinfo)
1045 * before the closing ")".
1046 */
1047static PyObject *
1048append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1049{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001050 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001051
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001052 assert(PyString_Check(repr));
1053 assert(tzinfo);
1054 if (tzinfo == Py_None)
1055 return repr;
1056 /* Get rid of the trailing ')'. */
1057 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1058 temp = PyString_FromStringAndSize(PyString_AsString(repr),
1059 PyString_Size(repr) - 1);
1060 Py_DECREF(repr);
1061 if (temp == NULL)
1062 return NULL;
1063 repr = temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001064
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001065 /* Append ", tzinfo=". */
1066 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
Tim Peters2a799bf2002-12-16 20:18:38 +00001067
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001068 /* Append repr(tzinfo). */
1069 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
Tim Peters2a799bf2002-12-16 20:18:38 +00001070
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001071 /* Add a closing paren. */
1072 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
1073 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001074}
1075
1076/* ---------------------------------------------------------------------------
1077 * String format helpers.
1078 */
1079
1080static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001081format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001082{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001083 static const char *DayNames[] = {
1084 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1085 };
1086 static const char *MonthNames[] = {
1087 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1088 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1089 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001090
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001091 char buffer[128];
1092 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001093
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001094 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
1095 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
1096 GET_DAY(date), hours, minutes, seconds,
1097 GET_YEAR(date));
1098 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00001099}
1100
1101/* Add an hours & minutes UTC offset string to buf. buf has no more than
1102 * buflen bytes remaining. The UTC offset is gotten by calling
1103 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1104 * *buf, and that's all. Else the returned value is checked for sanity (an
1105 * integer in range), and if that's OK it's converted to an hours & minutes
1106 * string of the form
1107 * sign HH sep MM
1108 * Returns 0 if everything is OK. If the return value from utcoffset() is
1109 * bogus, an appropriate exception is set and -1 is returned.
1110 */
1111static int
Tim Peters328fff72002-12-20 01:31:27 +00001112format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001113 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001114{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001115 int offset;
1116 int hours;
1117 int minutes;
1118 char sign;
1119 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00001120
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001121 assert(buflen >= 1);
Gregory P. Smith9d534572008-06-11 07:41:16 +00001122
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001123 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1124 if (offset == -1 && PyErr_Occurred())
1125 return -1;
1126 if (none) {
1127 *buf = '\0';
1128 return 0;
1129 }
1130 sign = '+';
1131 if (offset < 0) {
1132 sign = '-';
1133 offset = - offset;
1134 }
1135 hours = divmod(offset, 60, &minutes);
1136 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1137 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001138}
1139
Skip Montanarofc070d22008-03-15 16:04:45 +00001140static PyObject *
1141make_freplacement(PyObject *object)
1142{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001143 char freplacement[64];
1144 if (PyTime_Check(object))
1145 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1146 else if (PyDateTime_Check(object))
1147 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1148 else
1149 sprintf(freplacement, "%06d", 0);
Skip Montanarofc070d22008-03-15 16:04:45 +00001150
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001151 return PyString_FromStringAndSize(freplacement, strlen(freplacement));
Skip Montanarofc070d22008-03-15 16:04:45 +00001152}
1153
Tim Peters2a799bf2002-12-16 20:18:38 +00001154/* I sure don't want to reproduce the strftime code from the time module,
1155 * so this imports the module and calls it. All the hair is due to
Skip Montanarofc070d22008-03-15 16:04:45 +00001156 * giving special meanings to the %z, %Z and %f format codes via a
1157 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001158 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1159 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001160 */
1161static PyObject *
Gregory P. Smith137d8242008-06-02 04:05:52 +00001162wrap_strftime(PyObject *object, const char *format, size_t format_len,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001163 PyObject *timetuple, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001164{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001165 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001166
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001167 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1168 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1169 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001170
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001171 const char *pin; /* pointer to next char in input format */
1172 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001173
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001174 PyObject *newfmt = NULL; /* py string, the output format */
1175 char *pnew; /* pointer to available byte in output format */
1176 size_t totalnew; /* number bytes total in output format buffer,
1177 exclusive of trailing \0 */
1178 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001179
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001180 const char *ptoappend; /* ptr to string to append to output buffer */
1181 size_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001182
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001183 assert(object && format && timetuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001184
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001185 /* Give up if the year is before 1900.
1186 * Python strftime() plays games with the year, and different
1187 * games depending on whether envar PYTHON2K is set. This makes
1188 * years before 1900 a nightmare, even if the platform strftime
1189 * supports them (and not all do).
1190 * We could get a lot farther here by avoiding Python's strftime
1191 * wrapper and calling the C strftime() directly, but that isn't
1192 * an option in the Python implementation of this module.
1193 */
1194 {
1195 long year;
1196 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1197 if (pyyear == NULL) return NULL;
1198 assert(PyInt_Check(pyyear));
1199 year = PyInt_AsLong(pyyear);
1200 Py_DECREF(pyyear);
1201 if (year < 1900) {
1202 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1203 "1900; the datetime strftime() "
1204 "methods require year >= 1900",
1205 year);
1206 return NULL;
1207 }
1208 }
Tim Petersd6844152002-12-22 20:58:42 +00001209
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001210 /* Scan the input format, looking for %z/%Z/%f escapes, building
1211 * a new format. Since computing the replacements for those codes
1212 * is expensive, don't unless they're actually used.
1213 */
1214 if (format_len > INT_MAX - 1) {
1215 PyErr_NoMemory();
1216 goto Done;
1217 }
Gregory P. Smith9d534572008-06-11 07:41:16 +00001218
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001219 totalnew = format_len + 1; /* realistic if no %z/%Z/%f */
1220 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1221 if (newfmt == NULL) goto Done;
1222 pnew = PyString_AsString(newfmt);
1223 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001224
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001225 pin = format;
1226 while ((ch = *pin++) != '\0') {
1227 if (ch != '%') {
1228 ptoappend = pin - 1;
1229 ntoappend = 1;
1230 }
1231 else if ((ch = *pin++) == '\0') {
1232 /* There's a lone trailing %; doesn't make sense. */
1233 PyErr_SetString(PyExc_ValueError, "strftime format "
1234 "ends with raw %");
1235 goto Done;
1236 }
1237 /* A % has been seen and ch is the character after it. */
1238 else if (ch == 'z') {
1239 if (zreplacement == NULL) {
1240 /* format utcoffset */
1241 char buf[100];
1242 PyObject *tzinfo = get_tzinfo_member(object);
1243 zreplacement = PyString_FromString("");
1244 if (zreplacement == NULL) goto Done;
1245 if (tzinfo != Py_None && tzinfo != NULL) {
1246 assert(tzinfoarg != NULL);
1247 if (format_utcoffset(buf,
1248 sizeof(buf),
1249 "",
1250 tzinfo,
1251 tzinfoarg) < 0)
1252 goto Done;
1253 Py_DECREF(zreplacement);
1254 zreplacement = PyString_FromString(buf);
1255 if (zreplacement == NULL) goto Done;
1256 }
1257 }
1258 assert(zreplacement != NULL);
1259 ptoappend = PyString_AS_STRING(zreplacement);
1260 ntoappend = PyString_GET_SIZE(zreplacement);
1261 }
1262 else if (ch == 'Z') {
1263 /* format tzname */
1264 if (Zreplacement == NULL) {
1265 PyObject *tzinfo = get_tzinfo_member(object);
1266 Zreplacement = PyString_FromString("");
1267 if (Zreplacement == NULL) goto Done;
1268 if (tzinfo != Py_None && tzinfo != NULL) {
1269 PyObject *temp;
1270 assert(tzinfoarg != NULL);
1271 temp = call_tzname(tzinfo, tzinfoarg);
1272 if (temp == NULL) goto Done;
1273 if (temp != Py_None) {
1274 assert(PyString_Check(temp));
1275 /* Since the tzname is getting
1276 * stuffed into the format, we
1277 * have to double any % signs
1278 * so that strftime doesn't
1279 * treat them as format codes.
1280 */
1281 Py_DECREF(Zreplacement);
1282 Zreplacement = PyObject_CallMethod(
1283 temp, "replace",
1284 "ss", "%", "%%");
1285 Py_DECREF(temp);
1286 if (Zreplacement == NULL)
1287 goto Done;
1288 if (!PyString_Check(Zreplacement)) {
1289 PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
1290 goto Done;
1291 }
1292 }
1293 else
1294 Py_DECREF(temp);
1295 }
1296 }
1297 assert(Zreplacement != NULL);
1298 ptoappend = PyString_AS_STRING(Zreplacement);
1299 ntoappend = PyString_GET_SIZE(Zreplacement);
1300 }
1301 else if (ch == 'f') {
1302 /* format microseconds */
1303 if (freplacement == NULL) {
1304 freplacement = make_freplacement(object);
1305 if (freplacement == NULL)
1306 goto Done;
1307 }
1308 assert(freplacement != NULL);
1309 assert(PyString_Check(freplacement));
1310 ptoappend = PyString_AS_STRING(freplacement);
1311 ntoappend = PyString_GET_SIZE(freplacement);
1312 }
1313 else {
1314 /* percent followed by neither z nor Z */
1315 ptoappend = pin - 2;
1316 ntoappend = 2;
1317 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001318
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001319 /* Append the ntoappend chars starting at ptoappend to
1320 * the new format.
1321 */
1322 assert(ptoappend != NULL);
1323 assert(ntoappend >= 0);
1324 if (ntoappend == 0)
1325 continue;
1326 while (usednew + ntoappend > totalnew) {
1327 size_t bigger = totalnew << 1;
1328 if ((bigger >> 1) != totalnew) { /* overflow */
1329 PyErr_NoMemory();
1330 goto Done;
1331 }
1332 if (_PyString_Resize(&newfmt, bigger) < 0)
1333 goto Done;
1334 totalnew = bigger;
1335 pnew = PyString_AsString(newfmt) + usednew;
1336 }
1337 memcpy(pnew, ptoappend, ntoappend);
1338 pnew += ntoappend;
1339 usednew += ntoappend;
1340 assert(usednew <= totalnew);
1341 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001342
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001343 if (_PyString_Resize(&newfmt, usednew) < 0)
1344 goto Done;
1345 {
1346 PyObject *time = PyImport_ImportModuleNoBlock("time");
1347 if (time == NULL)
1348 goto Done;
1349 result = PyObject_CallMethod(time, "strftime", "OO",
1350 newfmt, timetuple);
1351 Py_DECREF(time);
1352 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001353 Done:
Antoine Pitrouc83ea132010-05-09 14:46:46 +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
1361static char *
1362isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1363{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001364 int x;
1365 x = PyOS_snprintf(buffer, bufflen,
1366 "%04d-%02d-%02d",
1367 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1368 assert(bufflen >= x);
1369 return buffer + x;
Tim Peters2a799bf2002-12-16 20:18:38 +00001370}
1371
Amaury Forgeot d'Arc8645a5c2009-12-29 22:03:38 +00001372static char *
Tim Peters2a799bf2002-12-16 20:18:38 +00001373isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1374{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001375 int x;
1376 int us = DATE_GET_MICROSECOND(dt);
Tim Peters2a799bf2002-12-16 20:18:38 +00001377
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001378 x = PyOS_snprintf(buffer, bufflen,
1379 "%02d:%02d:%02d",
1380 DATE_GET_HOUR(dt),
1381 DATE_GET_MINUTE(dt),
1382 DATE_GET_SECOND(dt));
1383 assert(bufflen >= x);
1384 if (us)
1385 x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us);
1386 assert(bufflen >= x);
1387 return buffer + x;
Tim Peters2a799bf2002-12-16 20:18:38 +00001388}
1389
1390/* ---------------------------------------------------------------------------
1391 * Wrap functions from the time module. These aren't directly available
1392 * from C. Perhaps they should be.
1393 */
1394
1395/* Call time.time() and return its result (a Python float). */
1396static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001397time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001398{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001399 PyObject *result = NULL;
1400 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001401
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001402 if (time != NULL) {
1403 result = PyObject_CallMethod(time, "time", "()");
1404 Py_DECREF(time);
1405 }
1406 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001407}
1408
1409/* Build a time.struct_time. The weekday and day number are automatically
1410 * computed from the y,m,d args.
1411 */
1412static PyObject *
1413build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1414{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001415 PyObject *time;
1416 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001417
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001418 time = PyImport_ImportModuleNoBlock("time");
1419 if (time != NULL) {
1420 result = PyObject_CallMethod(time, "struct_time",
1421 "((iiiiiiiii))",
1422 y, m, d,
1423 hh, mm, ss,
1424 weekday(y, m, d),
1425 days_before_month(y, m) + d,
1426 dstflag);
1427 Py_DECREF(time);
1428 }
1429 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001430}
1431
1432/* ---------------------------------------------------------------------------
1433 * Miscellaneous helpers.
1434 */
1435
1436/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1437 * The comparisons here all most naturally compute a cmp()-like result.
1438 * This little helper turns that into a bool result for rich comparisons.
1439 */
1440static PyObject *
1441diff_to_bool(int diff, int op)
1442{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001443 PyObject *result;
1444 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001445
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001446 switch (op) {
1447 case Py_EQ: istrue = diff == 0; break;
1448 case Py_NE: istrue = diff != 0; break;
1449 case Py_LE: istrue = diff <= 0; break;
1450 case Py_GE: istrue = diff >= 0; break;
1451 case Py_LT: istrue = diff < 0; break;
1452 case Py_GT: istrue = diff > 0; break;
1453 default:
1454 assert(! "op unknown");
1455 istrue = 0; /* To shut up compiler */
1456 }
1457 result = istrue ? Py_True : Py_False;
1458 Py_INCREF(result);
1459 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001460}
1461
Tim Peters07534a62003-02-07 22:50:28 +00001462/* Raises a "can't compare" TypeError and returns NULL. */
1463static PyObject *
1464cmperror(PyObject *a, PyObject *b)
1465{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001466 PyErr_Format(PyExc_TypeError,
1467 "can't compare %s to %s",
1468 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1469 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001470}
1471
Tim Peters2a799bf2002-12-16 20:18:38 +00001472/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001473 * Cached Python objects; these are set by the module init function.
1474 */
1475
1476/* Conversion factors. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001477static PyObject *us_per_us = NULL; /* 1 */
1478static PyObject *us_per_ms = NULL; /* 1000 */
1479static PyObject *us_per_second = NULL; /* 1000000 */
1480static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1481static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1482static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1483static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001484static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1485
Tim Peters2a799bf2002-12-16 20:18:38 +00001486/* ---------------------------------------------------------------------------
1487 * Class implementations.
1488 */
1489
1490/*
1491 * PyDateTime_Delta implementation.
1492 */
1493
1494/* Convert a timedelta to a number of us,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001495 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001496 * as a Python int or long.
1497 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1498 * due to ubiquitous overflow possibilities.
1499 */
1500static PyObject *
1501delta_to_microseconds(PyDateTime_Delta *self)
1502{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001503 PyObject *x1 = NULL;
1504 PyObject *x2 = NULL;
1505 PyObject *x3 = NULL;
1506 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001507
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001508 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1509 if (x1 == NULL)
1510 goto Done;
1511 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1512 if (x2 == NULL)
1513 goto Done;
1514 Py_DECREF(x1);
1515 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001516
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001517 /* x2 has days in seconds */
1518 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1519 if (x1 == NULL)
1520 goto Done;
1521 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1522 if (x3 == NULL)
1523 goto Done;
1524 Py_DECREF(x1);
1525 Py_DECREF(x2);
1526 x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001527
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001528 /* x3 has days+seconds in seconds */
1529 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1530 if (x1 == NULL)
1531 goto Done;
1532 Py_DECREF(x3);
1533 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001534
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001535 /* x1 has days+seconds in us */
1536 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1537 if (x2 == NULL)
1538 goto Done;
1539 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001540
1541Done:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001542 Py_XDECREF(x1);
1543 Py_XDECREF(x2);
1544 Py_XDECREF(x3);
1545 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001546}
1547
1548/* Convert a number of us (as a Python int or long) to a timedelta.
1549 */
1550static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001551microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001552{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001553 int us;
1554 int s;
1555 int d;
1556 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001557
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001558 PyObject *tuple = NULL;
1559 PyObject *num = NULL;
1560 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001561
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001562 tuple = PyNumber_Divmod(pyus, us_per_second);
1563 if (tuple == NULL)
1564 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001565
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001566 num = PyTuple_GetItem(tuple, 1); /* us */
1567 if (num == NULL)
1568 goto Done;
1569 temp = PyLong_AsLong(num);
1570 num = NULL;
1571 if (temp == -1 && PyErr_Occurred())
1572 goto Done;
1573 assert(0 <= temp && temp < 1000000);
1574 us = (int)temp;
1575 if (us < 0) {
1576 /* The divisor was positive, so this must be an error. */
1577 assert(PyErr_Occurred());
1578 goto Done;
1579 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001580
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001581 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1582 if (num == NULL)
1583 goto Done;
1584 Py_INCREF(num);
1585 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001586
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001587 tuple = PyNumber_Divmod(num, seconds_per_day);
1588 if (tuple == NULL)
1589 goto Done;
1590 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001591
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001592 num = PyTuple_GetItem(tuple, 1); /* seconds */
1593 if (num == NULL)
1594 goto Done;
1595 temp = PyLong_AsLong(num);
1596 num = NULL;
1597 if (temp == -1 && PyErr_Occurred())
1598 goto Done;
1599 assert(0 <= temp && temp < 24*3600);
1600 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001601
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001602 if (s < 0) {
1603 /* The divisor was positive, so this must be an error. */
1604 assert(PyErr_Occurred());
1605 goto Done;
1606 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001607
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001608 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1609 if (num == NULL)
1610 goto Done;
1611 Py_INCREF(num);
1612 temp = PyLong_AsLong(num);
1613 if (temp == -1 && PyErr_Occurred())
1614 goto Done;
1615 d = (int)temp;
1616 if ((long)d != temp) {
1617 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1618 "large to fit in a C int");
1619 goto Done;
1620 }
1621 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001622
1623Done:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001624 Py_XDECREF(tuple);
1625 Py_XDECREF(num);
1626 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001627}
1628
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001629#define microseconds_to_delta(pymicros) \
1630 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001631
Tim Peters2a799bf2002-12-16 20:18:38 +00001632static PyObject *
1633multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1634{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001635 PyObject *pyus_in;
1636 PyObject *pyus_out;
1637 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001638
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001639 pyus_in = delta_to_microseconds(delta);
1640 if (pyus_in == NULL)
1641 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001642
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001643 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1644 Py_DECREF(pyus_in);
1645 if (pyus_out == NULL)
1646 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001647
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001648 result = microseconds_to_delta(pyus_out);
1649 Py_DECREF(pyus_out);
1650 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001651}
1652
1653static PyObject *
1654divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1655{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001656 PyObject *pyus_in;
1657 PyObject *pyus_out;
1658 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001659
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001660 pyus_in = delta_to_microseconds(delta);
1661 if (pyus_in == NULL)
1662 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001663
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001664 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1665 Py_DECREF(pyus_in);
1666 if (pyus_out == NULL)
1667 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001668
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001669 result = microseconds_to_delta(pyus_out);
1670 Py_DECREF(pyus_out);
1671 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001672}
1673
1674static PyObject *
1675delta_add(PyObject *left, PyObject *right)
1676{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001677 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001678
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001679 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1680 /* delta + delta */
1681 /* The C-level additions can't overflow because of the
1682 * invariant bounds.
1683 */
1684 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1685 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1686 int microseconds = GET_TD_MICROSECONDS(left) +
1687 GET_TD_MICROSECONDS(right);
1688 result = new_delta(days, seconds, microseconds, 1);
1689 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001690
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001691 if (result == Py_NotImplemented)
1692 Py_INCREF(result);
1693 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001694}
1695
1696static PyObject *
1697delta_negative(PyDateTime_Delta *self)
1698{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001699 return new_delta(-GET_TD_DAYS(self),
1700 -GET_TD_SECONDS(self),
1701 -GET_TD_MICROSECONDS(self),
1702 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001703}
1704
1705static PyObject *
1706delta_positive(PyDateTime_Delta *self)
1707{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001708 /* Could optimize this (by returning self) if this isn't a
1709 * subclass -- but who uses unary + ? Approximately nobody.
1710 */
1711 return new_delta(GET_TD_DAYS(self),
1712 GET_TD_SECONDS(self),
1713 GET_TD_MICROSECONDS(self),
1714 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001715}
1716
1717static PyObject *
1718delta_abs(PyDateTime_Delta *self)
1719{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001720 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001721
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001722 assert(GET_TD_MICROSECONDS(self) >= 0);
1723 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001724
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001725 if (GET_TD_DAYS(self) < 0)
1726 result = delta_negative(self);
1727 else
1728 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001729
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001730 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001731}
1732
1733static PyObject *
1734delta_subtract(PyObject *left, PyObject *right)
1735{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001736 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001737
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001738 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1739 /* delta - delta */
Alexander Belopolsky07019bc2011-04-05 22:12:22 -04001740 /* The C-level additions can't overflow because of the
1741 * invariant bounds.
1742 */
1743 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1744 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1745 int microseconds = GET_TD_MICROSECONDS(left) -
1746 GET_TD_MICROSECONDS(right);
1747 result = new_delta(days, seconds, microseconds, 1);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001748 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001749
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001750 if (result == Py_NotImplemented)
1751 Py_INCREF(result);
1752 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001753}
1754
1755/* This is more natural as a tp_compare, but doesn't work then: for whatever
1756 * reason, Python's try_3way_compare ignores tp_compare unless
1757 * PyInstance_Check returns true, but these aren't old-style classes.
1758 */
1759static PyObject *
1760delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1761{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001762 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001763
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001764 if (PyDelta_Check(other)) {
1765 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1766 if (diff == 0) {
1767 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1768 if (diff == 0)
1769 diff = GET_TD_MICROSECONDS(self) -
1770 GET_TD_MICROSECONDS(other);
1771 }
1772 }
1773 else if (op == Py_EQ || op == Py_NE)
1774 diff = 1; /* any non-zero value will do */
Tim Peters07534a62003-02-07 22:50:28 +00001775
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001776 else /* stop this from falling back to address comparison */
1777 return cmperror((PyObject *)self, other);
Tim Peters07534a62003-02-07 22:50:28 +00001778
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001779 return diff_to_bool(diff, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00001780}
1781
1782static PyObject *delta_getstate(PyDateTime_Delta *self);
1783
1784static long
1785delta_hash(PyDateTime_Delta *self)
1786{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001787 if (self->hashcode == -1) {
1788 PyObject *temp = delta_getstate(self);
1789 if (temp != NULL) {
1790 self->hashcode = PyObject_Hash(temp);
1791 Py_DECREF(temp);
1792 }
1793 }
1794 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001795}
1796
1797static PyObject *
1798delta_multiply(PyObject *left, PyObject *right)
1799{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001800 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001801
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001802 if (PyDelta_Check(left)) {
1803 /* delta * ??? */
1804 if (PyInt_Check(right) || PyLong_Check(right))
1805 result = multiply_int_timedelta(right,
1806 (PyDateTime_Delta *) left);
1807 }
1808 else if (PyInt_Check(left) || PyLong_Check(left))
1809 result = multiply_int_timedelta(left,
1810 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001811
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001812 if (result == Py_NotImplemented)
1813 Py_INCREF(result);
1814 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001815}
1816
1817static PyObject *
1818delta_divide(PyObject *left, PyObject *right)
1819{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001820 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001821
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001822 if (PyDelta_Check(left)) {
1823 /* delta * ??? */
1824 if (PyInt_Check(right) || PyLong_Check(right))
1825 result = divide_timedelta_int(
1826 (PyDateTime_Delta *)left,
1827 right);
1828 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001829
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001830 if (result == Py_NotImplemented)
1831 Py_INCREF(result);
1832 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001833}
1834
1835/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1836 * timedelta constructor. sofar is the # of microseconds accounted for
1837 * so far, and there are factor microseconds per current unit, the number
1838 * of which is given by num. num * factor is added to sofar in a
1839 * numerically careful way, and that's the result. Any fractional
1840 * microseconds left over (this can happen if num is a float type) are
1841 * added into *leftover.
1842 * Note that there are many ways this can give an error (NULL) return.
1843 */
1844static PyObject *
1845accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1846 double *leftover)
1847{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001848 PyObject *prod;
1849 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00001850
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001851 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001852
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001853 if (PyInt_Check(num) || PyLong_Check(num)) {
1854 prod = PyNumber_Multiply(num, factor);
1855 if (prod == NULL)
1856 return NULL;
1857 sum = PyNumber_Add(sofar, prod);
1858 Py_DECREF(prod);
1859 return sum;
1860 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001861
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001862 if (PyFloat_Check(num)) {
1863 double dnum;
1864 double fracpart;
1865 double intpart;
1866 PyObject *x;
1867 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00001868
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001869 /* The Plan: decompose num into an integer part and a
1870 * fractional part, num = intpart + fracpart.
1871 * Then num * factor ==
1872 * intpart * factor + fracpart * factor
1873 * and the LHS can be computed exactly in long arithmetic.
1874 * The RHS is again broken into an int part and frac part.
1875 * and the frac part is added into *leftover.
1876 */
1877 dnum = PyFloat_AsDouble(num);
1878 if (dnum == -1.0 && PyErr_Occurred())
1879 return NULL;
1880 fracpart = modf(dnum, &intpart);
1881 x = PyLong_FromDouble(intpart);
1882 if (x == NULL)
1883 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001884
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001885 prod = PyNumber_Multiply(x, factor);
1886 Py_DECREF(x);
1887 if (prod == NULL)
1888 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001889
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001890 sum = PyNumber_Add(sofar, prod);
1891 Py_DECREF(prod);
1892 if (sum == NULL)
1893 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001894
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001895 if (fracpart == 0.0)
1896 return sum;
1897 /* So far we've lost no information. Dealing with the
1898 * fractional part requires float arithmetic, and may
1899 * lose a little info.
1900 */
1901 assert(PyInt_Check(factor) || PyLong_Check(factor));
1902 if (PyInt_Check(factor))
1903 dnum = (double)PyInt_AsLong(factor);
1904 else
1905 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00001906
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001907 dnum *= fracpart;
1908 fracpart = modf(dnum, &intpart);
1909 x = PyLong_FromDouble(intpart);
1910 if (x == NULL) {
1911 Py_DECREF(sum);
1912 return NULL;
1913 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001914
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001915 y = PyNumber_Add(sum, x);
1916 Py_DECREF(sum);
1917 Py_DECREF(x);
1918 *leftover += fracpart;
1919 return y;
1920 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001921
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001922 PyErr_Format(PyExc_TypeError,
1923 "unsupported type for timedelta %s component: %s",
1924 tag, Py_TYPE(num)->tp_name);
1925 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001926}
1927
1928static PyObject *
1929delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1930{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001931 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001932
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001933 /* Argument objects. */
1934 PyObject *day = NULL;
1935 PyObject *second = NULL;
1936 PyObject *us = NULL;
1937 PyObject *ms = NULL;
1938 PyObject *minute = NULL;
1939 PyObject *hour = NULL;
1940 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001941
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001942 PyObject *x = NULL; /* running sum of microseconds */
1943 PyObject *y = NULL; /* temp sum of microseconds */
1944 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001945
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001946 static char *keywords[] = {
1947 "days", "seconds", "microseconds", "milliseconds",
1948 "minutes", "hours", "weeks", NULL
1949 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001950
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001951 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1952 keywords,
1953 &day, &second, &us,
1954 &ms, &minute, &hour, &week) == 0)
1955 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001956
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001957 x = PyInt_FromLong(0);
1958 if (x == NULL)
1959 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001960
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001961#define CLEANUP \
1962 Py_DECREF(x); \
1963 x = y; \
1964 if (x == NULL) \
1965 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00001966
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001967 if (us) {
1968 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1969 CLEANUP;
1970 }
1971 if (ms) {
1972 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1973 CLEANUP;
1974 }
1975 if (second) {
1976 y = accum("seconds", x, second, us_per_second, &leftover_us);
1977 CLEANUP;
1978 }
1979 if (minute) {
1980 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1981 CLEANUP;
1982 }
1983 if (hour) {
1984 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1985 CLEANUP;
1986 }
1987 if (day) {
1988 y = accum("days", x, day, us_per_day, &leftover_us);
1989 CLEANUP;
1990 }
1991 if (week) {
1992 y = accum("weeks", x, week, us_per_week, &leftover_us);
1993 CLEANUP;
1994 }
1995 if (leftover_us) {
1996 /* Round to nearest whole # of us, and add into x. */
1997 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1998 if (temp == NULL) {
1999 Py_DECREF(x);
2000 goto Done;
2001 }
2002 y = PyNumber_Add(x, temp);
2003 Py_DECREF(temp);
2004 CLEANUP;
2005 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002006
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002007 self = microseconds_to_delta_ex(x, type);
2008 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002009Done:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002010 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002011
2012#undef CLEANUP
2013}
2014
2015static int
2016delta_nonzero(PyDateTime_Delta *self)
2017{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002018 return (GET_TD_DAYS(self) != 0
2019 || GET_TD_SECONDS(self) != 0
2020 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002021}
2022
2023static PyObject *
2024delta_repr(PyDateTime_Delta *self)
2025{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002026 if (GET_TD_MICROSECONDS(self) != 0)
2027 return PyString_FromFormat("%s(%d, %d, %d)",
2028 Py_TYPE(self)->tp_name,
2029 GET_TD_DAYS(self),
2030 GET_TD_SECONDS(self),
2031 GET_TD_MICROSECONDS(self));
2032 if (GET_TD_SECONDS(self) != 0)
2033 return PyString_FromFormat("%s(%d, %d)",
2034 Py_TYPE(self)->tp_name,
2035 GET_TD_DAYS(self),
2036 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002037
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002038 return PyString_FromFormat("%s(%d)",
2039 Py_TYPE(self)->tp_name,
2040 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002041}
2042
2043static PyObject *
2044delta_str(PyDateTime_Delta *self)
2045{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002046 int days = GET_TD_DAYS(self);
2047 int seconds = GET_TD_SECONDS(self);
2048 int us = GET_TD_MICROSECONDS(self);
2049 int hours;
2050 int minutes;
2051 char buf[100];
2052 char *pbuf = buf;
2053 size_t buflen = sizeof(buf);
2054 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002055
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002056 minutes = divmod(seconds, 60, &seconds);
2057 hours = divmod(minutes, 60, &minutes);
Tim Peters2a799bf2002-12-16 20:18:38 +00002058
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002059 if (days) {
2060 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2061 (days == 1 || days == -1) ? "" : "s");
2062 if (n < 0 || (size_t)n >= buflen)
2063 goto Fail;
2064 pbuf += n;
2065 buflen -= (size_t)n;
2066 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002067
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002068 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2069 hours, minutes, seconds);
2070 if (n < 0 || (size_t)n >= buflen)
2071 goto Fail;
2072 pbuf += n;
2073 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002074
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002075 if (us) {
2076 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2077 if (n < 0 || (size_t)n >= buflen)
2078 goto Fail;
2079 pbuf += n;
2080 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002081
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002082 return PyString_FromStringAndSize(buf, pbuf - buf);
Tim Petersba873472002-12-18 20:19:21 +00002083
2084 Fail:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002085 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2086 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002087}
2088
Tim Peters371935f2003-02-01 01:52:50 +00002089/* Pickle support, a simple use of __reduce__. */
2090
Tim Petersb57f8f02003-02-01 02:54:15 +00002091/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002092static PyObject *
2093delta_getstate(PyDateTime_Delta *self)
2094{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002095 return Py_BuildValue("iii", GET_TD_DAYS(self),
2096 GET_TD_SECONDS(self),
2097 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002098}
2099
Tim Peters2a799bf2002-12-16 20:18:38 +00002100static PyObject *
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002101delta_total_seconds(PyObject *self)
2102{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002103 PyObject *total_seconds;
2104 PyObject *total_microseconds;
2105 PyObject *one_million;
Mark Dickinson7000e9e2010-05-09 09:30:06 +00002106
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002107 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2108 if (total_microseconds == NULL)
2109 return NULL;
Mark Dickinson7000e9e2010-05-09 09:30:06 +00002110
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002111 one_million = PyLong_FromLong(1000000L);
2112 if (one_million == NULL) {
2113 Py_DECREF(total_microseconds);
2114 return NULL;
2115 }
Mark Dickinson7000e9e2010-05-09 09:30:06 +00002116
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002117 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson7000e9e2010-05-09 09:30:06 +00002118
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002119 Py_DECREF(total_microseconds);
2120 Py_DECREF(one_million);
2121 return total_seconds;
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002122}
2123
2124static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002125delta_reduce(PyDateTime_Delta* self)
2126{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002127 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002128}
2129
2130#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2131
2132static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002133
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002134 {"days", T_INT, OFFSET(days), READONLY,
2135 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002136
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002137 {"seconds", T_INT, OFFSET(seconds), READONLY,
2138 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002139
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002140 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2141 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2142 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002143};
2144
2145static PyMethodDef delta_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002146 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2147 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002148
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002149 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2150 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002151
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002152 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002153};
2154
2155static char delta_doc[] =
2156PyDoc_STR("Difference between two datetime values.");
2157
2158static PyNumberMethods delta_as_number = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002159 delta_add, /* nb_add */
2160 delta_subtract, /* nb_subtract */
2161 delta_multiply, /* nb_multiply */
2162 delta_divide, /* nb_divide */
2163 0, /* nb_remainder */
2164 0, /* nb_divmod */
2165 0, /* nb_power */
2166 (unaryfunc)delta_negative, /* nb_negative */
2167 (unaryfunc)delta_positive, /* nb_positive */
2168 (unaryfunc)delta_abs, /* nb_absolute */
2169 (inquiry)delta_nonzero, /* nb_nonzero */
2170 0, /*nb_invert*/
2171 0, /*nb_lshift*/
2172 0, /*nb_rshift*/
2173 0, /*nb_and*/
2174 0, /*nb_xor*/
2175 0, /*nb_or*/
2176 0, /*nb_coerce*/
2177 0, /*nb_int*/
2178 0, /*nb_long*/
2179 0, /*nb_float*/
2180 0, /*nb_oct*/
2181 0, /*nb_hex*/
2182 0, /*nb_inplace_add*/
2183 0, /*nb_inplace_subtract*/
2184 0, /*nb_inplace_multiply*/
2185 0, /*nb_inplace_divide*/
2186 0, /*nb_inplace_remainder*/
2187 0, /*nb_inplace_power*/
2188 0, /*nb_inplace_lshift*/
2189 0, /*nb_inplace_rshift*/
2190 0, /*nb_inplace_and*/
2191 0, /*nb_inplace_xor*/
2192 0, /*nb_inplace_or*/
2193 delta_divide, /* nb_floor_divide */
2194 0, /* nb_true_divide */
2195 0, /* nb_inplace_floor_divide */
2196 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002197};
2198
2199static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002200 PyVarObject_HEAD_INIT(NULL, 0)
2201 "datetime.timedelta", /* tp_name */
2202 sizeof(PyDateTime_Delta), /* tp_basicsize */
2203 0, /* tp_itemsize */
2204 0, /* tp_dealloc */
2205 0, /* tp_print */
2206 0, /* tp_getattr */
2207 0, /* tp_setattr */
2208 0, /* tp_compare */
2209 (reprfunc)delta_repr, /* tp_repr */
2210 &delta_as_number, /* tp_as_number */
2211 0, /* tp_as_sequence */
2212 0, /* tp_as_mapping */
2213 (hashfunc)delta_hash, /* tp_hash */
2214 0, /* tp_call */
2215 (reprfunc)delta_str, /* tp_str */
2216 PyObject_GenericGetAttr, /* tp_getattro */
2217 0, /* tp_setattro */
2218 0, /* tp_as_buffer */
2219 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2220 Py_TPFLAGS_BASETYPE, /* tp_flags */
2221 delta_doc, /* tp_doc */
2222 0, /* tp_traverse */
2223 0, /* tp_clear */
2224 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2225 0, /* tp_weaklistoffset */
2226 0, /* tp_iter */
2227 0, /* tp_iternext */
2228 delta_methods, /* tp_methods */
2229 delta_members, /* tp_members */
2230 0, /* tp_getset */
2231 0, /* tp_base */
2232 0, /* tp_dict */
2233 0, /* tp_descr_get */
2234 0, /* tp_descr_set */
2235 0, /* tp_dictoffset */
2236 0, /* tp_init */
2237 0, /* tp_alloc */
2238 delta_new, /* tp_new */
2239 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002240};
2241
2242/*
2243 * PyDateTime_Date implementation.
2244 */
2245
2246/* Accessor properties. */
2247
2248static PyObject *
2249date_year(PyDateTime_Date *self, void *unused)
2250{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002251 return PyInt_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002252}
2253
2254static PyObject *
2255date_month(PyDateTime_Date *self, void *unused)
2256{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002257 return PyInt_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002258}
2259
2260static PyObject *
2261date_day(PyDateTime_Date *self, void *unused)
2262{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002263 return PyInt_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002264}
2265
2266static PyGetSetDef date_getset[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002267 {"year", (getter)date_year},
2268 {"month", (getter)date_month},
2269 {"day", (getter)date_day},
2270 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002271};
2272
2273/* Constructors. */
2274
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002275static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002276
Tim Peters2a799bf2002-12-16 20:18:38 +00002277static PyObject *
2278date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2279{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002280 PyObject *self = NULL;
2281 PyObject *state;
2282 int year;
2283 int month;
2284 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002285
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002286 /* Check for invocation from pickle with __getstate__ state */
2287 if (PyTuple_GET_SIZE(args) == 1 &&
2288 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2289 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2290 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
2291 {
2292 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002293
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002294 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2295 if (me != NULL) {
2296 char *pdata = PyString_AS_STRING(state);
2297 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2298 me->hashcode = -1;
2299 }
2300 return (PyObject *)me;
2301 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002302
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002303 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2304 &year, &month, &day)) {
2305 if (check_date_args(year, month, day) < 0)
2306 return NULL;
2307 self = new_date_ex(year, month, day, type);
2308 }
2309 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002310}
2311
2312/* Return new date from localtime(t). */
2313static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002314date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002315{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002316 struct tm *tm;
2317 time_t t;
2318 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002319
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002320 t = _PyTime_DoubleToTimet(ts);
2321 if (t == (time_t)-1 && PyErr_Occurred())
2322 return NULL;
2323 tm = localtime(&t);
2324 if (tm)
2325 result = PyObject_CallFunction(cls, "iii",
2326 tm->tm_year + 1900,
2327 tm->tm_mon + 1,
2328 tm->tm_mday);
2329 else
2330 PyErr_SetString(PyExc_ValueError,
2331 "timestamp out of range for "
2332 "platform localtime() function");
2333 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002334}
2335
2336/* Return new date from current time.
2337 * We say this is equivalent to fromtimestamp(time.time()), and the
2338 * only way to be sure of that is to *call* time.time(). That's not
2339 * generally the same as calling C's time.
2340 */
2341static PyObject *
2342date_today(PyObject *cls, PyObject *dummy)
2343{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002344 PyObject *time;
2345 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002346
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002347 time = time_time();
2348 if (time == NULL)
2349 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002350
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002351 /* Note well: today() is a class method, so this may not call
2352 * date.fromtimestamp. For example, it may call
2353 * datetime.fromtimestamp. That's why we need all the accuracy
2354 * time.time() delivers; if someone were gonzo about optimization,
2355 * date.today() could get away with plain C time().
2356 */
2357 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2358 Py_DECREF(time);
2359 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002360}
2361
2362/* Return new date from given timestamp (Python timestamp -- a double). */
2363static PyObject *
2364date_fromtimestamp(PyObject *cls, PyObject *args)
2365{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002366 double timestamp;
2367 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002368
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002369 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2370 result = date_local_from_time_t(cls, timestamp);
2371 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002372}
2373
2374/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2375 * the ordinal is out of range.
2376 */
2377static PyObject *
2378date_fromordinal(PyObject *cls, PyObject *args)
2379{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002380 PyObject *result = NULL;
2381 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002382
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002383 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2384 int year;
2385 int month;
2386 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002387
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002388 if (ordinal < 1)
2389 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2390 ">= 1");
2391 else {
2392 ord_to_ymd(ordinal, &year, &month, &day);
2393 result = PyObject_CallFunction(cls, "iii",
2394 year, month, day);
2395 }
2396 }
2397 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002398}
2399
2400/*
2401 * Date arithmetic.
2402 */
2403
2404/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2405 * instead.
2406 */
2407static PyObject *
2408add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2409{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002410 PyObject *result = NULL;
2411 int year = GET_YEAR(date);
2412 int month = GET_MONTH(date);
2413 int deltadays = GET_TD_DAYS(delta);
2414 /* C-level overflow is impossible because |deltadays| < 1e9. */
2415 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002416
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002417 if (normalize_date(&year, &month, &day) >= 0)
2418 result = new_date(year, month, day);
2419 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002420}
2421
2422static PyObject *
2423date_add(PyObject *left, PyObject *right)
2424{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002425 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2426 Py_INCREF(Py_NotImplemented);
2427 return Py_NotImplemented;
2428 }
2429 if (PyDate_Check(left)) {
2430 /* date + ??? */
2431 if (PyDelta_Check(right))
2432 /* date + delta */
2433 return add_date_timedelta((PyDateTime_Date *) left,
2434 (PyDateTime_Delta *) right,
2435 0);
2436 }
2437 else {
2438 /* ??? + date
2439 * 'right' must be one of us, or we wouldn't have been called
2440 */
2441 if (PyDelta_Check(left))
2442 /* delta + date */
2443 return add_date_timedelta((PyDateTime_Date *) right,
2444 (PyDateTime_Delta *) left,
2445 0);
2446 }
2447 Py_INCREF(Py_NotImplemented);
2448 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002449}
2450
2451static PyObject *
2452date_subtract(PyObject *left, PyObject *right)
2453{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002454 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2455 Py_INCREF(Py_NotImplemented);
2456 return Py_NotImplemented;
2457 }
2458 if (PyDate_Check(left)) {
2459 if (PyDate_Check(right)) {
2460 /* date - date */
2461 int left_ord = ymd_to_ord(GET_YEAR(left),
2462 GET_MONTH(left),
2463 GET_DAY(left));
2464 int right_ord = ymd_to_ord(GET_YEAR(right),
2465 GET_MONTH(right),
2466 GET_DAY(right));
2467 return new_delta(left_ord - right_ord, 0, 0, 0);
2468 }
2469 if (PyDelta_Check(right)) {
2470 /* date - delta */
2471 return add_date_timedelta((PyDateTime_Date *) left,
2472 (PyDateTime_Delta *) right,
2473 1);
2474 }
2475 }
2476 Py_INCREF(Py_NotImplemented);
2477 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002478}
2479
2480
2481/* Various ways to turn a date into a string. */
2482
2483static PyObject *
2484date_repr(PyDateTime_Date *self)
2485{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002486 char buffer[1028];
2487 const char *type_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002488
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002489 type_name = Py_TYPE(self)->tp_name;
2490 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2491 type_name,
2492 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002493
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002494 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002495}
2496
2497static PyObject *
2498date_isoformat(PyDateTime_Date *self)
2499{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002500 char buffer[128];
Tim Peters2a799bf2002-12-16 20:18:38 +00002501
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002502 isoformat_date(self, buffer, sizeof(buffer));
2503 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002504}
2505
Tim Peterse2df5ff2003-05-02 18:39:55 +00002506/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002507static PyObject *
2508date_str(PyDateTime_Date *self)
2509{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002510 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002511}
2512
2513
2514static PyObject *
2515date_ctime(PyDateTime_Date *self)
2516{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002517 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002518}
2519
2520static PyObject *
2521date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2522{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002523 /* This method can be inherited, and needs to call the
2524 * timetuple() method appropriate to self's class.
2525 */
2526 PyObject *result;
2527 PyObject *tuple;
2528 const char *format;
2529 Py_ssize_t format_len;
2530 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002531
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002532 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2533 &format, &format_len))
2534 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002535
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002536 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2537 if (tuple == NULL)
2538 return NULL;
2539 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
2540 (PyObject *)self);
2541 Py_DECREF(tuple);
2542 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002543}
2544
Eric Smitha9f7d622008-02-17 19:46:49 +00002545static PyObject *
2546date_format(PyDateTime_Date *self, PyObject *args)
2547{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002548 PyObject *format;
Eric Smitha9f7d622008-02-17 19:46:49 +00002549
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002550 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2551 return NULL;
Eric Smitha9f7d622008-02-17 19:46:49 +00002552
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002553 /* Check for str or unicode */
2554 if (PyString_Check(format)) {
2555 /* If format is zero length, return str(self) */
2556 if (PyString_GET_SIZE(format) == 0)
2557 return PyObject_Str((PyObject *)self);
2558 } else if (PyUnicode_Check(format)) {
2559 /* If format is zero length, return str(self) */
2560 if (PyUnicode_GET_SIZE(format) == 0)
2561 return PyObject_Unicode((PyObject *)self);
2562 } else {
2563 PyErr_Format(PyExc_ValueError,
2564 "__format__ expects str or unicode, not %.200s",
2565 Py_TYPE(format)->tp_name);
2566 return NULL;
2567 }
2568 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smitha9f7d622008-02-17 19:46:49 +00002569}
2570
Tim Peters2a799bf2002-12-16 20:18:38 +00002571/* ISO methods. */
2572
2573static PyObject *
2574date_isoweekday(PyDateTime_Date *self)
2575{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002576 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002577
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002578 return PyInt_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002579}
2580
2581static PyObject *
2582date_isocalendar(PyDateTime_Date *self)
2583{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002584 int year = GET_YEAR(self);
2585 int week1_monday = iso_week1_monday(year);
2586 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2587 int week;
2588 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002589
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002590 week = divmod(today - week1_monday, 7, &day);
2591 if (week < 0) {
2592 --year;
2593 week1_monday = iso_week1_monday(year);
2594 week = divmod(today - week1_monday, 7, &day);
2595 }
2596 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2597 ++year;
2598 week = 0;
2599 }
2600 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002601}
2602
2603/* Miscellaneous methods. */
2604
2605/* This is more natural as a tp_compare, but doesn't work then: for whatever
2606 * reason, Python's try_3way_compare ignores tp_compare unless
2607 * PyInstance_Check returns true, but these aren't old-style classes.
2608 */
2609static PyObject *
2610date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2611{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002612 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002613
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002614 if (PyDate_Check(other))
2615 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2616 _PyDateTime_DATE_DATASIZE);
Tim Peters07534a62003-02-07 22:50:28 +00002617
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002618 else if (PyObject_HasAttrString(other, "timetuple")) {
2619 /* A hook for other kinds of date objects. */
2620 Py_INCREF(Py_NotImplemented);
2621 return Py_NotImplemented;
2622 }
2623 else if (op == Py_EQ || op == Py_NE)
2624 diff = 1; /* any non-zero value will do */
Tim Peters07534a62003-02-07 22:50:28 +00002625
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002626 else /* stop this from falling back to address comparison */
2627 return cmperror((PyObject *)self, other);
Tim Peters07534a62003-02-07 22:50:28 +00002628
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002629 return diff_to_bool(diff, op);
Tim Peters2a799bf2002-12-16 20:18:38 +00002630}
2631
2632static PyObject *
2633date_timetuple(PyDateTime_Date *self)
2634{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002635 return build_struct_time(GET_YEAR(self),
2636 GET_MONTH(self),
2637 GET_DAY(self),
2638 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002639}
2640
Tim Peters12bf3392002-12-24 05:41:27 +00002641static PyObject *
2642date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2643{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002644 PyObject *clone;
2645 PyObject *tuple;
2646 int year = GET_YEAR(self);
2647 int month = GET_MONTH(self);
2648 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002649
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002650 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2651 &year, &month, &day))
2652 return NULL;
2653 tuple = Py_BuildValue("iii", year, month, day);
2654 if (tuple == NULL)
2655 return NULL;
2656 clone = date_new(Py_TYPE(self), tuple, NULL);
2657 Py_DECREF(tuple);
2658 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002659}
2660
Tim Peters2a799bf2002-12-16 20:18:38 +00002661static PyObject *date_getstate(PyDateTime_Date *self);
2662
2663static long
2664date_hash(PyDateTime_Date *self)
2665{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002666 if (self->hashcode == -1) {
2667 PyObject *temp = date_getstate(self);
2668 if (temp != NULL) {
2669 self->hashcode = PyObject_Hash(temp);
2670 Py_DECREF(temp);
2671 }
2672 }
2673 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002674}
2675
2676static PyObject *
2677date_toordinal(PyDateTime_Date *self)
2678{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002679 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2680 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002681}
2682
2683static PyObject *
2684date_weekday(PyDateTime_Date *self)
2685{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002686 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002687
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002688 return PyInt_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002689}
2690
Tim Peters371935f2003-02-01 01:52:50 +00002691/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002692
Tim Petersb57f8f02003-02-01 02:54:15 +00002693/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002694static PyObject *
2695date_getstate(PyDateTime_Date *self)
2696{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002697 return Py_BuildValue(
2698 "(N)",
2699 PyString_FromStringAndSize((char *)self->data,
2700 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002701}
2702
2703static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002704date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002705{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002706 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002707}
2708
2709static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002710
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002711 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002712
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002713 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2714 METH_CLASS,
2715 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2716 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002717
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002718 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2719 METH_CLASS,
2720 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2721 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002722
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002723 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2724 PyDoc_STR("Current date or datetime: same as "
2725 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002726
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002727 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002728
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002729 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2730 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002731
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002732 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2733 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002734
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002735 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2736 PyDoc_STR("Formats self with strftime.")},
Eric Smitha9f7d622008-02-17 19:46:49 +00002737
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002738 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2739 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002740
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002741 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2742 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2743 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002744
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002745 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2746 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002747
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002748 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2749 PyDoc_STR("Return the day of the week represented by the date.\n"
2750 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002751
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002752 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2753 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2754 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002755
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002756 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2757 PyDoc_STR("Return the day of the week represented by the date.\n"
2758 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002759
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002760 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2761 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002762
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002763 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2764 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002765
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002766 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002767};
2768
2769static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002770PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002771
2772static PyNumberMethods date_as_number = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002773 date_add, /* nb_add */
2774 date_subtract, /* nb_subtract */
2775 0, /* nb_multiply */
2776 0, /* nb_divide */
2777 0, /* nb_remainder */
2778 0, /* nb_divmod */
2779 0, /* nb_power */
2780 0, /* nb_negative */
2781 0, /* nb_positive */
2782 0, /* nb_absolute */
2783 0, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00002784};
2785
2786static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002787 PyVarObject_HEAD_INIT(NULL, 0)
2788 "datetime.date", /* tp_name */
2789 sizeof(PyDateTime_Date), /* tp_basicsize */
2790 0, /* tp_itemsize */
2791 0, /* tp_dealloc */
2792 0, /* tp_print */
2793 0, /* tp_getattr */
2794 0, /* tp_setattr */
2795 0, /* tp_compare */
2796 (reprfunc)date_repr, /* tp_repr */
2797 &date_as_number, /* tp_as_number */
2798 0, /* tp_as_sequence */
2799 0, /* tp_as_mapping */
2800 (hashfunc)date_hash, /* tp_hash */
2801 0, /* tp_call */
2802 (reprfunc)date_str, /* tp_str */
2803 PyObject_GenericGetAttr, /* tp_getattro */
2804 0, /* tp_setattro */
2805 0, /* tp_as_buffer */
2806 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2807 Py_TPFLAGS_BASETYPE, /* tp_flags */
2808 date_doc, /* tp_doc */
2809 0, /* tp_traverse */
2810 0, /* tp_clear */
2811 (richcmpfunc)date_richcompare, /* tp_richcompare */
2812 0, /* tp_weaklistoffset */
2813 0, /* tp_iter */
2814 0, /* tp_iternext */
2815 date_methods, /* tp_methods */
2816 0, /* tp_members */
2817 date_getset, /* tp_getset */
2818 0, /* tp_base */
2819 0, /* tp_dict */
2820 0, /* tp_descr_get */
2821 0, /* tp_descr_set */
2822 0, /* tp_dictoffset */
2823 0, /* tp_init */
2824 0, /* tp_alloc */
2825 date_new, /* tp_new */
2826 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002827};
2828
2829/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002830 * PyDateTime_TZInfo implementation.
2831 */
2832
2833/* This is a pure abstract base class, so doesn't do anything beyond
2834 * raising NotImplemented exceptions. Real tzinfo classes need
2835 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002836 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002837 * be subclasses of this tzinfo class, which is easy and quick to check).
2838 *
2839 * Note: For reasons having to do with pickling of subclasses, we have
2840 * to allow tzinfo objects to be instantiated. This wasn't an issue
2841 * in the Python implementation (__init__() could raise NotImplementedError
2842 * there without ill effect), but doing so in the C implementation hit a
2843 * brick wall.
2844 */
2845
2846static PyObject *
2847tzinfo_nogo(const char* methodname)
2848{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002849 PyErr_Format(PyExc_NotImplementedError,
2850 "a tzinfo subclass must implement %s()",
2851 methodname);
2852 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002853}
2854
2855/* Methods. A subclass must implement these. */
2856
Tim Peters52dcce22003-01-23 16:36:11 +00002857static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002858tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2859{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002860 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002861}
2862
Tim Peters52dcce22003-01-23 16:36:11 +00002863static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002864tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2865{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002866 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002867}
2868
Tim Peters52dcce22003-01-23 16:36:11 +00002869static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002870tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2871{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002872 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002873}
2874
Tim Peters52dcce22003-01-23 16:36:11 +00002875static PyObject *
2876tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2877{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002878 int y, m, d, hh, mm, ss, us;
Tim Peters52dcce22003-01-23 16:36:11 +00002879
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002880 PyObject *result;
2881 int off, dst;
2882 int none;
2883 int delta;
Tim Peters52dcce22003-01-23 16:36:11 +00002884
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002885 if (! PyDateTime_Check(dt)) {
2886 PyErr_SetString(PyExc_TypeError,
2887 "fromutc: argument must be a datetime");
2888 return NULL;
2889 }
2890 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2891 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2892 "is not self");
2893 return NULL;
2894 }
Tim Peters52dcce22003-01-23 16:36:11 +00002895
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002896 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2897 if (off == -1 && PyErr_Occurred())
2898 return NULL;
2899 if (none) {
2900 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2901 "utcoffset() result required");
2902 return NULL;
2903 }
Tim Peters52dcce22003-01-23 16:36:11 +00002904
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002905 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2906 if (dst == -1 && PyErr_Occurred())
2907 return NULL;
2908 if (none) {
2909 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2910 "dst() result required");
2911 return NULL;
2912 }
Tim Peters52dcce22003-01-23 16:36:11 +00002913
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002914 y = GET_YEAR(dt);
2915 m = GET_MONTH(dt);
2916 d = GET_DAY(dt);
2917 hh = DATE_GET_HOUR(dt);
2918 mm = DATE_GET_MINUTE(dt);
2919 ss = DATE_GET_SECOND(dt);
2920 us = DATE_GET_MICROSECOND(dt);
Tim Peters52dcce22003-01-23 16:36:11 +00002921
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002922 delta = off - dst;
2923 mm += delta;
2924 if ((mm < 0 || mm >= 60) &&
2925 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2926 return NULL;
2927 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2928 if (result == NULL)
2929 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002930
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002931 dst = call_dst(dt->tzinfo, result, &none);
2932 if (dst == -1 && PyErr_Occurred())
2933 goto Fail;
2934 if (none)
2935 goto Inconsistent;
2936 if (dst == 0)
2937 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002938
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002939 mm += dst;
2940 if ((mm < 0 || mm >= 60) &&
2941 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2942 goto Fail;
2943 Py_DECREF(result);
2944 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2945 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002946
2947Inconsistent:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002948 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2949 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00002950
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002951 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00002952Fail:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002953 Py_DECREF(result);
2954 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002955}
2956
Tim Peters2a799bf2002-12-16 20:18:38 +00002957/*
2958 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002959 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002960 */
2961
Guido van Rossum177e41a2003-01-30 22:06:23 +00002962static PyObject *
2963tzinfo_reduce(PyObject *self)
2964{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002965 PyObject *args, *state, *tmp;
2966 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002967
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002968 tmp = PyTuple_New(0);
2969 if (tmp == NULL)
2970 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002971
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002972 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2973 if (getinitargs != NULL) {
2974 args = PyObject_CallObject(getinitargs, tmp);
2975 Py_DECREF(getinitargs);
2976 if (args == NULL) {
2977 Py_DECREF(tmp);
2978 return NULL;
2979 }
2980 }
2981 else {
2982 PyErr_Clear();
2983 args = tmp;
2984 Py_INCREF(args);
2985 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002986
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002987 getstate = PyObject_GetAttrString(self, "__getstate__");
2988 if (getstate != NULL) {
2989 state = PyObject_CallObject(getstate, tmp);
2990 Py_DECREF(getstate);
2991 if (state == NULL) {
2992 Py_DECREF(args);
2993 Py_DECREF(tmp);
2994 return NULL;
2995 }
2996 }
2997 else {
2998 PyObject **dictptr;
2999 PyErr_Clear();
3000 state = Py_None;
3001 dictptr = _PyObject_GetDictPtr(self);
3002 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3003 state = *dictptr;
3004 Py_INCREF(state);
3005 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003006
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003007 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003008
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003009 if (state == Py_None) {
3010 Py_DECREF(state);
3011 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3012 }
3013 else
3014 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003015}
Tim Peters2a799bf2002-12-16 20:18:38 +00003016
3017static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003018
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003019 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3020 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003021
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003022 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
3023 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3024 "west of UTC).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003025
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003026 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3027 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003028
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003029 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky1f6e2252010-07-03 03:27:12 +00003030 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003031
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003032 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3033 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003034
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003035 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003036};
3037
3038static char tzinfo_doc[] =
3039PyDoc_STR("Abstract base class for time zone info objects.");
3040
Neal Norwitzce3d34d2003-02-04 20:45:17 +00003041statichere PyTypeObject PyDateTime_TZInfoType = {
Benjamin Petersona72d15c2017-09-13 21:20:29 -07003042 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003043 "datetime.tzinfo", /* tp_name */
3044 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3045 0, /* tp_itemsize */
3046 0, /* tp_dealloc */
3047 0, /* tp_print */
3048 0, /* tp_getattr */
3049 0, /* tp_setattr */
3050 0, /* tp_compare */
3051 0, /* tp_repr */
3052 0, /* tp_as_number */
3053 0, /* tp_as_sequence */
3054 0, /* tp_as_mapping */
3055 0, /* tp_hash */
3056 0, /* tp_call */
3057 0, /* tp_str */
3058 PyObject_GenericGetAttr, /* tp_getattro */
3059 0, /* tp_setattro */
3060 0, /* tp_as_buffer */
3061 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3062 Py_TPFLAGS_BASETYPE, /* tp_flags */
3063 tzinfo_doc, /* tp_doc */
3064 0, /* tp_traverse */
3065 0, /* tp_clear */
3066 0, /* tp_richcompare */
3067 0, /* tp_weaklistoffset */
3068 0, /* tp_iter */
3069 0, /* tp_iternext */
3070 tzinfo_methods, /* tp_methods */
3071 0, /* tp_members */
3072 0, /* tp_getset */
3073 0, /* tp_base */
3074 0, /* tp_dict */
3075 0, /* tp_descr_get */
3076 0, /* tp_descr_set */
3077 0, /* tp_dictoffset */
3078 0, /* tp_init */
3079 0, /* tp_alloc */
3080 PyType_GenericNew, /* tp_new */
3081 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003082};
3083
3084/*
Tim Peters37f39822003-01-10 03:49:02 +00003085 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003086 */
3087
Tim Peters37f39822003-01-10 03:49:02 +00003088/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003089 */
3090
3091static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003092time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003093{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003094 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003095}
3096
Tim Peters37f39822003-01-10 03:49:02 +00003097static PyObject *
3098time_minute(PyDateTime_Time *self, void *unused)
3099{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003100 return PyInt_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003101}
3102
3103/* The name time_second conflicted with some platform header file. */
3104static PyObject *
3105py_time_second(PyDateTime_Time *self, void *unused)
3106{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003107 return PyInt_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003108}
3109
3110static PyObject *
3111time_microsecond(PyDateTime_Time *self, void *unused)
3112{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003113 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003114}
3115
3116static PyObject *
3117time_tzinfo(PyDateTime_Time *self, void *unused)
3118{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003119 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3120 Py_INCREF(result);
3121 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003122}
3123
3124static PyGetSetDef time_getset[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003125 {"hour", (getter)time_hour},
3126 {"minute", (getter)time_minute},
3127 {"second", (getter)py_time_second},
3128 {"microsecond", (getter)time_microsecond},
3129 {"tzinfo", (getter)time_tzinfo},
3130 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003131};
3132
3133/*
3134 * Constructors.
3135 */
3136
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003137static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003138 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003139
Tim Peters2a799bf2002-12-16 20:18:38 +00003140static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003141time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003142{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003143 PyObject *self = NULL;
3144 PyObject *state;
3145 int hour = 0;
3146 int minute = 0;
3147 int second = 0;
3148 int usecond = 0;
3149 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003150
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003151 /* Check for invocation from pickle with __getstate__ state */
3152 if (PyTuple_GET_SIZE(args) >= 1 &&
3153 PyTuple_GET_SIZE(args) <= 2 &&
3154 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3155 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3156 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
3157 {
3158 PyDateTime_Time *me;
3159 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003160
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003161 if (PyTuple_GET_SIZE(args) == 2) {
3162 tzinfo = PyTuple_GET_ITEM(args, 1);
3163 if (check_tzinfo_subclass(tzinfo) < 0) {
3164 PyErr_SetString(PyExc_TypeError, "bad "
3165 "tzinfo state arg");
3166 return NULL;
3167 }
3168 }
3169 aware = (char)(tzinfo != Py_None);
3170 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3171 if (me != NULL) {
3172 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003173
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003174 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3175 me->hashcode = -1;
3176 me->hastzinfo = aware;
3177 if (aware) {
3178 Py_INCREF(tzinfo);
3179 me->tzinfo = tzinfo;
3180 }
3181 }
3182 return (PyObject *)me;
3183 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003184
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003185 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3186 &hour, &minute, &second, &usecond,
3187 &tzinfo)) {
3188 if (check_time_args(hour, minute, second, usecond) < 0)
3189 return NULL;
3190 if (check_tzinfo_subclass(tzinfo) < 0)
3191 return NULL;
3192 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3193 type);
3194 }
3195 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003196}
3197
3198/*
3199 * Destructor.
3200 */
3201
3202static void
Tim Peters37f39822003-01-10 03:49:02 +00003203time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003204{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003205 if (HASTZINFO(self)) {
3206 Py_XDECREF(self->tzinfo);
3207 }
3208 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003209}
3210
3211/*
Tim Peters855fe882002-12-22 03:43:39 +00003212 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003213 */
3214
Tim Peters2a799bf2002-12-16 20:18:38 +00003215/* These are all METH_NOARGS, so don't need to check the arglist. */
3216static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003217time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003218 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3219 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003220}
3221
3222static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003223time_dst(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003224 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3225 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003226}
3227
3228static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003229time_tzname(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003230 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3231 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003232}
3233
3234/*
Tim Peters37f39822003-01-10 03:49:02 +00003235 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003236 */
3237
3238static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003239time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003240{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003241 char buffer[100];
3242 const char *type_name = Py_TYPE(self)->tp_name;
3243 int h = TIME_GET_HOUR(self);
3244 int m = TIME_GET_MINUTE(self);
3245 int s = TIME_GET_SECOND(self);
3246 int us = TIME_GET_MICROSECOND(self);
3247 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003248
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003249 if (us)
3250 PyOS_snprintf(buffer, sizeof(buffer),
3251 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
3252 else if (s)
3253 PyOS_snprintf(buffer, sizeof(buffer),
3254 "%s(%d, %d, %d)", type_name, h, m, s);
3255 else
3256 PyOS_snprintf(buffer, sizeof(buffer),
3257 "%s(%d, %d)", type_name, h, m);
3258 result = PyString_FromString(buffer);
3259 if (result != NULL && HASTZINFO(self))
3260 result = append_keyword_tzinfo(result, self->tzinfo);
3261 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003262}
3263
Tim Peters37f39822003-01-10 03:49:02 +00003264static PyObject *
3265time_str(PyDateTime_Time *self)
3266{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003267 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003268}
Tim Peters2a799bf2002-12-16 20:18:38 +00003269
3270static PyObject *
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003271time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003272{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003273 char buf[100];
3274 PyObject *result;
3275 /* Reuse the time format code from the datetime type. */
3276 PyDateTime_DateTime datetime;
3277 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003278
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003279 /* Copy over just the time bytes. */
3280 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3281 self->data,
3282 _PyDateTime_TIME_DATASIZE);
Tim Peters37f39822003-01-10 03:49:02 +00003283
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003284 isoformat_time(pdatetime, buf, sizeof(buf));
3285 result = PyString_FromString(buf);
3286 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3287 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003288
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003289 /* We need to append the UTC offset. */
3290 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3291 Py_None) < 0) {
3292 Py_DECREF(result);
3293 return NULL;
3294 }
3295 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3296 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003297}
3298
Tim Peters37f39822003-01-10 03:49:02 +00003299static PyObject *
3300time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3301{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003302 PyObject *result;
3303 PyObject *tuple;
3304 const char *format;
3305 Py_ssize_t format_len;
3306 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003307
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003308 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3309 &format, &format_len))
3310 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003311
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003312 /* Python's strftime does insane things with the year part of the
3313 * timetuple. The year is forced to (the otherwise nonsensical)
3314 * 1900 to worm around that.
3315 */
3316 tuple = Py_BuildValue("iiiiiiiii",
3317 1900, 1, 1, /* year, month, day */
3318 TIME_GET_HOUR(self),
3319 TIME_GET_MINUTE(self),
3320 TIME_GET_SECOND(self),
3321 0, 1, -1); /* weekday, daynum, dst */
3322 if (tuple == NULL)
3323 return NULL;
3324 assert(PyTuple_Size(tuple) == 9);
3325 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3326 Py_None);
3327 Py_DECREF(tuple);
3328 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003329}
Tim Peters2a799bf2002-12-16 20:18:38 +00003330
3331/*
3332 * Miscellaneous methods.
3333 */
3334
Tim Peters37f39822003-01-10 03:49:02 +00003335/* This is more natural as a tp_compare, but doesn't work then: for whatever
3336 * reason, Python's try_3way_compare ignores tp_compare unless
3337 * PyInstance_Check returns true, but these aren't old-style classes.
3338 */
3339static PyObject *
3340time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3341{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003342 int diff;
3343 naivety n1, n2;
3344 int offset1, offset2;
Tim Peters37f39822003-01-10 03:49:02 +00003345
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003346 if (! PyTime_Check(other)) {
3347 if (op == Py_EQ || op == Py_NE) {
3348 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3349 Py_INCREF(result);
3350 return result;
3351 }
3352 /* Stop this from falling back to address comparison. */
3353 return cmperror((PyObject *)self, other);
3354 }
3355 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3356 other, &offset2, &n2, Py_None) < 0)
3357 return NULL;
3358 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3359 /* If they're both naive, or both aware and have the same offsets,
3360 * we get off cheap. Note that if they're both naive, offset1 ==
3361 * offset2 == 0 at this point.
3362 */
3363 if (n1 == n2 && offset1 == offset2) {
3364 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3365 _PyDateTime_TIME_DATASIZE);
3366 return diff_to_bool(diff, op);
3367 }
Tim Peters37f39822003-01-10 03:49:02 +00003368
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003369 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3370 assert(offset1 != offset2); /* else last "if" handled it */
3371 /* Convert everything except microseconds to seconds. These
3372 * can't overflow (no more than the # of seconds in 2 days).
3373 */
3374 offset1 = TIME_GET_HOUR(self) * 3600 +
3375 (TIME_GET_MINUTE(self) - offset1) * 60 +
3376 TIME_GET_SECOND(self);
3377 offset2 = TIME_GET_HOUR(other) * 3600 +
3378 (TIME_GET_MINUTE(other) - offset2) * 60 +
3379 TIME_GET_SECOND(other);
3380 diff = offset1 - offset2;
3381 if (diff == 0)
3382 diff = TIME_GET_MICROSECOND(self) -
3383 TIME_GET_MICROSECOND(other);
3384 return diff_to_bool(diff, op);
3385 }
Tim Peters37f39822003-01-10 03:49:02 +00003386
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003387 assert(n1 != n2);
3388 PyErr_SetString(PyExc_TypeError,
3389 "can't compare offset-naive and "
3390 "offset-aware times");
3391 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003392}
3393
3394static long
3395time_hash(PyDateTime_Time *self)
3396{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003397 if (self->hashcode == -1) {
3398 naivety n;
3399 int offset;
3400 PyObject *temp;
Tim Peters37f39822003-01-10 03:49:02 +00003401
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003402 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3403 assert(n != OFFSET_UNKNOWN);
3404 if (n == OFFSET_ERROR)
3405 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003406
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003407 /* Reduce this to a hash of another object. */
3408 if (offset == 0)
3409 temp = PyString_FromStringAndSize((char *)self->data,
3410 _PyDateTime_TIME_DATASIZE);
3411 else {
3412 int hour;
3413 int minute;
Tim Peters37f39822003-01-10 03:49:02 +00003414
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003415 assert(n == OFFSET_AWARE);
3416 assert(HASTZINFO(self));
3417 hour = divmod(TIME_GET_HOUR(self) * 60 +
3418 TIME_GET_MINUTE(self) - offset,
3419 60,
3420 &minute);
3421 if (0 <= hour && hour < 24)
3422 temp = new_time(hour, minute,
3423 TIME_GET_SECOND(self),
3424 TIME_GET_MICROSECOND(self),
3425 Py_None);
3426 else
3427 temp = Py_BuildValue("iiii",
3428 hour, minute,
3429 TIME_GET_SECOND(self),
3430 TIME_GET_MICROSECOND(self));
3431 }
3432 if (temp != NULL) {
3433 self->hashcode = PyObject_Hash(temp);
3434 Py_DECREF(temp);
3435 }
3436 }
3437 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003438}
Tim Peters2a799bf2002-12-16 20:18:38 +00003439
Tim Peters12bf3392002-12-24 05:41:27 +00003440static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003441time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003442{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003443 PyObject *clone;
3444 PyObject *tuple;
3445 int hh = TIME_GET_HOUR(self);
3446 int mm = TIME_GET_MINUTE(self);
3447 int ss = TIME_GET_SECOND(self);
3448 int us = TIME_GET_MICROSECOND(self);
3449 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003450
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003451 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3452 time_kws,
3453 &hh, &mm, &ss, &us, &tzinfo))
3454 return NULL;
3455 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3456 if (tuple == NULL)
3457 return NULL;
3458 clone = time_new(Py_TYPE(self), tuple, NULL);
3459 Py_DECREF(tuple);
3460 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003461}
3462
Tim Peters2a799bf2002-12-16 20:18:38 +00003463static int
Tim Peters37f39822003-01-10 03:49:02 +00003464time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003465{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003466 int offset;
3467 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00003468
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003469 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3470 /* Since utcoffset is in whole minutes, nothing can
3471 * alter the conclusion that this is nonzero.
3472 */
3473 return 1;
3474 }
3475 offset = 0;
3476 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3477 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3478 if (offset == -1 && PyErr_Occurred())
3479 return -1;
3480 }
3481 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003482}
3483
Tim Peters371935f2003-02-01 01:52:50 +00003484/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003485
Tim Peters33e0f382003-01-10 02:05:14 +00003486/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003487 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3488 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003489 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003490 */
3491static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003492time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003493{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003494 PyObject *basestate;
3495 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003496
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003497 basestate = PyString_FromStringAndSize((char *)self->data,
3498 _PyDateTime_TIME_DATASIZE);
3499 if (basestate != NULL) {
3500 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3501 result = PyTuple_Pack(1, basestate);
3502 else
3503 result = PyTuple_Pack(2, basestate, self->tzinfo);
3504 Py_DECREF(basestate);
3505 }
3506 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003507}
3508
3509static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003510time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003511{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003512 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003513}
3514
Tim Peters37f39822003-01-10 03:49:02 +00003515static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003516
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003517 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3518 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3519 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003520
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003521 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3522 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003523
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003524 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3525 PyDoc_STR("Formats self with strftime.")},
Eric Smitha9f7d622008-02-17 19:46:49 +00003526
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003527 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3528 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003529
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003530 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3531 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003532
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003533 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3534 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003535
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003536 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3537 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003538
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003539 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3540 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003541
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003542 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003543};
3544
Tim Peters37f39822003-01-10 03:49:02 +00003545static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003546PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3547\n\
3548All arguments are optional. tzinfo may be None, or an instance of\n\
3549a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003550
Tim Peters37f39822003-01-10 03:49:02 +00003551static PyNumberMethods time_as_number = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003552 0, /* nb_add */
3553 0, /* nb_subtract */
3554 0, /* nb_multiply */
3555 0, /* nb_divide */
3556 0, /* nb_remainder */
3557 0, /* nb_divmod */
3558 0, /* nb_power */
3559 0, /* nb_negative */
3560 0, /* nb_positive */
3561 0, /* nb_absolute */
3562 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003563};
3564
Tim Peters37f39822003-01-10 03:49:02 +00003565statichere PyTypeObject PyDateTime_TimeType = {
Benjamin Petersona72d15c2017-09-13 21:20:29 -07003566 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003567 "datetime.time", /* tp_name */
3568 sizeof(PyDateTime_Time), /* tp_basicsize */
3569 0, /* tp_itemsize */
3570 (destructor)time_dealloc, /* tp_dealloc */
3571 0, /* tp_print */
3572 0, /* tp_getattr */
3573 0, /* tp_setattr */
3574 0, /* tp_compare */
3575 (reprfunc)time_repr, /* tp_repr */
3576 &time_as_number, /* tp_as_number */
3577 0, /* tp_as_sequence */
3578 0, /* tp_as_mapping */
3579 (hashfunc)time_hash, /* tp_hash */
3580 0, /* tp_call */
3581 (reprfunc)time_str, /* tp_str */
3582 PyObject_GenericGetAttr, /* tp_getattro */
3583 0, /* tp_setattro */
3584 0, /* tp_as_buffer */
3585 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3586 Py_TPFLAGS_BASETYPE, /* tp_flags */
3587 time_doc, /* tp_doc */
3588 0, /* tp_traverse */
3589 0, /* tp_clear */
3590 (richcmpfunc)time_richcompare, /* tp_richcompare */
3591 0, /* tp_weaklistoffset */
3592 0, /* tp_iter */
3593 0, /* tp_iternext */
3594 time_methods, /* tp_methods */
3595 0, /* tp_members */
3596 time_getset, /* tp_getset */
3597 0, /* tp_base */
3598 0, /* tp_dict */
3599 0, /* tp_descr_get */
3600 0, /* tp_descr_set */
3601 0, /* tp_dictoffset */
3602 0, /* tp_init */
3603 time_alloc, /* tp_alloc */
3604 time_new, /* tp_new */
3605 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003606};
3607
3608/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003609 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003610 */
3611
Tim Petersa9bc1682003-01-11 03:39:11 +00003612/* Accessor properties. Properties for day, month, and year are inherited
3613 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003614 */
3615
3616static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003617datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003618{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003619 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003620}
3621
Tim Petersa9bc1682003-01-11 03:39:11 +00003622static PyObject *
3623datetime_minute(PyDateTime_DateTime *self, void *unused)
3624{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003625 return PyInt_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003626}
3627
3628static PyObject *
3629datetime_second(PyDateTime_DateTime *self, void *unused)
3630{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003631 return PyInt_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003632}
3633
3634static PyObject *
3635datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3636{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003637 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003638}
3639
3640static PyObject *
3641datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3642{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003643 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3644 Py_INCREF(result);
3645 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003646}
3647
3648static PyGetSetDef datetime_getset[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003649 {"hour", (getter)datetime_hour},
3650 {"minute", (getter)datetime_minute},
3651 {"second", (getter)datetime_second},
3652 {"microsecond", (getter)datetime_microsecond},
3653 {"tzinfo", (getter)datetime_tzinfo},
3654 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003655};
3656
3657/*
3658 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003659 */
3660
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003661static char *datetime_kws[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003662 "year", "month", "day", "hour", "minute", "second",
3663 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003664};
3665
Tim Peters2a799bf2002-12-16 20:18:38 +00003666static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003667datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003668{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003669 PyObject *self = NULL;
3670 PyObject *state;
3671 int year;
3672 int month;
3673 int day;
3674 int hour = 0;
3675 int minute = 0;
3676 int second = 0;
3677 int usecond = 0;
3678 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003679
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003680 /* Check for invocation from pickle with __getstate__ state */
3681 if (PyTuple_GET_SIZE(args) >= 1 &&
3682 PyTuple_GET_SIZE(args) <= 2 &&
3683 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3684 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3685 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
3686 {
3687 PyDateTime_DateTime *me;
3688 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003689
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003690 if (PyTuple_GET_SIZE(args) == 2) {
3691 tzinfo = PyTuple_GET_ITEM(args, 1);
3692 if (check_tzinfo_subclass(tzinfo) < 0) {
3693 PyErr_SetString(PyExc_TypeError, "bad "
3694 "tzinfo state arg");
3695 return NULL;
3696 }
3697 }
3698 aware = (char)(tzinfo != Py_None);
3699 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3700 if (me != NULL) {
3701 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003702
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003703 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3704 me->hashcode = -1;
3705 me->hastzinfo = aware;
3706 if (aware) {
3707 Py_INCREF(tzinfo);
3708 me->tzinfo = tzinfo;
3709 }
3710 }
3711 return (PyObject *)me;
3712 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003713
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003714 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3715 &year, &month, &day, &hour, &minute,
3716 &second, &usecond, &tzinfo)) {
3717 if (check_date_args(year, month, day) < 0)
3718 return NULL;
3719 if (check_time_args(hour, minute, second, usecond) < 0)
3720 return NULL;
3721 if (check_tzinfo_subclass(tzinfo) < 0)
3722 return NULL;
3723 self = new_datetime_ex(year, month, day,
3724 hour, minute, second, usecond,
3725 tzinfo, type);
3726 }
3727 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003728}
3729
Tim Petersa9bc1682003-01-11 03:39:11 +00003730/* TM_FUNC is the shared type of localtime() and gmtime(). */
3731typedef struct tm *(*TM_FUNC)(const time_t *timer);
3732
3733/* Internal helper.
3734 * Build datetime from a time_t and a distinct count of microseconds.
3735 * Pass localtime or gmtime for f, to control the interpretation of timet.
3736 */
3737static PyObject *
3738datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003739 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00003740{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003741 struct tm *tm;
3742 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003743
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003744 tm = f(&timet);
3745 if (tm) {
3746 /* The platform localtime/gmtime may insert leap seconds,
3747 * indicated by tm->tm_sec > 59. We don't care about them,
3748 * except to the extent that passing them on to the datetime
3749 * constructor would raise ValueError for a reason that
3750 * made no sense to the user.
3751 */
3752 if (tm->tm_sec > 59)
3753 tm->tm_sec = 59;
3754 result = PyObject_CallFunction(cls, "iiiiiiiO",
3755 tm->tm_year + 1900,
3756 tm->tm_mon + 1,
3757 tm->tm_mday,
3758 tm->tm_hour,
3759 tm->tm_min,
3760 tm->tm_sec,
3761 us,
3762 tzinfo);
3763 }
3764 else
3765 PyErr_SetString(PyExc_ValueError,
3766 "timestamp out of range for "
3767 "platform localtime()/gmtime() function");
3768 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003769}
3770
3771/* Internal helper.
3772 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3773 * to control the interpretation of the timestamp. Since a double doesn't
3774 * have enough bits to cover a datetime's full range of precision, it's
3775 * better to call datetime_from_timet_and_us provided you have a way
3776 * to get that much precision (e.g., C time() isn't good enough).
3777 */
3778static PyObject *
3779datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003780 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00003781{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003782 time_t timet;
3783 double fraction;
3784 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00003785
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003786 timet = _PyTime_DoubleToTimet(timestamp);
3787 if (timet == (time_t)-1 && PyErr_Occurred())
3788 return NULL;
3789 fraction = timestamp - (double)timet;
3790 us = (int)round_to_long(fraction * 1e6);
3791 if (us < 0) {
3792 /* Truncation towards zero is not what we wanted
3793 for negative numbers (Python's mod semantics) */
3794 timet -= 1;
3795 us += 1000000;
3796 }
3797 /* If timestamp is less than one microsecond smaller than a
3798 * full second, round up. Otherwise, ValueErrors are raised
3799 * for some floats. */
3800 if (us == 1000000) {
3801 timet += 1;
3802 us = 0;
3803 }
3804 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003805}
3806
3807/* Internal helper.
3808 * Build most accurate possible datetime for current time. Pass localtime or
3809 * gmtime for f as appropriate.
3810 */
3811static PyObject *
3812datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3813{
3814#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003815 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00003816
3817#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003818 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00003819#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003820 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00003821#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003822 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3823 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003824
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003825#else /* ! HAVE_GETTIMEOFDAY */
3826 /* No flavor of gettimeofday exists on this platform. Python's
3827 * time.time() does a lot of other platform tricks to get the
3828 * best time it can on the platform, and we're not going to do
3829 * better than that (if we could, the better code would belong
3830 * in time.time()!) We're limited by the precision of a double,
3831 * though.
3832 */
3833 PyObject *time;
3834 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00003835
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003836 time = time_time();
3837 if (time == NULL)
3838 return NULL;
3839 dtime = PyFloat_AsDouble(time);
3840 Py_DECREF(time);
3841 if (dtime == -1.0 && PyErr_Occurred())
3842 return NULL;
3843 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3844#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00003845}
3846
Tim Peters2a799bf2002-12-16 20:18:38 +00003847/* Return best possible local time -- this isn't constrained by the
3848 * precision of a timestamp.
3849 */
3850static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003851datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003852{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003853 PyObject *self;
3854 PyObject *tzinfo = Py_None;
3855 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003856
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003857 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3858 &tzinfo))
3859 return NULL;
3860 if (check_tzinfo_subclass(tzinfo) < 0)
3861 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00003862
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003863 self = datetime_best_possible(cls,
3864 tzinfo == Py_None ? localtime : gmtime,
3865 tzinfo);
3866 if (self != NULL && tzinfo != Py_None) {
3867 /* Convert UTC to tzinfo's zone. */
3868 PyObject *temp = self;
3869 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3870 Py_DECREF(temp);
3871 }
3872 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003873}
3874
Tim Petersa9bc1682003-01-11 03:39:11 +00003875/* Return best possible UTC time -- this isn't constrained by the
3876 * precision of a timestamp.
3877 */
3878static PyObject *
3879datetime_utcnow(PyObject *cls, PyObject *dummy)
3880{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003881 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00003882}
3883
Tim Peters2a799bf2002-12-16 20:18:38 +00003884/* Return new local datetime from timestamp (Python timestamp -- a double). */
3885static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003886datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003887{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003888 PyObject *self;
3889 double timestamp;
3890 PyObject *tzinfo = Py_None;
3891 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003892
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003893 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3894 keywords, &timestamp, &tzinfo))
3895 return NULL;
3896 if (check_tzinfo_subclass(tzinfo) < 0)
3897 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003898
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003899 self = datetime_from_timestamp(cls,
3900 tzinfo == Py_None ? localtime : gmtime,
3901 timestamp,
3902 tzinfo);
3903 if (self != NULL && tzinfo != Py_None) {
3904 /* Convert UTC to tzinfo's zone. */
3905 PyObject *temp = self;
3906 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3907 Py_DECREF(temp);
3908 }
3909 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003910}
3911
Tim Petersa9bc1682003-01-11 03:39:11 +00003912/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3913static PyObject *
3914datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3915{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003916 double timestamp;
3917 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003918
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003919 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3920 result = datetime_from_timestamp(cls, gmtime, timestamp,
3921 Py_None);
3922 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003923}
3924
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003925/* Return new datetime from time.strptime(). */
3926static PyObject *
3927datetime_strptime(PyObject *cls, PyObject *args)
3928{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003929 static PyObject *module = NULL;
3930 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3931 const char *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003932
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003933 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3934 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003935
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003936 if (module == NULL &&
3937 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3938 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003939
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003940 /* _strptime._strptime returns a two-element tuple. The first
3941 element is a time.struct_time object. The second is the
3942 microseconds (which are not defined for time.struct_time). */
3943 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
3944 if (obj != NULL) {
3945 int i, good_timetuple = 1;
3946 long int ia[7];
3947 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3948 st = PySequence_GetItem(obj, 0);
3949 frac = PySequence_GetItem(obj, 1);
3950 if (st == NULL || frac == NULL)
3951 good_timetuple = 0;
3952 /* copy y/m/d/h/m/s values out of the
3953 time.struct_time */
3954 if (good_timetuple &&
3955 PySequence_Check(st) &&
3956 PySequence_Size(st) >= 6) {
3957 for (i=0; i < 6; i++) {
3958 PyObject *p = PySequence_GetItem(st, i);
3959 if (p == NULL) {
3960 good_timetuple = 0;
3961 break;
3962 }
3963 if (PyInt_Check(p))
3964 ia[i] = PyInt_AsLong(p);
3965 else
3966 good_timetuple = 0;
3967 Py_DECREF(p);
3968 }
3969 }
3970 else
3971 good_timetuple = 0;
3972 /* follow that up with a little dose of microseconds */
3973 if (good_timetuple && PyInt_Check(frac))
3974 ia[6] = PyInt_AsLong(frac);
3975 else
3976 good_timetuple = 0;
3977 }
3978 else
3979 good_timetuple = 0;
3980 if (good_timetuple)
3981 result = PyObject_CallFunction(cls, "iiiiiii",
3982 ia[0], ia[1], ia[2],
3983 ia[3], ia[4], ia[5],
3984 ia[6]);
3985 else
3986 PyErr_SetString(PyExc_ValueError,
3987 "unexpected value from _strptime._strptime");
3988 }
3989 Py_XDECREF(obj);
3990 Py_XDECREF(st);
3991 Py_XDECREF(frac);
3992 return result;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003993}
3994
Tim Petersa9bc1682003-01-11 03:39:11 +00003995/* Return new datetime from date/datetime and time arguments. */
3996static PyObject *
3997datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3998{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003999 static char *keywords[] = {"date", "time", NULL};
4000 PyObject *date;
4001 PyObject *time;
4002 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004003
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004004 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4005 &PyDateTime_DateType, &date,
4006 &PyDateTime_TimeType, &time)) {
4007 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004008
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004009 if (HASTZINFO(time))
4010 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4011 result = PyObject_CallFunction(cls, "iiiiiiiO",
4012 GET_YEAR(date),
4013 GET_MONTH(date),
4014 GET_DAY(date),
4015 TIME_GET_HOUR(time),
4016 TIME_GET_MINUTE(time),
4017 TIME_GET_SECOND(time),
4018 TIME_GET_MICROSECOND(time),
4019 tzinfo);
4020 }
4021 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004022}
Tim Peters2a799bf2002-12-16 20:18:38 +00004023
4024/*
4025 * Destructor.
4026 */
4027
4028static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004029datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004030{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004031 if (HASTZINFO(self)) {
4032 Py_XDECREF(self->tzinfo);
4033 }
4034 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004035}
4036
4037/*
4038 * Indirect access to tzinfo methods.
4039 */
4040
Tim Peters2a799bf2002-12-16 20:18:38 +00004041/* These are all METH_NOARGS, so don't need to check the arglist. */
4042static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004043datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004044 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4045 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004046}
4047
4048static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004049datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004050 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4051 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004052}
4053
4054static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004055datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004056 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4057 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004058}
4059
4060/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004061 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004062 */
4063
Tim Petersa9bc1682003-01-11 03:39:11 +00004064/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4065 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004066 */
4067static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004068add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004069 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004070{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004071 /* Note that the C-level additions can't overflow, because of
4072 * invariant bounds on the member values.
4073 */
4074 int year = GET_YEAR(date);
4075 int month = GET_MONTH(date);
4076 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4077 int hour = DATE_GET_HOUR(date);
4078 int minute = DATE_GET_MINUTE(date);
4079 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4080 int microsecond = DATE_GET_MICROSECOND(date) +
4081 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004082
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004083 assert(factor == 1 || factor == -1);
4084 if (normalize_datetime(&year, &month, &day,
4085 &hour, &minute, &second, &microsecond) < 0)
4086 return NULL;
4087 else
4088 return new_datetime(year, month, day,
4089 hour, minute, second, microsecond,
4090 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004091}
4092
4093static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004094datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004095{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004096 if (PyDateTime_Check(left)) {
4097 /* datetime + ??? */
4098 if (PyDelta_Check(right))
4099 /* datetime + delta */
4100 return add_datetime_timedelta(
4101 (PyDateTime_DateTime *)left,
4102 (PyDateTime_Delta *)right,
4103 1);
4104 }
4105 else if (PyDelta_Check(left)) {
4106 /* delta + datetime */
4107 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4108 (PyDateTime_Delta *) left,
4109 1);
4110 }
4111 Py_INCREF(Py_NotImplemented);
4112 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004113}
4114
4115static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004116datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004117{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004118 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004119
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004120 if (PyDateTime_Check(left)) {
4121 /* datetime - ??? */
4122 if (PyDateTime_Check(right)) {
4123 /* datetime - datetime */
4124 naivety n1, n2;
4125 int offset1, offset2;
4126 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004127
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004128 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4129 right, &offset2, &n2,
4130 right) < 0)
4131 return NULL;
4132 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4133 if (n1 != n2) {
4134 PyErr_SetString(PyExc_TypeError,
4135 "can't subtract offset-naive and "
4136 "offset-aware datetimes");
4137 return NULL;
4138 }
4139 delta_d = ymd_to_ord(GET_YEAR(left),
4140 GET_MONTH(left),
4141 GET_DAY(left)) -
4142 ymd_to_ord(GET_YEAR(right),
4143 GET_MONTH(right),
4144 GET_DAY(right));
4145 /* These can't overflow, since the values are
4146 * normalized. At most this gives the number of
4147 * seconds in one day.
4148 */
4149 delta_s = (DATE_GET_HOUR(left) -
4150 DATE_GET_HOUR(right)) * 3600 +
4151 (DATE_GET_MINUTE(left) -
4152 DATE_GET_MINUTE(right)) * 60 +
4153 (DATE_GET_SECOND(left) -
4154 DATE_GET_SECOND(right));
4155 delta_us = DATE_GET_MICROSECOND(left) -
4156 DATE_GET_MICROSECOND(right);
4157 /* (left - offset1) - (right - offset2) =
4158 * (left - right) + (offset2 - offset1)
4159 */
4160 delta_s += (offset2 - offset1) * 60;
4161 result = new_delta(delta_d, delta_s, delta_us, 1);
4162 }
4163 else if (PyDelta_Check(right)) {
4164 /* datetime - delta */
4165 result = add_datetime_timedelta(
4166 (PyDateTime_DateTime *)left,
4167 (PyDateTime_Delta *)right,
4168 -1);
4169 }
4170 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004171
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004172 if (result == Py_NotImplemented)
4173 Py_INCREF(result);
4174 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004175}
4176
4177/* Various ways to turn a datetime into a string. */
4178
4179static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004180datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004181{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004182 char buffer[1000];
4183 const char *type_name = Py_TYPE(self)->tp_name;
4184 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004185
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004186 if (DATE_GET_MICROSECOND(self)) {
4187 PyOS_snprintf(buffer, sizeof(buffer),
4188 "%s(%d, %d, %d, %d, %d, %d, %d)",
4189 type_name,
4190 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4191 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4192 DATE_GET_SECOND(self),
4193 DATE_GET_MICROSECOND(self));
4194 }
4195 else if (DATE_GET_SECOND(self)) {
4196 PyOS_snprintf(buffer, sizeof(buffer),
4197 "%s(%d, %d, %d, %d, %d, %d)",
4198 type_name,
4199 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4200 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4201 DATE_GET_SECOND(self));
4202 }
4203 else {
4204 PyOS_snprintf(buffer, sizeof(buffer),
4205 "%s(%d, %d, %d, %d, %d)",
4206 type_name,
4207 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4208 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4209 }
4210 baserepr = PyString_FromString(buffer);
4211 if (baserepr == NULL || ! HASTZINFO(self))
4212 return baserepr;
4213 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004214}
4215
Tim Petersa9bc1682003-01-11 03:39:11 +00004216static PyObject *
4217datetime_str(PyDateTime_DateTime *self)
4218{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004219 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004220}
Tim Peters2a799bf2002-12-16 20:18:38 +00004221
4222static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004223datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004224{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004225 char sep = 'T';
4226 static char *keywords[] = {"sep", NULL};
4227 char buffer[100];
4228 char *cp;
4229 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004230
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004231 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4232 &sep))
4233 return NULL;
4234 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4235 assert(cp != NULL);
4236 *cp++ = sep;
4237 cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4238 result = PyString_FromStringAndSize(buffer, cp - buffer);
4239 if (result == NULL || ! HASTZINFO(self))
4240 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004241
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004242 /* We need to append the UTC offset. */
4243 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4244 (PyObject *)self) < 0) {
4245 Py_DECREF(result);
4246 return NULL;
4247 }
4248 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
4249 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004250}
4251
Tim Petersa9bc1682003-01-11 03:39:11 +00004252static PyObject *
4253datetime_ctime(PyDateTime_DateTime *self)
4254{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004255 return format_ctime((PyDateTime_Date *)self,
4256 DATE_GET_HOUR(self),
4257 DATE_GET_MINUTE(self),
4258 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004259}
4260
Tim Peters2a799bf2002-12-16 20:18:38 +00004261/* Miscellaneous methods. */
4262
Tim Petersa9bc1682003-01-11 03:39:11 +00004263/* This is more natural as a tp_compare, but doesn't work then: for whatever
4264 * reason, Python's try_3way_compare ignores tp_compare unless
4265 * PyInstance_Check returns true, but these aren't old-style classes.
4266 */
4267static PyObject *
4268datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4269{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004270 int diff;
4271 naivety n1, n2;
4272 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004273
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004274 if (! PyDateTime_Check(other)) {
4275 /* If other has a "timetuple" attr, that's an advertised
4276 * hook for other classes to ask to get comparison control.
4277 * However, date instances have a timetuple attr, and we
4278 * don't want to allow that comparison. Because datetime
4279 * is a subclass of date, when mixing date and datetime
4280 * in a comparison, Python gives datetime the first shot
4281 * (it's the more specific subtype). So we can stop that
4282 * combination here reliably.
4283 */
4284 if (PyObject_HasAttrString(other, "timetuple") &&
4285 ! PyDate_Check(other)) {
4286 /* A hook for other kinds of datetime objects. */
4287 Py_INCREF(Py_NotImplemented);
4288 return Py_NotImplemented;
4289 }
4290 if (op == Py_EQ || op == Py_NE) {
4291 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4292 Py_INCREF(result);
4293 return result;
4294 }
4295 /* Stop this from falling back to address comparison. */
4296 return cmperror((PyObject *)self, other);
4297 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004298
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004299 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4300 (PyObject *)self,
4301 other, &offset2, &n2,
4302 other) < 0)
4303 return NULL;
4304 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4305 /* If they're both naive, or both aware and have the same offsets,
4306 * we get off cheap. Note that if they're both naive, offset1 ==
4307 * offset2 == 0 at this point.
4308 */
4309 if (n1 == n2 && offset1 == offset2) {
4310 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4311 _PyDateTime_DATETIME_DATASIZE);
4312 return diff_to_bool(diff, op);
4313 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004314
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004315 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4316 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004317
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004318 assert(offset1 != offset2); /* else last "if" handled it */
4319 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4320 other);
4321 if (delta == NULL)
4322 return NULL;
4323 diff = GET_TD_DAYS(delta);
4324 if (diff == 0)
4325 diff = GET_TD_SECONDS(delta) |
4326 GET_TD_MICROSECONDS(delta);
4327 Py_DECREF(delta);
4328 return diff_to_bool(diff, op);
4329 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004330
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004331 assert(n1 != n2);
4332 PyErr_SetString(PyExc_TypeError,
4333 "can't compare offset-naive and "
4334 "offset-aware datetimes");
4335 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004336}
4337
4338static long
4339datetime_hash(PyDateTime_DateTime *self)
4340{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004341 if (self->hashcode == -1) {
4342 naivety n;
4343 int offset;
4344 PyObject *temp;
Tim Petersa9bc1682003-01-11 03:39:11 +00004345
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004346 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4347 &offset);
4348 assert(n != OFFSET_UNKNOWN);
4349 if (n == OFFSET_ERROR)
4350 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004351
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004352 /* Reduce this to a hash of another object. */
4353 if (n == OFFSET_NAIVE)
4354 temp = PyString_FromStringAndSize(
4355 (char *)self->data,
4356 _PyDateTime_DATETIME_DATASIZE);
4357 else {
4358 int days;
4359 int seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004360
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004361 assert(n == OFFSET_AWARE);
4362 assert(HASTZINFO(self));
4363 days = ymd_to_ord(GET_YEAR(self),
4364 GET_MONTH(self),
4365 GET_DAY(self));
4366 seconds = DATE_GET_HOUR(self) * 3600 +
4367 (DATE_GET_MINUTE(self) - offset) * 60 +
4368 DATE_GET_SECOND(self);
4369 temp = new_delta(days,
4370 seconds,
4371 DATE_GET_MICROSECOND(self),
4372 1);
4373 }
4374 if (temp != NULL) {
4375 self->hashcode = PyObject_Hash(temp);
4376 Py_DECREF(temp);
4377 }
4378 }
4379 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004380}
Tim Peters2a799bf2002-12-16 20:18:38 +00004381
4382static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004383datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004384{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004385 PyObject *clone;
4386 PyObject *tuple;
4387 int y = GET_YEAR(self);
4388 int m = GET_MONTH(self);
4389 int d = GET_DAY(self);
4390 int hh = DATE_GET_HOUR(self);
4391 int mm = DATE_GET_MINUTE(self);
4392 int ss = DATE_GET_SECOND(self);
4393 int us = DATE_GET_MICROSECOND(self);
4394 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004395
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004396 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4397 datetime_kws,
4398 &y, &m, &d, &hh, &mm, &ss, &us,
4399 &tzinfo))
4400 return NULL;
4401 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4402 if (tuple == NULL)
4403 return NULL;
4404 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4405 Py_DECREF(tuple);
4406 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004407}
4408
4409static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004410datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004411{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004412 int y, m, d, hh, mm, ss, us;
4413 PyObject *result;
4414 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004415
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004416 PyObject *tzinfo;
4417 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004418
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004419 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4420 &PyDateTime_TZInfoType, &tzinfo))
4421 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004422
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004423 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4424 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004425
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004426 /* Conversion to self's own time zone is a NOP. */
4427 if (self->tzinfo == tzinfo) {
4428 Py_INCREF(self);
4429 return (PyObject *)self;
4430 }
Tim Peters521fc152002-12-31 17:36:56 +00004431
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004432 /* Convert self to UTC. */
4433 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4434 if (offset == -1 && PyErr_Occurred())
4435 return NULL;
4436 if (none)
4437 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004438
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004439 y = GET_YEAR(self);
4440 m = GET_MONTH(self);
4441 d = GET_DAY(self);
4442 hh = DATE_GET_HOUR(self);
4443 mm = DATE_GET_MINUTE(self);
4444 ss = DATE_GET_SECOND(self);
4445 us = DATE_GET_MICROSECOND(self);
Tim Peters52dcce22003-01-23 16:36:11 +00004446
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004447 mm -= offset;
4448 if ((mm < 0 || mm >= 60) &&
4449 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4450 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004451
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004452 /* Attach new tzinfo and let fromutc() do the rest. */
4453 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4454 if (result != NULL) {
4455 PyObject *temp = result;
Tim Peters52dcce22003-01-23 16:36:11 +00004456
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004457 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4458 Py_DECREF(temp);
4459 }
4460 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004461
Tim Peters52dcce22003-01-23 16:36:11 +00004462NeedAware:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004463 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4464 "a naive datetime");
4465 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004466}
4467
4468static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004469datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004470{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004471 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004472
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004473 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4474 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004475
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004476 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4477 if (dstflag == -1 && PyErr_Occurred())
4478 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004479
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004480 if (none)
4481 dstflag = -1;
4482 else if (dstflag != 0)
4483 dstflag = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004484
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004485 }
4486 return build_struct_time(GET_YEAR(self),
4487 GET_MONTH(self),
4488 GET_DAY(self),
4489 DATE_GET_HOUR(self),
4490 DATE_GET_MINUTE(self),
4491 DATE_GET_SECOND(self),
4492 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004493}
4494
4495static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004496datetime_getdate(PyDateTime_DateTime *self)
4497{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004498 return new_date(GET_YEAR(self),
4499 GET_MONTH(self),
4500 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004501}
4502
4503static PyObject *
4504datetime_gettime(PyDateTime_DateTime *self)
4505{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004506 return new_time(DATE_GET_HOUR(self),
4507 DATE_GET_MINUTE(self),
4508 DATE_GET_SECOND(self),
4509 DATE_GET_MICROSECOND(self),
4510 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004511}
4512
4513static PyObject *
4514datetime_gettimetz(PyDateTime_DateTime *self)
4515{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004516 return new_time(DATE_GET_HOUR(self),
4517 DATE_GET_MINUTE(self),
4518 DATE_GET_SECOND(self),
4519 DATE_GET_MICROSECOND(self),
4520 HASTZINFO(self) ? self->tzinfo : Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004521}
4522
4523static PyObject *
4524datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004525{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004526 int y = GET_YEAR(self);
4527 int m = GET_MONTH(self);
4528 int d = GET_DAY(self);
4529 int hh = DATE_GET_HOUR(self);
4530 int mm = DATE_GET_MINUTE(self);
4531 int ss = DATE_GET_SECOND(self);
4532 int us = 0; /* microseconds are ignored in a timetuple */
4533 int offset = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004534
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004535 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4536 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004537
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004538 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4539 if (offset == -1 && PyErr_Occurred())
4540 return NULL;
4541 }
4542 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4543 * 0 in a UTC timetuple regardless of what dst() says.
4544 */
4545 if (offset) {
4546 /* Subtract offset minutes & normalize. */
4547 int stat;
Tim Peters2a799bf2002-12-16 20:18:38 +00004548
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004549 mm -= offset;
4550 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4551 if (stat < 0) {
4552 /* At the edges, it's possible we overflowed
4553 * beyond MINYEAR or MAXYEAR.
4554 */
4555 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4556 PyErr_Clear();
4557 else
4558 return NULL;
4559 }
4560 }
4561 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004562}
4563
Tim Peters371935f2003-02-01 01:52:50 +00004564/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004565
Tim Petersa9bc1682003-01-11 03:39:11 +00004566/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004567 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4568 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004569 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004570 */
4571static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004572datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004573{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004574 PyObject *basestate;
4575 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004576
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004577 basestate = PyString_FromStringAndSize((char *)self->data,
4578 _PyDateTime_DATETIME_DATASIZE);
4579 if (basestate != NULL) {
4580 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4581 result = PyTuple_Pack(1, basestate);
4582 else
4583 result = PyTuple_Pack(2, basestate, self->tzinfo);
4584 Py_DECREF(basestate);
4585 }
4586 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004587}
4588
4589static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004590datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004591{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004592 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004593}
4594
Tim Petersa9bc1682003-01-11 03:39:11 +00004595static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004596
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004597 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004598
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004599 {"now", (PyCFunction)datetime_now,
4600 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4601 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004602
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004603 {"utcnow", (PyCFunction)datetime_utcnow,
4604 METH_NOARGS | METH_CLASS,
4605 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004606
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004607 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4608 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4609 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004610
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004611 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4612 METH_VARARGS | METH_CLASS,
4613 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4614 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004615
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004616 {"strptime", (PyCFunction)datetime_strptime,
4617 METH_VARARGS | METH_CLASS,
4618 PyDoc_STR("string, format -> new datetime parsed from a string "
4619 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004620
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004621 {"combine", (PyCFunction)datetime_combine,
4622 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4623 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004624
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004625 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004626
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004627 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4628 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004629
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004630 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4631 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004632
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004633 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4634 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004635
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004636 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4637 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004638
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004639 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4640 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004641
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004642 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4643 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004644
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004645 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4646 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4647 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4648 "sep is used to separate the year from the time, and "
4649 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004650
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004651 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4652 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004653
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004654 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4655 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004656
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004657 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4658 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004659
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004660 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4661 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004662
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004663 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4664 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004665
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004666 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4667 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004668
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004669 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004670};
4671
Tim Petersa9bc1682003-01-11 03:39:11 +00004672static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004673PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4674\n\
4675The year, month and day arguments are required. tzinfo may be None, or an\n\
4676instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004677
Tim Petersa9bc1682003-01-11 03:39:11 +00004678static PyNumberMethods datetime_as_number = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004679 datetime_add, /* nb_add */
4680 datetime_subtract, /* nb_subtract */
4681 0, /* nb_multiply */
4682 0, /* nb_divide */
4683 0, /* nb_remainder */
4684 0, /* nb_divmod */
4685 0, /* nb_power */
4686 0, /* nb_negative */
4687 0, /* nb_positive */
4688 0, /* nb_absolute */
4689 0, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00004690};
4691
Tim Petersa9bc1682003-01-11 03:39:11 +00004692statichere PyTypeObject PyDateTime_DateTimeType = {
Benjamin Petersona72d15c2017-09-13 21:20:29 -07004693 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004694 "datetime.datetime", /* tp_name */
4695 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4696 0, /* tp_itemsize */
4697 (destructor)datetime_dealloc, /* tp_dealloc */
4698 0, /* tp_print */
4699 0, /* tp_getattr */
4700 0, /* tp_setattr */
4701 0, /* tp_compare */
4702 (reprfunc)datetime_repr, /* tp_repr */
4703 &datetime_as_number, /* tp_as_number */
4704 0, /* tp_as_sequence */
4705 0, /* tp_as_mapping */
4706 (hashfunc)datetime_hash, /* tp_hash */
4707 0, /* tp_call */
4708 (reprfunc)datetime_str, /* tp_str */
4709 PyObject_GenericGetAttr, /* tp_getattro */
4710 0, /* tp_setattro */
4711 0, /* tp_as_buffer */
4712 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4713 Py_TPFLAGS_BASETYPE, /* tp_flags */
4714 datetime_doc, /* tp_doc */
4715 0, /* tp_traverse */
4716 0, /* tp_clear */
4717 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
4718 0, /* tp_weaklistoffset */
4719 0, /* tp_iter */
4720 0, /* tp_iternext */
4721 datetime_methods, /* tp_methods */
4722 0, /* tp_members */
4723 datetime_getset, /* tp_getset */
4724 &PyDateTime_DateType, /* tp_base */
4725 0, /* tp_dict */
4726 0, /* tp_descr_get */
4727 0, /* tp_descr_set */
4728 0, /* tp_dictoffset */
4729 0, /* tp_init */
4730 datetime_alloc, /* tp_alloc */
4731 datetime_new, /* tp_new */
4732 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004733};
4734
4735/* ---------------------------------------------------------------------------
4736 * Module methods and initialization.
4737 */
4738
4739static PyMethodDef module_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004740 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004741};
4742
Tim Peters9ddf40b2004-06-20 22:41:32 +00004743/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4744 * datetime.h.
4745 */
4746static PyDateTime_CAPI CAPI = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004747 &PyDateTime_DateType,
4748 &PyDateTime_DateTimeType,
4749 &PyDateTime_TimeType,
4750 &PyDateTime_DeltaType,
4751 &PyDateTime_TZInfoType,
4752 new_date_ex,
4753 new_datetime_ex,
4754 new_time_ex,
4755 new_delta_ex,
4756 datetime_fromtimestamp,
4757 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00004758};
4759
4760
Tim Peters2a799bf2002-12-16 20:18:38 +00004761PyMODINIT_FUNC
4762initdatetime(void)
4763{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004764 PyObject *m; /* a module object */
4765 PyObject *d; /* its dict */
4766 PyObject *x;
Tim Peters2a799bf2002-12-16 20:18:38 +00004767
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004768 m = Py_InitModule3("datetime", module_methods,
4769 "Fast implementation of the datetime type.");
4770 if (m == NULL)
4771 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004772
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004773 if (PyType_Ready(&PyDateTime_DateType) < 0)
4774 return;
4775 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4776 return;
4777 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4778 return;
4779 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4780 return;
4781 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4782 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004783
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004784 /* timedelta values */
4785 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004786
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004787 x = new_delta(0, 0, 1, 0);
4788 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4789 return;
4790 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004791
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004792 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4793 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4794 return;
4795 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004796
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004797 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4798 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4799 return;
4800 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004801
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004802 /* date values */
4803 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004804
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004805 x = new_date(1, 1, 1);
4806 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4807 return;
4808 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004809
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004810 x = new_date(MAXYEAR, 12, 31);
4811 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4812 return;
4813 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004814
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004815 x = new_delta(1, 0, 0, 0);
4816 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4817 return;
4818 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004819
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004820 /* time values */
4821 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004822
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004823 x = new_time(0, 0, 0, 0, Py_None);
4824 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4825 return;
4826 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004827
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004828 x = new_time(23, 59, 59, 999999, Py_None);
4829 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4830 return;
4831 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004832
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004833 x = new_delta(0, 0, 1, 0);
4834 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4835 return;
4836 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004837
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004838 /* datetime values */
4839 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004840
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004841 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4842 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4843 return;
4844 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004845
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004846 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4847 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4848 return;
4849 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004850
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004851 x = new_delta(0, 0, 1, 0);
4852 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4853 return;
4854 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004855
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004856 /* module initialization */
4857 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4858 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00004859
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004860 Py_INCREF(&PyDateTime_DateType);
4861 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004862
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004863 Py_INCREF(&PyDateTime_DateTimeType);
4864 PyModule_AddObject(m, "datetime",
4865 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00004866
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004867 Py_INCREF(&PyDateTime_TimeType);
4868 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00004869
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004870 Py_INCREF(&PyDateTime_DeltaType);
4871 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004872
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004873 Py_INCREF(&PyDateTime_TZInfoType);
4874 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004875
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004876 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
4877 if (x == NULL)
4878 return;
4879 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00004880
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004881 /* A 4-year cycle has an extra leap day over what we'd get from
4882 * pasting together 4 single years.
4883 */
4884 assert(DI4Y == 4 * 365 + 1);
4885 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004886
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004887 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4888 * get from pasting together 4 100-year cycles.
4889 */
4890 assert(DI400Y == 4 * DI100Y + 1);
4891 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004892
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004893 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4894 * pasting together 25 4-year cycles.
4895 */
4896 assert(DI100Y == 25 * DI4Y - 1);
4897 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004898
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004899 us_per_us = PyInt_FromLong(1);
4900 us_per_ms = PyInt_FromLong(1000);
4901 us_per_second = PyInt_FromLong(1000000);
4902 us_per_minute = PyInt_FromLong(60000000);
4903 seconds_per_day = PyInt_FromLong(24 * 3600);
4904 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4905 us_per_minute == NULL || seconds_per_day == NULL)
4906 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004907
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004908 /* The rest are too big for 32-bit ints, but even
4909 * us_per_week fits in 40 bits, so doubles should be exact.
4910 */
4911 us_per_hour = PyLong_FromDouble(3600000000.0);
4912 us_per_day = PyLong_FromDouble(86400000000.0);
4913 us_per_week = PyLong_FromDouble(604800000000.0);
4914 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4915 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004916}
Tim Petersf3615152003-01-01 21:51:37 +00004917
4918/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004919Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004920 x.n = x stripped of its timezone -- its naive time.
4921 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004922 return None
Tim Petersf3615152003-01-01 21:51:37 +00004923 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004924 return None
Tim Petersf3615152003-01-01 21:51:37 +00004925 x.s = x's standard offset, x.o - x.d
4926
4927Now some derived rules, where k is a duration (timedelta).
4928
49291. x.o = x.s + x.d
4930 This follows from the definition of x.s.
4931
Tim Petersc5dc4da2003-01-02 17:55:03 +000049322. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004933 This is actually a requirement, an assumption we need to make about
4934 sane tzinfo classes.
4935
49363. The naive UTC time corresponding to x is x.n - x.o.
4937 This is again a requirement for a sane tzinfo class.
4938
49394. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004940 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004941
Tim Petersc5dc4da2003-01-02 17:55:03 +000049425. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004943 Again follows from how arithmetic is defined.
4944
Tim Peters8bb5ad22003-01-24 02:44:45 +00004945Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004946(meaning that the various tzinfo methods exist, and don't blow up or return
4947None when called).
4948
Tim Petersa9bc1682003-01-11 03:39:11 +00004949The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004950x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004951
4952By #3, we want
4953
Tim Peters8bb5ad22003-01-24 02:44:45 +00004954 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004955
4956The algorithm starts by attaching tz to x.n, and calling that y. So
4957x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4958becomes true; in effect, we want to solve [2] for k:
4959
Tim Peters8bb5ad22003-01-24 02:44:45 +00004960 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004961
4962By #1, this is the same as
4963
Tim Peters8bb5ad22003-01-24 02:44:45 +00004964 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004965
4966By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4967Substituting that into [3],
4968
Tim Peters8bb5ad22003-01-24 02:44:45 +00004969 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4970 k - (y+k).s - (y+k).d = 0; rearranging,
4971 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4972 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004973
Tim Peters8bb5ad22003-01-24 02:44:45 +00004974On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4975approximate k by ignoring the (y+k).d term at first. Note that k can't be
4976very large, since all offset-returning methods return a duration of magnitude
4977less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4978be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004979
4980In any case, the new value is
4981
Tim Peters8bb5ad22003-01-24 02:44:45 +00004982 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004983
Tim Peters8bb5ad22003-01-24 02:44:45 +00004984It's helpful to step back at look at [4] from a higher level: it's simply
4985mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004986
4987At this point, if
4988
Tim Peters8bb5ad22003-01-24 02:44:45 +00004989 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004990
4991we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004992at the start of daylight time. Picture US Eastern for concreteness. The wall
4993time 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 +00004994sense then. The docs ask that an Eastern tzinfo class consider such a time to
4995be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4996on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004997the only spelling that makes sense on the local wall clock.
4998
Tim Petersc5dc4da2003-01-02 17:55:03 +00004999In fact, if [5] holds at this point, we do have the standard-time spelling,
5000but that takes a bit of proof. We first prove a stronger result. What's the
5001difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005002
Tim Peters8bb5ad22003-01-24 02:44:45 +00005003 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005004
Tim Petersc5dc4da2003-01-02 17:55:03 +00005005Now
5006 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005007 (y + y.s).n = by #5
5008 y.n + y.s = since y.n = x.n
5009 x.n + y.s = since z and y are have the same tzinfo member,
5010 y.s = z.s by #2
5011 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005012
Tim Petersc5dc4da2003-01-02 17:55:03 +00005013Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005014
Tim Petersc5dc4da2003-01-02 17:55:03 +00005015 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005016 x.n - ((x.n + z.s) - z.o) = expanding
5017 x.n - x.n - z.s + z.o = cancelling
5018 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005019 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005020
Tim Petersc5dc4da2003-01-02 17:55:03 +00005021So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005022
Tim Petersc5dc4da2003-01-02 17:55:03 +00005023If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005024spelling we wanted in the endcase described above. We're done. Contrarily,
5025if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005026
Tim Petersc5dc4da2003-01-02 17:55:03 +00005027If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5028add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005029local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005030
Tim Petersc5dc4da2003-01-02 17:55:03 +00005031Let
Tim Petersf3615152003-01-01 21:51:37 +00005032
Tim Peters4fede1a2003-01-04 00:26:59 +00005033 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005034
Tim Peters4fede1a2003-01-04 00:26:59 +00005035and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005036
Tim Peters8bb5ad22003-01-24 02:44:45 +00005037 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005038
Tim Peters8bb5ad22003-01-24 02:44:45 +00005039If so, we're done. If not, the tzinfo class is insane, according to the
5040assumptions we've made. This also requires a bit of proof. As before, let's
5041compute the difference between the LHS and RHS of [8] (and skipping some of
5042the justifications for the kinds of substitutions we've done several times
5043already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005044
Tim Peters8bb5ad22003-01-24 02:44:45 +00005045 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005046 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5047 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5048 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5049 - z.n + z.n - z.o + z'.o = cancel z.n
5050 - z.o + z'.o = #1 twice
5051 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5052 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005053
5054So 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 +00005055we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5056return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005057
Tim Peters8bb5ad22003-01-24 02:44:45 +00005058How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5059a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5060would have to change the result dst() returns: we start in DST, and moving
5061a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005062
Tim Peters8bb5ad22003-01-24 02:44:45 +00005063There isn't a sane case where this can happen. The closest it gets is at
5064the end of DST, where there's an hour in UTC with no spelling in a hybrid
5065tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5066that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5067UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5068time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5069clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5070standard time. Since that's what the local clock *does*, we want to map both
5071UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005072in local time, but so it goes -- it's the way the local clock works.
5073
Tim Peters8bb5ad22003-01-24 02:44:45 +00005074When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5075so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5076z' = 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 +00005077(correctly) concludes that z' is not UTC-equivalent to x.
5078
5079Because we know z.d said z was in daylight time (else [5] would have held and
5080we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005081and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005082return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5083but the reasoning doesn't depend on the example -- it depends on there being
5084two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005085z' must be in standard time, and is the spelling we want in this case.
5086
5087Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5088concerned (because it takes z' as being in standard time rather than the
5089daylight time we intend here), but returning it gives the real-life "local
5090clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5091tz.
5092
5093When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5094the 1:MM standard time spelling we want.
5095
5096So how can this break? One of the assumptions must be violated. Two
5097possibilities:
5098
50991) [2] effectively says that y.s is invariant across all y belong to a given
5100 time zone. This isn't true if, for political reasons or continental drift,
5101 a region decides to change its base offset from UTC.
5102
51032) There may be versions of "double daylight" time where the tail end of
5104 the analysis gives up a step too early. I haven't thought about that
5105 enough to say.
5106
5107In any case, it's clear that the default fromutc() is strong enough to handle
5108"almost all" time zones: so long as the standard offset is invariant, it
5109doesn't matter if daylight time transition points change from year to year, or
5110if daylight time is skipped in some years; it doesn't matter how large or
5111small dst() may get within its bounds; and it doesn't even matter if some
5112perverse time zone returns a negative dst()). So a breaking case must be
5113pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005114--------------------------------------------------------------------------- */