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