blob: 71c5cf5d557ba7e4ae95ece4c24eee68c03399d9 [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,
3280 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003282 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3283 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003285 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003286};
3287
3288static char tzinfo_doc[] =
3289PyDoc_STR("Abstract base class for time zone info objects.");
3290
Neal Norwitz227b5332006-03-22 09:28:35 +00003291static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003292 PyVarObject_HEAD_INIT(NULL, 0)
3293 "datetime.tzinfo", /* tp_name */
3294 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3295 0, /* tp_itemsize */
3296 0, /* tp_dealloc */
3297 0, /* tp_print */
3298 0, /* tp_getattr */
3299 0, /* tp_setattr */
3300 0, /* tp_reserved */
3301 0, /* tp_repr */
3302 0, /* tp_as_number */
3303 0, /* tp_as_sequence */
3304 0, /* tp_as_mapping */
3305 0, /* tp_hash */
3306 0, /* tp_call */
3307 0, /* tp_str */
3308 PyObject_GenericGetAttr, /* tp_getattro */
3309 0, /* tp_setattro */
3310 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003311 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003312 tzinfo_doc, /* tp_doc */
3313 0, /* tp_traverse */
3314 0, /* tp_clear */
3315 0, /* tp_richcompare */
3316 0, /* tp_weaklistoffset */
3317 0, /* tp_iter */
3318 0, /* tp_iternext */
3319 tzinfo_methods, /* tp_methods */
3320 0, /* tp_members */
3321 0, /* tp_getset */
3322 0, /* tp_base */
3323 0, /* tp_dict */
3324 0, /* tp_descr_get */
3325 0, /* tp_descr_set */
3326 0, /* tp_dictoffset */
3327 0, /* tp_init */
3328 0, /* tp_alloc */
3329 PyType_GenericNew, /* tp_new */
3330 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003331};
3332
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003333static char *timezone_kws[] = {"offset", "name", NULL};
3334
3335static PyObject *
3336timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3337{
3338 PyObject *offset;
3339 PyObject *name = NULL;
3340 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3341 &PyDateTime_DeltaType, &offset,
3342 &PyUnicode_Type, &name))
3343 return new_timezone(offset, name);
3344
3345 return NULL;
3346}
3347
3348static void
3349timezone_dealloc(PyDateTime_TimeZone *self)
3350{
3351 Py_CLEAR(self->offset);
3352 Py_CLEAR(self->name);
3353 Py_TYPE(self)->tp_free((PyObject *)self);
3354}
3355
3356static PyObject *
3357timezone_richcompare(PyDateTime_TimeZone *self,
3358 PyDateTime_TimeZone *other, int op)
3359{
3360 if (op != Py_EQ && op != Py_NE) {
3361 Py_INCREF(Py_NotImplemented);
3362 return Py_NotImplemented;
3363 }
3364 return delta_richcompare(self->offset, other->offset, op);
3365}
3366
3367static long
3368timezone_hash(PyDateTime_TimeZone *self)
3369{
3370 return delta_hash((PyDateTime_Delta *)self->offset);
3371}
3372
3373/* Check argument type passed to tzname, utcoffset, or dst methods.
3374 Returns 0 for good argument. Returns -1 and sets exception info
3375 otherwise.
3376 */
3377static int
3378_timezone_check_argument(PyObject *dt, const char *meth)
3379{
3380 if (dt == Py_None || PyDateTime_Check(dt))
3381 return 0;
3382 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3383 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3384 return -1;
3385}
3386
3387static PyObject *
3388timezone_str(PyDateTime_TimeZone *self)
3389{
3390 char buf[10];
3391 int hours, minutes, seconds;
3392 PyObject *offset;
3393 char sign;
3394
3395 if (self->name != NULL) {
3396 Py_INCREF(self->name);
3397 return self->name;
3398 }
3399 /* Offset is normalized, so it is negative if days < 0 */
3400 if (GET_TD_DAYS(self->offset) < 0) {
3401 sign = '-';
3402 offset = delta_negative((PyDateTime_Delta *)self->offset);
3403 if (offset == NULL)
3404 return NULL;
3405 }
3406 else {
3407 sign = '+';
3408 offset = self->offset;
3409 Py_INCREF(offset);
3410 }
3411 /* Offset is not negative here. */
3412 seconds = GET_TD_SECONDS(offset);
3413 Py_DECREF(offset);
3414 minutes = divmod(seconds, 60, &seconds);
3415 hours = divmod(minutes, 60, &minutes);
3416 assert(seconds == 0);
3417 /* XXX ignore sub-minute data, curently not allowed. */
3418 PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes);
3419
3420 return PyUnicode_FromString(buf);
3421}
3422
3423static PyObject *
3424timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3425{
3426 if (_timezone_check_argument(dt, "tzname") == -1)
3427 return NULL;
3428
3429 return timezone_str(self);
3430}
3431
3432static PyObject *
3433timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3434{
3435 if (_timezone_check_argument(dt, "utcoffset") == -1)
3436 return NULL;
3437
3438 Py_INCREF(self->offset);
3439 return self->offset;
3440}
3441
3442static PyObject *
3443timezone_dst(PyObject *self, PyObject *dt)
3444{
3445 if (_timezone_check_argument(dt, "dst") == -1)
3446 return NULL;
3447
3448 Py_RETURN_NONE;
3449}
3450
3451static PyObject *
3452add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3453 int factor);
3454
3455static PyObject *
3456timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3457{
3458 if (! PyDateTime_Check(dt)) {
3459 PyErr_SetString(PyExc_TypeError,
3460 "fromutc: argument must be a datetime");
3461 return NULL;
3462 }
3463 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3464 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3465 "is not self");
3466 return NULL;
3467 }
3468
3469 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3470}
3471
3472static PyMethodDef timezone_methods[] = {
3473 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3474 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003475 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003476
3477 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003478 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003479
3480 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003481 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003482
3483 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3484 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3485
3486 {NULL, NULL}
3487};
3488
3489static char timezone_doc[] =
3490PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3491
3492static PyTypeObject PyDateTime_TimeZoneType = {
3493 PyVarObject_HEAD_INIT(NULL, 0)
3494 "datetime.timezone", /* tp_name */
3495 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3496 0, /* tp_itemsize */
3497 (destructor)timezone_dealloc, /* tp_dealloc */
3498 0, /* tp_print */
3499 0, /* tp_getattr */
3500 0, /* tp_setattr */
3501 0, /* tp_reserved */
3502 0, /* tp_repr */
3503 0, /* tp_as_number */
3504 0, /* tp_as_sequence */
3505 0, /* tp_as_mapping */
3506 (hashfunc)timezone_hash, /* tp_hash */
3507 0, /* tp_call */
3508 (reprfunc)timezone_str, /* tp_str */
3509 0, /* tp_getattro */
3510 0, /* tp_setattro */
3511 0, /* tp_as_buffer */
3512 Py_TPFLAGS_DEFAULT, /* tp_flags */
3513 timezone_doc, /* tp_doc */
3514 0, /* tp_traverse */
3515 0, /* tp_clear */
3516 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3517 0, /* tp_weaklistoffset */
3518 0, /* tp_iter */
3519 0, /* tp_iternext */
3520 timezone_methods, /* tp_methods */
3521 0, /* tp_members */
3522 0, /* tp_getset */
3523 &PyDateTime_TZInfoType, /* tp_base */
3524 0, /* tp_dict */
3525 0, /* tp_descr_get */
3526 0, /* tp_descr_set */
3527 0, /* tp_dictoffset */
3528 0, /* tp_init */
3529 0, /* tp_alloc */
3530 timezone_new, /* tp_new */
3531};
3532
Tim Peters2a799bf2002-12-16 20:18:38 +00003533/*
Tim Peters37f39822003-01-10 03:49:02 +00003534 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003535 */
3536
Tim Peters37f39822003-01-10 03:49:02 +00003537/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003538 */
3539
3540static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003541time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003543 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003544}
3545
Tim Peters37f39822003-01-10 03:49:02 +00003546static PyObject *
3547time_minute(PyDateTime_Time *self, void *unused)
3548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003549 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003550}
3551
3552/* The name time_second conflicted with some platform header file. */
3553static PyObject *
3554py_time_second(PyDateTime_Time *self, void *unused)
3555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003556 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003557}
3558
3559static PyObject *
3560time_microsecond(PyDateTime_Time *self, void *unused)
3561{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003562 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003563}
3564
3565static PyObject *
3566time_tzinfo(PyDateTime_Time *self, void *unused)
3567{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003568 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3569 Py_INCREF(result);
3570 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003571}
3572
3573static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003574 {"hour", (getter)time_hour},
3575 {"minute", (getter)time_minute},
3576 {"second", (getter)py_time_second},
3577 {"microsecond", (getter)time_microsecond},
3578 {"tzinfo", (getter)time_tzinfo},
3579 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003580};
3581
3582/*
3583 * Constructors.
3584 */
3585
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003586static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003587 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003588
Tim Peters2a799bf2002-12-16 20:18:38 +00003589static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003590time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003591{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003592 PyObject *self = NULL;
3593 PyObject *state;
3594 int hour = 0;
3595 int minute = 0;
3596 int second = 0;
3597 int usecond = 0;
3598 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003600 /* Check for invocation from pickle with __getstate__ state */
3601 if (PyTuple_GET_SIZE(args) >= 1 &&
3602 PyTuple_GET_SIZE(args) <= 2 &&
3603 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3604 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3605 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3606 {
3607 PyDateTime_Time *me;
3608 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003610 if (PyTuple_GET_SIZE(args) == 2) {
3611 tzinfo = PyTuple_GET_ITEM(args, 1);
3612 if (check_tzinfo_subclass(tzinfo) < 0) {
3613 PyErr_SetString(PyExc_TypeError, "bad "
3614 "tzinfo state arg");
3615 return NULL;
3616 }
3617 }
3618 aware = (char)(tzinfo != Py_None);
3619 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3620 if (me != NULL) {
3621 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003623 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3624 me->hashcode = -1;
3625 me->hastzinfo = aware;
3626 if (aware) {
3627 Py_INCREF(tzinfo);
3628 me->tzinfo = tzinfo;
3629 }
3630 }
3631 return (PyObject *)me;
3632 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003634 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3635 &hour, &minute, &second, &usecond,
3636 &tzinfo)) {
3637 if (check_time_args(hour, minute, second, usecond) < 0)
3638 return NULL;
3639 if (check_tzinfo_subclass(tzinfo) < 0)
3640 return NULL;
3641 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3642 type);
3643 }
3644 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003645}
3646
3647/*
3648 * Destructor.
3649 */
3650
3651static void
Tim Peters37f39822003-01-10 03:49:02 +00003652time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003654 if (HASTZINFO(self)) {
3655 Py_XDECREF(self->tzinfo);
3656 }
3657 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003658}
3659
3660/*
Tim Peters855fe882002-12-22 03:43:39 +00003661 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003662 */
3663
Tim Peters2a799bf2002-12-16 20:18:38 +00003664/* These are all METH_NOARGS, so don't need to check the arglist. */
3665static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003666time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003667 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3668 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003669}
3670
3671static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003672time_dst(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003673 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3674 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003675}
3676
3677static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003678time_tzname(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003679 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3680 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003681}
3682
3683/*
Tim Peters37f39822003-01-10 03:49:02 +00003684 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003685 */
3686
3687static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003688time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003689{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003690 const char *type_name = Py_TYPE(self)->tp_name;
3691 int h = TIME_GET_HOUR(self);
3692 int m = TIME_GET_MINUTE(self);
3693 int s = TIME_GET_SECOND(self);
3694 int us = TIME_GET_MICROSECOND(self);
3695 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003697 if (us)
3698 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3699 type_name, h, m, s, us);
3700 else if (s)
3701 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3702 type_name, h, m, s);
3703 else
3704 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3705 if (result != NULL && HASTZINFO(self))
3706 result = append_keyword_tzinfo(result, self->tzinfo);
3707 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003708}
3709
Tim Peters37f39822003-01-10 03:49:02 +00003710static PyObject *
3711time_str(PyDateTime_Time *self)
3712{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003713 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003714}
Tim Peters2a799bf2002-12-16 20:18:38 +00003715
3716static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003717time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003719 char buf[100];
3720 PyObject *result;
3721 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003723 if (us)
3724 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3725 TIME_GET_HOUR(self),
3726 TIME_GET_MINUTE(self),
3727 TIME_GET_SECOND(self),
3728 us);
3729 else
3730 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3731 TIME_GET_HOUR(self),
3732 TIME_GET_MINUTE(self),
3733 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003735 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3736 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003738 /* We need to append the UTC offset. */
3739 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3740 Py_None) < 0) {
3741 Py_DECREF(result);
3742 return NULL;
3743 }
3744 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3745 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003746}
3747
Tim Peters37f39822003-01-10 03:49:02 +00003748static PyObject *
3749time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003751 PyObject *result;
3752 PyObject *tuple;
3753 PyObject *format;
3754 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003756 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3757 &format))
3758 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003760 /* Python's strftime does insane things with the year part of the
3761 * timetuple. The year is forced to (the otherwise nonsensical)
3762 * 1900 to worm around that.
3763 */
3764 tuple = Py_BuildValue("iiiiiiiii",
3765 1900, 1, 1, /* year, month, day */
3766 TIME_GET_HOUR(self),
3767 TIME_GET_MINUTE(self),
3768 TIME_GET_SECOND(self),
3769 0, 1, -1); /* weekday, daynum, dst */
3770 if (tuple == NULL)
3771 return NULL;
3772 assert(PyTuple_Size(tuple) == 9);
3773 result = wrap_strftime((PyObject *)self, format, tuple,
3774 Py_None);
3775 Py_DECREF(tuple);
3776 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003777}
Tim Peters2a799bf2002-12-16 20:18:38 +00003778
3779/*
3780 * Miscellaneous methods.
3781 */
3782
Tim Peters37f39822003-01-10 03:49:02 +00003783static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003784time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003786 int diff;
3787 naivety n1, n2;
3788 int offset1, offset2;
Tim Peters37f39822003-01-10 03:49:02 +00003789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003790 if (! PyTime_Check(other)) {
3791 Py_INCREF(Py_NotImplemented);
3792 return Py_NotImplemented;
3793 }
3794 if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
3795 other, &offset2, &n2, Py_None) < 0)
3796 return NULL;
3797 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3798 /* If they're both naive, or both aware and have the same offsets,
3799 * we get off cheap. Note that if they're both naive, offset1 ==
3800 * offset2 == 0 at this point.
3801 */
3802 if (n1 == n2 && offset1 == offset2) {
3803 diff = memcmp(((PyDateTime_Time *)self)->data,
3804 ((PyDateTime_Time *)other)->data,
3805 _PyDateTime_TIME_DATASIZE);
3806 return diff_to_bool(diff, op);
3807 }
Tim Peters37f39822003-01-10 03:49:02 +00003808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003809 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3810 assert(offset1 != offset2); /* else last "if" handled it */
3811 /* Convert everything except microseconds to seconds. These
3812 * can't overflow (no more than the # of seconds in 2 days).
3813 */
3814 offset1 = TIME_GET_HOUR(self) * 3600 +
3815 (TIME_GET_MINUTE(self) - offset1) * 60 +
3816 TIME_GET_SECOND(self);
3817 offset2 = TIME_GET_HOUR(other) * 3600 +
3818 (TIME_GET_MINUTE(other) - offset2) * 60 +
3819 TIME_GET_SECOND(other);
3820 diff = offset1 - offset2;
3821 if (diff == 0)
3822 diff = TIME_GET_MICROSECOND(self) -
3823 TIME_GET_MICROSECOND(other);
3824 return diff_to_bool(diff, op);
3825 }
Tim Peters37f39822003-01-10 03:49:02 +00003826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003827 assert(n1 != n2);
3828 PyErr_SetString(PyExc_TypeError,
3829 "can't compare offset-naive and "
3830 "offset-aware times");
3831 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003832}
3833
3834static long
3835time_hash(PyDateTime_Time *self)
3836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003837 if (self->hashcode == -1) {
3838 naivety n;
3839 int offset;
3840 PyObject *temp;
Tim Peters37f39822003-01-10 03:49:02 +00003841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003842 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3843 assert(n != OFFSET_UNKNOWN);
3844 if (n == OFFSET_ERROR)
3845 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003846
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003847 /* Reduce this to a hash of another object. */
3848 if (offset == 0) {
3849 self->hashcode = generic_hash(
3850 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3851 return self->hashcode;
3852 }
3853 else {
3854 int hour;
3855 int minute;
Tim Peters37f39822003-01-10 03:49:02 +00003856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003857 assert(n == OFFSET_AWARE);
3858 assert(HASTZINFO(self));
3859 hour = divmod(TIME_GET_HOUR(self) * 60 +
3860 TIME_GET_MINUTE(self) - offset,
3861 60,
3862 &minute);
3863 if (0 <= hour && hour < 24)
3864 temp = new_time(hour, minute,
3865 TIME_GET_SECOND(self),
3866 TIME_GET_MICROSECOND(self),
3867 Py_None);
3868 else
3869 temp = Py_BuildValue("iiii",
3870 hour, minute,
3871 TIME_GET_SECOND(self),
3872 TIME_GET_MICROSECOND(self));
3873 }
3874 if (temp != NULL) {
3875 self->hashcode = PyObject_Hash(temp);
3876 Py_DECREF(temp);
3877 }
3878 }
3879 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003880}
Tim Peters2a799bf2002-12-16 20:18:38 +00003881
Tim Peters12bf3392002-12-24 05:41:27 +00003882static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003883time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003885 PyObject *clone;
3886 PyObject *tuple;
3887 int hh = TIME_GET_HOUR(self);
3888 int mm = TIME_GET_MINUTE(self);
3889 int ss = TIME_GET_SECOND(self);
3890 int us = TIME_GET_MICROSECOND(self);
3891 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003893 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3894 time_kws,
3895 &hh, &mm, &ss, &us, &tzinfo))
3896 return NULL;
3897 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3898 if (tuple == NULL)
3899 return NULL;
3900 clone = time_new(Py_TYPE(self), tuple, NULL);
3901 Py_DECREF(tuple);
3902 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003903}
3904
Tim Peters2a799bf2002-12-16 20:18:38 +00003905static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00003906time_bool(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003908 int offset;
3909 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00003910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003911 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3912 /* Since utcoffset is in whole minutes, nothing can
3913 * alter the conclusion that this is nonzero.
3914 */
3915 return 1;
3916 }
3917 offset = 0;
3918 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3919 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3920 if (offset == -1 && PyErr_Occurred())
3921 return -1;
3922 }
3923 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003924}
3925
Tim Peters371935f2003-02-01 01:52:50 +00003926/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003927
Tim Peters33e0f382003-01-10 02:05:14 +00003928/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003929 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3930 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003931 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003932 */
3933static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003934time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003936 PyObject *basestate;
3937 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003939 basestate = PyBytes_FromStringAndSize((char *)self->data,
3940 _PyDateTime_TIME_DATASIZE);
3941 if (basestate != NULL) {
3942 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3943 result = PyTuple_Pack(1, basestate);
3944 else
3945 result = PyTuple_Pack(2, basestate, self->tzinfo);
3946 Py_DECREF(basestate);
3947 }
3948 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003949}
3950
3951static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003952time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003954 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003955}
3956
Tim Peters37f39822003-01-10 03:49:02 +00003957static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003959 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3960 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3961 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003963 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3964 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003966 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3967 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003969 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3970 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003972 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3973 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003975 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3976 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003978 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3979 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003981 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3982 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003984 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003985};
3986
Tim Peters37f39822003-01-10 03:49:02 +00003987static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003988PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3989\n\
3990All arguments are optional. tzinfo may be None, or an instance of\n\
3991a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003992
Tim Peters37f39822003-01-10 03:49:02 +00003993static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003994 0, /* nb_add */
3995 0, /* nb_subtract */
3996 0, /* nb_multiply */
3997 0, /* nb_remainder */
3998 0, /* nb_divmod */
3999 0, /* nb_power */
4000 0, /* nb_negative */
4001 0, /* nb_positive */
4002 0, /* nb_absolute */
4003 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004004};
4005
Neal Norwitz227b5332006-03-22 09:28:35 +00004006static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004007 PyVarObject_HEAD_INIT(NULL, 0)
4008 "datetime.time", /* tp_name */
4009 sizeof(PyDateTime_Time), /* tp_basicsize */
4010 0, /* tp_itemsize */
4011 (destructor)time_dealloc, /* tp_dealloc */
4012 0, /* tp_print */
4013 0, /* tp_getattr */
4014 0, /* tp_setattr */
4015 0, /* tp_reserved */
4016 (reprfunc)time_repr, /* tp_repr */
4017 &time_as_number, /* tp_as_number */
4018 0, /* tp_as_sequence */
4019 0, /* tp_as_mapping */
4020 (hashfunc)time_hash, /* tp_hash */
4021 0, /* tp_call */
4022 (reprfunc)time_str, /* tp_str */
4023 PyObject_GenericGetAttr, /* tp_getattro */
4024 0, /* tp_setattro */
4025 0, /* tp_as_buffer */
4026 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4027 time_doc, /* tp_doc */
4028 0, /* tp_traverse */
4029 0, /* tp_clear */
4030 time_richcompare, /* tp_richcompare */
4031 0, /* tp_weaklistoffset */
4032 0, /* tp_iter */
4033 0, /* tp_iternext */
4034 time_methods, /* tp_methods */
4035 0, /* tp_members */
4036 time_getset, /* tp_getset */
4037 0, /* tp_base */
4038 0, /* tp_dict */
4039 0, /* tp_descr_get */
4040 0, /* tp_descr_set */
4041 0, /* tp_dictoffset */
4042 0, /* tp_init */
4043 time_alloc, /* tp_alloc */
4044 time_new, /* tp_new */
4045 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004046};
4047
4048/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004049 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004050 */
4051
Tim Petersa9bc1682003-01-11 03:39:11 +00004052/* Accessor properties. Properties for day, month, and year are inherited
4053 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004054 */
4055
4056static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004057datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004059 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004060}
4061
Tim Petersa9bc1682003-01-11 03:39:11 +00004062static PyObject *
4063datetime_minute(PyDateTime_DateTime *self, void *unused)
4064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004065 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004066}
4067
4068static PyObject *
4069datetime_second(PyDateTime_DateTime *self, void *unused)
4070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004071 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004072}
4073
4074static PyObject *
4075datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004077 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004078}
4079
4080static PyObject *
4081datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004083 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4084 Py_INCREF(result);
4085 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004086}
4087
4088static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004089 {"hour", (getter)datetime_hour},
4090 {"minute", (getter)datetime_minute},
4091 {"second", (getter)datetime_second},
4092 {"microsecond", (getter)datetime_microsecond},
4093 {"tzinfo", (getter)datetime_tzinfo},
4094 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004095};
4096
4097/*
4098 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004099 */
4100
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004101static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 "year", "month", "day", "hour", "minute", "second",
4103 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004104};
4105
Tim Peters2a799bf2002-12-16 20:18:38 +00004106static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004107datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004109 PyObject *self = NULL;
4110 PyObject *state;
4111 int year;
4112 int month;
4113 int day;
4114 int hour = 0;
4115 int minute = 0;
4116 int second = 0;
4117 int usecond = 0;
4118 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004120 /* Check for invocation from pickle with __getstate__ state */
4121 if (PyTuple_GET_SIZE(args) >= 1 &&
4122 PyTuple_GET_SIZE(args) <= 2 &&
4123 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4124 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4125 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4126 {
4127 PyDateTime_DateTime *me;
4128 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004130 if (PyTuple_GET_SIZE(args) == 2) {
4131 tzinfo = PyTuple_GET_ITEM(args, 1);
4132 if (check_tzinfo_subclass(tzinfo) < 0) {
4133 PyErr_SetString(PyExc_TypeError, "bad "
4134 "tzinfo state arg");
4135 return NULL;
4136 }
4137 }
4138 aware = (char)(tzinfo != Py_None);
4139 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4140 if (me != NULL) {
4141 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004143 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4144 me->hashcode = -1;
4145 me->hastzinfo = aware;
4146 if (aware) {
4147 Py_INCREF(tzinfo);
4148 me->tzinfo = tzinfo;
4149 }
4150 }
4151 return (PyObject *)me;
4152 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004154 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4155 &year, &month, &day, &hour, &minute,
4156 &second, &usecond, &tzinfo)) {
4157 if (check_date_args(year, month, day) < 0)
4158 return NULL;
4159 if (check_time_args(hour, minute, second, usecond) < 0)
4160 return NULL;
4161 if (check_tzinfo_subclass(tzinfo) < 0)
4162 return NULL;
4163 self = new_datetime_ex(year, month, day,
4164 hour, minute, second, usecond,
4165 tzinfo, type);
4166 }
4167 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004168}
4169
Tim Petersa9bc1682003-01-11 03:39:11 +00004170/* TM_FUNC is the shared type of localtime() and gmtime(). */
4171typedef struct tm *(*TM_FUNC)(const time_t *timer);
4172
4173/* Internal helper.
4174 * Build datetime from a time_t and a distinct count of microseconds.
4175 * Pass localtime or gmtime for f, to control the interpretation of timet.
4176 */
4177static PyObject *
4178datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004179 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004181 struct tm *tm;
4182 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004184 tm = f(&timet);
4185 if (tm) {
4186 /* The platform localtime/gmtime may insert leap seconds,
4187 * indicated by tm->tm_sec > 59. We don't care about them,
4188 * except to the extent that passing them on to the datetime
4189 * constructor would raise ValueError for a reason that
4190 * made no sense to the user.
4191 */
4192 if (tm->tm_sec > 59)
4193 tm->tm_sec = 59;
4194 result = PyObject_CallFunction(cls, "iiiiiiiO",
4195 tm->tm_year + 1900,
4196 tm->tm_mon + 1,
4197 tm->tm_mday,
4198 tm->tm_hour,
4199 tm->tm_min,
4200 tm->tm_sec,
4201 us,
4202 tzinfo);
4203 }
4204 else
4205 PyErr_SetString(PyExc_ValueError,
4206 "timestamp out of range for "
4207 "platform localtime()/gmtime() function");
4208 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004209}
4210
4211/* Internal helper.
4212 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4213 * to control the interpretation of the timestamp. Since a double doesn't
4214 * have enough bits to cover a datetime's full range of precision, it's
4215 * better to call datetime_from_timet_and_us provided you have a way
4216 * to get that much precision (e.g., C time() isn't good enough).
4217 */
4218static PyObject *
4219datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004220 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004222 time_t timet;
4223 double fraction;
4224 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 timet = _PyTime_DoubleToTimet(timestamp);
4227 if (timet == (time_t)-1 && PyErr_Occurred())
4228 return NULL;
4229 fraction = timestamp - (double)timet;
4230 us = (int)round_to_long(fraction * 1e6);
4231 if (us < 0) {
4232 /* Truncation towards zero is not what we wanted
4233 for negative numbers (Python's mod semantics) */
4234 timet -= 1;
4235 us += 1000000;
4236 }
4237 /* If timestamp is less than one microsecond smaller than a
4238 * full second, round up. Otherwise, ValueErrors are raised
4239 * for some floats. */
4240 if (us == 1000000) {
4241 timet += 1;
4242 us = 0;
4243 }
4244 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004245}
4246
4247/* Internal helper.
4248 * Build most accurate possible datetime for current time. Pass localtime or
4249 * gmtime for f as appropriate.
4250 */
4251static PyObject *
4252datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4253{
4254#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004255 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00004256
4257#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004258 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00004259#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004260 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00004261#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004262 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4263 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004265#else /* ! HAVE_GETTIMEOFDAY */
4266 /* No flavor of gettimeofday exists on this platform. Python's
4267 * time.time() does a lot of other platform tricks to get the
4268 * best time it can on the platform, and we're not going to do
4269 * better than that (if we could, the better code would belong
4270 * in time.time()!) We're limited by the precision of a double,
4271 * though.
4272 */
4273 PyObject *time;
4274 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00004275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004276 time = time_time();
4277 if (time == NULL)
4278 return NULL;
4279 dtime = PyFloat_AsDouble(time);
4280 Py_DECREF(time);
4281 if (dtime == -1.0 && PyErr_Occurred())
4282 return NULL;
4283 return datetime_from_timestamp(cls, f, dtime, tzinfo);
4284#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00004285}
4286
Tim Peters2a799bf2002-12-16 20:18:38 +00004287/* Return best possible local time -- this isn't constrained by the
4288 * precision of a timestamp.
4289 */
4290static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004291datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004292{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004293 PyObject *self;
4294 PyObject *tzinfo = Py_None;
4295 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004297 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4298 &tzinfo))
4299 return NULL;
4300 if (check_tzinfo_subclass(tzinfo) < 0)
4301 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 self = datetime_best_possible(cls,
4304 tzinfo == Py_None ? localtime : gmtime,
4305 tzinfo);
4306 if (self != NULL && tzinfo != Py_None) {
4307 /* Convert UTC to tzinfo's zone. */
4308 PyObject *temp = self;
4309 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4310 Py_DECREF(temp);
4311 }
4312 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004313}
4314
Tim Petersa9bc1682003-01-11 03:39:11 +00004315/* Return best possible UTC time -- this isn't constrained by the
4316 * precision of a timestamp.
4317 */
4318static PyObject *
4319datetime_utcnow(PyObject *cls, PyObject *dummy)
4320{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004321 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004322}
4323
Tim Peters2a799bf2002-12-16 20:18:38 +00004324/* Return new local datetime from timestamp (Python timestamp -- a double). */
4325static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004326datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004328 PyObject *self;
4329 double timestamp;
4330 PyObject *tzinfo = Py_None;
4331 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004333 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4334 keywords, &timestamp, &tzinfo))
4335 return NULL;
4336 if (check_tzinfo_subclass(tzinfo) < 0)
4337 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004339 self = datetime_from_timestamp(cls,
4340 tzinfo == Py_None ? localtime : gmtime,
4341 timestamp,
4342 tzinfo);
4343 if (self != NULL && tzinfo != Py_None) {
4344 /* Convert UTC to tzinfo's zone. */
4345 PyObject *temp = self;
4346 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4347 Py_DECREF(temp);
4348 }
4349 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004350}
4351
Tim Petersa9bc1682003-01-11 03:39:11 +00004352/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4353static PyObject *
4354datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004356 double timestamp;
4357 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004359 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4360 result = datetime_from_timestamp(cls, gmtime, timestamp,
4361 Py_None);
4362 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004363}
4364
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004365/* Return new datetime from time.strptime(). */
4366static PyObject *
4367datetime_strptime(PyObject *cls, PyObject *args)
4368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004369 static PyObject *module = NULL;
4370 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
4371 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004373 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4374 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004376 if (module == NULL &&
4377 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
4378 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004380 /* _strptime._strptime returns a two-element tuple. The first
4381 element is a time.struct_time object. The second is the
4382 microseconds (which are not defined for time.struct_time). */
4383 obj = PyObject_CallMethod(module, "_strptime", "uu", string, format);
4384 if (obj != NULL) {
4385 int i, good_timetuple = 1;
4386 long int ia[7];
4387 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
4388 st = PySequence_GetItem(obj, 0);
4389 frac = PySequence_GetItem(obj, 1);
4390 if (st == NULL || frac == NULL)
4391 good_timetuple = 0;
4392 /* copy y/m/d/h/m/s values out of the
4393 time.struct_time */
4394 if (good_timetuple &&
4395 PySequence_Check(st) &&
4396 PySequence_Size(st) >= 6) {
4397 for (i=0; i < 6; i++) {
4398 PyObject *p = PySequence_GetItem(st, i);
4399 if (p == NULL) {
4400 good_timetuple = 0;
4401 break;
4402 }
4403 if (PyLong_Check(p))
4404 ia[i] = PyLong_AsLong(p);
4405 else
4406 good_timetuple = 0;
4407 Py_DECREF(p);
4408 }
4409/* if (PyLong_CheckExact(p)) {
4410 ia[i] = PyLong_AsLongAndOverflow(p, &overflow);
4411 if (overflow)
4412 good_timetuple = 0;
4413 }
4414 else
4415 good_timetuple = 0;
4416 Py_DECREF(p);
4417*/ }
4418 else
4419 good_timetuple = 0;
4420 /* follow that up with a little dose of microseconds */
4421 if (PyLong_Check(frac))
4422 ia[6] = PyLong_AsLong(frac);
4423 else
4424 good_timetuple = 0;
4425 }
4426 else
4427 good_timetuple = 0;
4428 if (good_timetuple)
4429 result = PyObject_CallFunction(cls, "iiiiiii",
4430 ia[0], ia[1], ia[2],
4431 ia[3], ia[4], ia[5],
4432 ia[6]);
4433 else
4434 PyErr_SetString(PyExc_ValueError,
4435 "unexpected value from _strptime._strptime");
4436 }
4437 Py_XDECREF(obj);
4438 Py_XDECREF(st);
4439 Py_XDECREF(frac);
4440 return result;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004441}
4442
Tim Petersa9bc1682003-01-11 03:39:11 +00004443/* Return new datetime from date/datetime and time arguments. */
4444static PyObject *
4445datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004447 static char *keywords[] = {"date", "time", NULL};
4448 PyObject *date;
4449 PyObject *time;
4450 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004452 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4453 &PyDateTime_DateType, &date,
4454 &PyDateTime_TimeType, &time)) {
4455 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004457 if (HASTZINFO(time))
4458 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4459 result = PyObject_CallFunction(cls, "iiiiiiiO",
4460 GET_YEAR(date),
4461 GET_MONTH(date),
4462 GET_DAY(date),
4463 TIME_GET_HOUR(time),
4464 TIME_GET_MINUTE(time),
4465 TIME_GET_SECOND(time),
4466 TIME_GET_MICROSECOND(time),
4467 tzinfo);
4468 }
4469 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004470}
Tim Peters2a799bf2002-12-16 20:18:38 +00004471
4472/*
4473 * Destructor.
4474 */
4475
4476static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004477datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004478{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004479 if (HASTZINFO(self)) {
4480 Py_XDECREF(self->tzinfo);
4481 }
4482 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004483}
4484
4485/*
4486 * Indirect access to tzinfo methods.
4487 */
4488
Tim Peters2a799bf2002-12-16 20:18:38 +00004489/* These are all METH_NOARGS, so don't need to check the arglist. */
4490static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004491datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004492 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4493 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004494}
4495
4496static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004497datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004498 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4499 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004500}
4501
4502static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004503datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004504 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4505 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004506}
4507
4508/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004509 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004510 */
4511
Tim Petersa9bc1682003-01-11 03:39:11 +00004512/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4513 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004514 */
4515static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004516add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004517 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004519 /* Note that the C-level additions can't overflow, because of
4520 * invariant bounds on the member values.
4521 */
4522 int year = GET_YEAR(date);
4523 int month = GET_MONTH(date);
4524 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4525 int hour = DATE_GET_HOUR(date);
4526 int minute = DATE_GET_MINUTE(date);
4527 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4528 int microsecond = DATE_GET_MICROSECOND(date) +
4529 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004531 assert(factor == 1 || factor == -1);
4532 if (normalize_datetime(&year, &month, &day,
4533 &hour, &minute, &second, &microsecond) < 0)
4534 return NULL;
4535 else
4536 return new_datetime(year, month, day,
4537 hour, minute, second, microsecond,
4538 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004539}
4540
4541static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004542datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004543{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 if (PyDateTime_Check(left)) {
4545 /* datetime + ??? */
4546 if (PyDelta_Check(right))
4547 /* datetime + delta */
4548 return add_datetime_timedelta(
4549 (PyDateTime_DateTime *)left,
4550 (PyDateTime_Delta *)right,
4551 1);
4552 }
4553 else if (PyDelta_Check(left)) {
4554 /* delta + datetime */
4555 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4556 (PyDateTime_Delta *) left,
4557 1);
4558 }
4559 Py_INCREF(Py_NotImplemented);
4560 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004561}
4562
4563static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004564datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004565{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004566 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004568 if (PyDateTime_Check(left)) {
4569 /* datetime - ??? */
4570 if (PyDateTime_Check(right)) {
4571 /* datetime - datetime */
4572 naivety n1, n2;
4573 int offset1, offset2;
4574 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004575
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004576 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4577 right, &offset2, &n2,
4578 right) < 0)
4579 return NULL;
4580 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4581 if (n1 != n2) {
4582 PyErr_SetString(PyExc_TypeError,
4583 "can't subtract offset-naive and "
4584 "offset-aware datetimes");
4585 return NULL;
4586 }
4587 delta_d = ymd_to_ord(GET_YEAR(left),
4588 GET_MONTH(left),
4589 GET_DAY(left)) -
4590 ymd_to_ord(GET_YEAR(right),
4591 GET_MONTH(right),
4592 GET_DAY(right));
4593 /* These can't overflow, since the values are
4594 * normalized. At most this gives the number of
4595 * seconds in one day.
4596 */
4597 delta_s = (DATE_GET_HOUR(left) -
4598 DATE_GET_HOUR(right)) * 3600 +
4599 (DATE_GET_MINUTE(left) -
4600 DATE_GET_MINUTE(right)) * 60 +
4601 (DATE_GET_SECOND(left) -
4602 DATE_GET_SECOND(right));
4603 delta_us = DATE_GET_MICROSECOND(left) -
4604 DATE_GET_MICROSECOND(right);
4605 /* (left - offset1) - (right - offset2) =
4606 * (left - right) + (offset2 - offset1)
4607 */
4608 delta_s += (offset2 - offset1) * 60;
4609 result = new_delta(delta_d, delta_s, delta_us, 1);
4610 }
4611 else if (PyDelta_Check(right)) {
4612 /* datetime - delta */
4613 result = add_datetime_timedelta(
4614 (PyDateTime_DateTime *)left,
4615 (PyDateTime_Delta *)right,
4616 -1);
4617 }
4618 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004620 if (result == Py_NotImplemented)
4621 Py_INCREF(result);
4622 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004623}
4624
4625/* Various ways to turn a datetime into a string. */
4626
4627static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004628datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004629{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004630 const char *type_name = Py_TYPE(self)->tp_name;
4631 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004633 if (DATE_GET_MICROSECOND(self)) {
4634 baserepr = PyUnicode_FromFormat(
4635 "%s(%d, %d, %d, %d, %d, %d, %d)",
4636 type_name,
4637 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4638 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4639 DATE_GET_SECOND(self),
4640 DATE_GET_MICROSECOND(self));
4641 }
4642 else if (DATE_GET_SECOND(self)) {
4643 baserepr = PyUnicode_FromFormat(
4644 "%s(%d, %d, %d, %d, %d, %d)",
4645 type_name,
4646 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4647 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4648 DATE_GET_SECOND(self));
4649 }
4650 else {
4651 baserepr = PyUnicode_FromFormat(
4652 "%s(%d, %d, %d, %d, %d)",
4653 type_name,
4654 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4655 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4656 }
4657 if (baserepr == NULL || ! HASTZINFO(self))
4658 return baserepr;
4659 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004660}
4661
Tim Petersa9bc1682003-01-11 03:39:11 +00004662static PyObject *
4663datetime_str(PyDateTime_DateTime *self)
4664{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004665 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004666}
Tim Peters2a799bf2002-12-16 20:18:38 +00004667
4668static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004669datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004671 int sep = 'T';
4672 static char *keywords[] = {"sep", NULL};
4673 char buffer[100];
4674 PyObject *result;
4675 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004677 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4678 return NULL;
4679 if (us)
4680 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4681 GET_YEAR(self), GET_MONTH(self),
4682 GET_DAY(self), (int)sep,
4683 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4684 DATE_GET_SECOND(self), us);
4685 else
4686 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4687 GET_YEAR(self), GET_MONTH(self),
4688 GET_DAY(self), (int)sep,
4689 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4690 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004692 if (!result || !HASTZINFO(self))
4693 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004695 /* We need to append the UTC offset. */
4696 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4697 (PyObject *)self) < 0) {
4698 Py_DECREF(result);
4699 return NULL;
4700 }
4701 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4702 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004703}
4704
Tim Petersa9bc1682003-01-11 03:39:11 +00004705static PyObject *
4706datetime_ctime(PyDateTime_DateTime *self)
4707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004708 return format_ctime((PyDateTime_Date *)self,
4709 DATE_GET_HOUR(self),
4710 DATE_GET_MINUTE(self),
4711 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004712}
4713
Tim Peters2a799bf2002-12-16 20:18:38 +00004714/* Miscellaneous methods. */
4715
Tim Petersa9bc1682003-01-11 03:39:11 +00004716static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004717datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004718{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004719 int diff;
4720 naivety n1, n2;
4721 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004723 if (! PyDateTime_Check(other)) {
4724 if (PyDate_Check(other)) {
4725 /* Prevent invocation of date_richcompare. We want to
4726 return NotImplemented here to give the other object
4727 a chance. But since DateTime is a subclass of
4728 Date, if the other object is a Date, it would
4729 compute an ordering based on the date part alone,
4730 and we don't want that. So force unequal or
4731 uncomparable here in that case. */
4732 if (op == Py_EQ)
4733 Py_RETURN_FALSE;
4734 if (op == Py_NE)
4735 Py_RETURN_TRUE;
4736 return cmperror(self, other);
4737 }
4738 Py_INCREF(Py_NotImplemented);
4739 return Py_NotImplemented;
4740 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004742 if (classify_two_utcoffsets(self, &offset1, &n1, self,
4743 other, &offset2, &n2, other) < 0)
4744 return NULL;
4745 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4746 /* If they're both naive, or both aware and have the same offsets,
4747 * we get off cheap. Note that if they're both naive, offset1 ==
4748 * offset2 == 0 at this point.
4749 */
4750 if (n1 == n2 && offset1 == offset2) {
4751 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4752 ((PyDateTime_DateTime *)other)->data,
4753 _PyDateTime_DATETIME_DATASIZE);
4754 return diff_to_bool(diff, op);
4755 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004756
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004757 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4758 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004760 assert(offset1 != offset2); /* else last "if" handled it */
4761 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4762 other);
4763 if (delta == NULL)
4764 return NULL;
4765 diff = GET_TD_DAYS(delta);
4766 if (diff == 0)
4767 diff = GET_TD_SECONDS(delta) |
4768 GET_TD_MICROSECONDS(delta);
4769 Py_DECREF(delta);
4770 return diff_to_bool(diff, op);
4771 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004773 assert(n1 != n2);
4774 PyErr_SetString(PyExc_TypeError,
4775 "can't compare offset-naive and "
4776 "offset-aware datetimes");
4777 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004778}
4779
4780static long
4781datetime_hash(PyDateTime_DateTime *self)
4782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004783 if (self->hashcode == -1) {
4784 naivety n;
4785 int offset;
4786 PyObject *temp;
Tim Petersa9bc1682003-01-11 03:39:11 +00004787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004788 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4789 &offset);
4790 assert(n != OFFSET_UNKNOWN);
4791 if (n == OFFSET_ERROR)
4792 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004794 /* Reduce this to a hash of another object. */
4795 if (n == OFFSET_NAIVE) {
4796 self->hashcode = generic_hash(
4797 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
4798 return self->hashcode;
4799 }
4800 else {
4801 int days;
4802 int seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004804 assert(n == OFFSET_AWARE);
4805 assert(HASTZINFO(self));
4806 days = ymd_to_ord(GET_YEAR(self),
4807 GET_MONTH(self),
4808 GET_DAY(self));
4809 seconds = DATE_GET_HOUR(self) * 3600 +
4810 (DATE_GET_MINUTE(self) - offset) * 60 +
4811 DATE_GET_SECOND(self);
4812 temp = new_delta(days,
4813 seconds,
4814 DATE_GET_MICROSECOND(self),
4815 1);
4816 }
4817 if (temp != NULL) {
4818 self->hashcode = PyObject_Hash(temp);
4819 Py_DECREF(temp);
4820 }
4821 }
4822 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004823}
Tim Peters2a799bf2002-12-16 20:18:38 +00004824
4825static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004826datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004827{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004828 PyObject *clone;
4829 PyObject *tuple;
4830 int y = GET_YEAR(self);
4831 int m = GET_MONTH(self);
4832 int d = GET_DAY(self);
4833 int hh = DATE_GET_HOUR(self);
4834 int mm = DATE_GET_MINUTE(self);
4835 int ss = DATE_GET_SECOND(self);
4836 int us = DATE_GET_MICROSECOND(self);
4837 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004839 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4840 datetime_kws,
4841 &y, &m, &d, &hh, &mm, &ss, &us,
4842 &tzinfo))
4843 return NULL;
4844 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4845 if (tuple == NULL)
4846 return NULL;
4847 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4848 Py_DECREF(tuple);
4849 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004850}
4851
4852static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004853datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004854{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004855 int y, m, d, hh, mm, ss, us;
4856 PyObject *result;
4857 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004859 PyObject *tzinfo;
4860 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004862 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4863 &PyDateTime_TZInfoType, &tzinfo))
4864 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004866 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4867 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004869 /* Conversion to self's own time zone is a NOP. */
4870 if (self->tzinfo == tzinfo) {
4871 Py_INCREF(self);
4872 return (PyObject *)self;
4873 }
Tim Peters521fc152002-12-31 17:36:56 +00004874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004875 /* Convert self to UTC. */
4876 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4877 if (offset == -1 && PyErr_Occurred())
4878 return NULL;
4879 if (none)
4880 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 y = GET_YEAR(self);
4883 m = GET_MONTH(self);
4884 d = GET_DAY(self);
4885 hh = DATE_GET_HOUR(self);
4886 mm = DATE_GET_MINUTE(self);
4887 ss = DATE_GET_SECOND(self);
4888 us = DATE_GET_MICROSECOND(self);
Tim Peters52dcce22003-01-23 16:36:11 +00004889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 mm -= offset;
4891 if ((mm < 0 || mm >= 60) &&
4892 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4893 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004895 /* Attach new tzinfo and let fromutc() do the rest. */
4896 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4897 if (result != NULL) {
4898 PyObject *temp = result;
Tim Peters52dcce22003-01-23 16:36:11 +00004899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004900 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4901 Py_DECREF(temp);
4902 }
4903 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004904
Tim Peters52dcce22003-01-23 16:36:11 +00004905NeedAware:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004906 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4907 "a naive datetime");
4908 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004909}
4910
4911static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004912datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004913{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004914 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004916 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4917 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004919 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4920 if (dstflag == -1 && PyErr_Occurred())
4921 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004923 if (none)
4924 dstflag = -1;
4925 else if (dstflag != 0)
4926 dstflag = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004928 }
4929 return build_struct_time(GET_YEAR(self),
4930 GET_MONTH(self),
4931 GET_DAY(self),
4932 DATE_GET_HOUR(self),
4933 DATE_GET_MINUTE(self),
4934 DATE_GET_SECOND(self),
4935 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004936}
4937
4938static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004939datetime_getdate(PyDateTime_DateTime *self)
4940{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004941 return new_date(GET_YEAR(self),
4942 GET_MONTH(self),
4943 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004944}
4945
4946static PyObject *
4947datetime_gettime(PyDateTime_DateTime *self)
4948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004949 return new_time(DATE_GET_HOUR(self),
4950 DATE_GET_MINUTE(self),
4951 DATE_GET_SECOND(self),
4952 DATE_GET_MICROSECOND(self),
4953 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004954}
4955
4956static PyObject *
4957datetime_gettimetz(PyDateTime_DateTime *self)
4958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004959 return new_time(DATE_GET_HOUR(self),
4960 DATE_GET_MINUTE(self),
4961 DATE_GET_SECOND(self),
4962 DATE_GET_MICROSECOND(self),
4963 HASTZINFO(self) ? self->tzinfo : Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004964}
4965
4966static PyObject *
4967datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004968{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004969 int y = GET_YEAR(self);
4970 int m = GET_MONTH(self);
4971 int d = GET_DAY(self);
4972 int hh = DATE_GET_HOUR(self);
4973 int mm = DATE_GET_MINUTE(self);
4974 int ss = DATE_GET_SECOND(self);
4975 int us = 0; /* microseconds are ignored in a timetuple */
4976 int offset = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004978 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4979 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004981 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4982 if (offset == -1 && PyErr_Occurred())
4983 return NULL;
4984 }
4985 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4986 * 0 in a UTC timetuple regardless of what dst() says.
4987 */
4988 if (offset) {
4989 /* Subtract offset minutes & normalize. */
4990 int stat;
Tim Peters2a799bf2002-12-16 20:18:38 +00004991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004992 mm -= offset;
4993 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4994 if (stat < 0) {
4995 /* At the edges, it's possible we overflowed
4996 * beyond MINYEAR or MAXYEAR.
4997 */
4998 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4999 PyErr_Clear();
5000 else
5001 return NULL;
5002 }
5003 }
5004 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00005005}
5006
Tim Peters371935f2003-02-01 01:52:50 +00005007/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00005008
Tim Petersa9bc1682003-01-11 03:39:11 +00005009/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00005010 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5011 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00005012 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00005013 */
5014static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00005015datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00005016{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005017 PyObject *basestate;
5018 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005020 basestate = PyBytes_FromStringAndSize((char *)self->data,
5021 _PyDateTime_DATETIME_DATASIZE);
5022 if (basestate != NULL) {
5023 if (! HASTZINFO(self) || self->tzinfo == Py_None)
5024 result = PyTuple_Pack(1, basestate);
5025 else
5026 result = PyTuple_Pack(2, basestate, self->tzinfo);
5027 Py_DECREF(basestate);
5028 }
5029 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00005030}
5031
5032static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00005033datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00005034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005035 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00005036}
5037
Tim Petersa9bc1682003-01-11 03:39:11 +00005038static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005040 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005042 {"now", (PyCFunction)datetime_now,
5043 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5044 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005046 {"utcnow", (PyCFunction)datetime_utcnow,
5047 METH_NOARGS | METH_CLASS,
5048 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005050 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5051 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5052 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005054 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5055 METH_VARARGS | METH_CLASS,
5056 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
5057 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005059 {"strptime", (PyCFunction)datetime_strptime,
5060 METH_VARARGS | METH_CLASS,
5061 PyDoc_STR("string, format -> new datetime parsed from a string "
5062 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005064 {"combine", (PyCFunction)datetime_combine,
5065 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5066 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005068 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005070 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5071 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005073 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5074 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005076 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5077 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005079 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5080 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005082 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5083 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005085 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5086 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005087
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005088 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5089 PyDoc_STR("[sep] -> string in ISO 8601 format, "
5090 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
5091 "sep is used to separate the year from the time, and "
5092 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005094 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5095 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005097 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5098 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005100 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5101 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005103 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5104 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005106 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5107 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005109 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5110 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005112 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005113};
5114
Tim Petersa9bc1682003-01-11 03:39:11 +00005115static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005116PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5117\n\
5118The year, month and day arguments are required. tzinfo may be None, or an\n\
5119instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005120
Tim Petersa9bc1682003-01-11 03:39:11 +00005121static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005122 datetime_add, /* nb_add */
5123 datetime_subtract, /* nb_subtract */
5124 0, /* nb_multiply */
5125 0, /* nb_remainder */
5126 0, /* nb_divmod */
5127 0, /* nb_power */
5128 0, /* nb_negative */
5129 0, /* nb_positive */
5130 0, /* nb_absolute */
5131 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005132};
5133
Neal Norwitz227b5332006-03-22 09:28:35 +00005134static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005135 PyVarObject_HEAD_INIT(NULL, 0)
5136 "datetime.datetime", /* tp_name */
5137 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5138 0, /* tp_itemsize */
5139 (destructor)datetime_dealloc, /* tp_dealloc */
5140 0, /* tp_print */
5141 0, /* tp_getattr */
5142 0, /* tp_setattr */
5143 0, /* tp_reserved */
5144 (reprfunc)datetime_repr, /* tp_repr */
5145 &datetime_as_number, /* tp_as_number */
5146 0, /* tp_as_sequence */
5147 0, /* tp_as_mapping */
5148 (hashfunc)datetime_hash, /* tp_hash */
5149 0, /* tp_call */
5150 (reprfunc)datetime_str, /* tp_str */
5151 PyObject_GenericGetAttr, /* tp_getattro */
5152 0, /* tp_setattro */
5153 0, /* tp_as_buffer */
5154 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5155 datetime_doc, /* tp_doc */
5156 0, /* tp_traverse */
5157 0, /* tp_clear */
5158 datetime_richcompare, /* tp_richcompare */
5159 0, /* tp_weaklistoffset */
5160 0, /* tp_iter */
5161 0, /* tp_iternext */
5162 datetime_methods, /* tp_methods */
5163 0, /* tp_members */
5164 datetime_getset, /* tp_getset */
5165 &PyDateTime_DateType, /* tp_base */
5166 0, /* tp_dict */
5167 0, /* tp_descr_get */
5168 0, /* tp_descr_set */
5169 0, /* tp_dictoffset */
5170 0, /* tp_init */
5171 datetime_alloc, /* tp_alloc */
5172 datetime_new, /* tp_new */
5173 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005174};
5175
5176/* ---------------------------------------------------------------------------
5177 * Module methods and initialization.
5178 */
5179
5180static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005181 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005182};
5183
Tim Peters9ddf40b2004-06-20 22:41:32 +00005184/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5185 * datetime.h.
5186 */
5187static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005188 &PyDateTime_DateType,
5189 &PyDateTime_DateTimeType,
5190 &PyDateTime_TimeType,
5191 &PyDateTime_DeltaType,
5192 &PyDateTime_TZInfoType,
5193 new_date_ex,
5194 new_datetime_ex,
5195 new_time_ex,
5196 new_delta_ex,
5197 datetime_fromtimestamp,
5198 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005199};
5200
5201
Martin v. Löwis1a214512008-06-11 05:26:20 +00005202
5203static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005204 PyModuleDef_HEAD_INIT,
5205 "datetime",
5206 "Fast implementation of the datetime type.",
5207 -1,
5208 module_methods,
5209 NULL,
5210 NULL,
5211 NULL,
5212 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005213};
5214
Tim Peters2a799bf2002-12-16 20:18:38 +00005215PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00005216PyInit_datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005218 PyObject *m; /* a module object */
5219 PyObject *d; /* its dict */
5220 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005221 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005223 m = PyModule_Create(&datetimemodule);
5224 if (m == NULL)
5225 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005227 if (PyType_Ready(&PyDateTime_DateType) < 0)
5228 return NULL;
5229 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5230 return NULL;
5231 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5232 return NULL;
5233 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5234 return NULL;
5235 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5236 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005237 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5238 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005240 /* timedelta values */
5241 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005243 x = new_delta(0, 0, 1, 0);
5244 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5245 return NULL;
5246 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005248 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5249 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5250 return NULL;
5251 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005253 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5254 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5255 return NULL;
5256 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005258 /* date values */
5259 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005261 x = new_date(1, 1, 1);
5262 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5263 return NULL;
5264 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005266 x = new_date(MAXYEAR, 12, 31);
5267 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5268 return NULL;
5269 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005271 x = new_delta(1, 0, 0, 0);
5272 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5273 return NULL;
5274 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005276 /* time values */
5277 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005279 x = new_time(0, 0, 0, 0, Py_None);
5280 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5281 return NULL;
5282 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005284 x = new_time(23, 59, 59, 999999, Py_None);
5285 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5286 return NULL;
5287 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005289 x = new_delta(0, 0, 1, 0);
5290 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5291 return NULL;
5292 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005294 /* datetime values */
5295 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005297 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5298 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5299 return NULL;
5300 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005302 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5303 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5304 return NULL;
5305 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005307 x = new_delta(0, 0, 1, 0);
5308 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5309 return NULL;
5310 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005311
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005312 /* timezone values */
5313 d = PyDateTime_TimeZoneType.tp_dict;
5314
5315 delta = new_delta(0, 0, 0, 0);
5316 if (delta == NULL)
5317 return NULL;
5318 x = new_timezone(delta, NULL);
5319 Py_DECREF(delta);
5320 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5321 return NULL;
5322 Py_DECREF(x);
5323
5324 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5325 if (delta == NULL)
5326 return NULL;
5327 x = new_timezone(delta, NULL);
5328 Py_DECREF(delta);
5329 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5330 return NULL;
5331 Py_DECREF(x);
5332
5333 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5334 if (delta == NULL)
5335 return NULL;
5336 x = new_timezone(delta, NULL);
5337 Py_DECREF(delta);
5338 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5339 return NULL;
5340 Py_DECREF(x);
5341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005342 /* module initialization */
5343 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5344 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005346 Py_INCREF(&PyDateTime_DateType);
5347 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005349 Py_INCREF(&PyDateTime_DateTimeType);
5350 PyModule_AddObject(m, "datetime",
5351 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005353 Py_INCREF(&PyDateTime_TimeType);
5354 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005356 Py_INCREF(&PyDateTime_DeltaType);
5357 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005359 Py_INCREF(&PyDateTime_TZInfoType);
5360 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005361
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005362 Py_INCREF(&PyDateTime_TimeZoneType);
5363 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005365 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5366 if (x == NULL)
5367 return NULL;
5368 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005370 /* A 4-year cycle has an extra leap day over what we'd get from
5371 * pasting together 4 single years.
5372 */
5373 assert(DI4Y == 4 * 365 + 1);
5374 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005376 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5377 * get from pasting together 4 100-year cycles.
5378 */
5379 assert(DI400Y == 4 * DI100Y + 1);
5380 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005382 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5383 * pasting together 25 4-year cycles.
5384 */
5385 assert(DI100Y == 25 * DI4Y - 1);
5386 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005388 us_per_us = PyLong_FromLong(1);
5389 us_per_ms = PyLong_FromLong(1000);
5390 us_per_second = PyLong_FromLong(1000000);
5391 us_per_minute = PyLong_FromLong(60000000);
5392 seconds_per_day = PyLong_FromLong(24 * 3600);
5393 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5394 us_per_minute == NULL || seconds_per_day == NULL)
5395 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005397 /* The rest are too big for 32-bit ints, but even
5398 * us_per_week fits in 40 bits, so doubles should be exact.
5399 */
5400 us_per_hour = PyLong_FromDouble(3600000000.0);
5401 us_per_day = PyLong_FromDouble(86400000000.0);
5402 us_per_week = PyLong_FromDouble(604800000000.0);
5403 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5404 return NULL;
5405 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005406}
Tim Petersf3615152003-01-01 21:51:37 +00005407
5408/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005409Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005410 x.n = x stripped of its timezone -- its naive time.
5411 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005412 return None
Tim Petersf3615152003-01-01 21:51:37 +00005413 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005414 return None
Tim Petersf3615152003-01-01 21:51:37 +00005415 x.s = x's standard offset, x.o - x.d
5416
5417Now some derived rules, where k is a duration (timedelta).
5418
54191. x.o = x.s + x.d
5420 This follows from the definition of x.s.
5421
Tim Petersc5dc4da2003-01-02 17:55:03 +000054222. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005423 This is actually a requirement, an assumption we need to make about
5424 sane tzinfo classes.
5425
54263. The naive UTC time corresponding to x is x.n - x.o.
5427 This is again a requirement for a sane tzinfo class.
5428
54294. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005430 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005431
Tim Petersc5dc4da2003-01-02 17:55:03 +000054325. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005433 Again follows from how arithmetic is defined.
5434
Tim Peters8bb5ad22003-01-24 02:44:45 +00005435Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005436(meaning that the various tzinfo methods exist, and don't blow up or return
5437None when called).
5438
Tim Petersa9bc1682003-01-11 03:39:11 +00005439The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005440x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005441
5442By #3, we want
5443
Tim Peters8bb5ad22003-01-24 02:44:45 +00005444 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005445
5446The algorithm starts by attaching tz to x.n, and calling that y. So
5447x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5448becomes true; in effect, we want to solve [2] for k:
5449
Tim Peters8bb5ad22003-01-24 02:44:45 +00005450 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005451
5452By #1, this is the same as
5453
Tim Peters8bb5ad22003-01-24 02:44:45 +00005454 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005455
5456By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5457Substituting that into [3],
5458
Tim Peters8bb5ad22003-01-24 02:44:45 +00005459 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5460 k - (y+k).s - (y+k).d = 0; rearranging,
5461 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5462 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005463
Tim Peters8bb5ad22003-01-24 02:44:45 +00005464On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5465approximate k by ignoring the (y+k).d term at first. Note that k can't be
5466very large, since all offset-returning methods return a duration of magnitude
5467less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5468be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005469
5470In any case, the new value is
5471
Tim Peters8bb5ad22003-01-24 02:44:45 +00005472 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005473
Tim Peters8bb5ad22003-01-24 02:44:45 +00005474It's helpful to step back at look at [4] from a higher level: it's simply
5475mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005476
5477At this point, if
5478
Tim Peters8bb5ad22003-01-24 02:44:45 +00005479 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005480
5481we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005482at the start of daylight time. Picture US Eastern for concreteness. The wall
5483time 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 +00005484sense then. The docs ask that an Eastern tzinfo class consider such a time to
5485be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5486on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005487the only spelling that makes sense on the local wall clock.
5488
Tim Petersc5dc4da2003-01-02 17:55:03 +00005489In fact, if [5] holds at this point, we do have the standard-time spelling,
5490but that takes a bit of proof. We first prove a stronger result. What's the
5491difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005492
Tim Peters8bb5ad22003-01-24 02:44:45 +00005493 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005494
Tim Petersc5dc4da2003-01-02 17:55:03 +00005495Now
5496 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005497 (y + y.s).n = by #5
5498 y.n + y.s = since y.n = x.n
5499 x.n + y.s = since z and y are have the same tzinfo member,
5500 y.s = z.s by #2
5501 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005502
Tim Petersc5dc4da2003-01-02 17:55:03 +00005503Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005504
Tim Petersc5dc4da2003-01-02 17:55:03 +00005505 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005506 x.n - ((x.n + z.s) - z.o) = expanding
5507 x.n - x.n - z.s + z.o = cancelling
5508 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005509 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005510
Tim Petersc5dc4da2003-01-02 17:55:03 +00005511So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005512
Tim Petersc5dc4da2003-01-02 17:55:03 +00005513If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005514spelling we wanted in the endcase described above. We're done. Contrarily,
5515if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005516
Tim Petersc5dc4da2003-01-02 17:55:03 +00005517If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5518add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005519local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005520
Tim Petersc5dc4da2003-01-02 17:55:03 +00005521Let
Tim Petersf3615152003-01-01 21:51:37 +00005522
Tim Peters4fede1a2003-01-04 00:26:59 +00005523 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005524
Tim Peters4fede1a2003-01-04 00:26:59 +00005525and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005526
Tim Peters8bb5ad22003-01-24 02:44:45 +00005527 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005528
Tim Peters8bb5ad22003-01-24 02:44:45 +00005529If so, we're done. If not, the tzinfo class is insane, according to the
5530assumptions we've made. This also requires a bit of proof. As before, let's
5531compute the difference between the LHS and RHS of [8] (and skipping some of
5532the justifications for the kinds of substitutions we've done several times
5533already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005534
Tim Peters8bb5ad22003-01-24 02:44:45 +00005535 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005536 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5537 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5538 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5539 - z.n + z.n - z.o + z'.o = cancel z.n
5540 - z.o + z'.o = #1 twice
5541 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5542 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005543
5544So 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 +00005545we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5546return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005547
Tim Peters8bb5ad22003-01-24 02:44:45 +00005548How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5549a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5550would have to change the result dst() returns: we start in DST, and moving
5551a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005552
Tim Peters8bb5ad22003-01-24 02:44:45 +00005553There isn't a sane case where this can happen. The closest it gets is at
5554the end of DST, where there's an hour in UTC with no spelling in a hybrid
5555tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5556that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5557UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5558time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5559clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5560standard time. Since that's what the local clock *does*, we want to map both
5561UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005562in local time, but so it goes -- it's the way the local clock works.
5563
Tim Peters8bb5ad22003-01-24 02:44:45 +00005564When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5565so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5566z' = 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 +00005567(correctly) concludes that z' is not UTC-equivalent to x.
5568
5569Because we know z.d said z was in daylight time (else [5] would have held and
5570we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005571and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005572return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5573but the reasoning doesn't depend on the example -- it depends on there being
5574two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005575z' must be in standard time, and is the spelling we want in this case.
5576
5577Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5578concerned (because it takes z' as being in standard time rather than the
5579daylight time we intend here), but returning it gives the real-life "local
5580clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5581tz.
5582
5583When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5584the 1:MM standard time spelling we want.
5585
5586So how can this break? One of the assumptions must be violated. Two
5587possibilities:
5588
55891) [2] effectively says that y.s is invariant across all y belong to a given
5590 time zone. This isn't true if, for political reasons or continental drift,
5591 a region decides to change its base offset from UTC.
5592
55932) There may be versions of "double daylight" time where the tail end of
5594 the analysis gives up a step too early. I haven't thought about that
5595 enough to say.
5596
5597In any case, it's clear that the default fromutc() is strong enough to handle
5598"almost all" time zones: so long as the standard offset is invariant, it
5599doesn't matter if daylight time transition points change from year to year, or
5600if daylight time is skipped in some years; it doesn't matter how large or
5601small dst() may get within its bounds; and it doesn't even matter if some
5602perverse time zone returns a negative dst()). So a breaking case must be
5603pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005604--------------------------------------------------------------------------- */