blob: ce94a1eef993fc566d7b6287dbb25a7d9ea7d829 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
6#include "modsupport.h"
7#include "structmember.h"
8
9#include <time.h>
10
Tim Peters1b6f7a92004-06-20 02:50:16 +000011#include "timefuncs.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000012
13/* Differentiate between building the core module and building extension
14 * modules.
15 */
Guido van Rossum360e4b82007-05-14 22:51:27 +000016#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000017#define Py_BUILD_CORE
Guido van Rossum360e4b82007-05-14 22:51:27 +000018#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000019#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000020#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000021
22/* We require that C int be at least 32 bits, and use int virtually
23 * everywhere. In just a few cases we use a temp long, where a Python
24 * API returns a C long. In such cases, we have to ensure that the
25 * final result fits in a C int (this can be an issue on 64-bit boxes).
26 */
27#if SIZEOF_INT < 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028# error "datetime.c requires that C int have at least 32 bits"
Tim Peters2a799bf2002-12-16 20:18:38 +000029#endif
30
31#define MINYEAR 1
32#define MAXYEAR 9999
Alexander Belopolskyf03a6162010-05-27 21:42:58 +000033#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
Tim Peters2a799bf2002-12-16 20:18:38 +000034
35/* Nine decimal digits is easy to communicate, and leaves enough room
36 * so that two delta days can be added w/o fear of overflowing a signed
37 * 32-bit int, and with plenty of room left over to absorb any possible
38 * carries from adding seconds.
39 */
40#define MAX_DELTA_DAYS 999999999
41
42/* Rename the long macros in datetime.h to more reasonable short names. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043#define GET_YEAR PyDateTime_GET_YEAR
44#define GET_MONTH PyDateTime_GET_MONTH
45#define GET_DAY PyDateTime_GET_DAY
46#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
47#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
48#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
49#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
Tim Peters2a799bf2002-12-16 20:18:38 +000050
51/* Date accessors for date and datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
53 ((o)->data[1] = ((v) & 0x00ff)))
54#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
55#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000056
57/* Date/Time accessors for datetime. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
59#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
60#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
61#define DATE_SET_MICROSECOND(o, v) \
62 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
63 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
64 ((o)->data[9] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000065
66/* Time accessors for time. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
68#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
69#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
70#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
71#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
72#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
73#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
74#define TIME_SET_MICROSECOND(o, v) \
75 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
76 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
77 ((o)->data[5] = ((v) & 0x0000ff)))
Tim Peters2a799bf2002-12-16 20:18:38 +000078
79/* Delta accessors for timedelta. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
81#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
82#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
Tim Peters2a799bf2002-12-16 20:18:38 +000083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084#define SET_TD_DAYS(o, v) ((o)->days = (v))
85#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
Tim Peters2a799bf2002-12-16 20:18:38 +000086#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
87
Tim Petersa032d2e2003-01-11 00:15:54 +000088/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
89 * p->hastzinfo.
90 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
Tim Petersa032d2e2003-01-11 00:15:54 +000092
Tim Peters3f606292004-03-21 23:38:41 +000093/* M is a char or int claiming to be a valid month. The macro is equivalent
94 * to the two-sided Python test
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 * 1 <= M <= 12
Tim Peters3f606292004-03-21 23:38:41 +000096 */
97#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
98
Tim Peters2a799bf2002-12-16 20:18:38 +000099/* Forward declarations. */
100static PyTypeObject PyDateTime_DateType;
101static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000102static PyTypeObject PyDateTime_DeltaType;
103static PyTypeObject PyDateTime_TimeType;
104static PyTypeObject PyDateTime_TZInfoType;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000105static PyTypeObject PyDateTime_TimeZoneType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000106
107/* ---------------------------------------------------------------------------
108 * Math utilities.
109 */
110
111/* k = i+j overflows iff k differs in sign from both inputs,
112 * iff k^i has sign bit set and k^j has sign bit set,
113 * iff (k^i)&(k^j) has sign bit set.
114 */
115#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000117
118/* Compute Python divmod(x, y), returning the quotient and storing the
119 * remainder into *r. The quotient is the floor of x/y, and that's
120 * the real point of this. C will probably truncate instead (C99
121 * requires truncation; C89 left it implementation-defined).
122 * Simplification: we *require* that y > 0 here. That's appropriate
123 * for all the uses made of it. This simplifies the code and makes
124 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
125 * overflow case).
126 */
127static int
128divmod(int x, int y, int *r)
129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 assert(y > 0);
133 quo = x / y;
134 *r = x - quo * y;
135 if (*r < 0) {
136 --quo;
137 *r += y;
138 }
139 assert(0 <= *r && *r < y);
140 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000141}
142
Tim Peters5d644dd2003-01-02 16:32:54 +0000143/* Round a double to the nearest long. |x| must be small enough to fit
144 * in a C long; this is not checked.
145 */
146static long
147round_to_long(double x)
148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 if (x >= 0.0)
150 x = floor(x + 0.5);
151 else
152 x = ceil(x - 0.5);
153 return (long)x;
Tim Peters5d644dd2003-01-02 16:32:54 +0000154}
155
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000156/* Nearest integer to m / n for integers m and n. Half-integer results
157 * are rounded to even.
158 */
159static PyObject *
160divide_nearest(PyObject *m, PyObject *n)
161{
162 PyObject *result;
163 PyObject *temp;
164
Mark Dickinsonfa68a612010-06-07 18:47:09 +0000165 temp = _PyLong_DivmodNear(m, n);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +0000166 if (temp == NULL)
167 return NULL;
168 result = PyTuple_GET_ITEM(temp, 0);
169 Py_INCREF(result);
170 Py_DECREF(temp);
171
172 return result;
173}
174
Tim Peters2a799bf2002-12-16 20:18:38 +0000175/* ---------------------------------------------------------------------------
176 * General calendrical helper functions
177 */
178
179/* For each month ordinal in 1..12, the number of days in that month,
180 * and the number of days before that month in the same year. These
181 * are correct for non-leap years only.
182 */
183static int _days_in_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 0, /* unused; this vector uses 1-based indexing */
185 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000186};
187
188static int _days_before_month[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 0, /* unused; this vector uses 1-based indexing */
190 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000191};
192
193/* year -> 1 if leap year, else 0. */
194static int
195is_leap(int year)
196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 /* Cast year to unsigned. The result is the same either way, but
198 * C can generate faster code for unsigned mod than for signed
199 * mod (especially for % 4 -- a good compiler should just grab
200 * the last 2 bits when the LHS is unsigned).
201 */
202 const unsigned int ayear = (unsigned int)year;
203 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000204}
205
206/* year, month -> number of days in that month in that year */
207static int
208days_in_month(int year, int month)
209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 assert(month >= 1);
211 assert(month <= 12);
212 if (month == 2 && is_leap(year))
213 return 29;
214 else
215 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000216}
217
218/* year, month -> number of days in year preceeding first day of month */
219static int
220days_before_month(int year, int month)
221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000223
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 assert(month >= 1);
225 assert(month <= 12);
226 days = _days_before_month[month];
227 if (month > 2 && is_leap(year))
228 ++days;
229 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000230}
231
232/* year -> number of days before January 1st of year. Remember that we
233 * start with year 1, so days_before_year(1) == 0.
234 */
235static int
236days_before_year(int year)
237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 int y = year - 1;
239 /* This is incorrect if year <= 0; we really want the floor
240 * here. But so long as MINYEAR is 1, the smallest year this
241 * can see is 0 (this can happen in some normalization endcases),
242 * so we'll just special-case that.
243 */
244 assert (year >= 0);
245 if (y >= 0)
246 return y*365 + y/4 - y/100 + y/400;
247 else {
248 assert(y == -1);
249 return -366;
250 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000251}
252
253/* Number of days in 4, 100, and 400 year cycles. That these have
254 * the correct values is asserted in the module init function.
255 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256#define DI4Y 1461 /* days_before_year(5); days in 4 years */
257#define DI100Y 36524 /* days_before_year(101); days in 100 years */
258#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000259
260/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
261static void
262ord_to_ymd(int ordinal, int *year, int *month, int *day)
263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
267 * leap years repeats exactly every 400 years. The basic strategy is
268 * to find the closest 400-year boundary at or before ordinal, then
269 * work with the offset from that boundary to ordinal. Life is much
270 * clearer if we subtract 1 from ordinal first -- then the values
271 * of ordinal at 400-year boundaries are exactly those divisible
272 * by DI400Y:
273 *
274 * D M Y n n-1
275 * -- --- ---- ---------- ----------------
276 * 31 Dec -400 -DI400Y -DI400Y -1
277 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
278 * ...
279 * 30 Dec 000 -1 -2
280 * 31 Dec 000 0 -1
281 * 1 Jan 001 1 0 400-year boundary
282 * 2 Jan 001 2 1
283 * 3 Jan 001 3 2
284 * ...
285 * 31 Dec 400 DI400Y DI400Y -1
286 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
287 */
288 assert(ordinal >= 1);
289 --ordinal;
290 n400 = ordinal / DI400Y;
291 n = ordinal % DI400Y;
292 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 /* Now n is the (non-negative) offset, in days, from January 1 of
295 * year, to the desired date. Now compute how many 100-year cycles
296 * precede n.
297 * Note that it's possible for n100 to equal 4! In that case 4 full
298 * 100-year cycles precede the desired day, which implies the
299 * desired day is December 31 at the end of a 400-year cycle.
300 */
301 n100 = n / DI100Y;
302 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 /* Now compute how many 4-year cycles precede it. */
305 n4 = n / DI4Y;
306 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 /* And now how many single years. Again n1 can be 4, and again
309 * meaning that the desired day is December 31 at the end of the
310 * 4-year cycle.
311 */
312 n1 = n / 365;
313 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 *year += n100 * 100 + n4 * 4 + n1;
316 if (n1 == 4 || n100 == 4) {
317 assert(n == 0);
318 *year -= 1;
319 *month = 12;
320 *day = 31;
321 return;
322 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 /* Now the year is correct, and n is the offset from January 1. We
325 * find the month via an estimate that's either exact or one too
326 * large.
327 */
328 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
329 assert(leapyear == is_leap(*year));
330 *month = (n + 50) >> 5;
331 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
332 if (preceding > n) {
333 /* estimate is too large */
334 *month -= 1;
335 preceding -= days_in_month(*year, *month);
336 }
337 n -= preceding;
338 assert(0 <= n);
339 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000342}
343
344/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
345static int
346ymd_to_ord(int year, int month, int day)
347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000349}
350
351/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
352static int
353weekday(int year, int month, int day)
354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000356}
357
358/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
359 * first calendar week containing a Thursday.
360 */
361static int
362iso_week1_monday(int year)
363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
365 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
366 int first_weekday = (first_day + 6) % 7;
367 /* ordinal of closest Monday at or before 1/1 */
368 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
371 week1_monday += 7;
372 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000373}
374
375/* ---------------------------------------------------------------------------
376 * Range checkers.
377 */
378
379/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
380 * If not, raise OverflowError and return -1.
381 */
382static int
383check_delta_day_range(int days)
384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
386 return 0;
387 PyErr_Format(PyExc_OverflowError,
388 "days=%d; must have magnitude <= %d",
389 days, MAX_DELTA_DAYS);
390 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000391}
392
393/* Check that date arguments are in range. Return 0 if they are. If they
394 * aren't, raise ValueError and return -1.
395 */
396static int
397check_date_args(int year, int month, int day)
398{
399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 if (year < MINYEAR || year > MAXYEAR) {
401 PyErr_SetString(PyExc_ValueError,
402 "year is out of range");
403 return -1;
404 }
405 if (month < 1 || month > 12) {
406 PyErr_SetString(PyExc_ValueError,
407 "month must be in 1..12");
408 return -1;
409 }
410 if (day < 1 || day > days_in_month(year, month)) {
411 PyErr_SetString(PyExc_ValueError,
412 "day is out of range for month");
413 return -1;
414 }
415 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000416}
417
418/* Check that time arguments are in range. Return 0 if they are. If they
419 * aren't, raise ValueError and return -1.
420 */
421static int
422check_time_args(int h, int m, int s, int us)
423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 if (h < 0 || h > 23) {
425 PyErr_SetString(PyExc_ValueError,
426 "hour must be in 0..23");
427 return -1;
428 }
429 if (m < 0 || m > 59) {
430 PyErr_SetString(PyExc_ValueError,
431 "minute must be in 0..59");
432 return -1;
433 }
434 if (s < 0 || s > 59) {
435 PyErr_SetString(PyExc_ValueError,
436 "second must be in 0..59");
437 return -1;
438 }
439 if (us < 0 || us > 999999) {
440 PyErr_SetString(PyExc_ValueError,
441 "microsecond must be in 0..999999");
442 return -1;
443 }
444 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000445}
446
447/* ---------------------------------------------------------------------------
448 * Normalization utilities.
449 */
450
451/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
452 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
453 * at least factor, enough of *lo is converted into "hi" units so that
454 * 0 <= *lo < factor. The input values must be such that int overflow
455 * is impossible.
456 */
457static void
458normalize_pair(int *hi, int *lo, int factor)
459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 assert(factor > 0);
461 assert(lo != hi);
462 if (*lo < 0 || *lo >= factor) {
463 const int num_hi = divmod(*lo, factor, lo);
464 const int new_hi = *hi + num_hi;
465 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
466 *hi = new_hi;
467 }
468 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000469}
470
471/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 * 0 <= *s < 24*3600
473 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000474 * The input values must be such that the internals don't overflow.
475 * The way this routine is used, we don't get close.
476 */
477static void
478normalize_d_s_us(int *d, int *s, int *us)
479{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 if (*us < 0 || *us >= 1000000) {
481 normalize_pair(s, us, 1000000);
482 /* |s| can't be bigger than about
483 * |original s| + |original us|/1000000 now.
484 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000485
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 }
487 if (*s < 0 || *s >= 24*3600) {
488 normalize_pair(d, s, 24*3600);
489 /* |d| can't be bigger than about
490 * |original d| +
491 * (|original s| + |original us|/1000000) / (24*3600) now.
492 */
493 }
494 assert(0 <= *s && *s < 24*3600);
495 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000496}
497
498/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 * 1 <= *m <= 12
500 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000501 * The input values must be such that the internals don't overflow.
502 * The way this routine is used, we don't get close.
503 */
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000504static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000505normalize_y_m_d(int *y, int *m, int *d)
506{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 /* This gets muddy: the proper range for day can't be determined
510 * without knowing the correct month and year, but if day is, e.g.,
511 * plus or minus a million, the current month and year values make
512 * no sense (and may also be out of bounds themselves).
513 * Saying 12 months == 1 year should be non-controversial.
514 */
515 if (*m < 1 || *m > 12) {
516 --*m;
517 normalize_pair(y, m, 12);
518 ++*m;
519 /* |y| can't be bigger than about
520 * |original y| + |original m|/12 now.
521 */
522 }
523 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 /* Now only day can be out of bounds (year may also be out of bounds
526 * for a datetime object, but we don't care about that here).
527 * If day is out of bounds, what to do is arguable, but at least the
528 * method here is principled and explainable.
529 */
530 dim = days_in_month(*y, *m);
531 if (*d < 1 || *d > dim) {
532 /* Move day-1 days from the first of the month. First try to
533 * get off cheap if we're only one day out of range
534 * (adjustments for timezone alone can't be worse than that).
535 */
536 if (*d == 0) {
537 --*m;
538 if (*m > 0)
539 *d = days_in_month(*y, *m);
540 else {
541 --*y;
542 *m = 12;
543 *d = 31;
544 }
545 }
546 else if (*d == dim + 1) {
547 /* move forward a day */
548 ++*m;
549 *d = 1;
550 if (*m > 12) {
551 *m = 1;
552 ++*y;
553 }
554 }
555 else {
556 int ordinal = ymd_to_ord(*y, *m, 1) +
557 *d - 1;
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000558 if (ordinal < 1 || ordinal > MAXORDINAL) {
559 goto error;
560 } else {
561 ord_to_ymd(ordinal, y, m, d);
562 return 0;
563 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 }
565 }
566 assert(*m > 0);
567 assert(*d > 0);
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000568 if (MINYEAR <= *y && *y <= MAXYEAR)
569 return 0;
570 error:
571 PyErr_SetString(PyExc_OverflowError,
572 "date value out of range");
573 return -1;
574
Tim Peters2a799bf2002-12-16 20:18:38 +0000575}
576
577/* Fiddle out-of-bounds months and days so that the result makes some kind
578 * of sense. The parameters are both inputs and outputs. Returns < 0 on
579 * failure, where failure means the adjusted year is out of bounds.
580 */
581static int
582normalize_date(int *year, int *month, int *day)
583{
Alexander Belopolskyf03a6162010-05-27 21:42:58 +0000584 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000585}
586
587/* Force all the datetime fields into range. The parameters are both
588 * inputs and outputs. Returns < 0 on error.
589 */
590static int
591normalize_datetime(int *year, int *month, int *day,
592 int *hour, int *minute, int *second,
593 int *microsecond)
594{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 normalize_pair(second, microsecond, 1000000);
596 normalize_pair(minute, second, 60);
597 normalize_pair(hour, minute, 60);
598 normalize_pair(day, hour, 24);
599 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000600}
601
602/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000603 * Basic object allocation: tp_alloc implementations. These allocate
604 * Python objects of the right size and type, and do the Python object-
605 * initialization bit. If there's not enough memory, they return NULL after
606 * setting MemoryError. All data members remain uninitialized trash.
607 *
608 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000609 * member is needed. This is ugly, imprecise, and possibly insecure.
610 * tp_basicsize for the time and datetime types is set to the size of the
611 * struct that has room for the tzinfo member, so subclasses in Python will
612 * allocate enough space for a tzinfo member whether or not one is actually
613 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
614 * part is that PyType_GenericAlloc() (which subclasses in Python end up
615 * using) just happens today to effectively ignore the nitems argument
616 * when tp_itemsize is 0, which it is for these type objects. If that
617 * changes, perhaps the callers of tp_alloc slots in this file should
618 * be changed to force a 0 nitems argument unless the type being allocated
619 * is a base type implemented in this file (so that tp_alloc is time_alloc
620 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000621 */
622
623static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000624time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 self = (PyObject *)
629 PyObject_MALLOC(aware ?
630 sizeof(PyDateTime_Time) :
631 sizeof(_PyDateTime_BaseTime));
632 if (self == NULL)
633 return (PyObject *)PyErr_NoMemory();
634 PyObject_INIT(self, type);
635 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000636}
637
638static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000639datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000640{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 self = (PyObject *)
644 PyObject_MALLOC(aware ?
645 sizeof(PyDateTime_DateTime) :
646 sizeof(_PyDateTime_BaseDateTime));
647 if (self == NULL)
648 return (PyObject *)PyErr_NoMemory();
649 PyObject_INIT(self, type);
650 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000651}
652
653/* ---------------------------------------------------------------------------
654 * Helpers for setting object fields. These work on pointers to the
655 * appropriate base class.
656 */
657
658/* For date and datetime. */
659static void
660set_date_fields(PyDateTime_Date *self, int y, int m, int d)
661{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 self->hashcode = -1;
663 SET_YEAR(self, y);
664 SET_MONTH(self, m);
665 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000666}
667
668/* ---------------------------------------------------------------------------
669 * Create various objects, mostly without range checking.
670 */
671
672/* Create a date instance with no range checking. */
673static PyObject *
674new_date_ex(int year, int month, int day, PyTypeObject *type)
675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
679 if (self != NULL)
680 set_date_fields(self, year, month, day);
681 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000682}
683
684#define new_date(year, month, day) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000686
687/* Create a datetime instance with no range checking. */
688static PyObject *
689new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 PyDateTime_DateTime *self;
693 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
696 if (self != NULL) {
697 self->hastzinfo = aware;
698 set_date_fields((PyDateTime_Date *)self, year, month, day);
699 DATE_SET_HOUR(self, hour);
700 DATE_SET_MINUTE(self, minute);
701 DATE_SET_SECOND(self, second);
702 DATE_SET_MICROSECOND(self, usecond);
703 if (aware) {
704 Py_INCREF(tzinfo);
705 self->tzinfo = tzinfo;
706 }
707 }
708 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000709}
710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
712 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
713 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000714
715/* Create a time instance with no range checking. */
716static PyObject *
717new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 PyDateTime_Time *self;
721 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
724 if (self != NULL) {
725 self->hastzinfo = aware;
726 self->hashcode = -1;
727 TIME_SET_HOUR(self, hour);
728 TIME_SET_MINUTE(self, minute);
729 TIME_SET_SECOND(self, second);
730 TIME_SET_MICROSECOND(self, usecond);
731 if (aware) {
732 Py_INCREF(tzinfo);
733 self->tzinfo = tzinfo;
734 }
735 }
736 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000737}
738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739#define new_time(hh, mm, ss, us, tzinfo) \
740 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000741
742/* Create a timedelta instance. Normalize the members iff normalize is
743 * true. Passing false is a speed optimization, if you know for sure
744 * that seconds and microseconds are already in their proper ranges. In any
745 * case, raises OverflowError and returns NULL if the normalized days is out
746 * of range).
747 */
748static PyObject *
749new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 if (normalize)
755 normalize_d_s_us(&days, &seconds, &microseconds);
756 assert(0 <= seconds && seconds < 24*3600);
757 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000758
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 if (check_delta_day_range(days) < 0)
760 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
763 if (self != NULL) {
764 self->hashcode = -1;
765 SET_TD_DAYS(self, days);
766 SET_TD_SECONDS(self, seconds);
767 SET_TD_MICROSECONDS(self, microseconds);
768 }
769 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000770}
771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772#define new_delta(d, s, us, normalize) \
773 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000774
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000775
776typedef struct
777{
778 PyObject_HEAD
779 PyObject *offset;
780 PyObject *name;
781} PyDateTime_TimeZone;
782
783/* Create new timezone instance checking offset range. This
784 function does not check the name argument. Caller must assure
785 that offset is a timedelta instance and name is either NULL
786 or a unicode object. */
787static PyObject *
788new_timezone(PyObject *offset, PyObject *name)
789{
790 PyDateTime_TimeZone *self;
791 PyTypeObject *type = &PyDateTime_TimeZoneType;
792
793 assert(offset != NULL);
794 assert(PyDelta_Check(offset));
795 assert(name == NULL || PyUnicode_Check(name));
796
797 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
798 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
799 " representing a whole number of minutes");
800 return NULL;
801 }
802 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
803 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
804 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
805 " strictly between -timedelta(hours=24) and"
806 " timedelta(hours=24).");
807 return NULL;
808 }
809
810 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
811 if (self == NULL) {
812 return NULL;
813 }
814 Py_INCREF(offset);
815 self->offset = offset;
816 Py_XINCREF(name);
817 self->name = name;
818 return (PyObject *)self;
819}
820
Tim Petersb0c854d2003-05-17 15:57:00 +0000821/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000822 * tzinfo helpers.
823 */
824
Tim Peters855fe882002-12-22 03:43:39 +0000825/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
826 * raise TypeError and return -1.
827 */
828static int
829check_tzinfo_subclass(PyObject *p)
830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 if (p == Py_None || PyTZInfo_Check(p))
832 return 0;
833 PyErr_Format(PyExc_TypeError,
834 "tzinfo argument must be None or of a tzinfo subclass, "
835 "not type '%s'",
836 Py_TYPE(p)->tp_name);
837 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000838}
839
Tim Petersbad8ff02002-12-30 20:52:32 +0000840/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000841 * If tzinfo is None, returns None.
842 */
843static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000844call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 assert(tzinfo && methname && tzinfoarg);
849 assert(check_tzinfo_subclass(tzinfo) >= 0);
850 if (tzinfo == Py_None) {
851 result = Py_None;
852 Py_INCREF(result);
853 }
854 else
855 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
856 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000857}
858
Tim Peters2a799bf2002-12-16 20:18:38 +0000859/* If self has a tzinfo member, return a BORROWED reference to it. Else
860 * return NULL, which is NOT AN ERROR. There are no error returns here,
861 * and the caller must not decref the result.
862 */
863static PyObject *
864get_tzinfo_member(PyObject *self)
865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 if (PyDateTime_Check(self) && HASTZINFO(self))
869 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
870 else if (PyTime_Check(self) && HASTZINFO(self))
871 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000874}
875
Tim Petersbad8ff02002-12-30 20:52:32 +0000876/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000877 * result. tzinfo must be an instance of the tzinfo class. If the method
878 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000879 * return None or timedelta, TypeError is raised and this returns -1. If it
880 * returnsa timedelta and the value is out of range or isn't a whole number
881 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000882 * Else *none is set to 0 and the integer method result is returned.
883 */
884static int
885call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 int *none)
Tim Peters2a799bf2002-12-16 20:18:38 +0000887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 PyObject *u;
889 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 assert(tzinfo != NULL);
892 assert(PyTZInfo_Check(tzinfo));
893 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 *none = 0;
896 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
897 if (u == NULL)
898 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 else if (u == Py_None) {
901 result = 0;
902 *none = 1;
903 }
904 else if (PyDelta_Check(u)) {
905 const int days = GET_TD_DAYS(u);
906 if (days < -1 || days > 0)
907 result = 24*60; /* trigger ValueError below */
908 else {
909 /* next line can't overflow because we know days
910 * is -1 or 0 now
911 */
912 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
913 result = divmod(ss, 60, &ss);
914 if (ss || GET_TD_MICROSECONDS(u)) {
915 PyErr_Format(PyExc_ValueError,
916 "tzinfo.%s() must return a "
917 "whole number of minutes",
918 name);
919 result = -1;
920 }
921 }
922 }
923 else {
924 PyErr_Format(PyExc_TypeError,
925 "tzinfo.%s() must return None or "
926 "timedelta, not '%s'",
927 name, Py_TYPE(u)->tp_name);
928 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 Py_DECREF(u);
931 if (result < -1439 || result > 1439) {
932 PyErr_Format(PyExc_ValueError,
933 "tzinfo.%s() returned %d; must be in "
934 "-1439 .. 1439",
935 name, result);
936 result = -1;
937 }
938 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000939}
940
941/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
942 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
943 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000944 * doesn't return None or timedelta, TypeError is raised and this returns -1.
945 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
946 * # of minutes), ValueError is raised and this returns -1. Else *none is
947 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000948 */
949static int
950call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000953}
954
Tim Petersbad8ff02002-12-30 20:52:32 +0000955/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
956 */
Tim Peters855fe882002-12-22 03:43:39 +0000957static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000958offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 assert(tzinfo && name && tzinfoarg);
962 if (tzinfo == Py_None) {
963 result = Py_None;
964 Py_INCREF(result);
965 }
966 else {
967 int none;
968 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
969 &none);
970 if (offset < 0 && PyErr_Occurred())
971 return NULL;
972 if (none) {
973 result = Py_None;
974 Py_INCREF(result);
975 }
976 else
977 result = new_delta(0, offset * 60, 0, 1);
978 }
979 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000980}
981
Tim Peters2a799bf2002-12-16 20:18:38 +0000982/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
983 * result. tzinfo must be an instance of the tzinfo class. If dst()
984 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000985 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000986 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000987 * ValueError is raised and this returns -1. Else *none is set to 0 and
988 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000989 */
990static int
991call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000994}
995
Tim Petersbad8ff02002-12-30 20:52:32 +0000996/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000997 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000998 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000999 * returns NULL. If the result is a string, we ensure it is a Unicode
1000 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001001 */
1002static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001003call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 assert(tzinfo != NULL);
1008 assert(check_tzinfo_subclass(tzinfo) >= 0);
1009 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 if (tzinfo == Py_None) {
1012 result = Py_None;
1013 Py_INCREF(result);
1014 }
1015 else
1016 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 if (result != NULL && result != Py_None) {
1019 if (!PyUnicode_Check(result)) {
1020 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1021 "return None or a string, not '%s'",
1022 Py_TYPE(result)->tp_name);
1023 Py_DECREF(result);
1024 result = NULL;
1025 }
1026 else if (!PyUnicode_Check(result)) {
1027 PyObject *temp = PyUnicode_FromObject(result);
1028 Py_DECREF(result);
1029 result = temp;
1030 }
1031 }
1032 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001033}
1034
1035typedef enum {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 /* an exception has been set; the caller should pass it on */
1037 OFFSET_ERROR,
Tim Peters2a799bf2002-12-16 20:18:38 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 /* type isn't date, datetime, or time subclass */
1040 OFFSET_UNKNOWN,
Tim Peters2a799bf2002-12-16 20:18:38 +00001041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 /* date,
1043 * datetime with !hastzinfo
1044 * datetime with None tzinfo,
1045 * datetime where utcoffset() returns None
1046 * time with !hastzinfo
1047 * time with None tzinfo,
1048 * time where utcoffset() returns None
1049 */
1050 OFFSET_NAIVE,
Tim Peters2a799bf2002-12-16 20:18:38 +00001051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 /* time or datetime where utcoffset() doesn't return None */
1053 OFFSET_AWARE
Tim Peters2a799bf2002-12-16 20:18:38 +00001054} naivety;
1055
Tim Peters14b69412002-12-22 18:10:22 +00001056/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +00001057 * the "naivety" typedef for details. If the type is aware, *offset is set
1058 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +00001059 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +00001060 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +00001061 */
1062static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +00001063classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +00001064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 int none;
1066 PyObject *tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 assert(tzinfoarg != NULL);
1069 *offset = 0;
1070 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
1071 if (tzinfo == Py_None)
1072 return OFFSET_NAIVE;
1073 if (tzinfo == NULL) {
1074 /* note that a datetime passes the PyDate_Check test */
1075 return (PyTime_Check(op) || PyDate_Check(op)) ?
1076 OFFSET_NAIVE : OFFSET_UNKNOWN;
1077 }
1078 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1079 if (*offset == -1 && PyErr_Occurred())
1080 return OFFSET_ERROR;
1081 return none ? OFFSET_NAIVE : OFFSET_AWARE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001082}
1083
Tim Peters00237032002-12-27 02:21:51 +00001084/* Classify two objects as to whether they're naive or offset-aware.
1085 * This isn't quite the same as calling classify_utcoffset() twice: for
1086 * binary operations (comparison and subtraction), we generally want to
1087 * ignore the tzinfo members if they're identical. This is by design,
1088 * so that results match "naive" expectations when mixing objects from a
1089 * single timezone. So in that case, this sets both offsets to 0 and
1090 * both naiveties to OFFSET_NAIVE.
1091 * The function returns 0 if everything's OK, and -1 on error.
1092 */
1093static int
1094classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 PyObject *tzinfoarg1,
1096 PyObject *o2, int *offset2, naivety *n2,
1097 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1100 *offset1 = *offset2 = 0;
1101 *n1 = *n2 = OFFSET_NAIVE;
1102 }
1103 else {
1104 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1105 if (*n1 == OFFSET_ERROR)
1106 return -1;
1107 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1108 if (*n2 == OFFSET_ERROR)
1109 return -1;
1110 }
1111 return 0;
Tim Peters00237032002-12-27 02:21:51 +00001112}
1113
Tim Peters2a799bf2002-12-16 20:18:38 +00001114/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1115 * stuff
1116 * ", tzinfo=" + repr(tzinfo)
1117 * before the closing ")".
1118 */
1119static PyObject *
1120append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 assert(PyUnicode_Check(repr));
1125 assert(tzinfo);
1126 if (tzinfo == Py_None)
1127 return repr;
1128 /* Get rid of the trailing ')'. */
1129 assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
1130 temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
1131 PyUnicode_GET_SIZE(repr) - 1);
1132 Py_DECREF(repr);
1133 if (temp == NULL)
1134 return NULL;
1135 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1136 Py_DECREF(temp);
1137 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001138}
1139
1140/* ---------------------------------------------------------------------------
1141 * String format helpers.
1142 */
1143
1144static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001145format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 static const char *DayNames[] = {
1148 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1149 };
1150 static const char *MonthNames[] = {
1151 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1152 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1153 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1158 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1159 GET_DAY(date), hours, minutes, seconds,
1160 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001161}
1162
1163/* Add an hours & minutes UTC offset string to buf. buf has no more than
1164 * buflen bytes remaining. The UTC offset is gotten by calling
1165 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1166 * *buf, and that's all. Else the returned value is checked for sanity (an
1167 * integer in range), and if that's OK it's converted to an hours & minutes
1168 * string of the form
1169 * sign HH sep MM
1170 * Returns 0 if everything is OK. If the return value from utcoffset() is
1171 * bogus, an appropriate exception is set and -1 is returned.
1172 */
1173static int
Tim Peters328fff72002-12-20 01:31:27 +00001174format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 int offset;
1178 int hours;
1179 int minutes;
1180 char sign;
1181 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00001182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1186 if (offset == -1 && PyErr_Occurred())
1187 return -1;
1188 if (none) {
1189 *buf = '\0';
1190 return 0;
1191 }
1192 sign = '+';
1193 if (offset < 0) {
1194 sign = '-';
1195 offset = - offset;
1196 }
1197 hours = divmod(offset, 60, &minutes);
1198 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1199 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001200}
1201
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001202static PyObject *
1203make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 PyObject *temp;
1206 PyObject *tzinfo = get_tzinfo_member(object);
1207 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1208 if (Zreplacement == NULL)
1209 return NULL;
1210 if (tzinfo == Py_None || tzinfo == NULL)
1211 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 assert(tzinfoarg != NULL);
1214 temp = call_tzname(tzinfo, tzinfoarg);
1215 if (temp == NULL)
1216 goto Error;
1217 if (temp == Py_None) {
1218 Py_DECREF(temp);
1219 return Zreplacement;
1220 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 assert(PyUnicode_Check(temp));
1223 /* Since the tzname is getting stuffed into the
1224 * format, we have to double any % signs so that
1225 * strftime doesn't treat them as format codes.
1226 */
1227 Py_DECREF(Zreplacement);
1228 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1229 Py_DECREF(temp);
1230 if (Zreplacement == NULL)
1231 return NULL;
1232 if (!PyUnicode_Check(Zreplacement)) {
1233 PyErr_SetString(PyExc_TypeError,
1234 "tzname.replace() did not return a string");
1235 goto Error;
1236 }
1237 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001238
1239 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 Py_DECREF(Zreplacement);
1241 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001242}
1243
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001244static PyObject *
1245make_freplacement(PyObject *object)
1246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 char freplacement[64];
1248 if (PyTime_Check(object))
1249 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1250 else if (PyDateTime_Check(object))
1251 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1252 else
1253 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001256}
1257
Tim Peters2a799bf2002-12-16 20:18:38 +00001258/* I sure don't want to reproduce the strftime code from the time module,
1259 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001260 * giving special meanings to the %z, %Z and %f format codes via a
1261 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001262 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1263 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001264 */
1265static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001266wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1272 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1273 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 const char *pin; /* pointer to next char in input format */
1276 Py_ssize_t flen; /* length of input format */
1277 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 PyObject *newfmt = NULL; /* py string, the output format */
1280 char *pnew; /* pointer to available byte in output format */
1281 size_t totalnew; /* number bytes total in output format buffer,
1282 exclusive of trailing \0 */
1283 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 const char *ptoappend; /* ptr to string to append to output buffer */
1286 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 assert(object && format && timetuple);
1289 assert(PyUnicode_Check(format));
1290 /* Convert the input format to a C string and size */
1291 pin = _PyUnicode_AsStringAndSize(format, &flen);
1292 if (!pin)
1293 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 /* Give up if the year is before 1900.
1296 * Python strftime() plays games with the year, and different
1297 * games depending on whether envar PYTHON2K is set. This makes
1298 * years before 1900 a nightmare, even if the platform strftime
1299 * supports them (and not all do).
1300 * We could get a lot farther here by avoiding Python's strftime
1301 * wrapper and calling the C strftime() directly, but that isn't
1302 * an option in the Python implementation of this module.
1303 */
1304 {
1305 long year;
1306 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1307 if (pyyear == NULL) return NULL;
1308 assert(PyLong_Check(pyyear));
1309 year = PyLong_AsLong(pyyear);
1310 Py_DECREF(pyyear);
1311 if (year < 1900) {
1312 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1313 "1900; the datetime strftime() "
1314 "methods require year >= 1900",
1315 year);
1316 return NULL;
1317 }
1318 }
Tim Petersd6844152002-12-22 20:58:42 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 /* Scan the input format, looking for %z/%Z/%f escapes, building
1321 * a new format. Since computing the replacements for those codes
1322 * is expensive, don't unless they're actually used.
1323 */
1324 if (flen > INT_MAX - 1) {
1325 PyErr_NoMemory();
1326 goto Done;
1327 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 totalnew = flen + 1; /* realistic if no %z/%Z */
1330 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1331 if (newfmt == NULL) goto Done;
1332 pnew = PyBytes_AsString(newfmt);
1333 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 while ((ch = *pin++) != '\0') {
1336 if (ch != '%') {
1337 ptoappend = pin - 1;
1338 ntoappend = 1;
1339 }
1340 else if ((ch = *pin++) == '\0') {
1341 /* There's a lone trailing %; doesn't make sense. */
1342 PyErr_SetString(PyExc_ValueError, "strftime format "
1343 "ends with raw %");
1344 goto Done;
1345 }
1346 /* A % has been seen and ch is the character after it. */
1347 else if (ch == 'z') {
1348 if (zreplacement == NULL) {
1349 /* format utcoffset */
1350 char buf[100];
1351 PyObject *tzinfo = get_tzinfo_member(object);
1352 zreplacement = PyBytes_FromStringAndSize("", 0);
1353 if (zreplacement == NULL) goto Done;
1354 if (tzinfo != Py_None && tzinfo != NULL) {
1355 assert(tzinfoarg != NULL);
1356 if (format_utcoffset(buf,
1357 sizeof(buf),
1358 "",
1359 tzinfo,
1360 tzinfoarg) < 0)
1361 goto Done;
1362 Py_DECREF(zreplacement);
1363 zreplacement =
1364 PyBytes_FromStringAndSize(buf,
1365 strlen(buf));
1366 if (zreplacement == NULL)
1367 goto Done;
1368 }
1369 }
1370 assert(zreplacement != NULL);
1371 ptoappend = PyBytes_AS_STRING(zreplacement);
1372 ntoappend = PyBytes_GET_SIZE(zreplacement);
1373 }
1374 else if (ch == 'Z') {
1375 /* format tzname */
1376 if (Zreplacement == NULL) {
1377 Zreplacement = make_Zreplacement(object,
1378 tzinfoarg);
1379 if (Zreplacement == NULL)
1380 goto Done;
1381 }
1382 assert(Zreplacement != NULL);
1383 assert(PyUnicode_Check(Zreplacement));
1384 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1385 &ntoappend);
1386 ntoappend = Py_SIZE(Zreplacement);
1387 }
1388 else if (ch == 'f') {
1389 /* format microseconds */
1390 if (freplacement == NULL) {
1391 freplacement = make_freplacement(object);
1392 if (freplacement == NULL)
1393 goto Done;
1394 }
1395 assert(freplacement != NULL);
1396 assert(PyBytes_Check(freplacement));
1397 ptoappend = PyBytes_AS_STRING(freplacement);
1398 ntoappend = PyBytes_GET_SIZE(freplacement);
1399 }
1400 else {
1401 /* percent followed by neither z nor Z */
1402 ptoappend = pin - 2;
1403 ntoappend = 2;
1404 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 /* Append the ntoappend chars starting at ptoappend to
1407 * the new format.
1408 */
1409 if (ntoappend == 0)
1410 continue;
1411 assert(ptoappend != NULL);
1412 assert(ntoappend > 0);
1413 while (usednew + ntoappend > totalnew) {
1414 size_t bigger = totalnew << 1;
1415 if ((bigger >> 1) != totalnew) { /* overflow */
1416 PyErr_NoMemory();
1417 goto Done;
1418 }
1419 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1420 goto Done;
1421 totalnew = bigger;
1422 pnew = PyBytes_AsString(newfmt) + usednew;
1423 }
1424 memcpy(pnew, ptoappend, ntoappend);
1425 pnew += ntoappend;
1426 usednew += ntoappend;
1427 assert(usednew <= totalnew);
1428 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1431 goto Done;
1432 {
1433 PyObject *format;
1434 PyObject *time = PyImport_ImportModuleNoBlock("time");
1435 if (time == NULL)
1436 goto Done;
1437 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1438 if (format != NULL) {
1439 result = PyObject_CallMethod(time, "strftime", "OO",
1440 format, timetuple);
1441 Py_DECREF(format);
1442 }
1443 Py_DECREF(time);
1444 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001445 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 Py_XDECREF(freplacement);
1447 Py_XDECREF(zreplacement);
1448 Py_XDECREF(Zreplacement);
1449 Py_XDECREF(newfmt);
1450 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001451}
1452
Tim Peters2a799bf2002-12-16 20:18:38 +00001453/* ---------------------------------------------------------------------------
1454 * Wrap functions from the time module. These aren't directly available
1455 * from C. Perhaps they should be.
1456 */
1457
1458/* Call time.time() and return its result (a Python float). */
1459static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001460time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 PyObject *result = NULL;
1463 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 if (time != NULL) {
1466 result = PyObject_CallMethod(time, "time", "()");
1467 Py_DECREF(time);
1468 }
1469 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001470}
1471
1472/* Build a time.struct_time. The weekday and day number are automatically
1473 * computed from the y,m,d args.
1474 */
1475static PyObject *
1476build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 PyObject *time;
1479 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 time = PyImport_ImportModuleNoBlock("time");
1482 if (time != NULL) {
1483 result = PyObject_CallMethod(time, "struct_time",
1484 "((iiiiiiiii))",
1485 y, m, d,
1486 hh, mm, ss,
1487 weekday(y, m, d),
1488 days_before_month(y, m) + d,
1489 dstflag);
1490 Py_DECREF(time);
1491 }
1492 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001493}
1494
1495/* ---------------------------------------------------------------------------
1496 * Miscellaneous helpers.
1497 */
1498
Mark Dickinsone94c6792009-02-02 20:36:42 +00001499/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001500 * The comparisons here all most naturally compute a cmp()-like result.
1501 * This little helper turns that into a bool result for rich comparisons.
1502 */
1503static PyObject *
1504diff_to_bool(int diff, int op)
1505{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 PyObject *result;
1507 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 switch (op) {
1510 case Py_EQ: istrue = diff == 0; break;
1511 case Py_NE: istrue = diff != 0; break;
1512 case Py_LE: istrue = diff <= 0; break;
1513 case Py_GE: istrue = diff >= 0; break;
1514 case Py_LT: istrue = diff < 0; break;
1515 case Py_GT: istrue = diff > 0; break;
1516 default:
1517 assert(! "op unknown");
1518 istrue = 0; /* To shut up compiler */
1519 }
1520 result = istrue ? Py_True : Py_False;
1521 Py_INCREF(result);
1522 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001523}
1524
Tim Peters07534a62003-02-07 22:50:28 +00001525/* Raises a "can't compare" TypeError and returns NULL. */
1526static PyObject *
1527cmperror(PyObject *a, PyObject *b)
1528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 PyErr_Format(PyExc_TypeError,
1530 "can't compare %s to %s",
1531 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1532 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001533}
1534
Tim Peters2a799bf2002-12-16 20:18:38 +00001535/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001536 * Cached Python objects; these are set by the module init function.
1537 */
1538
1539/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540static PyObject *us_per_us = NULL; /* 1 */
1541static PyObject *us_per_ms = NULL; /* 1000 */
1542static PyObject *us_per_second = NULL; /* 1000000 */
1543static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1544static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1545static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1546static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001547static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1548
Tim Peters2a799bf2002-12-16 20:18:38 +00001549/* ---------------------------------------------------------------------------
1550 * Class implementations.
1551 */
1552
1553/*
1554 * PyDateTime_Delta implementation.
1555 */
1556
1557/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001559 * as a Python int or long.
1560 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1561 * due to ubiquitous overflow possibilities.
1562 */
1563static PyObject *
1564delta_to_microseconds(PyDateTime_Delta *self)
1565{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 PyObject *x1 = NULL;
1567 PyObject *x2 = NULL;
1568 PyObject *x3 = NULL;
1569 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1572 if (x1 == NULL)
1573 goto Done;
1574 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1575 if (x2 == NULL)
1576 goto Done;
1577 Py_DECREF(x1);
1578 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 /* x2 has days in seconds */
1581 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1582 if (x1 == NULL)
1583 goto Done;
1584 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1585 if (x3 == NULL)
1586 goto Done;
1587 Py_DECREF(x1);
1588 Py_DECREF(x2);
1589 x1 = x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 /* x3 has days+seconds in seconds */
1592 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1593 if (x1 == NULL)
1594 goto Done;
1595 Py_DECREF(x3);
1596 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 /* x1 has days+seconds in us */
1599 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1600 if (x2 == NULL)
1601 goto Done;
1602 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001603
1604Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 Py_XDECREF(x1);
1606 Py_XDECREF(x2);
1607 Py_XDECREF(x3);
1608 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001609}
1610
1611/* Convert a number of us (as a Python int or long) to a timedelta.
1612 */
1613static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001614microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 int us;
1617 int s;
1618 int d;
1619 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyObject *tuple = NULL;
1622 PyObject *num = NULL;
1623 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 tuple = PyNumber_Divmod(pyus, us_per_second);
1626 if (tuple == NULL)
1627 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 num = PyTuple_GetItem(tuple, 1); /* us */
1630 if (num == NULL)
1631 goto Done;
1632 temp = PyLong_AsLong(num);
1633 num = NULL;
1634 if (temp == -1 && PyErr_Occurred())
1635 goto Done;
1636 assert(0 <= temp && temp < 1000000);
1637 us = (int)temp;
1638 if (us < 0) {
1639 /* The divisor was positive, so this must be an error. */
1640 assert(PyErr_Occurred());
1641 goto Done;
1642 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001644 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1645 if (num == NULL)
1646 goto Done;
1647 Py_INCREF(num);
1648 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 tuple = PyNumber_Divmod(num, seconds_per_day);
1651 if (tuple == NULL)
1652 goto Done;
1653 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 num = PyTuple_GetItem(tuple, 1); /* seconds */
1656 if (num == NULL)
1657 goto Done;
1658 temp = PyLong_AsLong(num);
1659 num = NULL;
1660 if (temp == -1 && PyErr_Occurred())
1661 goto Done;
1662 assert(0 <= temp && temp < 24*3600);
1663 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 if (s < 0) {
1666 /* The divisor was positive, so this must be an error. */
1667 assert(PyErr_Occurred());
1668 goto Done;
1669 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1672 if (num == NULL)
1673 goto Done;
1674 Py_INCREF(num);
1675 temp = PyLong_AsLong(num);
1676 if (temp == -1 && PyErr_Occurred())
1677 goto Done;
1678 d = (int)temp;
1679 if ((long)d != temp) {
1680 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1681 "large to fit in a C int");
1682 goto Done;
1683 }
1684 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001685
1686Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 Py_XDECREF(tuple);
1688 Py_XDECREF(num);
1689 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001690}
1691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692#define microseconds_to_delta(pymicros) \
1693 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001694
Tim Peters2a799bf2002-12-16 20:18:38 +00001695static PyObject *
1696multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1697{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 PyObject *pyus_in;
1699 PyObject *pyus_out;
1700 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001702 pyus_in = delta_to_microseconds(delta);
1703 if (pyus_in == NULL)
1704 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001706 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1707 Py_DECREF(pyus_in);
1708 if (pyus_out == NULL)
1709 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001711 result = microseconds_to_delta(pyus_out);
1712 Py_DECREF(pyus_out);
1713 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001714}
1715
1716static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001717multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1718{
1719 PyObject *result = NULL;
1720 PyObject *pyus_in = NULL, *temp, *pyus_out;
1721 PyObject *ratio = NULL;
1722
1723 pyus_in = delta_to_microseconds(delta);
1724 if (pyus_in == NULL)
1725 return NULL;
1726 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1727 if (ratio == NULL)
1728 goto error;
1729 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1730 Py_DECREF(pyus_in);
1731 pyus_in = NULL;
1732 if (temp == NULL)
1733 goto error;
1734 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1735 Py_DECREF(temp);
1736 if (pyus_out == NULL)
1737 goto error;
1738 result = microseconds_to_delta(pyus_out);
1739 Py_DECREF(pyus_out);
1740 error:
1741 Py_XDECREF(pyus_in);
1742 Py_XDECREF(ratio);
1743
1744 return result;
1745}
1746
1747static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001748divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 PyObject *pyus_in;
1751 PyObject *pyus_out;
1752 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 pyus_in = delta_to_microseconds(delta);
1755 if (pyus_in == NULL)
1756 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001758 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1759 Py_DECREF(pyus_in);
1760 if (pyus_out == NULL)
1761 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 result = microseconds_to_delta(pyus_out);
1764 Py_DECREF(pyus_out);
1765 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001766}
1767
1768static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001769divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1770{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 PyObject *pyus_left;
1772 PyObject *pyus_right;
1773 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 pyus_left = delta_to_microseconds(left);
1776 if (pyus_left == NULL)
1777 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 pyus_right = delta_to_microseconds(right);
1780 if (pyus_right == NULL) {
1781 Py_DECREF(pyus_left);
1782 return NULL;
1783 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001784
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1786 Py_DECREF(pyus_left);
1787 Py_DECREF(pyus_right);
1788 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001789}
1790
1791static PyObject *
1792truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1793{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 PyObject *pyus_left;
1795 PyObject *pyus_right;
1796 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001798 pyus_left = delta_to_microseconds(left);
1799 if (pyus_left == NULL)
1800 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 pyus_right = delta_to_microseconds(right);
1803 if (pyus_right == NULL) {
1804 Py_DECREF(pyus_left);
1805 return NULL;
1806 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1809 Py_DECREF(pyus_left);
1810 Py_DECREF(pyus_right);
1811 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001812}
1813
1814static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001815truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1816{
1817 PyObject *result = NULL;
1818 PyObject *pyus_in = NULL, *temp, *pyus_out;
1819 PyObject *ratio = NULL;
1820
1821 pyus_in = delta_to_microseconds(delta);
1822 if (pyus_in == NULL)
1823 return NULL;
1824 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1825 if (ratio == NULL)
1826 goto error;
1827 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1828 Py_DECREF(pyus_in);
1829 pyus_in = NULL;
1830 if (temp == NULL)
1831 goto error;
1832 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1833 Py_DECREF(temp);
1834 if (pyus_out == NULL)
1835 goto error;
1836 result = microseconds_to_delta(pyus_out);
1837 Py_DECREF(pyus_out);
1838 error:
1839 Py_XDECREF(pyus_in);
1840 Py_XDECREF(ratio);
1841
1842 return result;
1843}
1844
1845static PyObject *
1846truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1847{
1848 PyObject *result;
1849 PyObject *pyus_in, *pyus_out;
1850 pyus_in = delta_to_microseconds(delta);
1851 if (pyus_in == NULL)
1852 return NULL;
1853 pyus_out = divide_nearest(pyus_in, i);
1854 Py_DECREF(pyus_in);
1855 if (pyus_out == NULL)
1856 return NULL;
1857 result = microseconds_to_delta(pyus_out);
1858 Py_DECREF(pyus_out);
1859
1860 return result;
1861}
1862
1863static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001864delta_add(PyObject *left, PyObject *right)
1865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1869 /* delta + delta */
1870 /* The C-level additions can't overflow because of the
1871 * invariant bounds.
1872 */
1873 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1874 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1875 int microseconds = GET_TD_MICROSECONDS(left) +
1876 GET_TD_MICROSECONDS(right);
1877 result = new_delta(days, seconds, microseconds, 1);
1878 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 if (result == Py_NotImplemented)
1881 Py_INCREF(result);
1882 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001883}
1884
1885static PyObject *
1886delta_negative(PyDateTime_Delta *self)
1887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 return new_delta(-GET_TD_DAYS(self),
1889 -GET_TD_SECONDS(self),
1890 -GET_TD_MICROSECONDS(self),
1891 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001892}
1893
1894static PyObject *
1895delta_positive(PyDateTime_Delta *self)
1896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 /* Could optimize this (by returning self) if this isn't a
1898 * subclass -- but who uses unary + ? Approximately nobody.
1899 */
1900 return new_delta(GET_TD_DAYS(self),
1901 GET_TD_SECONDS(self),
1902 GET_TD_MICROSECONDS(self),
1903 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001904}
1905
1906static PyObject *
1907delta_abs(PyDateTime_Delta *self)
1908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 assert(GET_TD_MICROSECONDS(self) >= 0);
1912 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 if (GET_TD_DAYS(self) < 0)
1915 result = delta_negative(self);
1916 else
1917 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001920}
1921
1922static PyObject *
1923delta_subtract(PyObject *left, PyObject *right)
1924{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1928 /* delta - delta */
1929 PyObject *minus_right = PyNumber_Negative(right);
1930 if (minus_right) {
1931 result = delta_add(left, minus_right);
1932 Py_DECREF(minus_right);
1933 }
1934 else
1935 result = NULL;
1936 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 if (result == Py_NotImplemented)
1939 Py_INCREF(result);
1940 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001941}
1942
Tim Peters2a799bf2002-12-16 20:18:38 +00001943static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001944delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 if (PyDelta_Check(other)) {
1947 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1948 if (diff == 0) {
1949 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1950 if (diff == 0)
1951 diff = GET_TD_MICROSECONDS(self) -
1952 GET_TD_MICROSECONDS(other);
1953 }
1954 return diff_to_bool(diff, op);
1955 }
1956 else {
1957 Py_INCREF(Py_NotImplemented);
1958 return Py_NotImplemented;
1959 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001960}
1961
1962static PyObject *delta_getstate(PyDateTime_Delta *self);
1963
1964static long
1965delta_hash(PyDateTime_Delta *self)
1966{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 if (self->hashcode == -1) {
1968 PyObject *temp = delta_getstate(self);
1969 if (temp != NULL) {
1970 self->hashcode = PyObject_Hash(temp);
1971 Py_DECREF(temp);
1972 }
1973 }
1974 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001975}
1976
1977static PyObject *
1978delta_multiply(PyObject *left, PyObject *right)
1979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 if (PyDelta_Check(left)) {
1983 /* delta * ??? */
1984 if (PyLong_Check(right))
1985 result = multiply_int_timedelta(right,
1986 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001987 else if (PyFloat_Check(right))
1988 result = multiply_float_timedelta(right,
1989 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 }
1991 else if (PyLong_Check(left))
1992 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001993 (PyDateTime_Delta *) right);
1994 else if (PyFloat_Check(left))
1995 result = multiply_float_timedelta(left,
1996 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001998 if (result == Py_NotImplemented)
1999 Py_INCREF(result);
2000 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002001}
2002
2003static PyObject *
2004delta_divide(PyObject *left, PyObject *right)
2005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 if (PyDelta_Check(left)) {
2009 /* delta * ??? */
2010 if (PyLong_Check(right))
2011 result = divide_timedelta_int(
2012 (PyDateTime_Delta *)left,
2013 right);
2014 else if (PyDelta_Check(right))
2015 result = divide_timedelta_timedelta(
2016 (PyDateTime_Delta *)left,
2017 (PyDateTime_Delta *)right);
2018 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 if (result == Py_NotImplemented)
2021 Py_INCREF(result);
2022 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002023}
2024
Mark Dickinson7c186e22010-04-20 22:32:49 +00002025static PyObject *
2026delta_truedivide(PyObject *left, PyObject *right)
2027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002030 if (PyDelta_Check(left)) {
2031 if (PyDelta_Check(right))
2032 result = truedivide_timedelta_timedelta(
2033 (PyDateTime_Delta *)left,
2034 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002035 else if (PyFloat_Check(right))
2036 result = truedivide_timedelta_float(
2037 (PyDateTime_Delta *)left, right);
2038 else if (PyLong_Check(right))
2039 result = truedivide_timedelta_int(
2040 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 if (result == Py_NotImplemented)
2044 Py_INCREF(result);
2045 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002046}
2047
2048static PyObject *
2049delta_remainder(PyObject *left, PyObject *right)
2050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 PyObject *pyus_left;
2052 PyObject *pyus_right;
2053 PyObject *pyus_remainder;
2054 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
2057 Py_INCREF(Py_NotImplemented);
2058 return Py_NotImplemented;
2059 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2062 if (pyus_left == NULL)
2063 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2066 if (pyus_right == NULL) {
2067 Py_DECREF(pyus_left);
2068 return NULL;
2069 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2072 Py_DECREF(pyus_left);
2073 Py_DECREF(pyus_right);
2074 if (pyus_remainder == NULL)
2075 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 remainder = microseconds_to_delta(pyus_remainder);
2078 Py_DECREF(pyus_remainder);
2079 if (remainder == NULL)
2080 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002083}
2084
2085static PyObject *
2086delta_divmod(PyObject *left, PyObject *right)
2087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 PyObject *pyus_left;
2089 PyObject *pyus_right;
2090 PyObject *divmod;
2091 PyObject *delta;
2092 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
2095 Py_INCREF(Py_NotImplemented);
2096 return Py_NotImplemented;
2097 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2100 if (pyus_left == NULL)
2101 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2104 if (pyus_right == NULL) {
2105 Py_DECREF(pyus_left);
2106 return NULL;
2107 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2110 Py_DECREF(pyus_left);
2111 Py_DECREF(pyus_right);
2112 if (divmod == NULL)
2113 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 assert(PyTuple_Size(divmod) == 2);
2116 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2117 if (delta == NULL) {
2118 Py_DECREF(divmod);
2119 return NULL;
2120 }
2121 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2122 Py_DECREF(delta);
2123 Py_DECREF(divmod);
2124 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002125}
2126
Tim Peters2a799bf2002-12-16 20:18:38 +00002127/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2128 * timedelta constructor. sofar is the # of microseconds accounted for
2129 * so far, and there are factor microseconds per current unit, the number
2130 * of which is given by num. num * factor is added to sofar in a
2131 * numerically careful way, and that's the result. Any fractional
2132 * microseconds left over (this can happen if num is a float type) are
2133 * added into *leftover.
2134 * Note that there are many ways this can give an error (NULL) return.
2135 */
2136static PyObject *
2137accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2138 double *leftover)
2139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 PyObject *prod;
2141 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002145 if (PyLong_Check(num)) {
2146 prod = PyNumber_Multiply(num, factor);
2147 if (prod == NULL)
2148 return NULL;
2149 sum = PyNumber_Add(sofar, prod);
2150 Py_DECREF(prod);
2151 return sum;
2152 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002154 if (PyFloat_Check(num)) {
2155 double dnum;
2156 double fracpart;
2157 double intpart;
2158 PyObject *x;
2159 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 /* The Plan: decompose num into an integer part and a
2162 * fractional part, num = intpart + fracpart.
2163 * Then num * factor ==
2164 * intpart * factor + fracpart * factor
2165 * and the LHS can be computed exactly in long arithmetic.
2166 * The RHS is again broken into an int part and frac part.
2167 * and the frac part is added into *leftover.
2168 */
2169 dnum = PyFloat_AsDouble(num);
2170 if (dnum == -1.0 && PyErr_Occurred())
2171 return NULL;
2172 fracpart = modf(dnum, &intpart);
2173 x = PyLong_FromDouble(intpart);
2174 if (x == NULL)
2175 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 prod = PyNumber_Multiply(x, factor);
2178 Py_DECREF(x);
2179 if (prod == NULL)
2180 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 sum = PyNumber_Add(sofar, prod);
2183 Py_DECREF(prod);
2184 if (sum == NULL)
2185 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 if (fracpart == 0.0)
2188 return sum;
2189 /* So far we've lost no information. Dealing with the
2190 * fractional part requires float arithmetic, and may
2191 * lose a little info.
2192 */
2193 assert(PyLong_Check(factor));
2194 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 dnum *= fracpart;
2197 fracpart = modf(dnum, &intpart);
2198 x = PyLong_FromDouble(intpart);
2199 if (x == NULL) {
2200 Py_DECREF(sum);
2201 return NULL;
2202 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 y = PyNumber_Add(sum, x);
2205 Py_DECREF(sum);
2206 Py_DECREF(x);
2207 *leftover += fracpart;
2208 return y;
2209 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002211 PyErr_Format(PyExc_TypeError,
2212 "unsupported type for timedelta %s component: %s",
2213 tag, Py_TYPE(num)->tp_name);
2214 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002215}
2216
2217static PyObject *
2218delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 /* Argument objects. */
2223 PyObject *day = NULL;
2224 PyObject *second = NULL;
2225 PyObject *us = NULL;
2226 PyObject *ms = NULL;
2227 PyObject *minute = NULL;
2228 PyObject *hour = NULL;
2229 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 PyObject *x = NULL; /* running sum of microseconds */
2232 PyObject *y = NULL; /* temp sum of microseconds */
2233 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 static char *keywords[] = {
2236 "days", "seconds", "microseconds", "milliseconds",
2237 "minutes", "hours", "weeks", NULL
2238 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2241 keywords,
2242 &day, &second, &us,
2243 &ms, &minute, &hour, &week) == 0)
2244 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002246 x = PyLong_FromLong(0);
2247 if (x == NULL)
2248 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002250#define CLEANUP \
2251 Py_DECREF(x); \
2252 x = y; \
2253 if (x == NULL) \
2254 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 if (us) {
2257 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2258 CLEANUP;
2259 }
2260 if (ms) {
2261 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2262 CLEANUP;
2263 }
2264 if (second) {
2265 y = accum("seconds", x, second, us_per_second, &leftover_us);
2266 CLEANUP;
2267 }
2268 if (minute) {
2269 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2270 CLEANUP;
2271 }
2272 if (hour) {
2273 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2274 CLEANUP;
2275 }
2276 if (day) {
2277 y = accum("days", x, day, us_per_day, &leftover_us);
2278 CLEANUP;
2279 }
2280 if (week) {
2281 y = accum("weeks", x, week, us_per_week, &leftover_us);
2282 CLEANUP;
2283 }
2284 if (leftover_us) {
2285 /* Round to nearest whole # of us, and add into x. */
2286 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2287 if (temp == NULL) {
2288 Py_DECREF(x);
2289 goto Done;
2290 }
2291 y = PyNumber_Add(x, temp);
2292 Py_DECREF(temp);
2293 CLEANUP;
2294 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 self = microseconds_to_delta_ex(x, type);
2297 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002298Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002300
2301#undef CLEANUP
2302}
2303
2304static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002305delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 return (GET_TD_DAYS(self) != 0
2308 || GET_TD_SECONDS(self) != 0
2309 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002310}
2311
2312static PyObject *
2313delta_repr(PyDateTime_Delta *self)
2314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 if (GET_TD_MICROSECONDS(self) != 0)
2316 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2317 Py_TYPE(self)->tp_name,
2318 GET_TD_DAYS(self),
2319 GET_TD_SECONDS(self),
2320 GET_TD_MICROSECONDS(self));
2321 if (GET_TD_SECONDS(self) != 0)
2322 return PyUnicode_FromFormat("%s(%d, %d)",
2323 Py_TYPE(self)->tp_name,
2324 GET_TD_DAYS(self),
2325 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002327 return PyUnicode_FromFormat("%s(%d)",
2328 Py_TYPE(self)->tp_name,
2329 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002330}
2331
2332static PyObject *
2333delta_str(PyDateTime_Delta *self)
2334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 int us = GET_TD_MICROSECONDS(self);
2336 int seconds = GET_TD_SECONDS(self);
2337 int minutes = divmod(seconds, 60, &seconds);
2338 int hours = divmod(minutes, 60, &minutes);
2339 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 if (days) {
2342 if (us)
2343 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2344 days, (days == 1 || days == -1) ? "" : "s",
2345 hours, minutes, seconds, us);
2346 else
2347 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2348 days, (days == 1 || days == -1) ? "" : "s",
2349 hours, minutes, seconds);
2350 } else {
2351 if (us)
2352 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2353 hours, minutes, seconds, us);
2354 else
2355 return PyUnicode_FromFormat("%d:%02d:%02d",
2356 hours, minutes, seconds);
2357 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002358
Tim Peters2a799bf2002-12-16 20:18:38 +00002359}
2360
Tim Peters371935f2003-02-01 01:52:50 +00002361/* Pickle support, a simple use of __reduce__. */
2362
Tim Petersb57f8f02003-02-01 02:54:15 +00002363/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002364static PyObject *
2365delta_getstate(PyDateTime_Delta *self)
2366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002367 return Py_BuildValue("iii", GET_TD_DAYS(self),
2368 GET_TD_SECONDS(self),
2369 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002370}
2371
Tim Peters2a799bf2002-12-16 20:18:38 +00002372static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002373delta_total_seconds(PyObject *self)
2374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 PyObject *total_seconds;
2376 PyObject *total_microseconds;
2377 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2380 if (total_microseconds == NULL)
2381 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002383 one_million = PyLong_FromLong(1000000L);
2384 if (one_million == NULL) {
2385 Py_DECREF(total_microseconds);
2386 return NULL;
2387 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 Py_DECREF(total_microseconds);
2392 Py_DECREF(one_million);
2393 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002394}
2395
2396static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002397delta_reduce(PyDateTime_Delta* self)
2398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002400}
2401
2402#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2403
2404static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 {"days", T_INT, OFFSET(days), READONLY,
2407 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 {"seconds", T_INT, OFFSET(seconds), READONLY,
2410 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2413 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2414 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002415};
2416
2417static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2419 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2422 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002425};
2426
2427static char delta_doc[] =
2428PyDoc_STR("Difference between two datetime values.");
2429
2430static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 delta_add, /* nb_add */
2432 delta_subtract, /* nb_subtract */
2433 delta_multiply, /* nb_multiply */
2434 delta_remainder, /* nb_remainder */
2435 delta_divmod, /* nb_divmod */
2436 0, /* nb_power */
2437 (unaryfunc)delta_negative, /* nb_negative */
2438 (unaryfunc)delta_positive, /* nb_positive */
2439 (unaryfunc)delta_abs, /* nb_absolute */
2440 (inquiry)delta_bool, /* nb_bool */
2441 0, /*nb_invert*/
2442 0, /*nb_lshift*/
2443 0, /*nb_rshift*/
2444 0, /*nb_and*/
2445 0, /*nb_xor*/
2446 0, /*nb_or*/
2447 0, /*nb_int*/
2448 0, /*nb_reserved*/
2449 0, /*nb_float*/
2450 0, /*nb_inplace_add*/
2451 0, /*nb_inplace_subtract*/
2452 0, /*nb_inplace_multiply*/
2453 0, /*nb_inplace_remainder*/
2454 0, /*nb_inplace_power*/
2455 0, /*nb_inplace_lshift*/
2456 0, /*nb_inplace_rshift*/
2457 0, /*nb_inplace_and*/
2458 0, /*nb_inplace_xor*/
2459 0, /*nb_inplace_or*/
2460 delta_divide, /* nb_floor_divide */
2461 delta_truedivide, /* nb_true_divide */
2462 0, /* nb_inplace_floor_divide */
2463 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002464};
2465
2466static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 PyVarObject_HEAD_INIT(NULL, 0)
2468 "datetime.timedelta", /* tp_name */
2469 sizeof(PyDateTime_Delta), /* tp_basicsize */
2470 0, /* tp_itemsize */
2471 0, /* tp_dealloc */
2472 0, /* tp_print */
2473 0, /* tp_getattr */
2474 0, /* tp_setattr */
2475 0, /* tp_reserved */
2476 (reprfunc)delta_repr, /* tp_repr */
2477 &delta_as_number, /* tp_as_number */
2478 0, /* tp_as_sequence */
2479 0, /* tp_as_mapping */
2480 (hashfunc)delta_hash, /* tp_hash */
2481 0, /* tp_call */
2482 (reprfunc)delta_str, /* tp_str */
2483 PyObject_GenericGetAttr, /* tp_getattro */
2484 0, /* tp_setattro */
2485 0, /* tp_as_buffer */
2486 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2487 delta_doc, /* tp_doc */
2488 0, /* tp_traverse */
2489 0, /* tp_clear */
2490 delta_richcompare, /* tp_richcompare */
2491 0, /* tp_weaklistoffset */
2492 0, /* tp_iter */
2493 0, /* tp_iternext */
2494 delta_methods, /* tp_methods */
2495 delta_members, /* tp_members */
2496 0, /* tp_getset */
2497 0, /* tp_base */
2498 0, /* tp_dict */
2499 0, /* tp_descr_get */
2500 0, /* tp_descr_set */
2501 0, /* tp_dictoffset */
2502 0, /* tp_init */
2503 0, /* tp_alloc */
2504 delta_new, /* tp_new */
2505 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002506};
2507
2508/*
2509 * PyDateTime_Date implementation.
2510 */
2511
2512/* Accessor properties. */
2513
2514static PyObject *
2515date_year(PyDateTime_Date *self, void *unused)
2516{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002518}
2519
2520static PyObject *
2521date_month(PyDateTime_Date *self, void *unused)
2522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002524}
2525
2526static PyObject *
2527date_day(PyDateTime_Date *self, void *unused)
2528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002529 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002530}
2531
2532static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002533 {"year", (getter)date_year},
2534 {"month", (getter)date_month},
2535 {"day", (getter)date_day},
2536 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002537};
2538
2539/* Constructors. */
2540
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002541static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002542
Tim Peters2a799bf2002-12-16 20:18:38 +00002543static PyObject *
2544date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002546 PyObject *self = NULL;
2547 PyObject *state;
2548 int year;
2549 int month;
2550 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002552 /* Check for invocation from pickle with __getstate__ state */
2553 if (PyTuple_GET_SIZE(args) == 1 &&
2554 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2555 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2556 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2557 {
2558 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2561 if (me != NULL) {
2562 char *pdata = PyBytes_AS_STRING(state);
2563 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2564 me->hashcode = -1;
2565 }
2566 return (PyObject *)me;
2567 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002569 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2570 &year, &month, &day)) {
2571 if (check_date_args(year, month, day) < 0)
2572 return NULL;
2573 self = new_date_ex(year, month, day, type);
2574 }
2575 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002576}
2577
2578/* Return new date from localtime(t). */
2579static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002580date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002581{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002582 struct tm *tm;
2583 time_t t;
2584 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 t = _PyTime_DoubleToTimet(ts);
2587 if (t == (time_t)-1 && PyErr_Occurred())
2588 return NULL;
2589 tm = localtime(&t);
2590 if (tm)
2591 result = PyObject_CallFunction(cls, "iii",
2592 tm->tm_year + 1900,
2593 tm->tm_mon + 1,
2594 tm->tm_mday);
2595 else
2596 PyErr_SetString(PyExc_ValueError,
2597 "timestamp out of range for "
2598 "platform localtime() function");
2599 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002600}
2601
2602/* Return new date from current time.
2603 * We say this is equivalent to fromtimestamp(time.time()), and the
2604 * only way to be sure of that is to *call* time.time(). That's not
2605 * generally the same as calling C's time.
2606 */
2607static PyObject *
2608date_today(PyObject *cls, PyObject *dummy)
2609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002610 PyObject *time;
2611 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002613 time = time_time();
2614 if (time == NULL)
2615 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617 /* Note well: today() is a class method, so this may not call
2618 * date.fromtimestamp. For example, it may call
2619 * datetime.fromtimestamp. That's why we need all the accuracy
2620 * time.time() delivers; if someone were gonzo about optimization,
2621 * date.today() could get away with plain C time().
2622 */
2623 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2624 Py_DECREF(time);
2625 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002626}
2627
2628/* Return new date from given timestamp (Python timestamp -- a double). */
2629static PyObject *
2630date_fromtimestamp(PyObject *cls, PyObject *args)
2631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002632 double timestamp;
2633 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002635 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2636 result = date_local_from_time_t(cls, timestamp);
2637 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002638}
2639
2640/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2641 * the ordinal is out of range.
2642 */
2643static PyObject *
2644date_fromordinal(PyObject *cls, PyObject *args)
2645{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 PyObject *result = NULL;
2647 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002649 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2650 int year;
2651 int month;
2652 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 if (ordinal < 1)
2655 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2656 ">= 1");
2657 else {
2658 ord_to_ymd(ordinal, &year, &month, &day);
2659 result = PyObject_CallFunction(cls, "iii",
2660 year, month, day);
2661 }
2662 }
2663 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002664}
2665
2666/*
2667 * Date arithmetic.
2668 */
2669
2670/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2671 * instead.
2672 */
2673static PyObject *
2674add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002676 PyObject *result = NULL;
2677 int year = GET_YEAR(date);
2678 int month = GET_MONTH(date);
2679 int deltadays = GET_TD_DAYS(delta);
2680 /* C-level overflow is impossible because |deltadays| < 1e9. */
2681 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002683 if (normalize_date(&year, &month, &day) >= 0)
2684 result = new_date(year, month, day);
2685 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002686}
2687
2688static PyObject *
2689date_add(PyObject *left, PyObject *right)
2690{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002691 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2692 Py_INCREF(Py_NotImplemented);
2693 return Py_NotImplemented;
2694 }
2695 if (PyDate_Check(left)) {
2696 /* date + ??? */
2697 if (PyDelta_Check(right))
2698 /* date + delta */
2699 return add_date_timedelta((PyDateTime_Date *) left,
2700 (PyDateTime_Delta *) right,
2701 0);
2702 }
2703 else {
2704 /* ??? + date
2705 * 'right' must be one of us, or we wouldn't have been called
2706 */
2707 if (PyDelta_Check(left))
2708 /* delta + date */
2709 return add_date_timedelta((PyDateTime_Date *) right,
2710 (PyDateTime_Delta *) left,
2711 0);
2712 }
2713 Py_INCREF(Py_NotImplemented);
2714 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002715}
2716
2717static PyObject *
2718date_subtract(PyObject *left, PyObject *right)
2719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2721 Py_INCREF(Py_NotImplemented);
2722 return Py_NotImplemented;
2723 }
2724 if (PyDate_Check(left)) {
2725 if (PyDate_Check(right)) {
2726 /* date - date */
2727 int left_ord = ymd_to_ord(GET_YEAR(left),
2728 GET_MONTH(left),
2729 GET_DAY(left));
2730 int right_ord = ymd_to_ord(GET_YEAR(right),
2731 GET_MONTH(right),
2732 GET_DAY(right));
2733 return new_delta(left_ord - right_ord, 0, 0, 0);
2734 }
2735 if (PyDelta_Check(right)) {
2736 /* date - delta */
2737 return add_date_timedelta((PyDateTime_Date *) left,
2738 (PyDateTime_Delta *) right,
2739 1);
2740 }
2741 }
2742 Py_INCREF(Py_NotImplemented);
2743 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002744}
2745
2746
2747/* Various ways to turn a date into a string. */
2748
2749static PyObject *
2750date_repr(PyDateTime_Date *self)
2751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002752 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2753 Py_TYPE(self)->tp_name,
2754 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002755}
2756
2757static PyObject *
2758date_isoformat(PyDateTime_Date *self)
2759{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002760 return PyUnicode_FromFormat("%04d-%02d-%02d",
2761 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002762}
2763
Tim Peterse2df5ff2003-05-02 18:39:55 +00002764/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002765static PyObject *
2766date_str(PyDateTime_Date *self)
2767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002768 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002769}
2770
2771
2772static PyObject *
2773date_ctime(PyDateTime_Date *self)
2774{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002775 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002776}
2777
2778static PyObject *
2779date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2780{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002781 /* This method can be inherited, and needs to call the
2782 * timetuple() method appropriate to self's class.
2783 */
2784 PyObject *result;
2785 PyObject *tuple;
2786 PyObject *format;
2787 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002789 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2790 &format))
2791 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002793 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2794 if (tuple == NULL)
2795 return NULL;
2796 result = wrap_strftime((PyObject *)self, format, tuple,
2797 (PyObject *)self);
2798 Py_DECREF(tuple);
2799 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002800}
2801
Eric Smith1ba31142007-09-11 18:06:02 +00002802static PyObject *
2803date_format(PyDateTime_Date *self, PyObject *args)
2804{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002805 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002807 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2808 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002810 /* if the format is zero length, return str(self) */
2811 if (PyUnicode_GetSize(format) == 0)
2812 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002814 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002815}
2816
Tim Peters2a799bf2002-12-16 20:18:38 +00002817/* ISO methods. */
2818
2819static PyObject *
2820date_isoweekday(PyDateTime_Date *self)
2821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002824 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002825}
2826
2827static PyObject *
2828date_isocalendar(PyDateTime_Date *self)
2829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002830 int year = GET_YEAR(self);
2831 int week1_monday = iso_week1_monday(year);
2832 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2833 int week;
2834 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 week = divmod(today - week1_monday, 7, &day);
2837 if (week < 0) {
2838 --year;
2839 week1_monday = iso_week1_monday(year);
2840 week = divmod(today - week1_monday, 7, &day);
2841 }
2842 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2843 ++year;
2844 week = 0;
2845 }
2846 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002847}
2848
2849/* Miscellaneous methods. */
2850
Tim Peters2a799bf2002-12-16 20:18:38 +00002851static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002852date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 if (PyDate_Check(other)) {
2855 int diff = memcmp(((PyDateTime_Date *)self)->data,
2856 ((PyDateTime_Date *)other)->data,
2857 _PyDateTime_DATE_DATASIZE);
2858 return diff_to_bool(diff, op);
2859 }
2860 else {
2861 Py_INCREF(Py_NotImplemented);
2862 return Py_NotImplemented;
2863 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002864}
2865
2866static PyObject *
2867date_timetuple(PyDateTime_Date *self)
2868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002869 return build_struct_time(GET_YEAR(self),
2870 GET_MONTH(self),
2871 GET_DAY(self),
2872 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002873}
2874
Tim Peters12bf3392002-12-24 05:41:27 +00002875static PyObject *
2876date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2877{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 PyObject *clone;
2879 PyObject *tuple;
2880 int year = GET_YEAR(self);
2881 int month = GET_MONTH(self);
2882 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2885 &year, &month, &day))
2886 return NULL;
2887 tuple = Py_BuildValue("iii", year, month, day);
2888 if (tuple == NULL)
2889 return NULL;
2890 clone = date_new(Py_TYPE(self), tuple, NULL);
2891 Py_DECREF(tuple);
2892 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002893}
2894
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002895/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002896 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002897*/
2898static long
2899generic_hash(unsigned char *data, int len)
2900{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002901 register unsigned char *p;
2902 register long x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002904 p = (unsigned char *) data;
2905 x = *p << 7;
2906 while (--len >= 0)
2907 x = (1000003*x) ^ *p++;
2908 x ^= len;
2909 if (x == -1)
2910 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002912 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002913}
2914
2915
2916static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002917
2918static long
2919date_hash(PyDateTime_Date *self)
2920{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002921 if (self->hashcode == -1)
2922 self->hashcode = generic_hash(
2923 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002925 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002926}
2927
2928static PyObject *
2929date_toordinal(PyDateTime_Date *self)
2930{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002931 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2932 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002933}
2934
2935static PyObject *
2936date_weekday(PyDateTime_Date *self)
2937{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002938 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002940 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002941}
2942
Tim Peters371935f2003-02-01 01:52:50 +00002943/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002944
Tim Petersb57f8f02003-02-01 02:54:15 +00002945/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002946static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002947date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002949 PyObject* field;
2950 field = PyBytes_FromStringAndSize((char*)self->data,
2951 _PyDateTime_DATE_DATASIZE);
2952 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002953}
2954
2955static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002956date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002958 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002959}
2960
2961static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002963 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002965 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2966 METH_CLASS,
2967 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2968 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002970 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2971 METH_CLASS,
2972 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2973 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002975 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2976 PyDoc_STR("Current date or datetime: same as "
2977 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002979 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002981 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2982 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002984 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2985 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002987 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2988 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002990 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2991 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002993 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2994 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2995 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002997 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2998 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003000 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
3001 PyDoc_STR("Return the day of the week represented by the date.\n"
3002 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003004 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3005 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3006 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003008 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3009 PyDoc_STR("Return the day of the week represented by the date.\n"
3010 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003012 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3013 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3016 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003018 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003019};
3020
3021static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003022PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003023
3024static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003025 date_add, /* nb_add */
3026 date_subtract, /* nb_subtract */
3027 0, /* nb_multiply */
3028 0, /* nb_remainder */
3029 0, /* nb_divmod */
3030 0, /* nb_power */
3031 0, /* nb_negative */
3032 0, /* nb_positive */
3033 0, /* nb_absolute */
3034 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003035};
3036
3037static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 PyVarObject_HEAD_INIT(NULL, 0)
3039 "datetime.date", /* tp_name */
3040 sizeof(PyDateTime_Date), /* tp_basicsize */
3041 0, /* tp_itemsize */
3042 0, /* tp_dealloc */
3043 0, /* tp_print */
3044 0, /* tp_getattr */
3045 0, /* tp_setattr */
3046 0, /* tp_reserved */
3047 (reprfunc)date_repr, /* tp_repr */
3048 &date_as_number, /* tp_as_number */
3049 0, /* tp_as_sequence */
3050 0, /* tp_as_mapping */
3051 (hashfunc)date_hash, /* tp_hash */
3052 0, /* tp_call */
3053 (reprfunc)date_str, /* tp_str */
3054 PyObject_GenericGetAttr, /* tp_getattro */
3055 0, /* tp_setattro */
3056 0, /* tp_as_buffer */
3057 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3058 date_doc, /* tp_doc */
3059 0, /* tp_traverse */
3060 0, /* tp_clear */
3061 date_richcompare, /* tp_richcompare */
3062 0, /* tp_weaklistoffset */
3063 0, /* tp_iter */
3064 0, /* tp_iternext */
3065 date_methods, /* tp_methods */
3066 0, /* tp_members */
3067 date_getset, /* tp_getset */
3068 0, /* tp_base */
3069 0, /* tp_dict */
3070 0, /* tp_descr_get */
3071 0, /* tp_descr_set */
3072 0, /* tp_dictoffset */
3073 0, /* tp_init */
3074 0, /* tp_alloc */
3075 date_new, /* tp_new */
3076 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003077};
3078
3079/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003080 * PyDateTime_TZInfo implementation.
3081 */
3082
3083/* This is a pure abstract base class, so doesn't do anything beyond
3084 * raising NotImplemented exceptions. Real tzinfo classes need
3085 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003086 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003087 * be subclasses of this tzinfo class, which is easy and quick to check).
3088 *
3089 * Note: For reasons having to do with pickling of subclasses, we have
3090 * to allow tzinfo objects to be instantiated. This wasn't an issue
3091 * in the Python implementation (__init__() could raise NotImplementedError
3092 * there without ill effect), but doing so in the C implementation hit a
3093 * brick wall.
3094 */
3095
3096static PyObject *
3097tzinfo_nogo(const char* methodname)
3098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003099 PyErr_Format(PyExc_NotImplementedError,
3100 "a tzinfo subclass must implement %s()",
3101 methodname);
3102 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003103}
3104
3105/* Methods. A subclass must implement these. */
3106
Tim Peters52dcce22003-01-23 16:36:11 +00003107static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003108tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3109{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003111}
3112
Tim Peters52dcce22003-01-23 16:36:11 +00003113static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003114tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3115{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003116 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003117}
3118
Tim Peters52dcce22003-01-23 16:36:11 +00003119static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003120tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003123}
3124
Tim Peters52dcce22003-01-23 16:36:11 +00003125static PyObject *
3126tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
3127{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003128 int y, m, d, hh, mm, ss, us;
Tim Peters52dcce22003-01-23 16:36:11 +00003129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003130 PyObject *result;
3131 int off, dst;
3132 int none;
3133 int delta;
Tim Peters52dcce22003-01-23 16:36:11 +00003134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003135 if (! PyDateTime_Check(dt)) {
3136 PyErr_SetString(PyExc_TypeError,
3137 "fromutc: argument must be a datetime");
3138 return NULL;
3139 }
3140 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3141 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3142 "is not self");
3143 return NULL;
3144 }
Tim Peters52dcce22003-01-23 16:36:11 +00003145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003146 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
3147 if (off == -1 && PyErr_Occurred())
3148 return NULL;
3149 if (none) {
3150 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3151 "utcoffset() result required");
3152 return NULL;
3153 }
Tim Peters52dcce22003-01-23 16:36:11 +00003154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003155 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
3156 if (dst == -1 && PyErr_Occurred())
3157 return NULL;
3158 if (none) {
3159 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3160 "dst() result required");
3161 return NULL;
3162 }
Tim Peters52dcce22003-01-23 16:36:11 +00003163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003164 y = GET_YEAR(dt);
3165 m = GET_MONTH(dt);
3166 d = GET_DAY(dt);
3167 hh = DATE_GET_HOUR(dt);
3168 mm = DATE_GET_MINUTE(dt);
3169 ss = DATE_GET_SECOND(dt);
3170 us = DATE_GET_MICROSECOND(dt);
Tim Peters52dcce22003-01-23 16:36:11 +00003171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 delta = off - dst;
3173 mm += delta;
3174 if ((mm < 0 || mm >= 60) &&
3175 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
3176 return NULL;
3177 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
3178 if (result == NULL)
3179 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003181 dst = call_dst(dt->tzinfo, result, &none);
3182 if (dst == -1 && PyErr_Occurred())
3183 goto Fail;
3184 if (none)
3185 goto Inconsistent;
3186 if (dst == 0)
3187 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003189 mm += dst;
3190 if ((mm < 0 || mm >= 60) &&
3191 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
3192 goto Fail;
3193 Py_DECREF(result);
3194 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
3195 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003196
3197Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3199 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003201 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003202Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003203 Py_DECREF(result);
3204 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003205}
3206
Tim Peters2a799bf2002-12-16 20:18:38 +00003207/*
3208 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003209 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003210 */
3211
Guido van Rossum177e41a2003-01-30 22:06:23 +00003212static PyObject *
3213tzinfo_reduce(PyObject *self)
3214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 PyObject *args, *state, *tmp;
3216 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003218 tmp = PyTuple_New(0);
3219 if (tmp == NULL)
3220 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003222 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3223 if (getinitargs != NULL) {
3224 args = PyObject_CallObject(getinitargs, tmp);
3225 Py_DECREF(getinitargs);
3226 if (args == NULL) {
3227 Py_DECREF(tmp);
3228 return NULL;
3229 }
3230 }
3231 else {
3232 PyErr_Clear();
3233 args = tmp;
3234 Py_INCREF(args);
3235 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003237 getstate = PyObject_GetAttrString(self, "__getstate__");
3238 if (getstate != NULL) {
3239 state = PyObject_CallObject(getstate, tmp);
3240 Py_DECREF(getstate);
3241 if (state == NULL) {
3242 Py_DECREF(args);
3243 Py_DECREF(tmp);
3244 return NULL;
3245 }
3246 }
3247 else {
3248 PyObject **dictptr;
3249 PyErr_Clear();
3250 state = Py_None;
3251 dictptr = _PyObject_GetDictPtr(self);
3252 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3253 state = *dictptr;
3254 Py_INCREF(state);
3255 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003257 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003259 if (state == Py_None) {
3260 Py_DECREF(state);
3261 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3262 }
3263 else
3264 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003265}
Tim Peters2a799bf2002-12-16 20:18:38 +00003266
3267static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003269 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3270 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003272 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003273 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3274 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003276 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3277 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003279 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Benjamin Petersond7c3ed52010-06-27 22:32:30 +00003280 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3281 "values indicating West of UTC")},
Tim Peters52dcce22003-01-23 16:36:11 +00003282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003283 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3284 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003286 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003287};
3288
3289static char tzinfo_doc[] =
3290PyDoc_STR("Abstract base class for time zone info objects.");
3291
Neal Norwitz227b5332006-03-22 09:28:35 +00003292static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003293 PyVarObject_HEAD_INIT(NULL, 0)
3294 "datetime.tzinfo", /* tp_name */
3295 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3296 0, /* tp_itemsize */
3297 0, /* tp_dealloc */
3298 0, /* tp_print */
3299 0, /* tp_getattr */
3300 0, /* tp_setattr */
3301 0, /* tp_reserved */
3302 0, /* tp_repr */
3303 0, /* tp_as_number */
3304 0, /* tp_as_sequence */
3305 0, /* tp_as_mapping */
3306 0, /* tp_hash */
3307 0, /* tp_call */
3308 0, /* tp_str */
3309 PyObject_GenericGetAttr, /* tp_getattro */
3310 0, /* tp_setattro */
3311 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003312 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003313 tzinfo_doc, /* tp_doc */
3314 0, /* tp_traverse */
3315 0, /* tp_clear */
3316 0, /* tp_richcompare */
3317 0, /* tp_weaklistoffset */
3318 0, /* tp_iter */
3319 0, /* tp_iternext */
3320 tzinfo_methods, /* tp_methods */
3321 0, /* tp_members */
3322 0, /* tp_getset */
3323 0, /* tp_base */
3324 0, /* tp_dict */
3325 0, /* tp_descr_get */
3326 0, /* tp_descr_set */
3327 0, /* tp_dictoffset */
3328 0, /* tp_init */
3329 0, /* tp_alloc */
3330 PyType_GenericNew, /* tp_new */
3331 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003332};
3333
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003334static char *timezone_kws[] = {"offset", "name", NULL};
3335
3336static PyObject *
3337timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3338{
3339 PyObject *offset;
3340 PyObject *name = NULL;
3341 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3342 &PyDateTime_DeltaType, &offset,
3343 &PyUnicode_Type, &name))
3344 return new_timezone(offset, name);
3345
3346 return NULL;
3347}
3348
3349static void
3350timezone_dealloc(PyDateTime_TimeZone *self)
3351{
3352 Py_CLEAR(self->offset);
3353 Py_CLEAR(self->name);
3354 Py_TYPE(self)->tp_free((PyObject *)self);
3355}
3356
3357static PyObject *
3358timezone_richcompare(PyDateTime_TimeZone *self,
3359 PyDateTime_TimeZone *other, int op)
3360{
3361 if (op != Py_EQ && op != Py_NE) {
3362 Py_INCREF(Py_NotImplemented);
3363 return Py_NotImplemented;
3364 }
3365 return delta_richcompare(self->offset, other->offset, op);
3366}
3367
3368static long
3369timezone_hash(PyDateTime_TimeZone *self)
3370{
3371 return delta_hash((PyDateTime_Delta *)self->offset);
3372}
3373
3374/* Check argument type passed to tzname, utcoffset, or dst methods.
3375 Returns 0 for good argument. Returns -1 and sets exception info
3376 otherwise.
3377 */
3378static int
3379_timezone_check_argument(PyObject *dt, const char *meth)
3380{
3381 if (dt == Py_None || PyDateTime_Check(dt))
3382 return 0;
3383 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3384 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3385 return -1;
3386}
3387
3388static PyObject *
3389timezone_str(PyDateTime_TimeZone *self)
3390{
3391 char buf[10];
3392 int hours, minutes, seconds;
3393 PyObject *offset;
3394 char sign;
3395
3396 if (self->name != NULL) {
3397 Py_INCREF(self->name);
3398 return self->name;
3399 }
3400 /* Offset is normalized, so it is negative if days < 0 */
3401 if (GET_TD_DAYS(self->offset) < 0) {
3402 sign = '-';
3403 offset = delta_negative((PyDateTime_Delta *)self->offset);
3404 if (offset == NULL)
3405 return NULL;
3406 }
3407 else {
3408 sign = '+';
3409 offset = self->offset;
3410 Py_INCREF(offset);
3411 }
3412 /* Offset is not negative here. */
3413 seconds = GET_TD_SECONDS(offset);
3414 Py_DECREF(offset);
3415 minutes = divmod(seconds, 60, &seconds);
3416 hours = divmod(minutes, 60, &minutes);
3417 assert(seconds == 0);
3418 /* XXX ignore sub-minute data, curently not allowed. */
3419 PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes);
3420
3421 return PyUnicode_FromString(buf);
3422}
3423
3424static PyObject *
3425timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3426{
3427 if (_timezone_check_argument(dt, "tzname") == -1)
3428 return NULL;
3429
3430 return timezone_str(self);
3431}
3432
3433static PyObject *
3434timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3435{
3436 if (_timezone_check_argument(dt, "utcoffset") == -1)
3437 return NULL;
3438
3439 Py_INCREF(self->offset);
3440 return self->offset;
3441}
3442
3443static PyObject *
3444timezone_dst(PyObject *self, PyObject *dt)
3445{
3446 if (_timezone_check_argument(dt, "dst") == -1)
3447 return NULL;
3448
3449 Py_RETURN_NONE;
3450}
3451
3452static PyObject *
3453add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3454 int factor);
3455
3456static PyObject *
3457timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3458{
3459 if (! PyDateTime_Check(dt)) {
3460 PyErr_SetString(PyExc_TypeError,
3461 "fromutc: argument must be a datetime");
3462 return NULL;
3463 }
3464 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3465 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3466 "is not self");
3467 return NULL;
3468 }
3469
3470 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3471}
3472
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003473static PyObject *
3474timezone_getinitargs(PyDateTime_TimeZone *self)
3475{
3476 if (self->name == NULL)
3477 return Py_BuildValue("(O)", self->offset);
3478 return Py_BuildValue("(OO)", self->offset, self->name);
3479}
3480
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003481static PyMethodDef timezone_methods[] = {
3482 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3483 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003484 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003485
3486 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003487 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003488
3489 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003490 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003491
3492 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3493 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3494
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003495 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3496 PyDoc_STR("pickle support")},
3497
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003498 {NULL, NULL}
3499};
3500
3501static char timezone_doc[] =
3502PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3503
3504static PyTypeObject PyDateTime_TimeZoneType = {
3505 PyVarObject_HEAD_INIT(NULL, 0)
3506 "datetime.timezone", /* tp_name */
3507 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3508 0, /* tp_itemsize */
3509 (destructor)timezone_dealloc, /* tp_dealloc */
3510 0, /* tp_print */
3511 0, /* tp_getattr */
3512 0, /* tp_setattr */
3513 0, /* tp_reserved */
3514 0, /* tp_repr */
3515 0, /* tp_as_number */
3516 0, /* tp_as_sequence */
3517 0, /* tp_as_mapping */
3518 (hashfunc)timezone_hash, /* tp_hash */
3519 0, /* tp_call */
3520 (reprfunc)timezone_str, /* tp_str */
3521 0, /* tp_getattro */
3522 0, /* tp_setattro */
3523 0, /* tp_as_buffer */
3524 Py_TPFLAGS_DEFAULT, /* tp_flags */
3525 timezone_doc, /* tp_doc */
3526 0, /* tp_traverse */
3527 0, /* tp_clear */
3528 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3529 0, /* tp_weaklistoffset */
3530 0, /* tp_iter */
3531 0, /* tp_iternext */
3532 timezone_methods, /* tp_methods */
3533 0, /* tp_members */
3534 0, /* tp_getset */
3535 &PyDateTime_TZInfoType, /* tp_base */
3536 0, /* tp_dict */
3537 0, /* tp_descr_get */
3538 0, /* tp_descr_set */
3539 0, /* tp_dictoffset */
3540 0, /* tp_init */
3541 0, /* tp_alloc */
3542 timezone_new, /* tp_new */
3543};
3544
Tim Peters2a799bf2002-12-16 20:18:38 +00003545/*
Tim Peters37f39822003-01-10 03:49:02 +00003546 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003547 */
3548
Tim Peters37f39822003-01-10 03:49:02 +00003549/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003550 */
3551
3552static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003553time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003554{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003555 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003556}
3557
Tim Peters37f39822003-01-10 03:49:02 +00003558static PyObject *
3559time_minute(PyDateTime_Time *self, void *unused)
3560{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003561 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003562}
3563
3564/* The name time_second conflicted with some platform header file. */
3565static PyObject *
3566py_time_second(PyDateTime_Time *self, void *unused)
3567{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003569}
3570
3571static PyObject *
3572time_microsecond(PyDateTime_Time *self, void *unused)
3573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003574 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003575}
3576
3577static PyObject *
3578time_tzinfo(PyDateTime_Time *self, void *unused)
3579{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003580 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3581 Py_INCREF(result);
3582 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003583}
3584
3585static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003586 {"hour", (getter)time_hour},
3587 {"minute", (getter)time_minute},
3588 {"second", (getter)py_time_second},
3589 {"microsecond", (getter)time_microsecond},
3590 {"tzinfo", (getter)time_tzinfo},
3591 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003592};
3593
3594/*
3595 * Constructors.
3596 */
3597
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003598static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003599 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003600
Tim Peters2a799bf2002-12-16 20:18:38 +00003601static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003602time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003603{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003604 PyObject *self = NULL;
3605 PyObject *state;
3606 int hour = 0;
3607 int minute = 0;
3608 int second = 0;
3609 int usecond = 0;
3610 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003611
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003612 /* Check for invocation from pickle with __getstate__ state */
3613 if (PyTuple_GET_SIZE(args) >= 1 &&
3614 PyTuple_GET_SIZE(args) <= 2 &&
3615 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3616 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3617 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3618 {
3619 PyDateTime_Time *me;
3620 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003622 if (PyTuple_GET_SIZE(args) == 2) {
3623 tzinfo = PyTuple_GET_ITEM(args, 1);
3624 if (check_tzinfo_subclass(tzinfo) < 0) {
3625 PyErr_SetString(PyExc_TypeError, "bad "
3626 "tzinfo state arg");
3627 return NULL;
3628 }
3629 }
3630 aware = (char)(tzinfo != Py_None);
3631 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3632 if (me != NULL) {
3633 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003635 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3636 me->hashcode = -1;
3637 me->hastzinfo = aware;
3638 if (aware) {
3639 Py_INCREF(tzinfo);
3640 me->tzinfo = tzinfo;
3641 }
3642 }
3643 return (PyObject *)me;
3644 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003646 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3647 &hour, &minute, &second, &usecond,
3648 &tzinfo)) {
3649 if (check_time_args(hour, minute, second, usecond) < 0)
3650 return NULL;
3651 if (check_tzinfo_subclass(tzinfo) < 0)
3652 return NULL;
3653 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3654 type);
3655 }
3656 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003657}
3658
3659/*
3660 * Destructor.
3661 */
3662
3663static void
Tim Peters37f39822003-01-10 03:49:02 +00003664time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003665{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003666 if (HASTZINFO(self)) {
3667 Py_XDECREF(self->tzinfo);
3668 }
3669 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003670}
3671
3672/*
Tim Peters855fe882002-12-22 03:43:39 +00003673 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003674 */
3675
Tim Peters2a799bf2002-12-16 20:18:38 +00003676/* These are all METH_NOARGS, so don't need to check the arglist. */
3677static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003678time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003679 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3680 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003681}
3682
3683static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003684time_dst(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003685 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3686 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003687}
3688
3689static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003690time_tzname(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003691 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3692 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003693}
3694
3695/*
Tim Peters37f39822003-01-10 03:49:02 +00003696 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003697 */
3698
3699static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003700time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003701{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003702 const char *type_name = Py_TYPE(self)->tp_name;
3703 int h = TIME_GET_HOUR(self);
3704 int m = TIME_GET_MINUTE(self);
3705 int s = TIME_GET_SECOND(self);
3706 int us = TIME_GET_MICROSECOND(self);
3707 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003709 if (us)
3710 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3711 type_name, h, m, s, us);
3712 else if (s)
3713 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3714 type_name, h, m, s);
3715 else
3716 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3717 if (result != NULL && HASTZINFO(self))
3718 result = append_keyword_tzinfo(result, self->tzinfo);
3719 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003720}
3721
Tim Peters37f39822003-01-10 03:49:02 +00003722static PyObject *
3723time_str(PyDateTime_Time *self)
3724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003725 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003726}
Tim Peters2a799bf2002-12-16 20:18:38 +00003727
3728static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003729time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003731 char buf[100];
3732 PyObject *result;
3733 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003735 if (us)
3736 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3737 TIME_GET_HOUR(self),
3738 TIME_GET_MINUTE(self),
3739 TIME_GET_SECOND(self),
3740 us);
3741 else
3742 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3743 TIME_GET_HOUR(self),
3744 TIME_GET_MINUTE(self),
3745 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003746
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003747 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3748 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003750 /* We need to append the UTC offset. */
3751 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3752 Py_None) < 0) {
3753 Py_DECREF(result);
3754 return NULL;
3755 }
3756 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3757 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003758}
3759
Tim Peters37f39822003-01-10 03:49:02 +00003760static PyObject *
3761time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003763 PyObject *result;
3764 PyObject *tuple;
3765 PyObject *format;
3766 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003768 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3769 &format))
3770 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003772 /* Python's strftime does insane things with the year part of the
3773 * timetuple. The year is forced to (the otherwise nonsensical)
3774 * 1900 to worm around that.
3775 */
3776 tuple = Py_BuildValue("iiiiiiiii",
3777 1900, 1, 1, /* year, month, day */
3778 TIME_GET_HOUR(self),
3779 TIME_GET_MINUTE(self),
3780 TIME_GET_SECOND(self),
3781 0, 1, -1); /* weekday, daynum, dst */
3782 if (tuple == NULL)
3783 return NULL;
3784 assert(PyTuple_Size(tuple) == 9);
3785 result = wrap_strftime((PyObject *)self, format, tuple,
3786 Py_None);
3787 Py_DECREF(tuple);
3788 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003789}
Tim Peters2a799bf2002-12-16 20:18:38 +00003790
3791/*
3792 * Miscellaneous methods.
3793 */
3794
Tim Peters37f39822003-01-10 03:49:02 +00003795static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003796time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003798 int diff;
3799 naivety n1, n2;
3800 int offset1, offset2;
Tim Peters37f39822003-01-10 03:49:02 +00003801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003802 if (! PyTime_Check(other)) {
3803 Py_INCREF(Py_NotImplemented);
3804 return Py_NotImplemented;
3805 }
3806 if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
3807 other, &offset2, &n2, Py_None) < 0)
3808 return NULL;
3809 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3810 /* If they're both naive, or both aware and have the same offsets,
3811 * we get off cheap. Note that if they're both naive, offset1 ==
3812 * offset2 == 0 at this point.
3813 */
3814 if (n1 == n2 && offset1 == offset2) {
3815 diff = memcmp(((PyDateTime_Time *)self)->data,
3816 ((PyDateTime_Time *)other)->data,
3817 _PyDateTime_TIME_DATASIZE);
3818 return diff_to_bool(diff, op);
3819 }
Tim Peters37f39822003-01-10 03:49:02 +00003820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003821 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3822 assert(offset1 != offset2); /* else last "if" handled it */
3823 /* Convert everything except microseconds to seconds. These
3824 * can't overflow (no more than the # of seconds in 2 days).
3825 */
3826 offset1 = TIME_GET_HOUR(self) * 3600 +
3827 (TIME_GET_MINUTE(self) - offset1) * 60 +
3828 TIME_GET_SECOND(self);
3829 offset2 = TIME_GET_HOUR(other) * 3600 +
3830 (TIME_GET_MINUTE(other) - offset2) * 60 +
3831 TIME_GET_SECOND(other);
3832 diff = offset1 - offset2;
3833 if (diff == 0)
3834 diff = TIME_GET_MICROSECOND(self) -
3835 TIME_GET_MICROSECOND(other);
3836 return diff_to_bool(diff, op);
3837 }
Tim Peters37f39822003-01-10 03:49:02 +00003838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003839 assert(n1 != n2);
3840 PyErr_SetString(PyExc_TypeError,
3841 "can't compare offset-naive and "
3842 "offset-aware times");
3843 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003844}
3845
3846static long
3847time_hash(PyDateTime_Time *self)
3848{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003849 if (self->hashcode == -1) {
3850 naivety n;
3851 int offset;
3852 PyObject *temp;
Tim Peters37f39822003-01-10 03:49:02 +00003853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003854 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3855 assert(n != OFFSET_UNKNOWN);
3856 if (n == OFFSET_ERROR)
3857 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003859 /* Reduce this to a hash of another object. */
3860 if (offset == 0) {
3861 self->hashcode = generic_hash(
3862 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3863 return self->hashcode;
3864 }
3865 else {
3866 int hour;
3867 int minute;
Tim Peters37f39822003-01-10 03:49:02 +00003868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003869 assert(n == OFFSET_AWARE);
3870 assert(HASTZINFO(self));
3871 hour = divmod(TIME_GET_HOUR(self) * 60 +
3872 TIME_GET_MINUTE(self) - offset,
3873 60,
3874 &minute);
3875 if (0 <= hour && hour < 24)
3876 temp = new_time(hour, minute,
3877 TIME_GET_SECOND(self),
3878 TIME_GET_MICROSECOND(self),
3879 Py_None);
3880 else
3881 temp = Py_BuildValue("iiii",
3882 hour, minute,
3883 TIME_GET_SECOND(self),
3884 TIME_GET_MICROSECOND(self));
3885 }
3886 if (temp != NULL) {
3887 self->hashcode = PyObject_Hash(temp);
3888 Py_DECREF(temp);
3889 }
3890 }
3891 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003892}
Tim Peters2a799bf2002-12-16 20:18:38 +00003893
Tim Peters12bf3392002-12-24 05:41:27 +00003894static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003895time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003897 PyObject *clone;
3898 PyObject *tuple;
3899 int hh = TIME_GET_HOUR(self);
3900 int mm = TIME_GET_MINUTE(self);
3901 int ss = TIME_GET_SECOND(self);
3902 int us = TIME_GET_MICROSECOND(self);
3903 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003905 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3906 time_kws,
3907 &hh, &mm, &ss, &us, &tzinfo))
3908 return NULL;
3909 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3910 if (tuple == NULL)
3911 return NULL;
3912 clone = time_new(Py_TYPE(self), tuple, NULL);
3913 Py_DECREF(tuple);
3914 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003915}
3916
Tim Peters2a799bf2002-12-16 20:18:38 +00003917static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00003918time_bool(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003919{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003920 int offset;
3921 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00003922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003923 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3924 /* Since utcoffset is in whole minutes, nothing can
3925 * alter the conclusion that this is nonzero.
3926 */
3927 return 1;
3928 }
3929 offset = 0;
3930 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3931 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3932 if (offset == -1 && PyErr_Occurred())
3933 return -1;
3934 }
3935 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003936}
3937
Tim Peters371935f2003-02-01 01:52:50 +00003938/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003939
Tim Peters33e0f382003-01-10 02:05:14 +00003940/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003941 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3942 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003943 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003944 */
3945static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003946time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003948 PyObject *basestate;
3949 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003951 basestate = PyBytes_FromStringAndSize((char *)self->data,
3952 _PyDateTime_TIME_DATASIZE);
3953 if (basestate != NULL) {
3954 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3955 result = PyTuple_Pack(1, basestate);
3956 else
3957 result = PyTuple_Pack(2, basestate, self->tzinfo);
3958 Py_DECREF(basestate);
3959 }
3960 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003961}
3962
3963static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003964time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003965{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003966 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003967}
3968
Tim Peters37f39822003-01-10 03:49:02 +00003969static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003971 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3972 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3973 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003975 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3976 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3979 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003981 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3982 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003984 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3985 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003987 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3988 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003990 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3991 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003993 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3994 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003996 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003997};
3998
Tim Peters37f39822003-01-10 03:49:02 +00003999static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004000PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4001\n\
4002All arguments are optional. tzinfo may be None, or an instance of\n\
4003a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004004
Tim Peters37f39822003-01-10 03:49:02 +00004005static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004006 0, /* nb_add */
4007 0, /* nb_subtract */
4008 0, /* nb_multiply */
4009 0, /* nb_remainder */
4010 0, /* nb_divmod */
4011 0, /* nb_power */
4012 0, /* nb_negative */
4013 0, /* nb_positive */
4014 0, /* nb_absolute */
4015 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004016};
4017
Neal Norwitz227b5332006-03-22 09:28:35 +00004018static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004019 PyVarObject_HEAD_INIT(NULL, 0)
4020 "datetime.time", /* tp_name */
4021 sizeof(PyDateTime_Time), /* tp_basicsize */
4022 0, /* tp_itemsize */
4023 (destructor)time_dealloc, /* tp_dealloc */
4024 0, /* tp_print */
4025 0, /* tp_getattr */
4026 0, /* tp_setattr */
4027 0, /* tp_reserved */
4028 (reprfunc)time_repr, /* tp_repr */
4029 &time_as_number, /* tp_as_number */
4030 0, /* tp_as_sequence */
4031 0, /* tp_as_mapping */
4032 (hashfunc)time_hash, /* tp_hash */
4033 0, /* tp_call */
4034 (reprfunc)time_str, /* tp_str */
4035 PyObject_GenericGetAttr, /* tp_getattro */
4036 0, /* tp_setattro */
4037 0, /* tp_as_buffer */
4038 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4039 time_doc, /* tp_doc */
4040 0, /* tp_traverse */
4041 0, /* tp_clear */
4042 time_richcompare, /* tp_richcompare */
4043 0, /* tp_weaklistoffset */
4044 0, /* tp_iter */
4045 0, /* tp_iternext */
4046 time_methods, /* tp_methods */
4047 0, /* tp_members */
4048 time_getset, /* tp_getset */
4049 0, /* tp_base */
4050 0, /* tp_dict */
4051 0, /* tp_descr_get */
4052 0, /* tp_descr_set */
4053 0, /* tp_dictoffset */
4054 0, /* tp_init */
4055 time_alloc, /* tp_alloc */
4056 time_new, /* tp_new */
4057 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004058};
4059
4060/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004061 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004062 */
4063
Tim Petersa9bc1682003-01-11 03:39:11 +00004064/* Accessor properties. Properties for day, month, and year are inherited
4065 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004066 */
4067
4068static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004069datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004071 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004072}
4073
Tim Petersa9bc1682003-01-11 03:39:11 +00004074static PyObject *
4075datetime_minute(PyDateTime_DateTime *self, void *unused)
4076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004077 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004078}
4079
4080static PyObject *
4081datetime_second(PyDateTime_DateTime *self, void *unused)
4082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004083 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004084}
4085
4086static PyObject *
4087datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4088{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004089 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004090}
4091
4092static PyObject *
4093datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004095 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4096 Py_INCREF(result);
4097 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004098}
4099
4100static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004101 {"hour", (getter)datetime_hour},
4102 {"minute", (getter)datetime_minute},
4103 {"second", (getter)datetime_second},
4104 {"microsecond", (getter)datetime_microsecond},
4105 {"tzinfo", (getter)datetime_tzinfo},
4106 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004107};
4108
4109/*
4110 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004111 */
4112
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004113static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004114 "year", "month", "day", "hour", "minute", "second",
4115 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004116};
4117
Tim Peters2a799bf2002-12-16 20:18:38 +00004118static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004119datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004121 PyObject *self = NULL;
4122 PyObject *state;
4123 int year;
4124 int month;
4125 int day;
4126 int hour = 0;
4127 int minute = 0;
4128 int second = 0;
4129 int usecond = 0;
4130 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004132 /* Check for invocation from pickle with __getstate__ state */
4133 if (PyTuple_GET_SIZE(args) >= 1 &&
4134 PyTuple_GET_SIZE(args) <= 2 &&
4135 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4136 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4137 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4138 {
4139 PyDateTime_DateTime *me;
4140 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004142 if (PyTuple_GET_SIZE(args) == 2) {
4143 tzinfo = PyTuple_GET_ITEM(args, 1);
4144 if (check_tzinfo_subclass(tzinfo) < 0) {
4145 PyErr_SetString(PyExc_TypeError, "bad "
4146 "tzinfo state arg");
4147 return NULL;
4148 }
4149 }
4150 aware = (char)(tzinfo != Py_None);
4151 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4152 if (me != NULL) {
4153 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004155 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4156 me->hashcode = -1;
4157 me->hastzinfo = aware;
4158 if (aware) {
4159 Py_INCREF(tzinfo);
4160 me->tzinfo = tzinfo;
4161 }
4162 }
4163 return (PyObject *)me;
4164 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004166 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4167 &year, &month, &day, &hour, &minute,
4168 &second, &usecond, &tzinfo)) {
4169 if (check_date_args(year, month, day) < 0)
4170 return NULL;
4171 if (check_time_args(hour, minute, second, usecond) < 0)
4172 return NULL;
4173 if (check_tzinfo_subclass(tzinfo) < 0)
4174 return NULL;
4175 self = new_datetime_ex(year, month, day,
4176 hour, minute, second, usecond,
4177 tzinfo, type);
4178 }
4179 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004180}
4181
Tim Petersa9bc1682003-01-11 03:39:11 +00004182/* TM_FUNC is the shared type of localtime() and gmtime(). */
4183typedef struct tm *(*TM_FUNC)(const time_t *timer);
4184
4185/* Internal helper.
4186 * Build datetime from a time_t and a distinct count of microseconds.
4187 * Pass localtime or gmtime for f, to control the interpretation of timet.
4188 */
4189static PyObject *
4190datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 struct tm *tm;
4194 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004196 tm = f(&timet);
4197 if (tm) {
4198 /* The platform localtime/gmtime may insert leap seconds,
4199 * indicated by tm->tm_sec > 59. We don't care about them,
4200 * except to the extent that passing them on to the datetime
4201 * constructor would raise ValueError for a reason that
4202 * made no sense to the user.
4203 */
4204 if (tm->tm_sec > 59)
4205 tm->tm_sec = 59;
4206 result = PyObject_CallFunction(cls, "iiiiiiiO",
4207 tm->tm_year + 1900,
4208 tm->tm_mon + 1,
4209 tm->tm_mday,
4210 tm->tm_hour,
4211 tm->tm_min,
4212 tm->tm_sec,
4213 us,
4214 tzinfo);
4215 }
4216 else
4217 PyErr_SetString(PyExc_ValueError,
4218 "timestamp out of range for "
4219 "platform localtime()/gmtime() function");
4220 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004221}
4222
4223/* Internal helper.
4224 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4225 * to control the interpretation of the timestamp. Since a double doesn't
4226 * have enough bits to cover a datetime's full range of precision, it's
4227 * better to call datetime_from_timet_and_us provided you have a way
4228 * to get that much precision (e.g., C time() isn't good enough).
4229 */
4230static PyObject *
4231datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004234 time_t timet;
4235 double fraction;
4236 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004238 timet = _PyTime_DoubleToTimet(timestamp);
4239 if (timet == (time_t)-1 && PyErr_Occurred())
4240 return NULL;
4241 fraction = timestamp - (double)timet;
4242 us = (int)round_to_long(fraction * 1e6);
4243 if (us < 0) {
4244 /* Truncation towards zero is not what we wanted
4245 for negative numbers (Python's mod semantics) */
4246 timet -= 1;
4247 us += 1000000;
4248 }
4249 /* If timestamp is less than one microsecond smaller than a
4250 * full second, round up. Otherwise, ValueErrors are raised
4251 * for some floats. */
4252 if (us == 1000000) {
4253 timet += 1;
4254 us = 0;
4255 }
4256 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004257}
4258
4259/* Internal helper.
4260 * Build most accurate possible datetime for current time. Pass localtime or
4261 * gmtime for f as appropriate.
4262 */
4263static PyObject *
4264datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4265{
4266#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004267 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00004268
4269#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004270 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00004271#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004272 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00004273#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004274 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4275 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004277#else /* ! HAVE_GETTIMEOFDAY */
4278 /* No flavor of gettimeofday exists on this platform. Python's
4279 * time.time() does a lot of other platform tricks to get the
4280 * best time it can on the platform, and we're not going to do
4281 * better than that (if we could, the better code would belong
4282 * in time.time()!) We're limited by the precision of a double,
4283 * though.
4284 */
4285 PyObject *time;
4286 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00004287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004288 time = time_time();
4289 if (time == NULL)
4290 return NULL;
4291 dtime = PyFloat_AsDouble(time);
4292 Py_DECREF(time);
4293 if (dtime == -1.0 && PyErr_Occurred())
4294 return NULL;
4295 return datetime_from_timestamp(cls, f, dtime, tzinfo);
4296#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00004297}
4298
Tim Peters2a799bf2002-12-16 20:18:38 +00004299/* Return best possible local time -- this isn't constrained by the
4300 * precision of a timestamp.
4301 */
4302static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004303datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004305 PyObject *self;
4306 PyObject *tzinfo = Py_None;
4307 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004309 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4310 &tzinfo))
4311 return NULL;
4312 if (check_tzinfo_subclass(tzinfo) < 0)
4313 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004315 self = datetime_best_possible(cls,
4316 tzinfo == Py_None ? localtime : gmtime,
4317 tzinfo);
4318 if (self != NULL && tzinfo != Py_None) {
4319 /* Convert UTC to tzinfo's zone. */
4320 PyObject *temp = self;
4321 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4322 Py_DECREF(temp);
4323 }
4324 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004325}
4326
Tim Petersa9bc1682003-01-11 03:39:11 +00004327/* Return best possible UTC time -- this isn't constrained by the
4328 * precision of a timestamp.
4329 */
4330static PyObject *
4331datetime_utcnow(PyObject *cls, PyObject *dummy)
4332{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004333 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004334}
4335
Tim Peters2a799bf2002-12-16 20:18:38 +00004336/* Return new local datetime from timestamp (Python timestamp -- a double). */
4337static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004338datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004339{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004340 PyObject *self;
4341 double timestamp;
4342 PyObject *tzinfo = Py_None;
4343 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004345 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4346 keywords, &timestamp, &tzinfo))
4347 return NULL;
4348 if (check_tzinfo_subclass(tzinfo) < 0)
4349 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004351 self = datetime_from_timestamp(cls,
4352 tzinfo == Py_None ? localtime : gmtime,
4353 timestamp,
4354 tzinfo);
4355 if (self != NULL && tzinfo != Py_None) {
4356 /* Convert UTC to tzinfo's zone. */
4357 PyObject *temp = self;
4358 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4359 Py_DECREF(temp);
4360 }
4361 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004362}
4363
Tim Petersa9bc1682003-01-11 03:39:11 +00004364/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4365static PyObject *
4366datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004368 double timestamp;
4369 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004371 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4372 result = datetime_from_timestamp(cls, gmtime, timestamp,
4373 Py_None);
4374 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004375}
4376
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004377/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004378static PyObject *
4379datetime_strptime(PyObject *cls, PyObject *args)
4380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004381 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004382 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4385 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004386
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004387 if (module == NULL) {
4388 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004389 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004390 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004391 }
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004392 return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4393 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004394}
4395
Tim Petersa9bc1682003-01-11 03:39:11 +00004396/* Return new datetime from date/datetime and time arguments. */
4397static PyObject *
4398datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004400 static char *keywords[] = {"date", "time", NULL};
4401 PyObject *date;
4402 PyObject *time;
4403 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004405 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4406 &PyDateTime_DateType, &date,
4407 &PyDateTime_TimeType, &time)) {
4408 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004410 if (HASTZINFO(time))
4411 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4412 result = PyObject_CallFunction(cls, "iiiiiiiO",
4413 GET_YEAR(date),
4414 GET_MONTH(date),
4415 GET_DAY(date),
4416 TIME_GET_HOUR(time),
4417 TIME_GET_MINUTE(time),
4418 TIME_GET_SECOND(time),
4419 TIME_GET_MICROSECOND(time),
4420 tzinfo);
4421 }
4422 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004423}
Tim Peters2a799bf2002-12-16 20:18:38 +00004424
4425/*
4426 * Destructor.
4427 */
4428
4429static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004430datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004432 if (HASTZINFO(self)) {
4433 Py_XDECREF(self->tzinfo);
4434 }
4435 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004436}
4437
4438/*
4439 * Indirect access to tzinfo methods.
4440 */
4441
Tim Peters2a799bf2002-12-16 20:18:38 +00004442/* These are all METH_NOARGS, so don't need to check the arglist. */
4443static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004444datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004445 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4446 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004447}
4448
4449static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004450datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004451 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4452 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004453}
4454
4455static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004456datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004457 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4458 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004459}
4460
4461/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004462 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004463 */
4464
Tim Petersa9bc1682003-01-11 03:39:11 +00004465/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4466 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004467 */
4468static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004469add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004470 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004471{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004472 /* Note that the C-level additions can't overflow, because of
4473 * invariant bounds on the member values.
4474 */
4475 int year = GET_YEAR(date);
4476 int month = GET_MONTH(date);
4477 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4478 int hour = DATE_GET_HOUR(date);
4479 int minute = DATE_GET_MINUTE(date);
4480 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4481 int microsecond = DATE_GET_MICROSECOND(date) +
4482 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004484 assert(factor == 1 || factor == -1);
4485 if (normalize_datetime(&year, &month, &day,
4486 &hour, &minute, &second, &microsecond) < 0)
4487 return NULL;
4488 else
4489 return new_datetime(year, month, day,
4490 hour, minute, second, microsecond,
4491 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004492}
4493
4494static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004495datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004496{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004497 if (PyDateTime_Check(left)) {
4498 /* datetime + ??? */
4499 if (PyDelta_Check(right))
4500 /* datetime + delta */
4501 return add_datetime_timedelta(
4502 (PyDateTime_DateTime *)left,
4503 (PyDateTime_Delta *)right,
4504 1);
4505 }
4506 else if (PyDelta_Check(left)) {
4507 /* delta + datetime */
4508 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4509 (PyDateTime_Delta *) left,
4510 1);
4511 }
4512 Py_INCREF(Py_NotImplemented);
4513 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004514}
4515
4516static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004517datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004519 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004521 if (PyDateTime_Check(left)) {
4522 /* datetime - ??? */
4523 if (PyDateTime_Check(right)) {
4524 /* datetime - datetime */
4525 naivety n1, n2;
4526 int offset1, offset2;
4527 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004529 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4530 right, &offset2, &n2,
4531 right) < 0)
4532 return NULL;
4533 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4534 if (n1 != n2) {
4535 PyErr_SetString(PyExc_TypeError,
4536 "can't subtract offset-naive and "
4537 "offset-aware datetimes");
4538 return NULL;
4539 }
4540 delta_d = ymd_to_ord(GET_YEAR(left),
4541 GET_MONTH(left),
4542 GET_DAY(left)) -
4543 ymd_to_ord(GET_YEAR(right),
4544 GET_MONTH(right),
4545 GET_DAY(right));
4546 /* These can't overflow, since the values are
4547 * normalized. At most this gives the number of
4548 * seconds in one day.
4549 */
4550 delta_s = (DATE_GET_HOUR(left) -
4551 DATE_GET_HOUR(right)) * 3600 +
4552 (DATE_GET_MINUTE(left) -
4553 DATE_GET_MINUTE(right)) * 60 +
4554 (DATE_GET_SECOND(left) -
4555 DATE_GET_SECOND(right));
4556 delta_us = DATE_GET_MICROSECOND(left) -
4557 DATE_GET_MICROSECOND(right);
4558 /* (left - offset1) - (right - offset2) =
4559 * (left - right) + (offset2 - offset1)
4560 */
4561 delta_s += (offset2 - offset1) * 60;
4562 result = new_delta(delta_d, delta_s, delta_us, 1);
4563 }
4564 else if (PyDelta_Check(right)) {
4565 /* datetime - delta */
4566 result = add_datetime_timedelta(
4567 (PyDateTime_DateTime *)left,
4568 (PyDateTime_Delta *)right,
4569 -1);
4570 }
4571 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 if (result == Py_NotImplemented)
4574 Py_INCREF(result);
4575 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004576}
4577
4578/* Various ways to turn a datetime into a string. */
4579
4580static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004581datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004583 const char *type_name = Py_TYPE(self)->tp_name;
4584 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004586 if (DATE_GET_MICROSECOND(self)) {
4587 baserepr = PyUnicode_FromFormat(
4588 "%s(%d, %d, %d, %d, %d, %d, %d)",
4589 type_name,
4590 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4591 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4592 DATE_GET_SECOND(self),
4593 DATE_GET_MICROSECOND(self));
4594 }
4595 else if (DATE_GET_SECOND(self)) {
4596 baserepr = PyUnicode_FromFormat(
4597 "%s(%d, %d, %d, %d, %d, %d)",
4598 type_name,
4599 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4600 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4601 DATE_GET_SECOND(self));
4602 }
4603 else {
4604 baserepr = PyUnicode_FromFormat(
4605 "%s(%d, %d, %d, %d, %d)",
4606 type_name,
4607 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4608 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4609 }
4610 if (baserepr == NULL || ! HASTZINFO(self))
4611 return baserepr;
4612 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004613}
4614
Tim Petersa9bc1682003-01-11 03:39:11 +00004615static PyObject *
4616datetime_str(PyDateTime_DateTime *self)
4617{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004618 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004619}
Tim Peters2a799bf2002-12-16 20:18:38 +00004620
4621static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004622datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004624 int sep = 'T';
4625 static char *keywords[] = {"sep", NULL};
4626 char buffer[100];
4627 PyObject *result;
4628 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004630 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4631 return NULL;
4632 if (us)
4633 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4634 GET_YEAR(self), GET_MONTH(self),
4635 GET_DAY(self), (int)sep,
4636 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4637 DATE_GET_SECOND(self), us);
4638 else
4639 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4640 GET_YEAR(self), GET_MONTH(self),
4641 GET_DAY(self), (int)sep,
4642 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4643 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004645 if (!result || !HASTZINFO(self))
4646 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004648 /* We need to append the UTC offset. */
4649 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4650 (PyObject *)self) < 0) {
4651 Py_DECREF(result);
4652 return NULL;
4653 }
4654 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4655 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004656}
4657
Tim Petersa9bc1682003-01-11 03:39:11 +00004658static PyObject *
4659datetime_ctime(PyDateTime_DateTime *self)
4660{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004661 return format_ctime((PyDateTime_Date *)self,
4662 DATE_GET_HOUR(self),
4663 DATE_GET_MINUTE(self),
4664 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004665}
4666
Tim Peters2a799bf2002-12-16 20:18:38 +00004667/* Miscellaneous methods. */
4668
Tim Petersa9bc1682003-01-11 03:39:11 +00004669static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004670datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004671{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004672 int diff;
4673 naivety n1, n2;
4674 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004676 if (! PyDateTime_Check(other)) {
4677 if (PyDate_Check(other)) {
4678 /* Prevent invocation of date_richcompare. We want to
4679 return NotImplemented here to give the other object
4680 a chance. But since DateTime is a subclass of
4681 Date, if the other object is a Date, it would
4682 compute an ordering based on the date part alone,
4683 and we don't want that. So force unequal or
4684 uncomparable here in that case. */
4685 if (op == Py_EQ)
4686 Py_RETURN_FALSE;
4687 if (op == Py_NE)
4688 Py_RETURN_TRUE;
4689 return cmperror(self, other);
4690 }
4691 Py_INCREF(Py_NotImplemented);
4692 return Py_NotImplemented;
4693 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004695 if (classify_two_utcoffsets(self, &offset1, &n1, self,
4696 other, &offset2, &n2, other) < 0)
4697 return NULL;
4698 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4699 /* If they're both naive, or both aware and have the same offsets,
4700 * we get off cheap. Note that if they're both naive, offset1 ==
4701 * offset2 == 0 at this point.
4702 */
4703 if (n1 == n2 && offset1 == offset2) {
4704 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4705 ((PyDateTime_DateTime *)other)->data,
4706 _PyDateTime_DATETIME_DATASIZE);
4707 return diff_to_bool(diff, op);
4708 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004710 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4711 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004713 assert(offset1 != offset2); /* else last "if" handled it */
4714 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4715 other);
4716 if (delta == NULL)
4717 return NULL;
4718 diff = GET_TD_DAYS(delta);
4719 if (diff == 0)
4720 diff = GET_TD_SECONDS(delta) |
4721 GET_TD_MICROSECONDS(delta);
4722 Py_DECREF(delta);
4723 return diff_to_bool(diff, op);
4724 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004726 assert(n1 != n2);
4727 PyErr_SetString(PyExc_TypeError,
4728 "can't compare offset-naive and "
4729 "offset-aware datetimes");
4730 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004731}
4732
4733static long
4734datetime_hash(PyDateTime_DateTime *self)
4735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004736 if (self->hashcode == -1) {
4737 naivety n;
4738 int offset;
4739 PyObject *temp;
Tim Petersa9bc1682003-01-11 03:39:11 +00004740
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004741 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4742 &offset);
4743 assert(n != OFFSET_UNKNOWN);
4744 if (n == OFFSET_ERROR)
4745 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004746
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004747 /* Reduce this to a hash of another object. */
4748 if (n == OFFSET_NAIVE) {
4749 self->hashcode = generic_hash(
4750 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
4751 return self->hashcode;
4752 }
4753 else {
4754 int days;
4755 int seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004757 assert(n == OFFSET_AWARE);
4758 assert(HASTZINFO(self));
4759 days = ymd_to_ord(GET_YEAR(self),
4760 GET_MONTH(self),
4761 GET_DAY(self));
4762 seconds = DATE_GET_HOUR(self) * 3600 +
4763 (DATE_GET_MINUTE(self) - offset) * 60 +
4764 DATE_GET_SECOND(self);
4765 temp = new_delta(days,
4766 seconds,
4767 DATE_GET_MICROSECOND(self),
4768 1);
4769 }
4770 if (temp != NULL) {
4771 self->hashcode = PyObject_Hash(temp);
4772 Py_DECREF(temp);
4773 }
4774 }
4775 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004776}
Tim Peters2a799bf2002-12-16 20:18:38 +00004777
4778static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004779datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004780{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004781 PyObject *clone;
4782 PyObject *tuple;
4783 int y = GET_YEAR(self);
4784 int m = GET_MONTH(self);
4785 int d = GET_DAY(self);
4786 int hh = DATE_GET_HOUR(self);
4787 int mm = DATE_GET_MINUTE(self);
4788 int ss = DATE_GET_SECOND(self);
4789 int us = DATE_GET_MICROSECOND(self);
4790 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004792 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4793 datetime_kws,
4794 &y, &m, &d, &hh, &mm, &ss, &us,
4795 &tzinfo))
4796 return NULL;
4797 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4798 if (tuple == NULL)
4799 return NULL;
4800 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4801 Py_DECREF(tuple);
4802 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004803}
4804
4805static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004806datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004807{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004808 int y, m, d, hh, mm, ss, us;
4809 PyObject *result;
4810 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004812 PyObject *tzinfo;
4813 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004815 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4816 &PyDateTime_TZInfoType, &tzinfo))
4817 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004819 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4820 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004822 /* Conversion to self's own time zone is a NOP. */
4823 if (self->tzinfo == tzinfo) {
4824 Py_INCREF(self);
4825 return (PyObject *)self;
4826 }
Tim Peters521fc152002-12-31 17:36:56 +00004827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004828 /* Convert self to UTC. */
4829 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4830 if (offset == -1 && PyErr_Occurred())
4831 return NULL;
4832 if (none)
4833 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004835 y = GET_YEAR(self);
4836 m = GET_MONTH(self);
4837 d = GET_DAY(self);
4838 hh = DATE_GET_HOUR(self);
4839 mm = DATE_GET_MINUTE(self);
4840 ss = DATE_GET_SECOND(self);
4841 us = DATE_GET_MICROSECOND(self);
Tim Peters52dcce22003-01-23 16:36:11 +00004842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004843 mm -= offset;
4844 if ((mm < 0 || mm >= 60) &&
4845 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4846 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004847
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004848 /* Attach new tzinfo and let fromutc() do the rest. */
4849 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4850 if (result != NULL) {
4851 PyObject *temp = result;
Tim Peters52dcce22003-01-23 16:36:11 +00004852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004853 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4854 Py_DECREF(temp);
4855 }
4856 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004857
Tim Peters52dcce22003-01-23 16:36:11 +00004858NeedAware:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004859 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4860 "a naive datetime");
4861 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004862}
4863
4864static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004865datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004866{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004867 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004869 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4870 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004872 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4873 if (dstflag == -1 && PyErr_Occurred())
4874 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004876 if (none)
4877 dstflag = -1;
4878 else if (dstflag != 0)
4879 dstflag = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004881 }
4882 return build_struct_time(GET_YEAR(self),
4883 GET_MONTH(self),
4884 GET_DAY(self),
4885 DATE_GET_HOUR(self),
4886 DATE_GET_MINUTE(self),
4887 DATE_GET_SECOND(self),
4888 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004889}
4890
4891static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004892datetime_getdate(PyDateTime_DateTime *self)
4893{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004894 return new_date(GET_YEAR(self),
4895 GET_MONTH(self),
4896 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004897}
4898
4899static PyObject *
4900datetime_gettime(PyDateTime_DateTime *self)
4901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004902 return new_time(DATE_GET_HOUR(self),
4903 DATE_GET_MINUTE(self),
4904 DATE_GET_SECOND(self),
4905 DATE_GET_MICROSECOND(self),
4906 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004907}
4908
4909static PyObject *
4910datetime_gettimetz(PyDateTime_DateTime *self)
4911{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004912 return new_time(DATE_GET_HOUR(self),
4913 DATE_GET_MINUTE(self),
4914 DATE_GET_SECOND(self),
4915 DATE_GET_MICROSECOND(self),
4916 HASTZINFO(self) ? self->tzinfo : Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004917}
4918
4919static PyObject *
4920datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004922 int y = GET_YEAR(self);
4923 int m = GET_MONTH(self);
4924 int d = GET_DAY(self);
4925 int hh = DATE_GET_HOUR(self);
4926 int mm = DATE_GET_MINUTE(self);
4927 int ss = DATE_GET_SECOND(self);
4928 int us = 0; /* microseconds are ignored in a timetuple */
4929 int offset = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004931 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4932 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4935 if (offset == -1 && PyErr_Occurred())
4936 return NULL;
4937 }
4938 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4939 * 0 in a UTC timetuple regardless of what dst() says.
4940 */
4941 if (offset) {
4942 /* Subtract offset minutes & normalize. */
4943 int stat;
Tim Peters2a799bf2002-12-16 20:18:38 +00004944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004945 mm -= offset;
4946 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004947 /* OverflowError may be raised in the edge cases. */
4948 if (stat < 0)
4949 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004950 }
4951 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004952}
4953
Tim Peters371935f2003-02-01 01:52:50 +00004954/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004955
Tim Petersa9bc1682003-01-11 03:39:11 +00004956/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004957 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4958 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004959 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004960 */
4961static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004962datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004964 PyObject *basestate;
4965 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004967 basestate = PyBytes_FromStringAndSize((char *)self->data,
4968 _PyDateTime_DATETIME_DATASIZE);
4969 if (basestate != NULL) {
4970 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4971 result = PyTuple_Pack(1, basestate);
4972 else
4973 result = PyTuple_Pack(2, basestate, self->tzinfo);
4974 Py_DECREF(basestate);
4975 }
4976 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004977}
4978
4979static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004980datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004982 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004983}
4984
Tim Petersa9bc1682003-01-11 03:39:11 +00004985static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004987 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004989 {"now", (PyCFunction)datetime_now,
4990 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4991 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004993 {"utcnow", (PyCFunction)datetime_utcnow,
4994 METH_NOARGS | METH_CLASS,
4995 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004997 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4998 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4999 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005001 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5002 METH_VARARGS | METH_CLASS,
5003 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
5004 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005006 {"strptime", (PyCFunction)datetime_strptime,
5007 METH_VARARGS | METH_CLASS,
5008 PyDoc_STR("string, format -> new datetime parsed from a string "
5009 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005011 {"combine", (PyCFunction)datetime_combine,
5012 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5013 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005015 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005017 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5018 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005020 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5021 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005023 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5024 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005026 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5027 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005029 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5030 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005032 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5033 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5036 PyDoc_STR("[sep] -> string in ISO 8601 format, "
5037 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
5038 "sep is used to separate the year from the time, and "
5039 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005041 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5042 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005044 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5045 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005047 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5048 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005050 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5051 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005053 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5054 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005056 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5057 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005059 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005060};
5061
Tim Petersa9bc1682003-01-11 03:39:11 +00005062static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005063PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5064\n\
5065The year, month and day arguments are required. tzinfo may be None, or an\n\
5066instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005067
Tim Petersa9bc1682003-01-11 03:39:11 +00005068static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005069 datetime_add, /* nb_add */
5070 datetime_subtract, /* nb_subtract */
5071 0, /* nb_multiply */
5072 0, /* nb_remainder */
5073 0, /* nb_divmod */
5074 0, /* nb_power */
5075 0, /* nb_negative */
5076 0, /* nb_positive */
5077 0, /* nb_absolute */
5078 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005079};
5080
Neal Norwitz227b5332006-03-22 09:28:35 +00005081static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005082 PyVarObject_HEAD_INIT(NULL, 0)
5083 "datetime.datetime", /* tp_name */
5084 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5085 0, /* tp_itemsize */
5086 (destructor)datetime_dealloc, /* tp_dealloc */
5087 0, /* tp_print */
5088 0, /* tp_getattr */
5089 0, /* tp_setattr */
5090 0, /* tp_reserved */
5091 (reprfunc)datetime_repr, /* tp_repr */
5092 &datetime_as_number, /* tp_as_number */
5093 0, /* tp_as_sequence */
5094 0, /* tp_as_mapping */
5095 (hashfunc)datetime_hash, /* tp_hash */
5096 0, /* tp_call */
5097 (reprfunc)datetime_str, /* tp_str */
5098 PyObject_GenericGetAttr, /* tp_getattro */
5099 0, /* tp_setattro */
5100 0, /* tp_as_buffer */
5101 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5102 datetime_doc, /* tp_doc */
5103 0, /* tp_traverse */
5104 0, /* tp_clear */
5105 datetime_richcompare, /* tp_richcompare */
5106 0, /* tp_weaklistoffset */
5107 0, /* tp_iter */
5108 0, /* tp_iternext */
5109 datetime_methods, /* tp_methods */
5110 0, /* tp_members */
5111 datetime_getset, /* tp_getset */
5112 &PyDateTime_DateType, /* tp_base */
5113 0, /* tp_dict */
5114 0, /* tp_descr_get */
5115 0, /* tp_descr_set */
5116 0, /* tp_dictoffset */
5117 0, /* tp_init */
5118 datetime_alloc, /* tp_alloc */
5119 datetime_new, /* tp_new */
5120 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005121};
5122
5123/* ---------------------------------------------------------------------------
5124 * Module methods and initialization.
5125 */
5126
5127static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005128 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005129};
5130
Tim Peters9ddf40b2004-06-20 22:41:32 +00005131/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5132 * datetime.h.
5133 */
5134static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005135 &PyDateTime_DateType,
5136 &PyDateTime_DateTimeType,
5137 &PyDateTime_TimeType,
5138 &PyDateTime_DeltaType,
5139 &PyDateTime_TZInfoType,
5140 new_date_ex,
5141 new_datetime_ex,
5142 new_time_ex,
5143 new_delta_ex,
5144 datetime_fromtimestamp,
5145 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005146};
5147
5148
Martin v. Löwis1a214512008-06-11 05:26:20 +00005149
5150static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005151 PyModuleDef_HEAD_INIT,
5152 "datetime",
5153 "Fast implementation of the datetime type.",
5154 -1,
5155 module_methods,
5156 NULL,
5157 NULL,
5158 NULL,
5159 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005160};
5161
Tim Peters2a799bf2002-12-16 20:18:38 +00005162PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00005163PyInit_datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005165 PyObject *m; /* a module object */
5166 PyObject *d; /* its dict */
5167 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005168 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005170 m = PyModule_Create(&datetimemodule);
5171 if (m == NULL)
5172 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005174 if (PyType_Ready(&PyDateTime_DateType) < 0)
5175 return NULL;
5176 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5177 return NULL;
5178 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5179 return NULL;
5180 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5181 return NULL;
5182 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5183 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005184 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5185 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005187 /* timedelta values */
5188 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005190 x = new_delta(0, 0, 1, 0);
5191 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5192 return NULL;
5193 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005195 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5196 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5197 return NULL;
5198 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005200 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5201 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5202 return NULL;
5203 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005205 /* date values */
5206 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005208 x = new_date(1, 1, 1);
5209 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5210 return NULL;
5211 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005213 x = new_date(MAXYEAR, 12, 31);
5214 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5215 return NULL;
5216 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005218 x = new_delta(1, 0, 0, 0);
5219 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5220 return NULL;
5221 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005223 /* time values */
5224 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005226 x = new_time(0, 0, 0, 0, Py_None);
5227 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5228 return NULL;
5229 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005231 x = new_time(23, 59, 59, 999999, Py_None);
5232 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5233 return NULL;
5234 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005236 x = new_delta(0, 0, 1, 0);
5237 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5238 return NULL;
5239 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005241 /* datetime values */
5242 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005244 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5245 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5246 return NULL;
5247 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005249 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5250 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5251 return NULL;
5252 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005254 x = new_delta(0, 0, 1, 0);
5255 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5256 return NULL;
5257 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005258
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005259 /* timezone values */
5260 d = PyDateTime_TimeZoneType.tp_dict;
5261
5262 delta = new_delta(0, 0, 0, 0);
5263 if (delta == NULL)
5264 return NULL;
5265 x = new_timezone(delta, NULL);
5266 Py_DECREF(delta);
5267 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5268 return NULL;
5269 Py_DECREF(x);
5270
5271 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5272 if (delta == NULL)
5273 return NULL;
5274 x = new_timezone(delta, NULL);
5275 Py_DECREF(delta);
5276 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5277 return NULL;
5278 Py_DECREF(x);
5279
5280 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5281 if (delta == NULL)
5282 return NULL;
5283 x = new_timezone(delta, NULL);
5284 Py_DECREF(delta);
5285 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5286 return NULL;
5287 Py_DECREF(x);
5288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005289 /* module initialization */
5290 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5291 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005293 Py_INCREF(&PyDateTime_DateType);
5294 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005296 Py_INCREF(&PyDateTime_DateTimeType);
5297 PyModule_AddObject(m, "datetime",
5298 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005300 Py_INCREF(&PyDateTime_TimeType);
5301 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005303 Py_INCREF(&PyDateTime_DeltaType);
5304 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005306 Py_INCREF(&PyDateTime_TZInfoType);
5307 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005308
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005309 Py_INCREF(&PyDateTime_TimeZoneType);
5310 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005312 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5313 if (x == NULL)
5314 return NULL;
5315 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005317 /* A 4-year cycle has an extra leap day over what we'd get from
5318 * pasting together 4 single years.
5319 */
5320 assert(DI4Y == 4 * 365 + 1);
5321 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005323 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5324 * get from pasting together 4 100-year cycles.
5325 */
5326 assert(DI400Y == 4 * DI100Y + 1);
5327 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005329 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5330 * pasting together 25 4-year cycles.
5331 */
5332 assert(DI100Y == 25 * DI4Y - 1);
5333 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005335 us_per_us = PyLong_FromLong(1);
5336 us_per_ms = PyLong_FromLong(1000);
5337 us_per_second = PyLong_FromLong(1000000);
5338 us_per_minute = PyLong_FromLong(60000000);
5339 seconds_per_day = PyLong_FromLong(24 * 3600);
5340 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5341 us_per_minute == NULL || seconds_per_day == NULL)
5342 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005344 /* The rest are too big for 32-bit ints, but even
5345 * us_per_week fits in 40 bits, so doubles should be exact.
5346 */
5347 us_per_hour = PyLong_FromDouble(3600000000.0);
5348 us_per_day = PyLong_FromDouble(86400000000.0);
5349 us_per_week = PyLong_FromDouble(604800000000.0);
5350 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5351 return NULL;
5352 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005353}
Tim Petersf3615152003-01-01 21:51:37 +00005354
5355/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005356Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005357 x.n = x stripped of its timezone -- its naive time.
5358 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005359 return None
Tim Petersf3615152003-01-01 21:51:37 +00005360 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005361 return None
Tim Petersf3615152003-01-01 21:51:37 +00005362 x.s = x's standard offset, x.o - x.d
5363
5364Now some derived rules, where k is a duration (timedelta).
5365
53661. x.o = x.s + x.d
5367 This follows from the definition of x.s.
5368
Tim Petersc5dc4da2003-01-02 17:55:03 +000053692. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005370 This is actually a requirement, an assumption we need to make about
5371 sane tzinfo classes.
5372
53733. The naive UTC time corresponding to x is x.n - x.o.
5374 This is again a requirement for a sane tzinfo class.
5375
53764. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005377 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005378
Tim Petersc5dc4da2003-01-02 17:55:03 +000053795. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005380 Again follows from how arithmetic is defined.
5381
Tim Peters8bb5ad22003-01-24 02:44:45 +00005382Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005383(meaning that the various tzinfo methods exist, and don't blow up or return
5384None when called).
5385
Tim Petersa9bc1682003-01-11 03:39:11 +00005386The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005387x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005388
5389By #3, we want
5390
Tim Peters8bb5ad22003-01-24 02:44:45 +00005391 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005392
5393The algorithm starts by attaching tz to x.n, and calling that y. So
5394x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5395becomes true; in effect, we want to solve [2] for k:
5396
Tim Peters8bb5ad22003-01-24 02:44:45 +00005397 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005398
5399By #1, this is the same as
5400
Tim Peters8bb5ad22003-01-24 02:44:45 +00005401 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005402
5403By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5404Substituting that into [3],
5405
Tim Peters8bb5ad22003-01-24 02:44:45 +00005406 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5407 k - (y+k).s - (y+k).d = 0; rearranging,
5408 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5409 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005410
Tim Peters8bb5ad22003-01-24 02:44:45 +00005411On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5412approximate k by ignoring the (y+k).d term at first. Note that k can't be
5413very large, since all offset-returning methods return a duration of magnitude
5414less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5415be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005416
5417In any case, the new value is
5418
Tim Peters8bb5ad22003-01-24 02:44:45 +00005419 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005420
Tim Peters8bb5ad22003-01-24 02:44:45 +00005421It's helpful to step back at look at [4] from a higher level: it's simply
5422mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005423
5424At this point, if
5425
Tim Peters8bb5ad22003-01-24 02:44:45 +00005426 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005427
5428we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005429at the start of daylight time. Picture US Eastern for concreteness. The wall
5430time 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 +00005431sense then. The docs ask that an Eastern tzinfo class consider such a time to
5432be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5433on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005434the only spelling that makes sense on the local wall clock.
5435
Tim Petersc5dc4da2003-01-02 17:55:03 +00005436In fact, if [5] holds at this point, we do have the standard-time spelling,
5437but that takes a bit of proof. We first prove a stronger result. What's the
5438difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005439
Tim Peters8bb5ad22003-01-24 02:44:45 +00005440 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005441
Tim Petersc5dc4da2003-01-02 17:55:03 +00005442Now
5443 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005444 (y + y.s).n = by #5
5445 y.n + y.s = since y.n = x.n
5446 x.n + y.s = since z and y are have the same tzinfo member,
5447 y.s = z.s by #2
5448 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005449
Tim Petersc5dc4da2003-01-02 17:55:03 +00005450Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005451
Tim Petersc5dc4da2003-01-02 17:55:03 +00005452 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005453 x.n - ((x.n + z.s) - z.o) = expanding
5454 x.n - x.n - z.s + z.o = cancelling
5455 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005456 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005457
Tim Petersc5dc4da2003-01-02 17:55:03 +00005458So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005459
Tim Petersc5dc4da2003-01-02 17:55:03 +00005460If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005461spelling we wanted in the endcase described above. We're done. Contrarily,
5462if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005463
Tim Petersc5dc4da2003-01-02 17:55:03 +00005464If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5465add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005466local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005467
Tim Petersc5dc4da2003-01-02 17:55:03 +00005468Let
Tim Petersf3615152003-01-01 21:51:37 +00005469
Tim Peters4fede1a2003-01-04 00:26:59 +00005470 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005471
Tim Peters4fede1a2003-01-04 00:26:59 +00005472and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005473
Tim Peters8bb5ad22003-01-24 02:44:45 +00005474 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005475
Tim Peters8bb5ad22003-01-24 02:44:45 +00005476If so, we're done. If not, the tzinfo class is insane, according to the
5477assumptions we've made. This also requires a bit of proof. As before, let's
5478compute the difference between the LHS and RHS of [8] (and skipping some of
5479the justifications for the kinds of substitutions we've done several times
5480already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005481
Tim Peters8bb5ad22003-01-24 02:44:45 +00005482 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005483 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5484 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5485 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5486 - z.n + z.n - z.o + z'.o = cancel z.n
5487 - z.o + z'.o = #1 twice
5488 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5489 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005490
5491So 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 +00005492we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5493return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005494
Tim Peters8bb5ad22003-01-24 02:44:45 +00005495How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5496a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5497would have to change the result dst() returns: we start in DST, and moving
5498a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005499
Tim Peters8bb5ad22003-01-24 02:44:45 +00005500There isn't a sane case where this can happen. The closest it gets is at
5501the end of DST, where there's an hour in UTC with no spelling in a hybrid
5502tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5503that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5504UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5505time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5506clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5507standard time. Since that's what the local clock *does*, we want to map both
5508UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005509in local time, but so it goes -- it's the way the local clock works.
5510
Tim Peters8bb5ad22003-01-24 02:44:45 +00005511When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5512so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5513z' = 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 +00005514(correctly) concludes that z' is not UTC-equivalent to x.
5515
5516Because we know z.d said z was in daylight time (else [5] would have held and
5517we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005518and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005519return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5520but the reasoning doesn't depend on the example -- it depends on there being
5521two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005522z' must be in standard time, and is the spelling we want in this case.
5523
5524Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5525concerned (because it takes z' as being in standard time rather than the
5526daylight time we intend here), but returning it gives the real-life "local
5527clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5528tz.
5529
5530When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5531the 1:MM standard time spelling we want.
5532
5533So how can this break? One of the assumptions must be violated. Two
5534possibilities:
5535
55361) [2] effectively says that y.s is invariant across all y belong to a given
5537 time zone. This isn't true if, for political reasons or continental drift,
5538 a region decides to change its base offset from UTC.
5539
55402) There may be versions of "double daylight" time where the tail end of
5541 the analysis gives up a step too early. I haven't thought about that
5542 enough to say.
5543
5544In any case, it's clear that the default fromutc() is strong enough to handle
5545"almost all" time zones: so long as the standard offset is invariant, it
5546doesn't matter if daylight time transition points change from year to year, or
5547if daylight time is skipped in some years; it doesn't matter how large or
5548small dst() may get within its bounds; and it doesn't even matter if some
5549perverse time zone returns a negative dst()). So a breaking case must be
5550pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005551--------------------------------------------------------------------------- */