blob: a7e740e502e42bdf7e456ed66d18dc2449c74716 [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
Alexander Belopolskya11d8c02010-07-06 23:19:45 +0000783PyObject *PyDateTime_TimeZone_UTC;
784
Alexander Belopolsky4e749a12010-06-14 14:15:50 +0000785/* Create new timezone instance checking offset range. This
786 function does not check the name argument. Caller must assure
787 that offset is a timedelta instance and name is either NULL
788 or a unicode object. */
789static PyObject *
790new_timezone(PyObject *offset, PyObject *name)
791{
792 PyDateTime_TimeZone *self;
793 PyTypeObject *type = &PyDateTime_TimeZoneType;
794
795 assert(offset != NULL);
796 assert(PyDelta_Check(offset));
797 assert(name == NULL || PyUnicode_Check(name));
798
799 if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
800 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
801 " representing a whole number of minutes");
802 return NULL;
803 }
804 if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
805 GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
806 PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
807 " strictly between -timedelta(hours=24) and"
808 " timedelta(hours=24).");
809 return NULL;
810 }
811
812 self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
813 if (self == NULL) {
814 return NULL;
815 }
816 Py_INCREF(offset);
817 self->offset = offset;
818 Py_XINCREF(name);
819 self->name = name;
820 return (PyObject *)self;
821}
822
Tim Petersb0c854d2003-05-17 15:57:00 +0000823/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000824 * tzinfo helpers.
825 */
826
Tim Peters855fe882002-12-22 03:43:39 +0000827/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
828 * raise TypeError and return -1.
829 */
830static int
831check_tzinfo_subclass(PyObject *p)
832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 if (p == Py_None || PyTZInfo_Check(p))
834 return 0;
835 PyErr_Format(PyExc_TypeError,
836 "tzinfo argument must be None or of a tzinfo subclass, "
837 "not type '%s'",
838 Py_TYPE(p)->tp_name);
839 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000840}
841
Tim Petersbad8ff02002-12-30 20:52:32 +0000842/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000843 * If tzinfo is None, returns None.
844 */
845static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000846call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 assert(tzinfo && methname && tzinfoarg);
851 assert(check_tzinfo_subclass(tzinfo) >= 0);
852 if (tzinfo == Py_None) {
853 result = Py_None;
854 Py_INCREF(result);
855 }
856 else
857 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
858 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000859}
860
Tim Peters2a799bf2002-12-16 20:18:38 +0000861/* If self has a tzinfo member, return a BORROWED reference to it. Else
862 * return NULL, which is NOT AN ERROR. There are no error returns here,
863 * and the caller must not decref the result.
864 */
865static PyObject *
866get_tzinfo_member(PyObject *self)
867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 if (PyDateTime_Check(self) && HASTZINFO(self))
871 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
872 else if (PyTime_Check(self) && HASTZINFO(self))
873 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000876}
877
Tim Petersbad8ff02002-12-30 20:52:32 +0000878/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000879 * result. tzinfo must be an instance of the tzinfo class. If the method
880 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000881 * return None or timedelta, TypeError is raised and this returns -1. If it
882 * returnsa timedelta and the value is out of range or isn't a whole number
883 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000884 * Else *none is set to 0 and the integer method result is returned.
885 */
886static int
887call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 int *none)
Tim Peters2a799bf2002-12-16 20:18:38 +0000889{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 PyObject *u;
891 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000892
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 assert(tzinfo != NULL);
894 assert(PyTZInfo_Check(tzinfo));
895 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 *none = 0;
898 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
899 if (u == NULL)
900 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 else if (u == Py_None) {
903 result = 0;
904 *none = 1;
905 }
906 else if (PyDelta_Check(u)) {
907 const int days = GET_TD_DAYS(u);
908 if (days < -1 || days > 0)
909 result = 24*60; /* trigger ValueError below */
910 else {
911 /* next line can't overflow because we know days
912 * is -1 or 0 now
913 */
914 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
915 result = divmod(ss, 60, &ss);
916 if (ss || GET_TD_MICROSECONDS(u)) {
917 PyErr_Format(PyExc_ValueError,
918 "tzinfo.%s() must return a "
919 "whole number of minutes",
920 name);
921 result = -1;
922 }
923 }
924 }
925 else {
926 PyErr_Format(PyExc_TypeError,
927 "tzinfo.%s() must return None or "
928 "timedelta, not '%s'",
929 name, Py_TYPE(u)->tp_name);
930 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 Py_DECREF(u);
933 if (result < -1439 || result > 1439) {
934 PyErr_Format(PyExc_ValueError,
935 "tzinfo.%s() returned %d; must be in "
936 "-1439 .. 1439",
937 name, result);
938 result = -1;
939 }
940 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000941}
942
943/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
944 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
945 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000946 * doesn't return None or timedelta, TypeError is raised and this returns -1.
947 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
948 * # of minutes), ValueError is raised and this returns -1. Else *none is
949 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000950 */
951static int
952call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000955}
956
Tim Petersbad8ff02002-12-30 20:52:32 +0000957/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
958 */
Tim Peters855fe882002-12-22 03:43:39 +0000959static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000960offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 assert(tzinfo && name && tzinfoarg);
964 if (tzinfo == Py_None) {
965 result = Py_None;
966 Py_INCREF(result);
967 }
968 else {
969 int none;
970 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
971 &none);
972 if (offset < 0 && PyErr_Occurred())
973 return NULL;
974 if (none) {
975 result = Py_None;
976 Py_INCREF(result);
977 }
978 else
979 result = new_delta(0, offset * 60, 0, 1);
980 }
981 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000982}
983
Tim Peters2a799bf2002-12-16 20:18:38 +0000984/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
985 * result. tzinfo must be an instance of the tzinfo class. If dst()
986 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000987 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000988 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000989 * ValueError is raised and this returns -1. Else *none is set to 0 and
990 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000991 */
992static int
993call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000996}
997
Tim Petersbad8ff02002-12-30 20:52:32 +0000998/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000999 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +00001000 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +00001001 * returns NULL. If the result is a string, we ensure it is a Unicode
1002 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +00001003 */
1004static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001005call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001006{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 assert(tzinfo != NULL);
1010 assert(check_tzinfo_subclass(tzinfo) >= 0);
1011 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 if (tzinfo == Py_None) {
1014 result = Py_None;
1015 Py_INCREF(result);
1016 }
1017 else
1018 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +00001019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 if (result != NULL && result != Py_None) {
1021 if (!PyUnicode_Check(result)) {
1022 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1023 "return None or a string, not '%s'",
1024 Py_TYPE(result)->tp_name);
1025 Py_DECREF(result);
1026 result = NULL;
1027 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 }
1029 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001030}
1031
1032typedef enum {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 /* an exception has been set; the caller should pass it on */
1034 OFFSET_ERROR,
Tim Peters2a799bf2002-12-16 20:18:38 +00001035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 /* type isn't date, datetime, or time subclass */
1037 OFFSET_UNKNOWN,
Tim Peters2a799bf2002-12-16 20:18:38 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 /* date,
1040 * datetime with !hastzinfo
1041 * datetime with None tzinfo,
1042 * datetime where utcoffset() returns None
1043 * time with !hastzinfo
1044 * time with None tzinfo,
1045 * time where utcoffset() returns None
1046 */
1047 OFFSET_NAIVE,
Tim Peters2a799bf2002-12-16 20:18:38 +00001048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 /* time or datetime where utcoffset() doesn't return None */
1050 OFFSET_AWARE
Tim Peters2a799bf2002-12-16 20:18:38 +00001051} naivety;
1052
Tim Peters14b69412002-12-22 18:10:22 +00001053/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +00001054 * the "naivety" typedef for details. If the type is aware, *offset is set
1055 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +00001056 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +00001057 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +00001058 */
1059static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +00001060classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +00001061{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 int none;
1063 PyObject *tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 assert(tzinfoarg != NULL);
1066 *offset = 0;
1067 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
1068 if (tzinfo == Py_None)
1069 return OFFSET_NAIVE;
1070 if (tzinfo == NULL) {
1071 /* note that a datetime passes the PyDate_Check test */
1072 return (PyTime_Check(op) || PyDate_Check(op)) ?
1073 OFFSET_NAIVE : OFFSET_UNKNOWN;
1074 }
1075 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1076 if (*offset == -1 && PyErr_Occurred())
1077 return OFFSET_ERROR;
1078 return none ? OFFSET_NAIVE : OFFSET_AWARE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001079}
1080
Tim Peters00237032002-12-27 02:21:51 +00001081/* Classify two objects as to whether they're naive or offset-aware.
1082 * This isn't quite the same as calling classify_utcoffset() twice: for
1083 * binary operations (comparison and subtraction), we generally want to
1084 * ignore the tzinfo members if they're identical. This is by design,
1085 * so that results match "naive" expectations when mixing objects from a
1086 * single timezone. So in that case, this sets both offsets to 0 and
1087 * both naiveties to OFFSET_NAIVE.
1088 * The function returns 0 if everything's OK, and -1 on error.
1089 */
1090static int
1091classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 PyObject *tzinfoarg1,
1093 PyObject *o2, int *offset2, naivety *n2,
1094 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1097 *offset1 = *offset2 = 0;
1098 *n1 = *n2 = OFFSET_NAIVE;
1099 }
1100 else {
1101 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1102 if (*n1 == OFFSET_ERROR)
1103 return -1;
1104 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1105 if (*n2 == OFFSET_ERROR)
1106 return -1;
1107 }
1108 return 0;
Tim Peters00237032002-12-27 02:21:51 +00001109}
1110
Tim Peters2a799bf2002-12-16 20:18:38 +00001111/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1112 * stuff
1113 * ", tzinfo=" + repr(tzinfo)
1114 * before the closing ")".
1115 */
1116static PyObject *
1117append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1118{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 assert(PyUnicode_Check(repr));
1122 assert(tzinfo);
1123 if (tzinfo == Py_None)
1124 return repr;
1125 /* Get rid of the trailing ')'. */
1126 assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
1127 temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
1128 PyUnicode_GET_SIZE(repr) - 1);
1129 Py_DECREF(repr);
1130 if (temp == NULL)
1131 return NULL;
1132 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1133 Py_DECREF(temp);
1134 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001135}
1136
1137/* ---------------------------------------------------------------------------
1138 * String format helpers.
1139 */
1140
1141static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001142format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 static const char *DayNames[] = {
1145 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1146 };
1147 static const char *MonthNames[] = {
1148 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1149 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1150 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1155 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1156 GET_DAY(date), hours, minutes, seconds,
1157 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001158}
1159
1160/* Add an hours & minutes UTC offset string to buf. buf has no more than
1161 * buflen bytes remaining. The UTC offset is gotten by calling
1162 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1163 * *buf, and that's all. Else the returned value is checked for sanity (an
1164 * integer in range), and if that's OK it's converted to an hours & minutes
1165 * string of the form
1166 * sign HH sep MM
1167 * Returns 0 if everything is OK. If the return value from utcoffset() is
1168 * bogus, an appropriate exception is set and -1 is returned.
1169 */
1170static int
Tim Peters328fff72002-12-20 01:31:27 +00001171format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 int offset;
1175 int hours;
1176 int minutes;
1177 char sign;
1178 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00001179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001181
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1183 if (offset == -1 && PyErr_Occurred())
1184 return -1;
1185 if (none) {
1186 *buf = '\0';
1187 return 0;
1188 }
1189 sign = '+';
1190 if (offset < 0) {
1191 sign = '-';
1192 offset = - offset;
1193 }
1194 hours = divmod(offset, 60, &minutes);
1195 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1196 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001197}
1198
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001199static PyObject *
1200make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 PyObject *temp;
1203 PyObject *tzinfo = get_tzinfo_member(object);
1204 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1205 if (Zreplacement == NULL)
1206 return NULL;
1207 if (tzinfo == Py_None || tzinfo == NULL)
1208 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 assert(tzinfoarg != NULL);
1211 temp = call_tzname(tzinfo, tzinfoarg);
1212 if (temp == NULL)
1213 goto Error;
1214 if (temp == Py_None) {
1215 Py_DECREF(temp);
1216 return Zreplacement;
1217 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 assert(PyUnicode_Check(temp));
1220 /* Since the tzname is getting stuffed into the
1221 * format, we have to double any % signs so that
1222 * strftime doesn't treat them as format codes.
1223 */
1224 Py_DECREF(Zreplacement);
1225 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1226 Py_DECREF(temp);
1227 if (Zreplacement == NULL)
1228 return NULL;
1229 if (!PyUnicode_Check(Zreplacement)) {
1230 PyErr_SetString(PyExc_TypeError,
1231 "tzname.replace() did not return a string");
1232 goto Error;
1233 }
1234 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001235
1236 Error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 Py_DECREF(Zreplacement);
1238 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001239}
1240
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001241static PyObject *
1242make_freplacement(PyObject *object)
1243{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 char freplacement[64];
1245 if (PyTime_Check(object))
1246 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1247 else if (PyDateTime_Check(object))
1248 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1249 else
1250 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001253}
1254
Tim Peters2a799bf2002-12-16 20:18:38 +00001255/* I sure don't want to reproduce the strftime code from the time module,
1256 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001257 * giving special meanings to the %z, %Z and %f format codes via a
1258 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001259 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1260 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001261 */
1262static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001263wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001264 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1269 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1270 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 const char *pin; /* pointer to next char in input format */
1273 Py_ssize_t flen; /* length of input format */
1274 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 PyObject *newfmt = NULL; /* py string, the output format */
1277 char *pnew; /* pointer to available byte in output format */
1278 size_t totalnew; /* number bytes total in output format buffer,
1279 exclusive of trailing \0 */
1280 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 const char *ptoappend; /* ptr to string to append to output buffer */
1283 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 assert(object && format && timetuple);
1286 assert(PyUnicode_Check(format));
1287 /* Convert the input format to a C string and size */
1288 pin = _PyUnicode_AsStringAndSize(format, &flen);
1289 if (!pin)
1290 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 /* Give up if the year is before 1900.
1293 * Python strftime() plays games with the year, and different
1294 * games depending on whether envar PYTHON2K is set. This makes
1295 * years before 1900 a nightmare, even if the platform strftime
1296 * supports them (and not all do).
1297 * We could get a lot farther here by avoiding Python's strftime
1298 * wrapper and calling the C strftime() directly, but that isn't
1299 * an option in the Python implementation of this module.
1300 */
1301 {
1302 long year;
1303 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1304 if (pyyear == NULL) return NULL;
1305 assert(PyLong_Check(pyyear));
1306 year = PyLong_AsLong(pyyear);
1307 Py_DECREF(pyyear);
1308 if (year < 1900) {
1309 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1310 "1900; the datetime strftime() "
1311 "methods require year >= 1900",
1312 year);
1313 return NULL;
1314 }
1315 }
Tim Petersd6844152002-12-22 20:58:42 +00001316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 /* Scan the input format, looking for %z/%Z/%f escapes, building
1318 * a new format. Since computing the replacements for those codes
1319 * is expensive, don't unless they're actually used.
1320 */
1321 if (flen > INT_MAX - 1) {
1322 PyErr_NoMemory();
1323 goto Done;
1324 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 totalnew = flen + 1; /* realistic if no %z/%Z */
1327 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1328 if (newfmt == NULL) goto Done;
1329 pnew = PyBytes_AsString(newfmt);
1330 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 while ((ch = *pin++) != '\0') {
1333 if (ch != '%') {
1334 ptoappend = pin - 1;
1335 ntoappend = 1;
1336 }
1337 else if ((ch = *pin++) == '\0') {
1338 /* There's a lone trailing %; doesn't make sense. */
1339 PyErr_SetString(PyExc_ValueError, "strftime format "
1340 "ends with raw %");
1341 goto Done;
1342 }
1343 /* A % has been seen and ch is the character after it. */
1344 else if (ch == 'z') {
1345 if (zreplacement == NULL) {
1346 /* format utcoffset */
1347 char buf[100];
1348 PyObject *tzinfo = get_tzinfo_member(object);
1349 zreplacement = PyBytes_FromStringAndSize("", 0);
1350 if (zreplacement == NULL) goto Done;
1351 if (tzinfo != Py_None && tzinfo != NULL) {
1352 assert(tzinfoarg != NULL);
1353 if (format_utcoffset(buf,
1354 sizeof(buf),
1355 "",
1356 tzinfo,
1357 tzinfoarg) < 0)
1358 goto Done;
1359 Py_DECREF(zreplacement);
1360 zreplacement =
1361 PyBytes_FromStringAndSize(buf,
1362 strlen(buf));
1363 if (zreplacement == NULL)
1364 goto Done;
1365 }
1366 }
1367 assert(zreplacement != NULL);
1368 ptoappend = PyBytes_AS_STRING(zreplacement);
1369 ntoappend = PyBytes_GET_SIZE(zreplacement);
1370 }
1371 else if (ch == 'Z') {
1372 /* format tzname */
1373 if (Zreplacement == NULL) {
1374 Zreplacement = make_Zreplacement(object,
1375 tzinfoarg);
1376 if (Zreplacement == NULL)
1377 goto Done;
1378 }
1379 assert(Zreplacement != NULL);
1380 assert(PyUnicode_Check(Zreplacement));
1381 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1382 &ntoappend);
1383 ntoappend = Py_SIZE(Zreplacement);
1384 }
1385 else if (ch == 'f') {
1386 /* format microseconds */
1387 if (freplacement == NULL) {
1388 freplacement = make_freplacement(object);
1389 if (freplacement == NULL)
1390 goto Done;
1391 }
1392 assert(freplacement != NULL);
1393 assert(PyBytes_Check(freplacement));
1394 ptoappend = PyBytes_AS_STRING(freplacement);
1395 ntoappend = PyBytes_GET_SIZE(freplacement);
1396 }
1397 else {
1398 /* percent followed by neither z nor Z */
1399 ptoappend = pin - 2;
1400 ntoappend = 2;
1401 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 /* Append the ntoappend chars starting at ptoappend to
1404 * the new format.
1405 */
1406 if (ntoappend == 0)
1407 continue;
1408 assert(ptoappend != NULL);
1409 assert(ntoappend > 0);
1410 while (usednew + ntoappend > totalnew) {
1411 size_t bigger = totalnew << 1;
1412 if ((bigger >> 1) != totalnew) { /* overflow */
1413 PyErr_NoMemory();
1414 goto Done;
1415 }
1416 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1417 goto Done;
1418 totalnew = bigger;
1419 pnew = PyBytes_AsString(newfmt) + usednew;
1420 }
1421 memcpy(pnew, ptoappend, ntoappend);
1422 pnew += ntoappend;
1423 usednew += ntoappend;
1424 assert(usednew <= totalnew);
1425 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1428 goto Done;
1429 {
1430 PyObject *format;
1431 PyObject *time = PyImport_ImportModuleNoBlock("time");
1432 if (time == NULL)
1433 goto Done;
1434 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1435 if (format != NULL) {
1436 result = PyObject_CallMethod(time, "strftime", "OO",
1437 format, timetuple);
1438 Py_DECREF(format);
1439 }
1440 Py_DECREF(time);
1441 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001442 Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 Py_XDECREF(freplacement);
1444 Py_XDECREF(zreplacement);
1445 Py_XDECREF(Zreplacement);
1446 Py_XDECREF(newfmt);
1447 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001448}
1449
Tim Peters2a799bf2002-12-16 20:18:38 +00001450/* ---------------------------------------------------------------------------
1451 * Wrap functions from the time module. These aren't directly available
1452 * from C. Perhaps they should be.
1453 */
1454
1455/* Call time.time() and return its result (a Python float). */
1456static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001457time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 PyObject *result = NULL;
1460 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 if (time != NULL) {
1463 result = PyObject_CallMethod(time, "time", "()");
1464 Py_DECREF(time);
1465 }
1466 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001467}
1468
1469/* Build a time.struct_time. The weekday and day number are automatically
1470 * computed from the y,m,d args.
1471 */
1472static PyObject *
1473build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 PyObject *time;
1476 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 time = PyImport_ImportModuleNoBlock("time");
1479 if (time != NULL) {
1480 result = PyObject_CallMethod(time, "struct_time",
1481 "((iiiiiiiii))",
1482 y, m, d,
1483 hh, mm, ss,
1484 weekday(y, m, d),
1485 days_before_month(y, m) + d,
1486 dstflag);
1487 Py_DECREF(time);
1488 }
1489 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001490}
1491
1492/* ---------------------------------------------------------------------------
1493 * Miscellaneous helpers.
1494 */
1495
Mark Dickinsone94c6792009-02-02 20:36:42 +00001496/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001497 * The comparisons here all most naturally compute a cmp()-like result.
1498 * This little helper turns that into a bool result for rich comparisons.
1499 */
1500static PyObject *
1501diff_to_bool(int diff, int op)
1502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 PyObject *result;
1504 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 switch (op) {
1507 case Py_EQ: istrue = diff == 0; break;
1508 case Py_NE: istrue = diff != 0; break;
1509 case Py_LE: istrue = diff <= 0; break;
1510 case Py_GE: istrue = diff >= 0; break;
1511 case Py_LT: istrue = diff < 0; break;
1512 case Py_GT: istrue = diff > 0; break;
1513 default:
1514 assert(! "op unknown");
1515 istrue = 0; /* To shut up compiler */
1516 }
1517 result = istrue ? Py_True : Py_False;
1518 Py_INCREF(result);
1519 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001520}
1521
Tim Peters07534a62003-02-07 22:50:28 +00001522/* Raises a "can't compare" TypeError and returns NULL. */
1523static PyObject *
1524cmperror(PyObject *a, PyObject *b)
1525{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 PyErr_Format(PyExc_TypeError,
1527 "can't compare %s to %s",
1528 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1529 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001530}
1531
Tim Peters2a799bf2002-12-16 20:18:38 +00001532/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001533 * Cached Python objects; these are set by the module init function.
1534 */
1535
1536/* Conversion factors. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537static PyObject *us_per_us = NULL; /* 1 */
1538static PyObject *us_per_ms = NULL; /* 1000 */
1539static PyObject *us_per_second = NULL; /* 1000000 */
1540static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1541static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1542static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1543static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001544static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1545
Tim Peters2a799bf2002-12-16 20:18:38 +00001546/* ---------------------------------------------------------------------------
1547 * Class implementations.
1548 */
1549
1550/*
1551 * PyDateTime_Delta implementation.
1552 */
1553
1554/* Convert a timedelta to a number of us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001556 * as a Python int or long.
1557 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1558 * due to ubiquitous overflow possibilities.
1559 */
1560static PyObject *
1561delta_to_microseconds(PyDateTime_Delta *self)
1562{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 PyObject *x1 = NULL;
1564 PyObject *x2 = NULL;
1565 PyObject *x3 = NULL;
1566 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1569 if (x1 == NULL)
1570 goto Done;
1571 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1572 if (x2 == NULL)
1573 goto Done;
1574 Py_DECREF(x1);
1575 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 /* x2 has days in seconds */
1578 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1579 if (x1 == NULL)
1580 goto Done;
1581 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1582 if (x3 == NULL)
1583 goto Done;
1584 Py_DECREF(x1);
1585 Py_DECREF(x2);
1586 x1 = x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 /* x3 has days+seconds in seconds */
1589 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1590 if (x1 == NULL)
1591 goto Done;
1592 Py_DECREF(x3);
1593 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 /* x1 has days+seconds in us */
1596 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1597 if (x2 == NULL)
1598 goto Done;
1599 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001600
1601Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 Py_XDECREF(x1);
1603 Py_XDECREF(x2);
1604 Py_XDECREF(x3);
1605 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001606}
1607
1608/* Convert a number of us (as a Python int or long) to a timedelta.
1609 */
1610static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001611microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 int us;
1614 int s;
1615 int d;
1616 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 PyObject *tuple = NULL;
1619 PyObject *num = NULL;
1620 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 tuple = PyNumber_Divmod(pyus, us_per_second);
1623 if (tuple == NULL)
1624 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 num = PyTuple_GetItem(tuple, 1); /* us */
1627 if (num == NULL)
1628 goto Done;
1629 temp = PyLong_AsLong(num);
1630 num = NULL;
1631 if (temp == -1 && PyErr_Occurred())
1632 goto Done;
1633 assert(0 <= temp && temp < 1000000);
1634 us = (int)temp;
1635 if (us < 0) {
1636 /* The divisor was positive, so this must be an error. */
1637 assert(PyErr_Occurred());
1638 goto Done;
1639 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1642 if (num == NULL)
1643 goto Done;
1644 Py_INCREF(num);
1645 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001646
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 tuple = PyNumber_Divmod(num, seconds_per_day);
1648 if (tuple == NULL)
1649 goto Done;
1650 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001652 num = PyTuple_GetItem(tuple, 1); /* seconds */
1653 if (num == NULL)
1654 goto Done;
1655 temp = PyLong_AsLong(num);
1656 num = NULL;
1657 if (temp == -1 && PyErr_Occurred())
1658 goto Done;
1659 assert(0 <= temp && temp < 24*3600);
1660 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 if (s < 0) {
1663 /* The divisor was positive, so this must be an error. */
1664 assert(PyErr_Occurred());
1665 goto Done;
1666 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1669 if (num == NULL)
1670 goto Done;
1671 Py_INCREF(num);
1672 temp = PyLong_AsLong(num);
1673 if (temp == -1 && PyErr_Occurred())
1674 goto Done;
1675 d = (int)temp;
1676 if ((long)d != temp) {
1677 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1678 "large to fit in a C int");
1679 goto Done;
1680 }
1681 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001682
1683Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 Py_XDECREF(tuple);
1685 Py_XDECREF(num);
1686 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001687}
1688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689#define microseconds_to_delta(pymicros) \
1690 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001691
Tim Peters2a799bf2002-12-16 20:18:38 +00001692static PyObject *
1693multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001695 PyObject *pyus_in;
1696 PyObject *pyus_out;
1697 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 pyus_in = delta_to_microseconds(delta);
1700 if (pyus_in == NULL)
1701 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1704 Py_DECREF(pyus_in);
1705 if (pyus_out == NULL)
1706 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 result = microseconds_to_delta(pyus_out);
1709 Py_DECREF(pyus_out);
1710 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001711}
1712
1713static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001714multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1715{
1716 PyObject *result = NULL;
1717 PyObject *pyus_in = NULL, *temp, *pyus_out;
1718 PyObject *ratio = NULL;
1719
1720 pyus_in = delta_to_microseconds(delta);
1721 if (pyus_in == NULL)
1722 return NULL;
1723 ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
1724 if (ratio == NULL)
1725 goto error;
1726 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1727 Py_DECREF(pyus_in);
1728 pyus_in = NULL;
1729 if (temp == NULL)
1730 goto error;
1731 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1732 Py_DECREF(temp);
1733 if (pyus_out == NULL)
1734 goto error;
1735 result = microseconds_to_delta(pyus_out);
1736 Py_DECREF(pyus_out);
1737 error:
1738 Py_XDECREF(pyus_in);
1739 Py_XDECREF(ratio);
1740
1741 return result;
1742}
1743
1744static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001745divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 PyObject *pyus_in;
1748 PyObject *pyus_out;
1749 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 pyus_in = delta_to_microseconds(delta);
1752 if (pyus_in == NULL)
1753 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001755 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1756 Py_DECREF(pyus_in);
1757 if (pyus_out == NULL)
1758 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001759
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 result = microseconds_to_delta(pyus_out);
1761 Py_DECREF(pyus_out);
1762 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001763}
1764
1765static PyObject *
Mark Dickinson7c186e22010-04-20 22:32:49 +00001766divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1767{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 PyObject *pyus_left;
1769 PyObject *pyus_right;
1770 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 pyus_left = delta_to_microseconds(left);
1773 if (pyus_left == NULL)
1774 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001775
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 pyus_right = delta_to_microseconds(right);
1777 if (pyus_right == NULL) {
1778 Py_DECREF(pyus_left);
1779 return NULL;
1780 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 result = PyNumber_FloorDivide(pyus_left, pyus_right);
1783 Py_DECREF(pyus_left);
1784 Py_DECREF(pyus_right);
1785 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001786}
1787
1788static PyObject *
1789truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1790{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001791 PyObject *pyus_left;
1792 PyObject *pyus_right;
1793 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001795 pyus_left = delta_to_microseconds(left);
1796 if (pyus_left == NULL)
1797 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 pyus_right = delta_to_microseconds(right);
1800 if (pyus_right == NULL) {
1801 Py_DECREF(pyus_left);
1802 return NULL;
1803 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00001804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 result = PyNumber_TrueDivide(pyus_left, pyus_right);
1806 Py_DECREF(pyus_left);
1807 Py_DECREF(pyus_right);
1808 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00001809}
1810
1811static PyObject *
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001812truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1813{
1814 PyObject *result = NULL;
1815 PyObject *pyus_in = NULL, *temp, *pyus_out;
1816 PyObject *ratio = NULL;
1817
1818 pyus_in = delta_to_microseconds(delta);
1819 if (pyus_in == NULL)
1820 return NULL;
1821 ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
1822 if (ratio == NULL)
1823 goto error;
1824 temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1825 Py_DECREF(pyus_in);
1826 pyus_in = NULL;
1827 if (temp == NULL)
1828 goto error;
1829 pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1830 Py_DECREF(temp);
1831 if (pyus_out == NULL)
1832 goto error;
1833 result = microseconds_to_delta(pyus_out);
1834 Py_DECREF(pyus_out);
1835 error:
1836 Py_XDECREF(pyus_in);
1837 Py_XDECREF(ratio);
1838
1839 return result;
1840}
1841
1842static PyObject *
1843truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1844{
1845 PyObject *result;
1846 PyObject *pyus_in, *pyus_out;
1847 pyus_in = delta_to_microseconds(delta);
1848 if (pyus_in == NULL)
1849 return NULL;
1850 pyus_out = divide_nearest(pyus_in, i);
1851 Py_DECREF(pyus_in);
1852 if (pyus_out == NULL)
1853 return NULL;
1854 result = microseconds_to_delta(pyus_out);
1855 Py_DECREF(pyus_out);
1856
1857 return result;
1858}
1859
1860static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00001861delta_add(PyObject *left, PyObject *right)
1862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001864
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1866 /* delta + delta */
1867 /* The C-level additions can't overflow because of the
1868 * invariant bounds.
1869 */
1870 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1871 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1872 int microseconds = GET_TD_MICROSECONDS(left) +
1873 GET_TD_MICROSECONDS(right);
1874 result = new_delta(days, seconds, microseconds, 1);
1875 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 if (result == Py_NotImplemented)
1878 Py_INCREF(result);
1879 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001880}
1881
1882static PyObject *
1883delta_negative(PyDateTime_Delta *self)
1884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 return new_delta(-GET_TD_DAYS(self),
1886 -GET_TD_SECONDS(self),
1887 -GET_TD_MICROSECONDS(self),
1888 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001889}
1890
1891static PyObject *
1892delta_positive(PyDateTime_Delta *self)
1893{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 /* Could optimize this (by returning self) if this isn't a
1895 * subclass -- but who uses unary + ? Approximately nobody.
1896 */
1897 return new_delta(GET_TD_DAYS(self),
1898 GET_TD_SECONDS(self),
1899 GET_TD_MICROSECONDS(self),
1900 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001901}
1902
1903static PyObject *
1904delta_abs(PyDateTime_Delta *self)
1905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 assert(GET_TD_MICROSECONDS(self) >= 0);
1909 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (GET_TD_DAYS(self) < 0)
1912 result = delta_negative(self);
1913 else
1914 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001917}
1918
1919static PyObject *
1920delta_subtract(PyObject *left, PyObject *right)
1921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1925 /* delta - delta */
1926 PyObject *minus_right = PyNumber_Negative(right);
1927 if (minus_right) {
1928 result = delta_add(left, minus_right);
1929 Py_DECREF(minus_right);
1930 }
1931 else
1932 result = NULL;
1933 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 if (result == Py_NotImplemented)
1936 Py_INCREF(result);
1937 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001938}
1939
Tim Peters2a799bf2002-12-16 20:18:38 +00001940static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001941delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001942{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 if (PyDelta_Check(other)) {
1944 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1945 if (diff == 0) {
1946 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1947 if (diff == 0)
1948 diff = GET_TD_MICROSECONDS(self) -
1949 GET_TD_MICROSECONDS(other);
1950 }
1951 return diff_to_bool(diff, op);
1952 }
1953 else {
1954 Py_INCREF(Py_NotImplemented);
1955 return Py_NotImplemented;
1956 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001957}
1958
1959static PyObject *delta_getstate(PyDateTime_Delta *self);
1960
1961static long
1962delta_hash(PyDateTime_Delta *self)
1963{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 if (self->hashcode == -1) {
1965 PyObject *temp = delta_getstate(self);
1966 if (temp != NULL) {
1967 self->hashcode = PyObject_Hash(temp);
1968 Py_DECREF(temp);
1969 }
1970 }
1971 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001972}
1973
1974static PyObject *
1975delta_multiply(PyObject *left, PyObject *right)
1976{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001977 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 if (PyDelta_Check(left)) {
1980 /* delta * ??? */
1981 if (PyLong_Check(right))
1982 result = multiply_int_timedelta(right,
1983 (PyDateTime_Delta *) left);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001984 else if (PyFloat_Check(right))
1985 result = multiply_float_timedelta(right,
1986 (PyDateTime_Delta *) left);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 }
1988 else if (PyLong_Check(left))
1989 result = multiply_int_timedelta(left,
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00001990 (PyDateTime_Delta *) right);
1991 else if (PyFloat_Check(left))
1992 result = multiply_float_timedelta(left,
1993 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 if (result == Py_NotImplemented)
1996 Py_INCREF(result);
1997 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001998}
1999
2000static PyObject *
2001delta_divide(PyObject *left, PyObject *right)
2002{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 if (PyDelta_Check(left)) {
2006 /* delta * ??? */
2007 if (PyLong_Check(right))
2008 result = divide_timedelta_int(
2009 (PyDateTime_Delta *)left,
2010 right);
2011 else if (PyDelta_Check(right))
2012 result = divide_timedelta_timedelta(
2013 (PyDateTime_Delta *)left,
2014 (PyDateTime_Delta *)right);
2015 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 if (result == Py_NotImplemented)
2018 Py_INCREF(result);
2019 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002020}
2021
Mark Dickinson7c186e22010-04-20 22:32:49 +00002022static PyObject *
2023delta_truedivide(PyObject *left, PyObject *right)
2024{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 PyObject *result = Py_NotImplemented;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 if (PyDelta_Check(left)) {
2028 if (PyDelta_Check(right))
2029 result = truedivide_timedelta_timedelta(
2030 (PyDateTime_Delta *)left,
2031 (PyDateTime_Delta *)right);
Alexander Belopolsky1790bc42010-05-31 17:33:47 +00002032 else if (PyFloat_Check(right))
2033 result = truedivide_timedelta_float(
2034 (PyDateTime_Delta *)left, right);
2035 else if (PyLong_Check(right))
2036 result = truedivide_timedelta_int(
2037 (PyDateTime_Delta *)left, right);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002038 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 if (result == Py_NotImplemented)
2041 Py_INCREF(result);
2042 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002043}
2044
2045static PyObject *
2046delta_remainder(PyObject *left, PyObject *right)
2047{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 PyObject *pyus_left;
2049 PyObject *pyus_right;
2050 PyObject *pyus_remainder;
2051 PyObject *remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
2054 Py_INCREF(Py_NotImplemented);
2055 return Py_NotImplemented;
2056 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2059 if (pyus_left == NULL)
2060 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002062 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2063 if (pyus_right == NULL) {
2064 Py_DECREF(pyus_left);
2065 return NULL;
2066 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2069 Py_DECREF(pyus_left);
2070 Py_DECREF(pyus_right);
2071 if (pyus_remainder == NULL)
2072 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 remainder = microseconds_to_delta(pyus_remainder);
2075 Py_DECREF(pyus_remainder);
2076 if (remainder == NULL)
2077 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002079 return remainder;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002080}
2081
2082static PyObject *
2083delta_divmod(PyObject *left, PyObject *right)
2084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 PyObject *pyus_left;
2086 PyObject *pyus_right;
2087 PyObject *divmod;
2088 PyObject *delta;
2089 PyObject *result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 if (!PyDelta_Check(left) || !PyDelta_Check(right)) {
2092 Py_INCREF(Py_NotImplemented);
2093 return Py_NotImplemented;
2094 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2097 if (pyus_left == NULL)
2098 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2101 if (pyus_right == NULL) {
2102 Py_DECREF(pyus_left);
2103 return NULL;
2104 }
Mark Dickinson7c186e22010-04-20 22:32:49 +00002105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 divmod = PyNumber_Divmod(pyus_left, pyus_right);
2107 Py_DECREF(pyus_left);
2108 Py_DECREF(pyus_right);
2109 if (divmod == NULL)
2110 return NULL;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 assert(PyTuple_Size(divmod) == 2);
2113 delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2114 if (delta == NULL) {
2115 Py_DECREF(divmod);
2116 return NULL;
2117 }
2118 result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2119 Py_DECREF(delta);
2120 Py_DECREF(divmod);
2121 return result;
Mark Dickinson7c186e22010-04-20 22:32:49 +00002122}
2123
Tim Peters2a799bf2002-12-16 20:18:38 +00002124/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2125 * timedelta constructor. sofar is the # of microseconds accounted for
2126 * so far, and there are factor microseconds per current unit, the number
2127 * of which is given by num. num * factor is added to sofar in a
2128 * numerically careful way, and that's the result. Any fractional
2129 * microseconds left over (this can happen if num is a float type) are
2130 * added into *leftover.
2131 * Note that there are many ways this can give an error (NULL) return.
2132 */
2133static PyObject *
2134accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2135 double *leftover)
2136{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 PyObject *prod;
2138 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00002139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00002141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 if (PyLong_Check(num)) {
2143 prod = PyNumber_Multiply(num, factor);
2144 if (prod == NULL)
2145 return NULL;
2146 sum = PyNumber_Add(sofar, prod);
2147 Py_DECREF(prod);
2148 return sum;
2149 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 if (PyFloat_Check(num)) {
2152 double dnum;
2153 double fracpart;
2154 double intpart;
2155 PyObject *x;
2156 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00002157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 /* The Plan: decompose num into an integer part and a
2159 * fractional part, num = intpart + fracpart.
2160 * Then num * factor ==
2161 * intpart * factor + fracpart * factor
2162 * and the LHS can be computed exactly in long arithmetic.
2163 * The RHS is again broken into an int part and frac part.
2164 * and the frac part is added into *leftover.
2165 */
2166 dnum = PyFloat_AsDouble(num);
2167 if (dnum == -1.0 && PyErr_Occurred())
2168 return NULL;
2169 fracpart = modf(dnum, &intpart);
2170 x = PyLong_FromDouble(intpart);
2171 if (x == NULL)
2172 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002174 prod = PyNumber_Multiply(x, factor);
2175 Py_DECREF(x);
2176 if (prod == NULL)
2177 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 sum = PyNumber_Add(sofar, prod);
2180 Py_DECREF(prod);
2181 if (sum == NULL)
2182 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 if (fracpart == 0.0)
2185 return sum;
2186 /* So far we've lost no information. Dealing with the
2187 * fractional part requires float arithmetic, and may
2188 * lose a little info.
2189 */
2190 assert(PyLong_Check(factor));
2191 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00002192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002193 dnum *= fracpart;
2194 fracpart = modf(dnum, &intpart);
2195 x = PyLong_FromDouble(intpart);
2196 if (x == NULL) {
2197 Py_DECREF(sum);
2198 return NULL;
2199 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002201 y = PyNumber_Add(sum, x);
2202 Py_DECREF(sum);
2203 Py_DECREF(x);
2204 *leftover += fracpart;
2205 return y;
2206 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002208 PyErr_Format(PyExc_TypeError,
2209 "unsupported type for timedelta %s component: %s",
2210 tag, Py_TYPE(num)->tp_name);
2211 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002212}
2213
2214static PyObject *
2215delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219 /* Argument objects. */
2220 PyObject *day = NULL;
2221 PyObject *second = NULL;
2222 PyObject *us = NULL;
2223 PyObject *ms = NULL;
2224 PyObject *minute = NULL;
2225 PyObject *hour = NULL;
2226 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 PyObject *x = NULL; /* running sum of microseconds */
2229 PyObject *y = NULL; /* temp sum of microseconds */
2230 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00002231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 static char *keywords[] = {
2233 "days", "seconds", "microseconds", "milliseconds",
2234 "minutes", "hours", "weeks", NULL
2235 };
Tim Peters2a799bf2002-12-16 20:18:38 +00002236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002237 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2238 keywords,
2239 &day, &second, &us,
2240 &ms, &minute, &hour, &week) == 0)
2241 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002243 x = PyLong_FromLong(0);
2244 if (x == NULL)
2245 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00002246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247#define CLEANUP \
2248 Py_DECREF(x); \
2249 x = y; \
2250 if (x == NULL) \
2251 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00002252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 if (us) {
2254 y = accum("microseconds", x, us, us_per_us, &leftover_us);
2255 CLEANUP;
2256 }
2257 if (ms) {
2258 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2259 CLEANUP;
2260 }
2261 if (second) {
2262 y = accum("seconds", x, second, us_per_second, &leftover_us);
2263 CLEANUP;
2264 }
2265 if (minute) {
2266 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2267 CLEANUP;
2268 }
2269 if (hour) {
2270 y = accum("hours", x, hour, us_per_hour, &leftover_us);
2271 CLEANUP;
2272 }
2273 if (day) {
2274 y = accum("days", x, day, us_per_day, &leftover_us);
2275 CLEANUP;
2276 }
2277 if (week) {
2278 y = accum("weeks", x, week, us_per_week, &leftover_us);
2279 CLEANUP;
2280 }
2281 if (leftover_us) {
2282 /* Round to nearest whole # of us, and add into x. */
2283 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
2284 if (temp == NULL) {
2285 Py_DECREF(x);
2286 goto Done;
2287 }
2288 y = PyNumber_Add(x, temp);
2289 Py_DECREF(temp);
2290 CLEANUP;
2291 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002293 self = microseconds_to_delta_ex(x, type);
2294 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00002295Done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002297
2298#undef CLEANUP
2299}
2300
2301static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002302delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 return (GET_TD_DAYS(self) != 0
2305 || GET_TD_SECONDS(self) != 0
2306 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002307}
2308
2309static PyObject *
2310delta_repr(PyDateTime_Delta *self)
2311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 if (GET_TD_MICROSECONDS(self) != 0)
2313 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2314 Py_TYPE(self)->tp_name,
2315 GET_TD_DAYS(self),
2316 GET_TD_SECONDS(self),
2317 GET_TD_MICROSECONDS(self));
2318 if (GET_TD_SECONDS(self) != 0)
2319 return PyUnicode_FromFormat("%s(%d, %d)",
2320 Py_TYPE(self)->tp_name,
2321 GET_TD_DAYS(self),
2322 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002324 return PyUnicode_FromFormat("%s(%d)",
2325 Py_TYPE(self)->tp_name,
2326 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002327}
2328
2329static PyObject *
2330delta_str(PyDateTime_Delta *self)
2331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002332 int us = GET_TD_MICROSECONDS(self);
2333 int seconds = GET_TD_SECONDS(self);
2334 int minutes = divmod(seconds, 60, &seconds);
2335 int hours = divmod(minutes, 60, &minutes);
2336 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002338 if (days) {
2339 if (us)
2340 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2341 days, (days == 1 || days == -1) ? "" : "s",
2342 hours, minutes, seconds, us);
2343 else
2344 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2345 days, (days == 1 || days == -1) ? "" : "s",
2346 hours, minutes, seconds);
2347 } else {
2348 if (us)
2349 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2350 hours, minutes, seconds, us);
2351 else
2352 return PyUnicode_FromFormat("%d:%02d:%02d",
2353 hours, minutes, seconds);
2354 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002355
Tim Peters2a799bf2002-12-16 20:18:38 +00002356}
2357
Tim Peters371935f2003-02-01 01:52:50 +00002358/* Pickle support, a simple use of __reduce__. */
2359
Tim Petersb57f8f02003-02-01 02:54:15 +00002360/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002361static PyObject *
2362delta_getstate(PyDateTime_Delta *self)
2363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 return Py_BuildValue("iii", GET_TD_DAYS(self),
2365 GET_TD_SECONDS(self),
2366 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002367}
2368
Tim Peters2a799bf2002-12-16 20:18:38 +00002369static PyObject *
Antoine Pitroube6859d2009-11-25 23:02:32 +00002370delta_total_seconds(PyObject *self)
2371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372 PyObject *total_seconds;
2373 PyObject *total_microseconds;
2374 PyObject *one_million;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2377 if (total_microseconds == NULL)
2378 return NULL;
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 one_million = PyLong_FromLong(1000000L);
2381 if (one_million == NULL) {
2382 Py_DECREF(total_microseconds);
2383 return NULL;
2384 }
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Mark Dickinson0381e3f2010-05-08 14:35:02 +00002387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 Py_DECREF(total_microseconds);
2389 Py_DECREF(one_million);
2390 return total_seconds;
Antoine Pitroube6859d2009-11-25 23:02:32 +00002391}
2392
2393static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002394delta_reduce(PyDateTime_Delta* self)
2395{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002397}
2398
2399#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2400
2401static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 {"days", T_INT, OFFSET(days), READONLY,
2404 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 {"seconds", T_INT, OFFSET(seconds), READONLY,
2407 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2410 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2411 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002412};
2413
2414static PyMethodDef delta_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2416 PyDoc_STR("Total seconds in the duration.")},
Antoine Pitroube6859d2009-11-25 23:02:32 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2419 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002420
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002422};
2423
2424static char delta_doc[] =
2425PyDoc_STR("Difference between two datetime values.");
2426
2427static PyNumberMethods delta_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 delta_add, /* nb_add */
2429 delta_subtract, /* nb_subtract */
2430 delta_multiply, /* nb_multiply */
2431 delta_remainder, /* nb_remainder */
2432 delta_divmod, /* nb_divmod */
2433 0, /* nb_power */
2434 (unaryfunc)delta_negative, /* nb_negative */
2435 (unaryfunc)delta_positive, /* nb_positive */
2436 (unaryfunc)delta_abs, /* nb_absolute */
2437 (inquiry)delta_bool, /* nb_bool */
2438 0, /*nb_invert*/
2439 0, /*nb_lshift*/
2440 0, /*nb_rshift*/
2441 0, /*nb_and*/
2442 0, /*nb_xor*/
2443 0, /*nb_or*/
2444 0, /*nb_int*/
2445 0, /*nb_reserved*/
2446 0, /*nb_float*/
2447 0, /*nb_inplace_add*/
2448 0, /*nb_inplace_subtract*/
2449 0, /*nb_inplace_multiply*/
2450 0, /*nb_inplace_remainder*/
2451 0, /*nb_inplace_power*/
2452 0, /*nb_inplace_lshift*/
2453 0, /*nb_inplace_rshift*/
2454 0, /*nb_inplace_and*/
2455 0, /*nb_inplace_xor*/
2456 0, /*nb_inplace_or*/
2457 delta_divide, /* nb_floor_divide */
2458 delta_truedivide, /* nb_true_divide */
2459 0, /* nb_inplace_floor_divide */
2460 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002461};
2462
2463static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 PyVarObject_HEAD_INIT(NULL, 0)
2465 "datetime.timedelta", /* tp_name */
2466 sizeof(PyDateTime_Delta), /* tp_basicsize */
2467 0, /* tp_itemsize */
2468 0, /* tp_dealloc */
2469 0, /* tp_print */
2470 0, /* tp_getattr */
2471 0, /* tp_setattr */
2472 0, /* tp_reserved */
2473 (reprfunc)delta_repr, /* tp_repr */
2474 &delta_as_number, /* tp_as_number */
2475 0, /* tp_as_sequence */
2476 0, /* tp_as_mapping */
2477 (hashfunc)delta_hash, /* tp_hash */
2478 0, /* tp_call */
2479 (reprfunc)delta_str, /* tp_str */
2480 PyObject_GenericGetAttr, /* tp_getattro */
2481 0, /* tp_setattro */
2482 0, /* tp_as_buffer */
2483 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2484 delta_doc, /* tp_doc */
2485 0, /* tp_traverse */
2486 0, /* tp_clear */
2487 delta_richcompare, /* tp_richcompare */
2488 0, /* tp_weaklistoffset */
2489 0, /* tp_iter */
2490 0, /* tp_iternext */
2491 delta_methods, /* tp_methods */
2492 delta_members, /* tp_members */
2493 0, /* tp_getset */
2494 0, /* tp_base */
2495 0, /* tp_dict */
2496 0, /* tp_descr_get */
2497 0, /* tp_descr_set */
2498 0, /* tp_dictoffset */
2499 0, /* tp_init */
2500 0, /* tp_alloc */
2501 delta_new, /* tp_new */
2502 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002503};
2504
2505/*
2506 * PyDateTime_Date implementation.
2507 */
2508
2509/* Accessor properties. */
2510
2511static PyObject *
2512date_year(PyDateTime_Date *self, void *unused)
2513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002514 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002515}
2516
2517static PyObject *
2518date_month(PyDateTime_Date *self, void *unused)
2519{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002521}
2522
2523static PyObject *
2524date_day(PyDateTime_Date *self, void *unused)
2525{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002526 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002527}
2528
2529static PyGetSetDef date_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002530 {"year", (getter)date_year},
2531 {"month", (getter)date_month},
2532 {"day", (getter)date_day},
2533 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002534};
2535
2536/* Constructors. */
2537
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002538static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002539
Tim Peters2a799bf2002-12-16 20:18:38 +00002540static PyObject *
2541date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002543 PyObject *self = NULL;
2544 PyObject *state;
2545 int year;
2546 int month;
2547 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002549 /* Check for invocation from pickle with __getstate__ state */
2550 if (PyTuple_GET_SIZE(args) == 1 &&
2551 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2552 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2553 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2554 {
2555 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002557 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2558 if (me != NULL) {
2559 char *pdata = PyBytes_AS_STRING(state);
2560 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2561 me->hashcode = -1;
2562 }
2563 return (PyObject *)me;
2564 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002566 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2567 &year, &month, &day)) {
2568 if (check_date_args(year, month, day) < 0)
2569 return NULL;
2570 self = new_date_ex(year, month, day, type);
2571 }
2572 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002573}
2574
2575/* Return new date from localtime(t). */
2576static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002577date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002578{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002579 struct tm *tm;
2580 time_t t;
2581 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002583 t = _PyTime_DoubleToTimet(ts);
2584 if (t == (time_t)-1 && PyErr_Occurred())
2585 return NULL;
2586 tm = localtime(&t);
2587 if (tm)
2588 result = PyObject_CallFunction(cls, "iii",
2589 tm->tm_year + 1900,
2590 tm->tm_mon + 1,
2591 tm->tm_mday);
2592 else
2593 PyErr_SetString(PyExc_ValueError,
2594 "timestamp out of range for "
2595 "platform localtime() function");
2596 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002597}
2598
2599/* Return new date from current time.
2600 * We say this is equivalent to fromtimestamp(time.time()), and the
2601 * only way to be sure of that is to *call* time.time(). That's not
2602 * generally the same as calling C's time.
2603 */
2604static PyObject *
2605date_today(PyObject *cls, PyObject *dummy)
2606{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 PyObject *time;
2608 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002610 time = time_time();
2611 if (time == NULL)
2612 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002614 /* Note well: today() is a class method, so this may not call
2615 * date.fromtimestamp. For example, it may call
2616 * datetime.fromtimestamp. That's why we need all the accuracy
2617 * time.time() delivers; if someone were gonzo about optimization,
2618 * date.today() could get away with plain C time().
2619 */
2620 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2621 Py_DECREF(time);
2622 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002623}
2624
2625/* Return new date from given timestamp (Python timestamp -- a double). */
2626static PyObject *
2627date_fromtimestamp(PyObject *cls, PyObject *args)
2628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002629 double timestamp;
2630 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002632 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2633 result = date_local_from_time_t(cls, timestamp);
2634 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002635}
2636
2637/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2638 * the ordinal is out of range.
2639 */
2640static PyObject *
2641date_fromordinal(PyObject *cls, PyObject *args)
2642{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643 PyObject *result = NULL;
2644 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002646 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2647 int year;
2648 int month;
2649 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002651 if (ordinal < 1)
2652 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2653 ">= 1");
2654 else {
2655 ord_to_ymd(ordinal, &year, &month, &day);
2656 result = PyObject_CallFunction(cls, "iii",
2657 year, month, day);
2658 }
2659 }
2660 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002661}
2662
2663/*
2664 * Date arithmetic.
2665 */
2666
2667/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2668 * instead.
2669 */
2670static PyObject *
2671add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002673 PyObject *result = NULL;
2674 int year = GET_YEAR(date);
2675 int month = GET_MONTH(date);
2676 int deltadays = GET_TD_DAYS(delta);
2677 /* C-level overflow is impossible because |deltadays| < 1e9. */
2678 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002680 if (normalize_date(&year, &month, &day) >= 0)
2681 result = new_date(year, month, day);
2682 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002683}
2684
2685static PyObject *
2686date_add(PyObject *left, PyObject *right)
2687{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002688 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2689 Py_INCREF(Py_NotImplemented);
2690 return Py_NotImplemented;
2691 }
2692 if (PyDate_Check(left)) {
2693 /* date + ??? */
2694 if (PyDelta_Check(right))
2695 /* date + delta */
2696 return add_date_timedelta((PyDateTime_Date *) left,
2697 (PyDateTime_Delta *) right,
2698 0);
2699 }
2700 else {
2701 /* ??? + date
2702 * 'right' must be one of us, or we wouldn't have been called
2703 */
2704 if (PyDelta_Check(left))
2705 /* delta + date */
2706 return add_date_timedelta((PyDateTime_Date *) right,
2707 (PyDateTime_Delta *) left,
2708 0);
2709 }
2710 Py_INCREF(Py_NotImplemented);
2711 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002712}
2713
2714static PyObject *
2715date_subtract(PyObject *left, PyObject *right)
2716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002717 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2718 Py_INCREF(Py_NotImplemented);
2719 return Py_NotImplemented;
2720 }
2721 if (PyDate_Check(left)) {
2722 if (PyDate_Check(right)) {
2723 /* date - date */
2724 int left_ord = ymd_to_ord(GET_YEAR(left),
2725 GET_MONTH(left),
2726 GET_DAY(left));
2727 int right_ord = ymd_to_ord(GET_YEAR(right),
2728 GET_MONTH(right),
2729 GET_DAY(right));
2730 return new_delta(left_ord - right_ord, 0, 0, 0);
2731 }
2732 if (PyDelta_Check(right)) {
2733 /* date - delta */
2734 return add_date_timedelta((PyDateTime_Date *) left,
2735 (PyDateTime_Delta *) right,
2736 1);
2737 }
2738 }
2739 Py_INCREF(Py_NotImplemented);
2740 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002741}
2742
2743
2744/* Various ways to turn a date into a string. */
2745
2746static PyObject *
2747date_repr(PyDateTime_Date *self)
2748{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002749 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2750 Py_TYPE(self)->tp_name,
2751 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002752}
2753
2754static PyObject *
2755date_isoformat(PyDateTime_Date *self)
2756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002757 return PyUnicode_FromFormat("%04d-%02d-%02d",
2758 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002759}
2760
Tim Peterse2df5ff2003-05-02 18:39:55 +00002761/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002762static PyObject *
2763date_str(PyDateTime_Date *self)
2764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002765 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002766}
2767
2768
2769static PyObject *
2770date_ctime(PyDateTime_Date *self)
2771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002772 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002773}
2774
2775static PyObject *
2776date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002778 /* This method can be inherited, and needs to call the
2779 * timetuple() method appropriate to self's class.
2780 */
2781 PyObject *result;
2782 PyObject *tuple;
2783 PyObject *format;
2784 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002786 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2787 &format))
2788 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002790 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2791 if (tuple == NULL)
2792 return NULL;
2793 result = wrap_strftime((PyObject *)self, format, tuple,
2794 (PyObject *)self);
2795 Py_DECREF(tuple);
2796 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002797}
2798
Eric Smith1ba31142007-09-11 18:06:02 +00002799static PyObject *
2800date_format(PyDateTime_Date *self, PyObject *args)
2801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002802 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002804 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2805 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002807 /* if the format is zero length, return str(self) */
2808 if (PyUnicode_GetSize(format) == 0)
2809 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002810
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002811 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002812}
2813
Tim Peters2a799bf2002-12-16 20:18:38 +00002814/* ISO methods. */
2815
2816static PyObject *
2817date_isoweekday(PyDateTime_Date *self)
2818{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002819 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002821 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002822}
2823
2824static PyObject *
2825date_isocalendar(PyDateTime_Date *self)
2826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002827 int year = GET_YEAR(self);
2828 int week1_monday = iso_week1_monday(year);
2829 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2830 int week;
2831 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002833 week = divmod(today - week1_monday, 7, &day);
2834 if (week < 0) {
2835 --year;
2836 week1_monday = iso_week1_monday(year);
2837 week = divmod(today - week1_monday, 7, &day);
2838 }
2839 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2840 ++year;
2841 week = 0;
2842 }
2843 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002844}
2845
2846/* Miscellaneous methods. */
2847
Tim Peters2a799bf2002-12-16 20:18:38 +00002848static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002849date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 if (PyDate_Check(other)) {
2852 int diff = memcmp(((PyDateTime_Date *)self)->data,
2853 ((PyDateTime_Date *)other)->data,
2854 _PyDateTime_DATE_DATASIZE);
2855 return diff_to_bool(diff, op);
2856 }
2857 else {
2858 Py_INCREF(Py_NotImplemented);
2859 return Py_NotImplemented;
2860 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002861}
2862
2863static PyObject *
2864date_timetuple(PyDateTime_Date *self)
2865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002866 return build_struct_time(GET_YEAR(self),
2867 GET_MONTH(self),
2868 GET_DAY(self),
2869 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002870}
2871
Tim Peters12bf3392002-12-24 05:41:27 +00002872static PyObject *
2873date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 PyObject *clone;
2876 PyObject *tuple;
2877 int year = GET_YEAR(self);
2878 int month = GET_MONTH(self);
2879 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002881 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2882 &year, &month, &day))
2883 return NULL;
2884 tuple = Py_BuildValue("iii", year, month, day);
2885 if (tuple == NULL)
2886 return NULL;
2887 clone = date_new(Py_TYPE(self), tuple, NULL);
2888 Py_DECREF(tuple);
2889 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002890}
2891
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002892/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002894*/
2895static long
2896generic_hash(unsigned char *data, int len)
2897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002898 register unsigned char *p;
2899 register long x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002901 p = (unsigned char *) data;
2902 x = *p << 7;
2903 while (--len >= 0)
2904 x = (1000003*x) ^ *p++;
2905 x ^= len;
2906 if (x == -1)
2907 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002908
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002909 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002910}
2911
2912
2913static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002914
2915static long
2916date_hash(PyDateTime_Date *self)
2917{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002918 if (self->hashcode == -1)
2919 self->hashcode = generic_hash(
2920 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002922 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002923}
2924
2925static PyObject *
2926date_toordinal(PyDateTime_Date *self)
2927{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002928 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2929 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002930}
2931
2932static PyObject *
2933date_weekday(PyDateTime_Date *self)
2934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002935 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002937 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002938}
2939
Tim Peters371935f2003-02-01 01:52:50 +00002940/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002941
Tim Petersb57f8f02003-02-01 02:54:15 +00002942/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002943static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002944date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002946 PyObject* field;
2947 field = PyBytes_FromStringAndSize((char*)self->data,
2948 _PyDateTime_DATE_DATASIZE);
2949 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002950}
2951
2952static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002953date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002955 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002956}
2957
2958static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002960 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002962 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2963 METH_CLASS,
2964 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2965 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002967 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2968 METH_CLASS,
2969 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2970 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002972 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2973 PyDoc_STR("Current date or datetime: same as "
2974 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002976 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002978 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2979 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002981 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2982 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002984 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2985 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002987 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2988 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002990 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2991 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2992 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002994 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2995 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002997 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2998 PyDoc_STR("Return the day of the week represented by the date.\n"
2999 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003001 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
3002 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
3003 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003005 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
3006 PyDoc_STR("Return the day of the week represented by the date.\n"
3007 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003009 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
3010 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003012 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
3013 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003016};
3017
3018static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003019PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00003020
3021static PyNumberMethods date_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003022 date_add, /* nb_add */
3023 date_subtract, /* nb_subtract */
3024 0, /* nb_multiply */
3025 0, /* nb_remainder */
3026 0, /* nb_divmod */
3027 0, /* nb_power */
3028 0, /* nb_negative */
3029 0, /* nb_positive */
3030 0, /* nb_absolute */
3031 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003032};
3033
3034static PyTypeObject PyDateTime_DateType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003035 PyVarObject_HEAD_INIT(NULL, 0)
3036 "datetime.date", /* tp_name */
3037 sizeof(PyDateTime_Date), /* tp_basicsize */
3038 0, /* tp_itemsize */
3039 0, /* tp_dealloc */
3040 0, /* tp_print */
3041 0, /* tp_getattr */
3042 0, /* tp_setattr */
3043 0, /* tp_reserved */
3044 (reprfunc)date_repr, /* tp_repr */
3045 &date_as_number, /* tp_as_number */
3046 0, /* tp_as_sequence */
3047 0, /* tp_as_mapping */
3048 (hashfunc)date_hash, /* tp_hash */
3049 0, /* tp_call */
3050 (reprfunc)date_str, /* tp_str */
3051 PyObject_GenericGetAttr, /* tp_getattro */
3052 0, /* tp_setattro */
3053 0, /* tp_as_buffer */
3054 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3055 date_doc, /* tp_doc */
3056 0, /* tp_traverse */
3057 0, /* tp_clear */
3058 date_richcompare, /* tp_richcompare */
3059 0, /* tp_weaklistoffset */
3060 0, /* tp_iter */
3061 0, /* tp_iternext */
3062 date_methods, /* tp_methods */
3063 0, /* tp_members */
3064 date_getset, /* tp_getset */
3065 0, /* tp_base */
3066 0, /* tp_dict */
3067 0, /* tp_descr_get */
3068 0, /* tp_descr_set */
3069 0, /* tp_dictoffset */
3070 0, /* tp_init */
3071 0, /* tp_alloc */
3072 date_new, /* tp_new */
3073 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003074};
3075
3076/*
Tim Peters2a799bf2002-12-16 20:18:38 +00003077 * PyDateTime_TZInfo implementation.
3078 */
3079
3080/* This is a pure abstract base class, so doesn't do anything beyond
3081 * raising NotImplemented exceptions. Real tzinfo classes need
3082 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00003083 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00003084 * be subclasses of this tzinfo class, which is easy and quick to check).
3085 *
3086 * Note: For reasons having to do with pickling of subclasses, we have
3087 * to allow tzinfo objects to be instantiated. This wasn't an issue
3088 * in the Python implementation (__init__() could raise NotImplementedError
3089 * there without ill effect), but doing so in the C implementation hit a
3090 * brick wall.
3091 */
3092
3093static PyObject *
3094tzinfo_nogo(const char* methodname)
3095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003096 PyErr_Format(PyExc_NotImplementedError,
3097 "a tzinfo subclass must implement %s()",
3098 methodname);
3099 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003100}
3101
3102/* Methods. A subclass must implement these. */
3103
Tim Peters52dcce22003-01-23 16:36:11 +00003104static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003105tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3106{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003107 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00003108}
3109
Tim Peters52dcce22003-01-23 16:36:11 +00003110static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003111tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3112{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003113 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00003114}
3115
Tim Peters52dcce22003-01-23 16:36:11 +00003116static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00003117tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3118{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003119 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00003120}
3121
Tim Peters52dcce22003-01-23 16:36:11 +00003122static PyObject *
3123tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
3124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003125 int y, m, d, hh, mm, ss, us;
Tim Peters52dcce22003-01-23 16:36:11 +00003126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003127 PyObject *result;
3128 int off, dst;
3129 int none;
3130 int delta;
Tim Peters52dcce22003-01-23 16:36:11 +00003131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003132 if (! PyDateTime_Check(dt)) {
3133 PyErr_SetString(PyExc_TypeError,
3134 "fromutc: argument must be a datetime");
3135 return NULL;
3136 }
3137 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3138 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3139 "is not self");
3140 return NULL;
3141 }
Tim Peters52dcce22003-01-23 16:36:11 +00003142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003143 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
3144 if (off == -1 && PyErr_Occurred())
3145 return NULL;
3146 if (none) {
3147 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3148 "utcoffset() result required");
3149 return NULL;
3150 }
Tim Peters52dcce22003-01-23 16:36:11 +00003151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003152 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
3153 if (dst == -1 && PyErr_Occurred())
3154 return NULL;
3155 if (none) {
3156 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3157 "dst() result required");
3158 return NULL;
3159 }
Tim Peters52dcce22003-01-23 16:36:11 +00003160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003161 y = GET_YEAR(dt);
3162 m = GET_MONTH(dt);
3163 d = GET_DAY(dt);
3164 hh = DATE_GET_HOUR(dt);
3165 mm = DATE_GET_MINUTE(dt);
3166 ss = DATE_GET_SECOND(dt);
3167 us = DATE_GET_MICROSECOND(dt);
Tim Peters52dcce22003-01-23 16:36:11 +00003168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003169 delta = off - dst;
3170 mm += delta;
3171 if ((mm < 0 || mm >= 60) &&
3172 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
3173 return NULL;
3174 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
3175 if (result == NULL)
3176 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003178 dst = call_dst(dt->tzinfo, result, &none);
3179 if (dst == -1 && PyErr_Occurred())
3180 goto Fail;
3181 if (none)
3182 goto Inconsistent;
3183 if (dst == 0)
3184 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003186 mm += dst;
3187 if ((mm < 0 || mm >= 60) &&
3188 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
3189 goto Fail;
3190 Py_DECREF(result);
3191 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
3192 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00003193
3194Inconsistent:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003195 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3196 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00003197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003198 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00003199Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003200 Py_DECREF(result);
3201 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00003202}
3203
Tim Peters2a799bf2002-12-16 20:18:38 +00003204/*
3205 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00003206 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00003207 */
3208
Guido van Rossum177e41a2003-01-30 22:06:23 +00003209static PyObject *
3210tzinfo_reduce(PyObject *self)
3211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003212 PyObject *args, *state, *tmp;
3213 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00003214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003215 tmp = PyTuple_New(0);
3216 if (tmp == NULL)
3217 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003219 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
3220 if (getinitargs != NULL) {
3221 args = PyObject_CallObject(getinitargs, tmp);
3222 Py_DECREF(getinitargs);
3223 if (args == NULL) {
3224 Py_DECREF(tmp);
3225 return NULL;
3226 }
3227 }
3228 else {
3229 PyErr_Clear();
3230 args = tmp;
3231 Py_INCREF(args);
3232 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003234 getstate = PyObject_GetAttrString(self, "__getstate__");
3235 if (getstate != NULL) {
3236 state = PyObject_CallObject(getstate, tmp);
3237 Py_DECREF(getstate);
3238 if (state == NULL) {
3239 Py_DECREF(args);
3240 Py_DECREF(tmp);
3241 return NULL;
3242 }
3243 }
3244 else {
3245 PyObject **dictptr;
3246 PyErr_Clear();
3247 state = Py_None;
3248 dictptr = _PyObject_GetDictPtr(self);
3249 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3250 state = *dictptr;
3251 Py_INCREF(state);
3252 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003254 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003256 if (state == Py_None) {
3257 Py_DECREF(state);
3258 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3259 }
3260 else
3261 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00003262}
Tim Peters2a799bf2002-12-16 20:18:38 +00003263
3264static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003266 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3267 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003269 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
Sean Reifscheiderdeda8cb2010-06-04 01:51:38 +00003270 PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3271 "values indicating West of UTC")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003273 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3274 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003276 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
Alexander Belopolsky2f194b92010-07-03 03:35:27 +00003277 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00003278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003279 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3280 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003282 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003283};
3284
3285static char tzinfo_doc[] =
3286PyDoc_STR("Abstract base class for time zone info objects.");
3287
Neal Norwitz227b5332006-03-22 09:28:35 +00003288static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003289 PyVarObject_HEAD_INIT(NULL, 0)
3290 "datetime.tzinfo", /* tp_name */
3291 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3292 0, /* tp_itemsize */
3293 0, /* tp_dealloc */
3294 0, /* tp_print */
3295 0, /* tp_getattr */
3296 0, /* tp_setattr */
3297 0, /* tp_reserved */
3298 0, /* tp_repr */
3299 0, /* tp_as_number */
3300 0, /* tp_as_sequence */
3301 0, /* tp_as_mapping */
3302 0, /* tp_hash */
3303 0, /* tp_call */
3304 0, /* tp_str */
3305 PyObject_GenericGetAttr, /* tp_getattro */
3306 0, /* tp_setattro */
3307 0, /* tp_as_buffer */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003308 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003309 tzinfo_doc, /* tp_doc */
3310 0, /* tp_traverse */
3311 0, /* tp_clear */
3312 0, /* tp_richcompare */
3313 0, /* tp_weaklistoffset */
3314 0, /* tp_iter */
3315 0, /* tp_iternext */
3316 tzinfo_methods, /* tp_methods */
3317 0, /* tp_members */
3318 0, /* tp_getset */
3319 0, /* tp_base */
3320 0, /* tp_dict */
3321 0, /* tp_descr_get */
3322 0, /* tp_descr_set */
3323 0, /* tp_dictoffset */
3324 0, /* tp_init */
3325 0, /* tp_alloc */
3326 PyType_GenericNew, /* tp_new */
3327 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003328};
3329
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003330static char *timezone_kws[] = {"offset", "name", NULL};
3331
3332static PyObject *
3333timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3334{
3335 PyObject *offset;
3336 PyObject *name = NULL;
3337 if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws,
3338 &PyDateTime_DeltaType, &offset,
3339 &PyUnicode_Type, &name))
3340 return new_timezone(offset, name);
3341
3342 return NULL;
3343}
3344
3345static void
3346timezone_dealloc(PyDateTime_TimeZone *self)
3347{
3348 Py_CLEAR(self->offset);
3349 Py_CLEAR(self->name);
3350 Py_TYPE(self)->tp_free((PyObject *)self);
3351}
3352
3353static PyObject *
3354timezone_richcompare(PyDateTime_TimeZone *self,
3355 PyDateTime_TimeZone *other, int op)
3356{
3357 if (op != Py_EQ && op != Py_NE) {
3358 Py_INCREF(Py_NotImplemented);
3359 return Py_NotImplemented;
3360 }
3361 return delta_richcompare(self->offset, other->offset, op);
3362}
3363
3364static long
3365timezone_hash(PyDateTime_TimeZone *self)
3366{
3367 return delta_hash((PyDateTime_Delta *)self->offset);
3368}
3369
3370/* Check argument type passed to tzname, utcoffset, or dst methods.
3371 Returns 0 for good argument. Returns -1 and sets exception info
3372 otherwise.
3373 */
3374static int
3375_timezone_check_argument(PyObject *dt, const char *meth)
3376{
3377 if (dt == Py_None || PyDateTime_Check(dt))
3378 return 0;
3379 PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3380 " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3381 return -1;
3382}
3383
3384static PyObject *
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003385timezone_repr(PyDateTime_TimeZone *self)
3386{
3387 /* Note that although timezone is not subclassable, it is convenient
3388 to use Py_TYPE(self)->tp_name here. */
3389 const char *type_name = Py_TYPE(self)->tp_name;
3390
3391 if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3392 return PyUnicode_FromFormat("%s.utc", type_name);
3393
3394 if (self->name == NULL)
3395 return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3396
3397 return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3398 self->name);
3399}
3400
3401
3402static PyObject *
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003403timezone_str(PyDateTime_TimeZone *self)
3404{
3405 char buf[10];
3406 int hours, minutes, seconds;
3407 PyObject *offset;
3408 char sign;
3409
3410 if (self->name != NULL) {
3411 Py_INCREF(self->name);
3412 return self->name;
3413 }
3414 /* Offset is normalized, so it is negative if days < 0 */
3415 if (GET_TD_DAYS(self->offset) < 0) {
3416 sign = '-';
3417 offset = delta_negative((PyDateTime_Delta *)self->offset);
3418 if (offset == NULL)
3419 return NULL;
3420 }
3421 else {
3422 sign = '+';
3423 offset = self->offset;
3424 Py_INCREF(offset);
3425 }
3426 /* Offset is not negative here. */
3427 seconds = GET_TD_SECONDS(offset);
3428 Py_DECREF(offset);
3429 minutes = divmod(seconds, 60, &seconds);
3430 hours = divmod(minutes, 60, &minutes);
3431 assert(seconds == 0);
3432 /* XXX ignore sub-minute data, curently not allowed. */
3433 PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes);
3434
3435 return PyUnicode_FromString(buf);
3436}
3437
3438static PyObject *
3439timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3440{
3441 if (_timezone_check_argument(dt, "tzname") == -1)
3442 return NULL;
3443
3444 return timezone_str(self);
3445}
3446
3447static PyObject *
3448timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3449{
3450 if (_timezone_check_argument(dt, "utcoffset") == -1)
3451 return NULL;
3452
3453 Py_INCREF(self->offset);
3454 return self->offset;
3455}
3456
3457static PyObject *
3458timezone_dst(PyObject *self, PyObject *dt)
3459{
3460 if (_timezone_check_argument(dt, "dst") == -1)
3461 return NULL;
3462
3463 Py_RETURN_NONE;
3464}
3465
3466static PyObject *
3467add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3468 int factor);
3469
3470static PyObject *
3471timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3472{
3473 if (! PyDateTime_Check(dt)) {
3474 PyErr_SetString(PyExc_TypeError,
3475 "fromutc: argument must be a datetime");
3476 return NULL;
3477 }
3478 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3479 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3480 "is not self");
3481 return NULL;
3482 }
3483
3484 return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3485}
3486
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003487static PyObject *
3488timezone_getinitargs(PyDateTime_TimeZone *self)
3489{
3490 if (self->name == NULL)
3491 return Py_BuildValue("(O)", self->offset);
3492 return Py_BuildValue("(OO)", self->offset, self->name);
3493}
3494
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003495static PyMethodDef timezone_methods[] = {
3496 {"tzname", (PyCFunction)timezone_tzname, METH_O,
3497 PyDoc_STR("If name is specified when timezone is created, returns the name."
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003498 " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003499
3500 {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003501 PyDoc_STR("Return fixed offset.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003502
3503 {"dst", (PyCFunction)timezone_dst, METH_O,
Alexander Belopolskyb39a0c22010-06-15 19:24:52 +00003504 PyDoc_STR("Return None.")},
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003505
3506 {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3507 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3508
Alexander Belopolsky1b7046b2010-06-23 21:40:15 +00003509 {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3510 PyDoc_STR("pickle support")},
3511
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003512 {NULL, NULL}
3513};
3514
3515static char timezone_doc[] =
3516PyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3517
3518static PyTypeObject PyDateTime_TimeZoneType = {
3519 PyVarObject_HEAD_INIT(NULL, 0)
3520 "datetime.timezone", /* tp_name */
3521 sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3522 0, /* tp_itemsize */
3523 (destructor)timezone_dealloc, /* tp_dealloc */
3524 0, /* tp_print */
3525 0, /* tp_getattr */
3526 0, /* tp_setattr */
3527 0, /* tp_reserved */
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00003528 (reprfunc)timezone_repr, /* tp_repr */
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00003529 0, /* tp_as_number */
3530 0, /* tp_as_sequence */
3531 0, /* tp_as_mapping */
3532 (hashfunc)timezone_hash, /* tp_hash */
3533 0, /* tp_call */
3534 (reprfunc)timezone_str, /* tp_str */
3535 0, /* tp_getattro */
3536 0, /* tp_setattro */
3537 0, /* tp_as_buffer */
3538 Py_TPFLAGS_DEFAULT, /* tp_flags */
3539 timezone_doc, /* tp_doc */
3540 0, /* tp_traverse */
3541 0, /* tp_clear */
3542 (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3543 0, /* tp_weaklistoffset */
3544 0, /* tp_iter */
3545 0, /* tp_iternext */
3546 timezone_methods, /* tp_methods */
3547 0, /* tp_members */
3548 0, /* tp_getset */
3549 &PyDateTime_TZInfoType, /* tp_base */
3550 0, /* tp_dict */
3551 0, /* tp_descr_get */
3552 0, /* tp_descr_set */
3553 0, /* tp_dictoffset */
3554 0, /* tp_init */
3555 0, /* tp_alloc */
3556 timezone_new, /* tp_new */
3557};
3558
Tim Peters2a799bf2002-12-16 20:18:38 +00003559/*
Tim Peters37f39822003-01-10 03:49:02 +00003560 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003561 */
3562
Tim Peters37f39822003-01-10 03:49:02 +00003563/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003564 */
3565
3566static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003567time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003568{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003569 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003570}
3571
Tim Peters37f39822003-01-10 03:49:02 +00003572static PyObject *
3573time_minute(PyDateTime_Time *self, void *unused)
3574{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003575 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003576}
3577
3578/* The name time_second conflicted with some platform header file. */
3579static PyObject *
3580py_time_second(PyDateTime_Time *self, void *unused)
3581{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003582 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003583}
3584
3585static PyObject *
3586time_microsecond(PyDateTime_Time *self, void *unused)
3587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003588 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003589}
3590
3591static PyObject *
3592time_tzinfo(PyDateTime_Time *self, void *unused)
3593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003594 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3595 Py_INCREF(result);
3596 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003597}
3598
3599static PyGetSetDef time_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003600 {"hour", (getter)time_hour},
3601 {"minute", (getter)time_minute},
3602 {"second", (getter)py_time_second},
3603 {"microsecond", (getter)time_microsecond},
3604 {"tzinfo", (getter)time_tzinfo},
3605 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003606};
3607
3608/*
3609 * Constructors.
3610 */
3611
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003612static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003613 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003614
Tim Peters2a799bf2002-12-16 20:18:38 +00003615static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003616time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003617{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003618 PyObject *self = NULL;
3619 PyObject *state;
3620 int hour = 0;
3621 int minute = 0;
3622 int second = 0;
3623 int usecond = 0;
3624 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003626 /* Check for invocation from pickle with __getstate__ state */
3627 if (PyTuple_GET_SIZE(args) >= 1 &&
3628 PyTuple_GET_SIZE(args) <= 2 &&
3629 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3630 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3631 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3632 {
3633 PyDateTime_Time *me;
3634 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003636 if (PyTuple_GET_SIZE(args) == 2) {
3637 tzinfo = PyTuple_GET_ITEM(args, 1);
3638 if (check_tzinfo_subclass(tzinfo) < 0) {
3639 PyErr_SetString(PyExc_TypeError, "bad "
3640 "tzinfo state arg");
3641 return NULL;
3642 }
3643 }
3644 aware = (char)(tzinfo != Py_None);
3645 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3646 if (me != NULL) {
3647 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003648
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003649 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3650 me->hashcode = -1;
3651 me->hastzinfo = aware;
3652 if (aware) {
3653 Py_INCREF(tzinfo);
3654 me->tzinfo = tzinfo;
3655 }
3656 }
3657 return (PyObject *)me;
3658 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003660 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3661 &hour, &minute, &second, &usecond,
3662 &tzinfo)) {
3663 if (check_time_args(hour, minute, second, usecond) < 0)
3664 return NULL;
3665 if (check_tzinfo_subclass(tzinfo) < 0)
3666 return NULL;
3667 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3668 type);
3669 }
3670 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003671}
3672
3673/*
3674 * Destructor.
3675 */
3676
3677static void
Tim Peters37f39822003-01-10 03:49:02 +00003678time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003680 if (HASTZINFO(self)) {
3681 Py_XDECREF(self->tzinfo);
3682 }
3683 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003684}
3685
3686/*
Tim Peters855fe882002-12-22 03:43:39 +00003687 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003688 */
3689
Tim Peters2a799bf2002-12-16 20:18:38 +00003690/* These are all METH_NOARGS, so don't need to check the arglist. */
3691static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003692time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003693 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3694 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003695}
3696
3697static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003698time_dst(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003699 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3700 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003701}
3702
3703static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003704time_tzname(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003705 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3706 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003707}
3708
3709/*
Tim Peters37f39822003-01-10 03:49:02 +00003710 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003711 */
3712
3713static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003714time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003715{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003716 const char *type_name = Py_TYPE(self)->tp_name;
3717 int h = TIME_GET_HOUR(self);
3718 int m = TIME_GET_MINUTE(self);
3719 int s = TIME_GET_SECOND(self);
3720 int us = TIME_GET_MICROSECOND(self);
3721 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003723 if (us)
3724 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3725 type_name, h, m, s, us);
3726 else if (s)
3727 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3728 type_name, h, m, s);
3729 else
3730 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3731 if (result != NULL && HASTZINFO(self))
3732 result = append_keyword_tzinfo(result, self->tzinfo);
3733 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003734}
3735
Tim Peters37f39822003-01-10 03:49:02 +00003736static PyObject *
3737time_str(PyDateTime_Time *self)
3738{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003739 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003740}
Tim Peters2a799bf2002-12-16 20:18:38 +00003741
3742static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003743time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003744{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003745 char buf[100];
3746 PyObject *result;
3747 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003749 if (us)
3750 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3751 TIME_GET_HOUR(self),
3752 TIME_GET_MINUTE(self),
3753 TIME_GET_SECOND(self),
3754 us);
3755 else
3756 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3757 TIME_GET_HOUR(self),
3758 TIME_GET_MINUTE(self),
3759 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003761 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3762 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003764 /* We need to append the UTC offset. */
3765 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3766 Py_None) < 0) {
3767 Py_DECREF(result);
3768 return NULL;
3769 }
3770 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3771 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003772}
3773
Tim Peters37f39822003-01-10 03:49:02 +00003774static PyObject *
3775time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003777 PyObject *result;
3778 PyObject *tuple;
3779 PyObject *format;
3780 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003782 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3783 &format))
3784 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003786 /* Python's strftime does insane things with the year part of the
3787 * timetuple. The year is forced to (the otherwise nonsensical)
3788 * 1900 to worm around that.
3789 */
3790 tuple = Py_BuildValue("iiiiiiiii",
3791 1900, 1, 1, /* year, month, day */
3792 TIME_GET_HOUR(self),
3793 TIME_GET_MINUTE(self),
3794 TIME_GET_SECOND(self),
3795 0, 1, -1); /* weekday, daynum, dst */
3796 if (tuple == NULL)
3797 return NULL;
3798 assert(PyTuple_Size(tuple) == 9);
3799 result = wrap_strftime((PyObject *)self, format, tuple,
3800 Py_None);
3801 Py_DECREF(tuple);
3802 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003803}
Tim Peters2a799bf2002-12-16 20:18:38 +00003804
3805/*
3806 * Miscellaneous methods.
3807 */
3808
Tim Peters37f39822003-01-10 03:49:02 +00003809static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003810time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003811{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003812 int diff;
3813 naivety n1, n2;
3814 int offset1, offset2;
Tim Peters37f39822003-01-10 03:49:02 +00003815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003816 if (! PyTime_Check(other)) {
3817 Py_INCREF(Py_NotImplemented);
3818 return Py_NotImplemented;
3819 }
3820 if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
3821 other, &offset2, &n2, Py_None) < 0)
3822 return NULL;
3823 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3824 /* If they're both naive, or both aware and have the same offsets,
3825 * we get off cheap. Note that if they're both naive, offset1 ==
3826 * offset2 == 0 at this point.
3827 */
3828 if (n1 == n2 && offset1 == offset2) {
3829 diff = memcmp(((PyDateTime_Time *)self)->data,
3830 ((PyDateTime_Time *)other)->data,
3831 _PyDateTime_TIME_DATASIZE);
3832 return diff_to_bool(diff, op);
3833 }
Tim Peters37f39822003-01-10 03:49:02 +00003834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3836 assert(offset1 != offset2); /* else last "if" handled it */
3837 /* Convert everything except microseconds to seconds. These
3838 * can't overflow (no more than the # of seconds in 2 days).
3839 */
3840 offset1 = TIME_GET_HOUR(self) * 3600 +
3841 (TIME_GET_MINUTE(self) - offset1) * 60 +
3842 TIME_GET_SECOND(self);
3843 offset2 = TIME_GET_HOUR(other) * 3600 +
3844 (TIME_GET_MINUTE(other) - offset2) * 60 +
3845 TIME_GET_SECOND(other);
3846 diff = offset1 - offset2;
3847 if (diff == 0)
3848 diff = TIME_GET_MICROSECOND(self) -
3849 TIME_GET_MICROSECOND(other);
3850 return diff_to_bool(diff, op);
3851 }
Tim Peters37f39822003-01-10 03:49:02 +00003852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003853 assert(n1 != n2);
3854 PyErr_SetString(PyExc_TypeError,
3855 "can't compare offset-naive and "
3856 "offset-aware times");
3857 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003858}
3859
3860static long
3861time_hash(PyDateTime_Time *self)
3862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003863 if (self->hashcode == -1) {
3864 naivety n;
3865 int offset;
3866 PyObject *temp;
Tim Peters37f39822003-01-10 03:49:02 +00003867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003868 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3869 assert(n != OFFSET_UNKNOWN);
3870 if (n == OFFSET_ERROR)
3871 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003873 /* Reduce this to a hash of another object. */
3874 if (offset == 0) {
3875 self->hashcode = generic_hash(
3876 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3877 return self->hashcode;
3878 }
3879 else {
3880 int hour;
3881 int minute;
Tim Peters37f39822003-01-10 03:49:02 +00003882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 assert(n == OFFSET_AWARE);
3884 assert(HASTZINFO(self));
3885 hour = divmod(TIME_GET_HOUR(self) * 60 +
3886 TIME_GET_MINUTE(self) - offset,
3887 60,
3888 &minute);
3889 if (0 <= hour && hour < 24)
3890 temp = new_time(hour, minute,
3891 TIME_GET_SECOND(self),
3892 TIME_GET_MICROSECOND(self),
3893 Py_None);
3894 else
3895 temp = Py_BuildValue("iiii",
3896 hour, minute,
3897 TIME_GET_SECOND(self),
3898 TIME_GET_MICROSECOND(self));
3899 }
3900 if (temp != NULL) {
3901 self->hashcode = PyObject_Hash(temp);
3902 Py_DECREF(temp);
3903 }
3904 }
3905 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003906}
Tim Peters2a799bf2002-12-16 20:18:38 +00003907
Tim Peters12bf3392002-12-24 05:41:27 +00003908static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003909time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003911 PyObject *clone;
3912 PyObject *tuple;
3913 int hh = TIME_GET_HOUR(self);
3914 int mm = TIME_GET_MINUTE(self);
3915 int ss = TIME_GET_SECOND(self);
3916 int us = TIME_GET_MICROSECOND(self);
3917 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003919 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3920 time_kws,
3921 &hh, &mm, &ss, &us, &tzinfo))
3922 return NULL;
3923 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3924 if (tuple == NULL)
3925 return NULL;
3926 clone = time_new(Py_TYPE(self), tuple, NULL);
3927 Py_DECREF(tuple);
3928 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003929}
3930
Tim Peters2a799bf2002-12-16 20:18:38 +00003931static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00003932time_bool(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003933{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003934 int offset;
3935 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00003936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003937 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3938 /* Since utcoffset is in whole minutes, nothing can
3939 * alter the conclusion that this is nonzero.
3940 */
3941 return 1;
3942 }
3943 offset = 0;
3944 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3945 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3946 if (offset == -1 && PyErr_Occurred())
3947 return -1;
3948 }
3949 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003950}
3951
Tim Peters371935f2003-02-01 01:52:50 +00003952/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003953
Tim Peters33e0f382003-01-10 02:05:14 +00003954/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003955 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3956 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003957 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003958 */
3959static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003960time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003961{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003962 PyObject *basestate;
3963 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003965 basestate = PyBytes_FromStringAndSize((char *)self->data,
3966 _PyDateTime_TIME_DATASIZE);
3967 if (basestate != NULL) {
3968 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3969 result = PyTuple_Pack(1, basestate);
3970 else
3971 result = PyTuple_Pack(2, basestate, self->tzinfo);
3972 Py_DECREF(basestate);
3973 }
3974 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003975}
3976
3977static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003978time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003979{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003980 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003981}
3982
Tim Peters37f39822003-01-10 03:49:02 +00003983static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003985 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3986 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3987 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003989 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3990 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003992 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3993 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003995 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3996 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003997
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003998 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3999 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 {"dst", (PyCFunction)time_dst, METH_NOARGS,
4002 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4005 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004007 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4008 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004010 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004011};
4012
Tim Peters37f39822003-01-10 03:49:02 +00004013static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004014PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4015\n\
4016All arguments are optional. tzinfo may be None, or an instance of\n\
4017a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004018
Tim Peters37f39822003-01-10 03:49:02 +00004019static PyNumberMethods time_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004020 0, /* nb_add */
4021 0, /* nb_subtract */
4022 0, /* nb_multiply */
4023 0, /* nb_remainder */
4024 0, /* nb_divmod */
4025 0, /* nb_power */
4026 0, /* nb_negative */
4027 0, /* nb_positive */
4028 0, /* nb_absolute */
4029 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004030};
4031
Neal Norwitz227b5332006-03-22 09:28:35 +00004032static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004033 PyVarObject_HEAD_INIT(NULL, 0)
4034 "datetime.time", /* tp_name */
4035 sizeof(PyDateTime_Time), /* tp_basicsize */
4036 0, /* tp_itemsize */
4037 (destructor)time_dealloc, /* tp_dealloc */
4038 0, /* tp_print */
4039 0, /* tp_getattr */
4040 0, /* tp_setattr */
4041 0, /* tp_reserved */
4042 (reprfunc)time_repr, /* tp_repr */
4043 &time_as_number, /* tp_as_number */
4044 0, /* tp_as_sequence */
4045 0, /* tp_as_mapping */
4046 (hashfunc)time_hash, /* tp_hash */
4047 0, /* tp_call */
4048 (reprfunc)time_str, /* tp_str */
4049 PyObject_GenericGetAttr, /* tp_getattro */
4050 0, /* tp_setattro */
4051 0, /* tp_as_buffer */
4052 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4053 time_doc, /* tp_doc */
4054 0, /* tp_traverse */
4055 0, /* tp_clear */
4056 time_richcompare, /* tp_richcompare */
4057 0, /* tp_weaklistoffset */
4058 0, /* tp_iter */
4059 0, /* tp_iternext */
4060 time_methods, /* tp_methods */
4061 0, /* tp_members */
4062 time_getset, /* tp_getset */
4063 0, /* tp_base */
4064 0, /* tp_dict */
4065 0, /* tp_descr_get */
4066 0, /* tp_descr_set */
4067 0, /* tp_dictoffset */
4068 0, /* tp_init */
4069 time_alloc, /* tp_alloc */
4070 time_new, /* tp_new */
4071 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004072};
4073
4074/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004075 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00004076 */
4077
Tim Petersa9bc1682003-01-11 03:39:11 +00004078/* Accessor properties. Properties for day, month, and year are inherited
4079 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004080 */
4081
4082static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004083datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00004084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004085 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004086}
4087
Tim Petersa9bc1682003-01-11 03:39:11 +00004088static PyObject *
4089datetime_minute(PyDateTime_DateTime *self, void *unused)
4090{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004091 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004092}
4093
4094static PyObject *
4095datetime_second(PyDateTime_DateTime *self, void *unused)
4096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004097 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004098}
4099
4100static PyObject *
4101datetime_microsecond(PyDateTime_DateTime *self, void *unused)
4102{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004103 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004104}
4105
4106static PyObject *
4107datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004109 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4110 Py_INCREF(result);
4111 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004112}
4113
4114static PyGetSetDef datetime_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004115 {"hour", (getter)datetime_hour},
4116 {"minute", (getter)datetime_minute},
4117 {"second", (getter)datetime_second},
4118 {"microsecond", (getter)datetime_microsecond},
4119 {"tzinfo", (getter)datetime_tzinfo},
4120 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004121};
4122
4123/*
4124 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00004125 */
4126
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004127static char *datetime_kws[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004128 "year", "month", "day", "hour", "minute", "second",
4129 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00004130};
4131
Tim Peters2a799bf2002-12-16 20:18:38 +00004132static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004133datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004135 PyObject *self = NULL;
4136 PyObject *state;
4137 int year;
4138 int month;
4139 int day;
4140 int hour = 0;
4141 int minute = 0;
4142 int second = 0;
4143 int usecond = 0;
4144 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00004145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004146 /* Check for invocation from pickle with __getstate__ state */
4147 if (PyTuple_GET_SIZE(args) >= 1 &&
4148 PyTuple_GET_SIZE(args) <= 2 &&
4149 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4150 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4151 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
4152 {
4153 PyDateTime_DateTime *me;
4154 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00004155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004156 if (PyTuple_GET_SIZE(args) == 2) {
4157 tzinfo = PyTuple_GET_ITEM(args, 1);
4158 if (check_tzinfo_subclass(tzinfo) < 0) {
4159 PyErr_SetString(PyExc_TypeError, "bad "
4160 "tzinfo state arg");
4161 return NULL;
4162 }
4163 }
4164 aware = (char)(tzinfo != Py_None);
4165 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4166 if (me != NULL) {
4167 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00004168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004169 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4170 me->hashcode = -1;
4171 me->hastzinfo = aware;
4172 if (aware) {
4173 Py_INCREF(tzinfo);
4174 me->tzinfo = tzinfo;
4175 }
4176 }
4177 return (PyObject *)me;
4178 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00004179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004180 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
4181 &year, &month, &day, &hour, &minute,
4182 &second, &usecond, &tzinfo)) {
4183 if (check_date_args(year, month, day) < 0)
4184 return NULL;
4185 if (check_time_args(hour, minute, second, usecond) < 0)
4186 return NULL;
4187 if (check_tzinfo_subclass(tzinfo) < 0)
4188 return NULL;
4189 self = new_datetime_ex(year, month, day,
4190 hour, minute, second, usecond,
4191 tzinfo, type);
4192 }
4193 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004194}
4195
Tim Petersa9bc1682003-01-11 03:39:11 +00004196/* TM_FUNC is the shared type of localtime() and gmtime(). */
4197typedef struct tm *(*TM_FUNC)(const time_t *timer);
4198
4199/* Internal helper.
4200 * Build datetime from a time_t and a distinct count of microseconds.
4201 * Pass localtime or gmtime for f, to control the interpretation of timet.
4202 */
4203static PyObject *
4204datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004205 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004207 struct tm *tm;
4208 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004210 tm = f(&timet);
4211 if (tm) {
4212 /* The platform localtime/gmtime may insert leap seconds,
4213 * indicated by tm->tm_sec > 59. We don't care about them,
4214 * except to the extent that passing them on to the datetime
4215 * constructor would raise ValueError for a reason that
4216 * made no sense to the user.
4217 */
4218 if (tm->tm_sec > 59)
4219 tm->tm_sec = 59;
4220 result = PyObject_CallFunction(cls, "iiiiiiiO",
4221 tm->tm_year + 1900,
4222 tm->tm_mon + 1,
4223 tm->tm_mday,
4224 tm->tm_hour,
4225 tm->tm_min,
4226 tm->tm_sec,
4227 us,
4228 tzinfo);
4229 }
4230 else
4231 PyErr_SetString(PyExc_ValueError,
4232 "timestamp out of range for "
4233 "platform localtime()/gmtime() function");
4234 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004235}
4236
4237/* Internal helper.
4238 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4239 * to control the interpretation of the timestamp. Since a double doesn't
4240 * have enough bits to cover a datetime's full range of precision, it's
4241 * better to call datetime_from_timet_and_us provided you have a way
4242 * to get that much precision (e.g., C time() isn't good enough).
4243 */
4244static PyObject *
4245datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004246 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00004247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004248 time_t timet;
4249 double fraction;
4250 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00004251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004252 timet = _PyTime_DoubleToTimet(timestamp);
4253 if (timet == (time_t)-1 && PyErr_Occurred())
4254 return NULL;
4255 fraction = timestamp - (double)timet;
4256 us = (int)round_to_long(fraction * 1e6);
4257 if (us < 0) {
4258 /* Truncation towards zero is not what we wanted
4259 for negative numbers (Python's mod semantics) */
4260 timet -= 1;
4261 us += 1000000;
4262 }
4263 /* If timestamp is less than one microsecond smaller than a
4264 * full second, round up. Otherwise, ValueErrors are raised
4265 * for some floats. */
4266 if (us == 1000000) {
4267 timet += 1;
4268 us = 0;
4269 }
4270 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004271}
4272
4273/* Internal helper.
4274 * Build most accurate possible datetime for current time. Pass localtime or
4275 * gmtime for f as appropriate.
4276 */
4277static PyObject *
4278datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4279{
4280#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004281 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00004282
4283#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004284 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00004285#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004286 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00004287#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004288 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
4289 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00004290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004291#else /* ! HAVE_GETTIMEOFDAY */
4292 /* No flavor of gettimeofday exists on this platform. Python's
4293 * time.time() does a lot of other platform tricks to get the
4294 * best time it can on the platform, and we're not going to do
4295 * better than that (if we could, the better code would belong
4296 * in time.time()!) We're limited by the precision of a double,
4297 * though.
4298 */
4299 PyObject *time;
4300 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00004301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004302 time = time_time();
4303 if (time == NULL)
4304 return NULL;
4305 dtime = PyFloat_AsDouble(time);
4306 Py_DECREF(time);
4307 if (dtime == -1.0 && PyErr_Occurred())
4308 return NULL;
4309 return datetime_from_timestamp(cls, f, dtime, tzinfo);
4310#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00004311}
4312
Tim Peters2a799bf2002-12-16 20:18:38 +00004313/* Return best possible local time -- this isn't constrained by the
4314 * precision of a timestamp.
4315 */
4316static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004317datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004319 PyObject *self;
4320 PyObject *tzinfo = Py_None;
4321 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004323 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4324 &tzinfo))
4325 return NULL;
4326 if (check_tzinfo_subclass(tzinfo) < 0)
4327 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00004328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004329 self = datetime_best_possible(cls,
4330 tzinfo == Py_None ? localtime : gmtime,
4331 tzinfo);
4332 if (self != NULL && tzinfo != Py_None) {
4333 /* Convert UTC to tzinfo's zone. */
4334 PyObject *temp = self;
4335 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4336 Py_DECREF(temp);
4337 }
4338 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004339}
4340
Tim Petersa9bc1682003-01-11 03:39:11 +00004341/* Return best possible UTC time -- this isn't constrained by the
4342 * precision of a timestamp.
4343 */
4344static PyObject *
4345datetime_utcnow(PyObject *cls, PyObject *dummy)
4346{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004347 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004348}
4349
Tim Peters2a799bf2002-12-16 20:18:38 +00004350/* Return new local datetime from timestamp (Python timestamp -- a double). */
4351static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004352datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004354 PyObject *self;
4355 double timestamp;
4356 PyObject *tzinfo = Py_None;
4357 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00004358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004359 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4360 keywords, &timestamp, &tzinfo))
4361 return NULL;
4362 if (check_tzinfo_subclass(tzinfo) < 0)
4363 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00004364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004365 self = datetime_from_timestamp(cls,
4366 tzinfo == Py_None ? localtime : gmtime,
4367 timestamp,
4368 tzinfo);
4369 if (self != NULL && tzinfo != Py_None) {
4370 /* Convert UTC to tzinfo's zone. */
4371 PyObject *temp = self;
4372 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
4373 Py_DECREF(temp);
4374 }
4375 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004376}
4377
Tim Petersa9bc1682003-01-11 03:39:11 +00004378/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4379static PyObject *
4380datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004382 double timestamp;
4383 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004385 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
4386 result = datetime_from_timestamp(cls, gmtime, timestamp,
4387 Py_None);
4388 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004389}
4390
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004391/* Return new datetime from _strptime.strptime_datetime(). */
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004392static PyObject *
4393datetime_strptime(PyObject *cls, PyObject *args)
4394{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004395 static PyObject *module = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004396 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004398 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
4399 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004400
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004401 if (module == NULL) {
4402 module = PyImport_ImportModuleNoBlock("_strptime");
Alexander Belopolsky311d2a92010-06-28 14:36:55 +00004403 if (module == NULL)
Alexander Belopolskyca94f552010-06-17 18:30:34 +00004404 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004405 }
Alexander Belopolskyf5682182010-06-18 18:44:37 +00004406 return PyObject_CallMethod(module, "_strptime_datetime", "Ouu",
4407 cls, string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004408}
4409
Tim Petersa9bc1682003-01-11 03:39:11 +00004410/* Return new datetime from date/datetime and time arguments. */
4411static PyObject *
4412datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004414 static char *keywords[] = {"date", "time", NULL};
4415 PyObject *date;
4416 PyObject *time;
4417 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004419 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4420 &PyDateTime_DateType, &date,
4421 &PyDateTime_TimeType, &time)) {
4422 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00004423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004424 if (HASTZINFO(time))
4425 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4426 result = PyObject_CallFunction(cls, "iiiiiiiO",
4427 GET_YEAR(date),
4428 GET_MONTH(date),
4429 GET_DAY(date),
4430 TIME_GET_HOUR(time),
4431 TIME_GET_MINUTE(time),
4432 TIME_GET_SECOND(time),
4433 TIME_GET_MICROSECOND(time),
4434 tzinfo);
4435 }
4436 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00004437}
Tim Peters2a799bf2002-12-16 20:18:38 +00004438
4439/*
4440 * Destructor.
4441 */
4442
4443static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004444datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004446 if (HASTZINFO(self)) {
4447 Py_XDECREF(self->tzinfo);
4448 }
4449 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004450}
4451
4452/*
4453 * Indirect access to tzinfo methods.
4454 */
4455
Tim Peters2a799bf2002-12-16 20:18:38 +00004456/* These are all METH_NOARGS, so don't need to check the arglist. */
4457static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004458datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004459 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4460 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004461}
4462
4463static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004464datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004465 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4466 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004467}
4468
4469static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004470datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004471 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4472 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004473}
4474
4475/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004476 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004477 */
4478
Tim Petersa9bc1682003-01-11 03:39:11 +00004479/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4480 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004481 */
4482static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004483add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004484 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004485{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004486 /* Note that the C-level additions can't overflow, because of
4487 * invariant bounds on the member values.
4488 */
4489 int year = GET_YEAR(date);
4490 int month = GET_MONTH(date);
4491 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4492 int hour = DATE_GET_HOUR(date);
4493 int minute = DATE_GET_MINUTE(date);
4494 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4495 int microsecond = DATE_GET_MICROSECOND(date) +
4496 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004498 assert(factor == 1 || factor == -1);
4499 if (normalize_datetime(&year, &month, &day,
4500 &hour, &minute, &second, &microsecond) < 0)
4501 return NULL;
4502 else
4503 return new_datetime(year, month, day,
4504 hour, minute, second, microsecond,
4505 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004506}
4507
4508static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004509datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004510{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004511 if (PyDateTime_Check(left)) {
4512 /* datetime + ??? */
4513 if (PyDelta_Check(right))
4514 /* datetime + delta */
4515 return add_datetime_timedelta(
4516 (PyDateTime_DateTime *)left,
4517 (PyDateTime_Delta *)right,
4518 1);
4519 }
4520 else if (PyDelta_Check(left)) {
4521 /* delta + datetime */
4522 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4523 (PyDateTime_Delta *) left,
4524 1);
4525 }
4526 Py_INCREF(Py_NotImplemented);
4527 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004528}
4529
4530static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004531datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004533 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004535 if (PyDateTime_Check(left)) {
4536 /* datetime - ??? */
4537 if (PyDateTime_Check(right)) {
4538 /* datetime - datetime */
4539 naivety n1, n2;
4540 int offset1, offset2;
4541 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004543 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4544 right, &offset2, &n2,
4545 right) < 0)
4546 return NULL;
4547 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4548 if (n1 != n2) {
4549 PyErr_SetString(PyExc_TypeError,
4550 "can't subtract offset-naive and "
4551 "offset-aware datetimes");
4552 return NULL;
4553 }
4554 delta_d = ymd_to_ord(GET_YEAR(left),
4555 GET_MONTH(left),
4556 GET_DAY(left)) -
4557 ymd_to_ord(GET_YEAR(right),
4558 GET_MONTH(right),
4559 GET_DAY(right));
4560 /* These can't overflow, since the values are
4561 * normalized. At most this gives the number of
4562 * seconds in one day.
4563 */
4564 delta_s = (DATE_GET_HOUR(left) -
4565 DATE_GET_HOUR(right)) * 3600 +
4566 (DATE_GET_MINUTE(left) -
4567 DATE_GET_MINUTE(right)) * 60 +
4568 (DATE_GET_SECOND(left) -
4569 DATE_GET_SECOND(right));
4570 delta_us = DATE_GET_MICROSECOND(left) -
4571 DATE_GET_MICROSECOND(right);
4572 /* (left - offset1) - (right - offset2) =
4573 * (left - right) + (offset2 - offset1)
4574 */
4575 delta_s += (offset2 - offset1) * 60;
4576 result = new_delta(delta_d, delta_s, delta_us, 1);
4577 }
4578 else if (PyDelta_Check(right)) {
4579 /* datetime - delta */
4580 result = add_datetime_timedelta(
4581 (PyDateTime_DateTime *)left,
4582 (PyDateTime_Delta *)right,
4583 -1);
4584 }
4585 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004587 if (result == Py_NotImplemented)
4588 Py_INCREF(result);
4589 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004590}
4591
4592/* Various ways to turn a datetime into a string. */
4593
4594static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004595datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004596{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004597 const char *type_name = Py_TYPE(self)->tp_name;
4598 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004600 if (DATE_GET_MICROSECOND(self)) {
4601 baserepr = PyUnicode_FromFormat(
4602 "%s(%d, %d, %d, %d, %d, %d, %d)",
4603 type_name,
4604 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4605 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4606 DATE_GET_SECOND(self),
4607 DATE_GET_MICROSECOND(self));
4608 }
4609 else if (DATE_GET_SECOND(self)) {
4610 baserepr = PyUnicode_FromFormat(
4611 "%s(%d, %d, %d, %d, %d, %d)",
4612 type_name,
4613 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4614 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4615 DATE_GET_SECOND(self));
4616 }
4617 else {
4618 baserepr = PyUnicode_FromFormat(
4619 "%s(%d, %d, %d, %d, %d)",
4620 type_name,
4621 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4622 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4623 }
4624 if (baserepr == NULL || ! HASTZINFO(self))
4625 return baserepr;
4626 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004627}
4628
Tim Petersa9bc1682003-01-11 03:39:11 +00004629static PyObject *
4630datetime_str(PyDateTime_DateTime *self)
4631{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004632 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004633}
Tim Peters2a799bf2002-12-16 20:18:38 +00004634
4635static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004636datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004638 int sep = 'T';
4639 static char *keywords[] = {"sep", NULL};
4640 char buffer[100];
4641 PyObject *result;
4642 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004644 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4645 return NULL;
4646 if (us)
4647 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4648 GET_YEAR(self), GET_MONTH(self),
4649 GET_DAY(self), (int)sep,
4650 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4651 DATE_GET_SECOND(self), us);
4652 else
4653 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4654 GET_YEAR(self), GET_MONTH(self),
4655 GET_DAY(self), (int)sep,
4656 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4657 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004659 if (!result || !HASTZINFO(self))
4660 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004662 /* We need to append the UTC offset. */
4663 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4664 (PyObject *)self) < 0) {
4665 Py_DECREF(result);
4666 return NULL;
4667 }
4668 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4669 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004670}
4671
Tim Petersa9bc1682003-01-11 03:39:11 +00004672static PyObject *
4673datetime_ctime(PyDateTime_DateTime *self)
4674{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004675 return format_ctime((PyDateTime_Date *)self,
4676 DATE_GET_HOUR(self),
4677 DATE_GET_MINUTE(self),
4678 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004679}
4680
Tim Peters2a799bf2002-12-16 20:18:38 +00004681/* Miscellaneous methods. */
4682
Tim Petersa9bc1682003-01-11 03:39:11 +00004683static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004684datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004685{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004686 int diff;
4687 naivety n1, n2;
4688 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004690 if (! PyDateTime_Check(other)) {
4691 if (PyDate_Check(other)) {
4692 /* Prevent invocation of date_richcompare. We want to
4693 return NotImplemented here to give the other object
4694 a chance. But since DateTime is a subclass of
4695 Date, if the other object is a Date, it would
4696 compute an ordering based on the date part alone,
4697 and we don't want that. So force unequal or
4698 uncomparable here in that case. */
4699 if (op == Py_EQ)
4700 Py_RETURN_FALSE;
4701 if (op == Py_NE)
4702 Py_RETURN_TRUE;
4703 return cmperror(self, other);
4704 }
4705 Py_INCREF(Py_NotImplemented);
4706 return Py_NotImplemented;
4707 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004709 if (classify_two_utcoffsets(self, &offset1, &n1, self,
4710 other, &offset2, &n2, other) < 0)
4711 return NULL;
4712 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4713 /* If they're both naive, or both aware and have the same offsets,
4714 * we get off cheap. Note that if they're both naive, offset1 ==
4715 * offset2 == 0 at this point.
4716 */
4717 if (n1 == n2 && offset1 == offset2) {
4718 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4719 ((PyDateTime_DateTime *)other)->data,
4720 _PyDateTime_DATETIME_DATASIZE);
4721 return diff_to_bool(diff, op);
4722 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004723
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004724 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4725 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004727 assert(offset1 != offset2); /* else last "if" handled it */
4728 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4729 other);
4730 if (delta == NULL)
4731 return NULL;
4732 diff = GET_TD_DAYS(delta);
4733 if (diff == 0)
4734 diff = GET_TD_SECONDS(delta) |
4735 GET_TD_MICROSECONDS(delta);
4736 Py_DECREF(delta);
4737 return diff_to_bool(diff, op);
4738 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004740 assert(n1 != n2);
4741 PyErr_SetString(PyExc_TypeError,
4742 "can't compare offset-naive and "
4743 "offset-aware datetimes");
4744 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004745}
4746
4747static long
4748datetime_hash(PyDateTime_DateTime *self)
4749{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004750 if (self->hashcode == -1) {
4751 naivety n;
4752 int offset;
4753 PyObject *temp;
Tim Petersa9bc1682003-01-11 03:39:11 +00004754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004755 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4756 &offset);
4757 assert(n != OFFSET_UNKNOWN);
4758 if (n == OFFSET_ERROR)
4759 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004761 /* Reduce this to a hash of another object. */
4762 if (n == OFFSET_NAIVE) {
4763 self->hashcode = generic_hash(
4764 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
4765 return self->hashcode;
4766 }
4767 else {
4768 int days;
4769 int seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004771 assert(n == OFFSET_AWARE);
4772 assert(HASTZINFO(self));
4773 days = ymd_to_ord(GET_YEAR(self),
4774 GET_MONTH(self),
4775 GET_DAY(self));
4776 seconds = DATE_GET_HOUR(self) * 3600 +
4777 (DATE_GET_MINUTE(self) - offset) * 60 +
4778 DATE_GET_SECOND(self);
4779 temp = new_delta(days,
4780 seconds,
4781 DATE_GET_MICROSECOND(self),
4782 1);
4783 }
4784 if (temp != NULL) {
4785 self->hashcode = PyObject_Hash(temp);
4786 Py_DECREF(temp);
4787 }
4788 }
4789 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004790}
Tim Peters2a799bf2002-12-16 20:18:38 +00004791
4792static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004793datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004794{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004795 PyObject *clone;
4796 PyObject *tuple;
4797 int y = GET_YEAR(self);
4798 int m = GET_MONTH(self);
4799 int d = GET_DAY(self);
4800 int hh = DATE_GET_HOUR(self);
4801 int mm = DATE_GET_MINUTE(self);
4802 int ss = DATE_GET_SECOND(self);
4803 int us = DATE_GET_MICROSECOND(self);
4804 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004806 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4807 datetime_kws,
4808 &y, &m, &d, &hh, &mm, &ss, &us,
4809 &tzinfo))
4810 return NULL;
4811 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4812 if (tuple == NULL)
4813 return NULL;
4814 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4815 Py_DECREF(tuple);
4816 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004817}
4818
4819static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004820datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004822 int y, m, d, hh, mm, ss, us;
4823 PyObject *result;
4824 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004825
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004826 PyObject *tzinfo;
4827 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004829 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4830 &PyDateTime_TZInfoType, &tzinfo))
4831 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004833 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4834 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004836 /* Conversion to self's own time zone is a NOP. */
4837 if (self->tzinfo == tzinfo) {
4838 Py_INCREF(self);
4839 return (PyObject *)self;
4840 }
Tim Peters521fc152002-12-31 17:36:56 +00004841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004842 /* Convert self to UTC. */
4843 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4844 if (offset == -1 && PyErr_Occurred())
4845 return NULL;
4846 if (none)
4847 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004849 y = GET_YEAR(self);
4850 m = GET_MONTH(self);
4851 d = GET_DAY(self);
4852 hh = DATE_GET_HOUR(self);
4853 mm = DATE_GET_MINUTE(self);
4854 ss = DATE_GET_SECOND(self);
4855 us = DATE_GET_MICROSECOND(self);
Tim Peters52dcce22003-01-23 16:36:11 +00004856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004857 mm -= offset;
4858 if ((mm < 0 || mm >= 60) &&
4859 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4860 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004862 /* Attach new tzinfo and let fromutc() do the rest. */
4863 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4864 if (result != NULL) {
4865 PyObject *temp = result;
Tim Peters52dcce22003-01-23 16:36:11 +00004866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004867 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4868 Py_DECREF(temp);
4869 }
4870 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004871
Tim Peters52dcce22003-01-23 16:36:11 +00004872NeedAware:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004873 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4874 "a naive datetime");
4875 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004876}
4877
4878static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004879datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004881 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004883 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4884 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004886 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4887 if (dstflag == -1 && PyErr_Occurred())
4888 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004890 if (none)
4891 dstflag = -1;
4892 else if (dstflag != 0)
4893 dstflag = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004895 }
4896 return build_struct_time(GET_YEAR(self),
4897 GET_MONTH(self),
4898 GET_DAY(self),
4899 DATE_GET_HOUR(self),
4900 DATE_GET_MINUTE(self),
4901 DATE_GET_SECOND(self),
4902 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004903}
4904
4905static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004906datetime_getdate(PyDateTime_DateTime *self)
4907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004908 return new_date(GET_YEAR(self),
4909 GET_MONTH(self),
4910 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004911}
4912
4913static PyObject *
4914datetime_gettime(PyDateTime_DateTime *self)
4915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004916 return new_time(DATE_GET_HOUR(self),
4917 DATE_GET_MINUTE(self),
4918 DATE_GET_SECOND(self),
4919 DATE_GET_MICROSECOND(self),
4920 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004921}
4922
4923static PyObject *
4924datetime_gettimetz(PyDateTime_DateTime *self)
4925{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004926 return new_time(DATE_GET_HOUR(self),
4927 DATE_GET_MINUTE(self),
4928 DATE_GET_SECOND(self),
4929 DATE_GET_MICROSECOND(self),
4930 HASTZINFO(self) ? self->tzinfo : Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004931}
4932
4933static PyObject *
4934datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004935{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004936 int y = GET_YEAR(self);
4937 int m = GET_MONTH(self);
4938 int d = GET_DAY(self);
4939 int hh = DATE_GET_HOUR(self);
4940 int mm = DATE_GET_MINUTE(self);
4941 int ss = DATE_GET_SECOND(self);
4942 int us = 0; /* microseconds are ignored in a timetuple */
4943 int offset = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004945 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4946 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004948 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4949 if (offset == -1 && PyErr_Occurred())
4950 return NULL;
4951 }
4952 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4953 * 0 in a UTC timetuple regardless of what dst() says.
4954 */
4955 if (offset) {
4956 /* Subtract offset minutes & normalize. */
4957 int stat;
Tim Peters2a799bf2002-12-16 20:18:38 +00004958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004959 mm -= offset;
4960 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
Alexander Belopolsky75f94c22010-06-21 15:21:14 +00004961 /* OverflowError may be raised in the edge cases. */
4962 if (stat < 0)
4963 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004964 }
4965 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004966}
4967
Tim Peters371935f2003-02-01 01:52:50 +00004968/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004969
Tim Petersa9bc1682003-01-11 03:39:11 +00004970/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004971 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4972 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004973 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004974 */
4975static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004976datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004978 PyObject *basestate;
4979 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004981 basestate = PyBytes_FromStringAndSize((char *)self->data,
4982 _PyDateTime_DATETIME_DATASIZE);
4983 if (basestate != NULL) {
4984 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4985 result = PyTuple_Pack(1, basestate);
4986 else
4987 result = PyTuple_Pack(2, basestate, self->tzinfo);
4988 Py_DECREF(basestate);
4989 }
4990 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004991}
4992
4993static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004994datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004995{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004996 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004997}
4998
Tim Petersa9bc1682003-01-11 03:39:11 +00004999static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00005000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005001 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00005002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005003 {"now", (PyCFunction)datetime_now,
5004 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5005 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005007 {"utcnow", (PyCFunction)datetime_utcnow,
5008 METH_NOARGS | METH_CLASS,
5009 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005011 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5012 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5013 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005015 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5016 METH_VARARGS | METH_CLASS,
5017 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
5018 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005020 {"strptime", (PyCFunction)datetime_strptime,
5021 METH_VARARGS | METH_CLASS,
5022 PyDoc_STR("string, format -> new datetime parsed from a string "
5023 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00005024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005025 {"combine", (PyCFunction)datetime_combine,
5026 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5027 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005029 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00005030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005031 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5032 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005033
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005034 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5035 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005037 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5038 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005040 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5041 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00005042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005043 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5044 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005046 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5047 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005049 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5050 PyDoc_STR("[sep] -> string in ISO 8601 format, "
5051 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
5052 "sep is used to separate the year from the time, and "
5053 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005054
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005055 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5056 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005058 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5059 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005061 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5062 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00005063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005064 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5065 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00005066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005067 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5068 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00005069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005070 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5071 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00005072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005073 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005074};
5075
Tim Petersa9bc1682003-01-11 03:39:11 +00005076static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00005077PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5078\n\
5079The year, month and day arguments are required. tzinfo may be None, or an\n\
5080instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00005081
Tim Petersa9bc1682003-01-11 03:39:11 +00005082static PyNumberMethods datetime_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005083 datetime_add, /* nb_add */
5084 datetime_subtract, /* nb_subtract */
5085 0, /* nb_multiply */
5086 0, /* nb_remainder */
5087 0, /* nb_divmod */
5088 0, /* nb_power */
5089 0, /* nb_negative */
5090 0, /* nb_positive */
5091 0, /* nb_absolute */
5092 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00005093};
5094
Neal Norwitz227b5332006-03-22 09:28:35 +00005095static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005096 PyVarObject_HEAD_INIT(NULL, 0)
5097 "datetime.datetime", /* tp_name */
5098 sizeof(PyDateTime_DateTime), /* tp_basicsize */
5099 0, /* tp_itemsize */
5100 (destructor)datetime_dealloc, /* tp_dealloc */
5101 0, /* tp_print */
5102 0, /* tp_getattr */
5103 0, /* tp_setattr */
5104 0, /* tp_reserved */
5105 (reprfunc)datetime_repr, /* tp_repr */
5106 &datetime_as_number, /* tp_as_number */
5107 0, /* tp_as_sequence */
5108 0, /* tp_as_mapping */
5109 (hashfunc)datetime_hash, /* tp_hash */
5110 0, /* tp_call */
5111 (reprfunc)datetime_str, /* tp_str */
5112 PyObject_GenericGetAttr, /* tp_getattro */
5113 0, /* tp_setattro */
5114 0, /* tp_as_buffer */
5115 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5116 datetime_doc, /* tp_doc */
5117 0, /* tp_traverse */
5118 0, /* tp_clear */
5119 datetime_richcompare, /* tp_richcompare */
5120 0, /* tp_weaklistoffset */
5121 0, /* tp_iter */
5122 0, /* tp_iternext */
5123 datetime_methods, /* tp_methods */
5124 0, /* tp_members */
5125 datetime_getset, /* tp_getset */
5126 &PyDateTime_DateType, /* tp_base */
5127 0, /* tp_dict */
5128 0, /* tp_descr_get */
5129 0, /* tp_descr_set */
5130 0, /* tp_dictoffset */
5131 0, /* tp_init */
5132 datetime_alloc, /* tp_alloc */
5133 datetime_new, /* tp_new */
5134 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00005135};
5136
5137/* ---------------------------------------------------------------------------
5138 * Module methods and initialization.
5139 */
5140
5141static PyMethodDef module_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005142 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00005143};
5144
Tim Peters9ddf40b2004-06-20 22:41:32 +00005145/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5146 * datetime.h.
5147 */
5148static PyDateTime_CAPI CAPI = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005149 &PyDateTime_DateType,
5150 &PyDateTime_DateTimeType,
5151 &PyDateTime_TimeType,
5152 &PyDateTime_DeltaType,
5153 &PyDateTime_TZInfoType,
5154 new_date_ex,
5155 new_datetime_ex,
5156 new_time_ex,
5157 new_delta_ex,
5158 datetime_fromtimestamp,
5159 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00005160};
5161
5162
Martin v. Löwis1a214512008-06-11 05:26:20 +00005163
5164static struct PyModuleDef datetimemodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005165 PyModuleDef_HEAD_INIT,
5166 "datetime",
5167 "Fast implementation of the datetime type.",
5168 -1,
5169 module_methods,
5170 NULL,
5171 NULL,
5172 NULL,
5173 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005174};
5175
Tim Peters2a799bf2002-12-16 20:18:38 +00005176PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00005177PyInit_datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00005178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005179 PyObject *m; /* a module object */
5180 PyObject *d; /* its dict */
5181 PyObject *x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005182 PyObject *delta;
Tim Peters2a799bf2002-12-16 20:18:38 +00005183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005184 m = PyModule_Create(&datetimemodule);
5185 if (m == NULL)
5186 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005188 if (PyType_Ready(&PyDateTime_DateType) < 0)
5189 return NULL;
5190 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5191 return NULL;
5192 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5193 return NULL;
5194 if (PyType_Ready(&PyDateTime_TimeType) < 0)
5195 return NULL;
5196 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5197 return NULL;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005198 if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5199 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005201 /* timedelta values */
5202 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005204 x = new_delta(0, 0, 1, 0);
5205 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5206 return NULL;
5207 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005209 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5210 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5211 return NULL;
5212 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005214 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5215 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5216 return NULL;
5217 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005219 /* date values */
5220 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005222 x = new_date(1, 1, 1);
5223 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5224 return NULL;
5225 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005227 x = new_date(MAXYEAR, 12, 31);
5228 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5229 return NULL;
5230 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005232 x = new_delta(1, 0, 0, 0);
5233 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5234 return NULL;
5235 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005237 /* time values */
5238 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005240 x = new_time(0, 0, 0, 0, Py_None);
5241 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5242 return NULL;
5243 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005245 x = new_time(23, 59, 59, 999999, Py_None);
5246 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5247 return NULL;
5248 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005250 x = new_delta(0, 0, 1, 0);
5251 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5252 return NULL;
5253 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005255 /* datetime values */
5256 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00005257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005258 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
5259 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5260 return NULL;
5261 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005263 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5264 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5265 return NULL;
5266 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005268 x = new_delta(0, 0, 1, 0);
5269 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5270 return NULL;
5271 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00005272
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005273 /* timezone values */
5274 d = PyDateTime_TimeZoneType.tp_dict;
5275
5276 delta = new_delta(0, 0, 0, 0);
5277 if (delta == NULL)
5278 return NULL;
5279 x = new_timezone(delta, NULL);
5280 Py_DECREF(delta);
5281 if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5282 return NULL;
Alexander Belopolskya11d8c02010-07-06 23:19:45 +00005283 PyDateTime_TimeZone_UTC = x;
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005284
5285 delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5286 if (delta == NULL)
5287 return NULL;
5288 x = new_timezone(delta, NULL);
5289 Py_DECREF(delta);
5290 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5291 return NULL;
5292 Py_DECREF(x);
5293
5294 delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5295 if (delta == NULL)
5296 return NULL;
5297 x = new_timezone(delta, NULL);
5298 Py_DECREF(delta);
5299 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5300 return NULL;
5301 Py_DECREF(x);
5302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005303 /* module initialization */
5304 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5305 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00005306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005307 Py_INCREF(&PyDateTime_DateType);
5308 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005310 Py_INCREF(&PyDateTime_DateTimeType);
5311 PyModule_AddObject(m, "datetime",
5312 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005314 Py_INCREF(&PyDateTime_TimeType);
5315 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00005316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005317 Py_INCREF(&PyDateTime_DeltaType);
5318 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005320 Py_INCREF(&PyDateTime_TZInfoType);
5321 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00005322
Alexander Belopolsky4e749a12010-06-14 14:15:50 +00005323 Py_INCREF(&PyDateTime_TimeZoneType);
5324 PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005326 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5327 if (x == NULL)
5328 return NULL;
5329 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00005330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005331 /* A 4-year cycle has an extra leap day over what we'd get from
5332 * pasting together 4 single years.
5333 */
5334 assert(DI4Y == 4 * 365 + 1);
5335 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005337 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5338 * get from pasting together 4 100-year cycles.
5339 */
5340 assert(DI400Y == 4 * DI100Y + 1);
5341 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005343 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5344 * pasting together 25 4-year cycles.
5345 */
5346 assert(DI100Y == 25 * DI4Y - 1);
5347 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00005348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005349 us_per_us = PyLong_FromLong(1);
5350 us_per_ms = PyLong_FromLong(1000);
5351 us_per_second = PyLong_FromLong(1000000);
5352 us_per_minute = PyLong_FromLong(60000000);
5353 seconds_per_day = PyLong_FromLong(24 * 3600);
5354 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5355 us_per_minute == NULL || seconds_per_day == NULL)
5356 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00005357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005358 /* The rest are too big for 32-bit ints, but even
5359 * us_per_week fits in 40 bits, so doubles should be exact.
5360 */
5361 us_per_hour = PyLong_FromDouble(3600000000.0);
5362 us_per_day = PyLong_FromDouble(86400000000.0);
5363 us_per_week = PyLong_FromDouble(604800000000.0);
5364 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5365 return NULL;
5366 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00005367}
Tim Petersf3615152003-01-01 21:51:37 +00005368
5369/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00005370Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00005371 x.n = x stripped of its timezone -- its naive time.
5372 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005373 return None
Tim Petersf3615152003-01-01 21:51:37 +00005374 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005375 return None
Tim Petersf3615152003-01-01 21:51:37 +00005376 x.s = x's standard offset, x.o - x.d
5377
5378Now some derived rules, where k is a duration (timedelta).
5379
53801. x.o = x.s + x.d
5381 This follows from the definition of x.s.
5382
Tim Petersc5dc4da2003-01-02 17:55:03 +000053832. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00005384 This is actually a requirement, an assumption we need to make about
5385 sane tzinfo classes.
5386
53873. The naive UTC time corresponding to x is x.n - x.o.
5388 This is again a requirement for a sane tzinfo class.
5389
53904. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00005391 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00005392
Tim Petersc5dc4da2003-01-02 17:55:03 +000053935. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00005394 Again follows from how arithmetic is defined.
5395
Tim Peters8bb5ad22003-01-24 02:44:45 +00005396Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00005397(meaning that the various tzinfo methods exist, and don't blow up or return
5398None when called).
5399
Tim Petersa9bc1682003-01-11 03:39:11 +00005400The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00005401x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00005402
5403By #3, we want
5404
Tim Peters8bb5ad22003-01-24 02:44:45 +00005405 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00005406
5407The algorithm starts by attaching tz to x.n, and calling that y. So
5408x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5409becomes true; in effect, we want to solve [2] for k:
5410
Tim Peters8bb5ad22003-01-24 02:44:45 +00005411 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00005412
5413By #1, this is the same as
5414
Tim Peters8bb5ad22003-01-24 02:44:45 +00005415 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00005416
5417By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5418Substituting that into [3],
5419
Tim Peters8bb5ad22003-01-24 02:44:45 +00005420 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5421 k - (y+k).s - (y+k).d = 0; rearranging,
5422 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5423 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00005424
Tim Peters8bb5ad22003-01-24 02:44:45 +00005425On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5426approximate k by ignoring the (y+k).d term at first. Note that k can't be
5427very large, since all offset-returning methods return a duration of magnitude
5428less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5429be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00005430
5431In any case, the new value is
5432
Tim Peters8bb5ad22003-01-24 02:44:45 +00005433 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00005434
Tim Peters8bb5ad22003-01-24 02:44:45 +00005435It's helpful to step back at look at [4] from a higher level: it's simply
5436mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00005437
5438At this point, if
5439
Tim Peters8bb5ad22003-01-24 02:44:45 +00005440 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00005441
5442we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00005443at the start of daylight time. Picture US Eastern for concreteness. The wall
5444time 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 +00005445sense then. The docs ask that an Eastern tzinfo class consider such a time to
5446be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5447on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00005448the only spelling that makes sense on the local wall clock.
5449
Tim Petersc5dc4da2003-01-02 17:55:03 +00005450In fact, if [5] holds at this point, we do have the standard-time spelling,
5451but that takes a bit of proof. We first prove a stronger result. What's the
5452difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00005453
Tim Peters8bb5ad22003-01-24 02:44:45 +00005454 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00005455
Tim Petersc5dc4da2003-01-02 17:55:03 +00005456Now
5457 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00005458 (y + y.s).n = by #5
5459 y.n + y.s = since y.n = x.n
5460 x.n + y.s = since z and y are have the same tzinfo member,
5461 y.s = z.s by #2
5462 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00005463
Tim Petersc5dc4da2003-01-02 17:55:03 +00005464Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00005465
Tim Petersc5dc4da2003-01-02 17:55:03 +00005466 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00005467 x.n - ((x.n + z.s) - z.o) = expanding
5468 x.n - x.n - z.s + z.o = cancelling
5469 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005470 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005471
Tim Petersc5dc4da2003-01-02 17:55:03 +00005472So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005473
Tim Petersc5dc4da2003-01-02 17:55:03 +00005474If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005475spelling we wanted in the endcase described above. We're done. Contrarily,
5476if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005477
Tim Petersc5dc4da2003-01-02 17:55:03 +00005478If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5479add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005480local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005481
Tim Petersc5dc4da2003-01-02 17:55:03 +00005482Let
Tim Petersf3615152003-01-01 21:51:37 +00005483
Tim Peters4fede1a2003-01-04 00:26:59 +00005484 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005485
Tim Peters4fede1a2003-01-04 00:26:59 +00005486and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005487
Tim Peters8bb5ad22003-01-24 02:44:45 +00005488 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005489
Tim Peters8bb5ad22003-01-24 02:44:45 +00005490If so, we're done. If not, the tzinfo class is insane, according to the
5491assumptions we've made. This also requires a bit of proof. As before, let's
5492compute the difference between the LHS and RHS of [8] (and skipping some of
5493the justifications for the kinds of substitutions we've done several times
5494already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005495
Tim Peters8bb5ad22003-01-24 02:44:45 +00005496 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005497 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5498 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5499 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5500 - z.n + z.n - z.o + z'.o = cancel z.n
5501 - z.o + z'.o = #1 twice
5502 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5503 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00005504
5505So 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 +00005506we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5507return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005508
Tim Peters8bb5ad22003-01-24 02:44:45 +00005509How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5510a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5511would have to change the result dst() returns: we start in DST, and moving
5512a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005513
Tim Peters8bb5ad22003-01-24 02:44:45 +00005514There isn't a sane case where this can happen. The closest it gets is at
5515the end of DST, where there's an hour in UTC with no spelling in a hybrid
5516tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5517that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5518UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5519time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5520clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5521standard time. Since that's what the local clock *does*, we want to map both
5522UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005523in local time, but so it goes -- it's the way the local clock works.
5524
Tim Peters8bb5ad22003-01-24 02:44:45 +00005525When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5526so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5527z' = 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 +00005528(correctly) concludes that z' is not UTC-equivalent to x.
5529
5530Because we know z.d said z was in daylight time (else [5] would have held and
5531we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005532and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005533return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5534but the reasoning doesn't depend on the example -- it depends on there being
5535two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005536z' must be in standard time, and is the spelling we want in this case.
5537
5538Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5539concerned (because it takes z' as being in standard time rather than the
5540daylight time we intend here), but returning it gives the real-life "local
5541clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5542tz.
5543
5544When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5545the 1:MM standard time spelling we want.
5546
5547So how can this break? One of the assumptions must be violated. Two
5548possibilities:
5549
55501) [2] effectively says that y.s is invariant across all y belong to a given
5551 time zone. This isn't true if, for political reasons or continental drift,
5552 a region decides to change its base offset from UTC.
5553
55542) There may be versions of "double daylight" time where the tail end of
5555 the analysis gives up a step too early. I haven't thought about that
5556 enough to say.
5557
5558In any case, it's clear that the default fromutc() is strong enough to handle
5559"almost all" time zones: so long as the standard offset is invariant, it
5560doesn't matter if daylight time transition points change from year to year, or
5561if daylight time is skipped in some years; it doesn't matter how large or
5562small dst() may get within its bounds; and it doesn't even matter if some
5563perverse time zone returns a negative dst()). So a breaking case must be
5564pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005565--------------------------------------------------------------------------- */