blob: 419eb7b6d58b16cfcbb29fd47a7ae9bec3b1ceb8 [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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Belopolsky3efc2fd2010-05-27 22:03:53 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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 Pitrou7f14f0d2010-05-09 16:14:21 +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;
Tim Peters2a799bf2002-12-16 20:18:38 +0000105
106/* ---------------------------------------------------------------------------
107 * Math utilities.
108 */
109
110/* k = i+j overflows iff k differs in sign from both inputs,
111 * iff k^i has sign bit set and k^j has sign bit set,
112 * iff (k^i)&(k^j) has sign bit set.
113 */
114#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000115 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +0000116
117/* Compute Python divmod(x, y), returning the quotient and storing the
118 * remainder into *r. The quotient is the floor of x/y, and that's
119 * the real point of this. C will probably truncate instead (C99
120 * requires truncation; C89 left it implementation-defined).
121 * Simplification: we *require* that y > 0 here. That's appropriate
122 * for all the uses made of it. This simplifies the code and makes
123 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
124 * overflow case).
125 */
126static int
127divmod(int x, int y, int *r)
128{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000129 int quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000130
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000131 assert(y > 0);
132 quo = x / y;
133 *r = x - quo * y;
134 if (*r < 0) {
135 --quo;
136 *r += y;
137 }
138 assert(0 <= *r && *r < y);
139 return quo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000140}
141
Tim Peters5d644dd2003-01-02 16:32:54 +0000142/* Round a double to the nearest long. |x| must be small enough to fit
143 * in a C long; this is not checked.
144 */
145static long
146round_to_long(double x)
147{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000148 if (x >= 0.0)
149 x = floor(x + 0.5);
150 else
151 x = ceil(x - 0.5);
152 return (long)x;
Tim Peters5d644dd2003-01-02 16:32:54 +0000153}
154
Tim Peters2a799bf2002-12-16 20:18:38 +0000155/* ---------------------------------------------------------------------------
156 * General calendrical helper functions
157 */
158
159/* For each month ordinal in 1..12, the number of days in that month,
160 * and the number of days before that month in the same year. These
161 * are correct for non-leap years only.
162 */
163static int _days_in_month[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000164 0, /* unused; this vector uses 1-based indexing */
165 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
Tim Peters2a799bf2002-12-16 20:18:38 +0000166};
167
168static int _days_before_month[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000169 0, /* unused; this vector uses 1-based indexing */
170 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
Tim Peters2a799bf2002-12-16 20:18:38 +0000171};
172
173/* year -> 1 if leap year, else 0. */
174static int
175is_leap(int year)
176{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000177 /* Cast year to unsigned. The result is the same either way, but
178 * C can generate faster code for unsigned mod than for signed
179 * mod (especially for % 4 -- a good compiler should just grab
180 * the last 2 bits when the LHS is unsigned).
181 */
182 const unsigned int ayear = (unsigned int)year;
183 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000184}
185
186/* year, month -> number of days in that month in that year */
187static int
188days_in_month(int year, int month)
189{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000190 assert(month >= 1);
191 assert(month <= 12);
192 if (month == 2 && is_leap(year))
193 return 29;
194 else
195 return _days_in_month[month];
Tim Peters2a799bf2002-12-16 20:18:38 +0000196}
197
198/* year, month -> number of days in year preceeding first day of month */
199static int
200days_before_month(int year, int month)
201{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000202 int days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000203
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000204 assert(month >= 1);
205 assert(month <= 12);
206 days = _days_before_month[month];
207 if (month > 2 && is_leap(year))
208 ++days;
209 return days;
Tim Peters2a799bf2002-12-16 20:18:38 +0000210}
211
212/* year -> number of days before January 1st of year. Remember that we
213 * start with year 1, so days_before_year(1) == 0.
214 */
215static int
216days_before_year(int year)
217{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000218 int y = year - 1;
219 /* This is incorrect if year <= 0; we really want the floor
220 * here. But so long as MINYEAR is 1, the smallest year this
221 * can see is 0 (this can happen in some normalization endcases),
222 * so we'll just special-case that.
223 */
224 assert (year >= 0);
225 if (y >= 0)
226 return y*365 + y/4 - y/100 + y/400;
227 else {
228 assert(y == -1);
229 return -366;
230 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000231}
232
233/* Number of days in 4, 100, and 400 year cycles. That these have
234 * the correct values is asserted in the module init function.
235 */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000236#define DI4Y 1461 /* days_before_year(5); days in 4 years */
237#define DI100Y 36524 /* days_before_year(101); days in 100 years */
238#define DI400Y 146097 /* days_before_year(401); days in 400 years */
Tim Peters2a799bf2002-12-16 20:18:38 +0000239
240/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
241static void
242ord_to_ymd(int ordinal, int *year, int *month, int *day)
243{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000244 int n, n1, n4, n100, n400, leapyear, preceding;
Tim Peters2a799bf2002-12-16 20:18:38 +0000245
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000246 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
247 * leap years repeats exactly every 400 years. The basic strategy is
248 * to find the closest 400-year boundary at or before ordinal, then
249 * work with the offset from that boundary to ordinal. Life is much
250 * clearer if we subtract 1 from ordinal first -- then the values
251 * of ordinal at 400-year boundaries are exactly those divisible
252 * by DI400Y:
253 *
254 * D M Y n n-1
255 * -- --- ---- ---------- ----------------
256 * 31 Dec -400 -DI400Y -DI400Y -1
257 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
258 * ...
259 * 30 Dec 000 -1 -2
260 * 31 Dec 000 0 -1
261 * 1 Jan 001 1 0 400-year boundary
262 * 2 Jan 001 2 1
263 * 3 Jan 001 3 2
264 * ...
265 * 31 Dec 400 DI400Y DI400Y -1
266 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
267 */
268 assert(ordinal >= 1);
269 --ordinal;
270 n400 = ordinal / DI400Y;
271 n = ordinal % DI400Y;
272 *year = n400 * 400 + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000273
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000274 /* Now n is the (non-negative) offset, in days, from January 1 of
275 * year, to the desired date. Now compute how many 100-year cycles
276 * precede n.
277 * Note that it's possible for n100 to equal 4! In that case 4 full
278 * 100-year cycles precede the desired day, which implies the
279 * desired day is December 31 at the end of a 400-year cycle.
280 */
281 n100 = n / DI100Y;
282 n = n % DI100Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000283
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000284 /* Now compute how many 4-year cycles precede it. */
285 n4 = n / DI4Y;
286 n = n % DI4Y;
Tim Peters2a799bf2002-12-16 20:18:38 +0000287
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000288 /* And now how many single years. Again n1 can be 4, and again
289 * meaning that the desired day is December 31 at the end of the
290 * 4-year cycle.
291 */
292 n1 = n / 365;
293 n = n % 365;
Tim Peters2a799bf2002-12-16 20:18:38 +0000294
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000295 *year += n100 * 100 + n4 * 4 + n1;
296 if (n1 == 4 || n100 == 4) {
297 assert(n == 0);
298 *year -= 1;
299 *month = 12;
300 *day = 31;
301 return;
302 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000303
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000304 /* Now the year is correct, and n is the offset from January 1. We
305 * find the month via an estimate that's either exact or one too
306 * large.
307 */
308 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
309 assert(leapyear == is_leap(*year));
310 *month = (n + 50) >> 5;
311 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
312 if (preceding > n) {
313 /* estimate is too large */
314 *month -= 1;
315 preceding -= days_in_month(*year, *month);
316 }
317 n -= preceding;
318 assert(0 <= n);
319 assert(n < days_in_month(*year, *month));
Tim Peters2a799bf2002-12-16 20:18:38 +0000320
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000321 *day = n + 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000322}
323
324/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
325static int
326ymd_to_ord(int year, int month, int day)
327{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000328 return days_before_year(year) + days_before_month(year, month) + day;
Tim Peters2a799bf2002-12-16 20:18:38 +0000329}
330
331/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
332static int
333weekday(int year, int month, int day)
334{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000335 return (ymd_to_ord(year, month, day) + 6) % 7;
Tim Peters2a799bf2002-12-16 20:18:38 +0000336}
337
338/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
339 * first calendar week containing a Thursday.
340 */
341static int
342iso_week1_monday(int year)
343{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000344 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
345 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
346 int first_weekday = (first_day + 6) % 7;
347 /* ordinal of closest Monday at or before 1/1 */
348 int week1_monday = first_day - first_weekday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000349
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000350 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
351 week1_monday += 7;
352 return week1_monday;
Tim Peters2a799bf2002-12-16 20:18:38 +0000353}
354
355/* ---------------------------------------------------------------------------
356 * Range checkers.
357 */
358
359/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
360 * If not, raise OverflowError and return -1.
361 */
362static int
363check_delta_day_range(int days)
364{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000365 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
366 return 0;
367 PyErr_Format(PyExc_OverflowError,
368 "days=%d; must have magnitude <= %d",
369 days, MAX_DELTA_DAYS);
370 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000371}
372
373/* Check that date arguments are in range. Return 0 if they are. If they
374 * aren't, raise ValueError and return -1.
375 */
376static int
377check_date_args(int year, int month, int day)
378{
379
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000380 if (year < MINYEAR || year > MAXYEAR) {
381 PyErr_SetString(PyExc_ValueError,
382 "year is out of range");
383 return -1;
384 }
385 if (month < 1 || month > 12) {
386 PyErr_SetString(PyExc_ValueError,
387 "month must be in 1..12");
388 return -1;
389 }
390 if (day < 1 || day > days_in_month(year, month)) {
391 PyErr_SetString(PyExc_ValueError,
392 "day is out of range for month");
393 return -1;
394 }
395 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000396}
397
398/* Check that time arguments are in range. Return 0 if they are. If they
399 * aren't, raise ValueError and return -1.
400 */
401static int
402check_time_args(int h, int m, int s, int us)
403{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000404 if (h < 0 || h > 23) {
405 PyErr_SetString(PyExc_ValueError,
406 "hour must be in 0..23");
407 return -1;
408 }
409 if (m < 0 || m > 59) {
410 PyErr_SetString(PyExc_ValueError,
411 "minute must be in 0..59");
412 return -1;
413 }
414 if (s < 0 || s > 59) {
415 PyErr_SetString(PyExc_ValueError,
416 "second must be in 0..59");
417 return -1;
418 }
419 if (us < 0 || us > 999999) {
420 PyErr_SetString(PyExc_ValueError,
421 "microsecond must be in 0..999999");
422 return -1;
423 }
424 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +0000425}
426
427/* ---------------------------------------------------------------------------
428 * Normalization utilities.
429 */
430
431/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
432 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
433 * at least factor, enough of *lo is converted into "hi" units so that
434 * 0 <= *lo < factor. The input values must be such that int overflow
435 * is impossible.
436 */
437static void
438normalize_pair(int *hi, int *lo, int factor)
439{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000440 assert(factor > 0);
441 assert(lo != hi);
442 if (*lo < 0 || *lo >= factor) {
443 const int num_hi = divmod(*lo, factor, lo);
444 const int new_hi = *hi + num_hi;
445 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
446 *hi = new_hi;
447 }
448 assert(0 <= *lo && *lo < factor);
Tim Peters2a799bf2002-12-16 20:18:38 +0000449}
450
451/* Fiddle days (d), seconds (s), and microseconds (us) so that
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000452 * 0 <= *s < 24*3600
453 * 0 <= *us < 1000000
Tim Peters2a799bf2002-12-16 20:18:38 +0000454 * The input values must be such that the internals don't overflow.
455 * The way this routine is used, we don't get close.
456 */
457static void
458normalize_d_s_us(int *d, int *s, int *us)
459{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000460 if (*us < 0 || *us >= 1000000) {
461 normalize_pair(s, us, 1000000);
462 /* |s| can't be bigger than about
463 * |original s| + |original us|/1000000 now.
464 */
Tim Peters2a799bf2002-12-16 20:18:38 +0000465
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000466 }
467 if (*s < 0 || *s >= 24*3600) {
468 normalize_pair(d, s, 24*3600);
469 /* |d| can't be bigger than about
470 * |original d| +
471 * (|original s| + |original us|/1000000) / (24*3600) now.
472 */
473 }
474 assert(0 <= *s && *s < 24*3600);
475 assert(0 <= *us && *us < 1000000);
Tim Peters2a799bf2002-12-16 20:18:38 +0000476}
477
478/* Fiddle years (y), months (m), and days (d) so that
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000479 * 1 <= *m <= 12
480 * 1 <= *d <= days_in_month(*y, *m)
Tim Peters2a799bf2002-12-16 20:18:38 +0000481 * The input values must be such that the internals don't overflow.
482 * The way this routine is used, we don't get close.
483 */
Alexander Belopolsky3efc2fd2010-05-27 22:03:53 +0000484static int
Tim Peters2a799bf2002-12-16 20:18:38 +0000485normalize_y_m_d(int *y, int *m, int *d)
486{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000487 int dim; /* # of days in month */
Tim Peters2a799bf2002-12-16 20:18:38 +0000488
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000489 /* This gets muddy: the proper range for day can't be determined
490 * without knowing the correct month and year, but if day is, e.g.,
491 * plus or minus a million, the current month and year values make
492 * no sense (and may also be out of bounds themselves).
493 * Saying 12 months == 1 year should be non-controversial.
494 */
495 if (*m < 1 || *m > 12) {
496 --*m;
497 normalize_pair(y, m, 12);
498 ++*m;
499 /* |y| can't be bigger than about
500 * |original y| + |original m|/12 now.
501 */
502 }
503 assert(1 <= *m && *m <= 12);
Tim Peters2a799bf2002-12-16 20:18:38 +0000504
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000505 /* Now only day can be out of bounds (year may also be out of bounds
506 * for a datetime object, but we don't care about that here).
507 * If day is out of bounds, what to do is arguable, but at least the
508 * method here is principled and explainable.
509 */
510 dim = days_in_month(*y, *m);
511 if (*d < 1 || *d > dim) {
512 /* Move day-1 days from the first of the month. First try to
513 * get off cheap if we're only one day out of range
514 * (adjustments for timezone alone can't be worse than that).
515 */
516 if (*d == 0) {
517 --*m;
518 if (*m > 0)
519 *d = days_in_month(*y, *m);
520 else {
521 --*y;
522 *m = 12;
523 *d = 31;
524 }
525 }
526 else if (*d == dim + 1) {
527 /* move forward a day */
528 ++*m;
529 *d = 1;
530 if (*m > 12) {
531 *m = 1;
532 ++*y;
533 }
534 }
535 else {
536 int ordinal = ymd_to_ord(*y, *m, 1) +
537 *d - 1;
Alexander Belopolsky3efc2fd2010-05-27 22:03:53 +0000538 if (ordinal < 1 || ordinal > MAXORDINAL) {
539 goto error;
540 } else {
541 ord_to_ymd(ordinal, y, m, d);
542 return 0;
543 }
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000544 }
545 }
546 assert(*m > 0);
547 assert(*d > 0);
Alexander Belopolsky3efc2fd2010-05-27 22:03:53 +0000548 if (MINYEAR <= *y && *y <= MAXYEAR)
549 return 0;
550 error:
551 PyErr_SetString(PyExc_OverflowError,
552 "date value out of range");
553 return -1;
554
Tim Peters2a799bf2002-12-16 20:18:38 +0000555}
556
557/* Fiddle out-of-bounds months and days so that the result makes some kind
558 * of sense. The parameters are both inputs and outputs. Returns < 0 on
559 * failure, where failure means the adjusted year is out of bounds.
560 */
561static int
562normalize_date(int *year, int *month, int *day)
563{
Alexander Belopolsky3efc2fd2010-05-27 22:03:53 +0000564 return normalize_y_m_d(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000565}
566
567/* Force all the datetime fields into range. The parameters are both
568 * inputs and outputs. Returns < 0 on error.
569 */
570static int
571normalize_datetime(int *year, int *month, int *day,
572 int *hour, int *minute, int *second,
573 int *microsecond)
574{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000575 normalize_pair(second, microsecond, 1000000);
576 normalize_pair(minute, second, 60);
577 normalize_pair(hour, minute, 60);
578 normalize_pair(day, hour, 24);
579 return normalize_date(year, month, day);
Tim Peters2a799bf2002-12-16 20:18:38 +0000580}
581
582/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000583 * Basic object allocation: tp_alloc implementations. These allocate
584 * Python objects of the right size and type, and do the Python object-
585 * initialization bit. If there's not enough memory, they return NULL after
586 * setting MemoryError. All data members remain uninitialized trash.
587 *
588 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000589 * member is needed. This is ugly, imprecise, and possibly insecure.
590 * tp_basicsize for the time and datetime types is set to the size of the
591 * struct that has room for the tzinfo member, so subclasses in Python will
592 * allocate enough space for a tzinfo member whether or not one is actually
593 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
594 * part is that PyType_GenericAlloc() (which subclasses in Python end up
595 * using) just happens today to effectively ignore the nitems argument
596 * when tp_itemsize is 0, which it is for these type objects. If that
597 * changes, perhaps the callers of tp_alloc slots in this file should
598 * be changed to force a 0 nitems argument unless the type being allocated
599 * is a base type implemented in this file (so that tp_alloc is time_alloc
600 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000601 */
602
603static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000604time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000605{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000606 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000607
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000608 self = (PyObject *)
609 PyObject_MALLOC(aware ?
610 sizeof(PyDateTime_Time) :
611 sizeof(_PyDateTime_BaseTime));
612 if (self == NULL)
613 return (PyObject *)PyErr_NoMemory();
614 PyObject_INIT(self, type);
615 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000616}
617
618static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000619datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000620{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000621 PyObject *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000622
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000623 self = (PyObject *)
624 PyObject_MALLOC(aware ?
625 sizeof(PyDateTime_DateTime) :
626 sizeof(_PyDateTime_BaseDateTime));
627 if (self == NULL)
628 return (PyObject *)PyErr_NoMemory();
629 PyObject_INIT(self, type);
630 return self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000631}
632
633/* ---------------------------------------------------------------------------
634 * Helpers for setting object fields. These work on pointers to the
635 * appropriate base class.
636 */
637
638/* For date and datetime. */
639static void
640set_date_fields(PyDateTime_Date *self, int y, int m, int d)
641{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000642 self->hashcode = -1;
643 SET_YEAR(self, y);
644 SET_MONTH(self, m);
645 SET_DAY(self, d);
Tim Petersb0c854d2003-05-17 15:57:00 +0000646}
647
648/* ---------------------------------------------------------------------------
649 * Create various objects, mostly without range checking.
650 */
651
652/* Create a date instance with no range checking. */
653static PyObject *
654new_date_ex(int year, int month, int day, PyTypeObject *type)
655{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000656 PyDateTime_Date *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000657
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000658 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
659 if (self != NULL)
660 set_date_fields(self, year, month, day);
661 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000662}
663
664#define new_date(year, month, day) \
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000665 new_date_ex(year, month, day, &PyDateTime_DateType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000666
667/* Create a datetime instance with no range checking. */
668static PyObject *
669new_datetime_ex(int year, int month, int day, int hour, int minute,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000670 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000671{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000672 PyDateTime_DateTime *self;
673 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000674
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000675 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
676 if (self != NULL) {
677 self->hastzinfo = aware;
678 set_date_fields((PyDateTime_Date *)self, year, month, day);
679 DATE_SET_HOUR(self, hour);
680 DATE_SET_MINUTE(self, minute);
681 DATE_SET_SECOND(self, second);
682 DATE_SET_MICROSECOND(self, usecond);
683 if (aware) {
684 Py_INCREF(tzinfo);
685 self->tzinfo = tzinfo;
686 }
687 }
688 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000689}
690
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000691#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
692 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
693 &PyDateTime_DateTimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000694
695/* Create a time instance with no range checking. */
696static PyObject *
697new_time_ex(int hour, int minute, int second, int usecond,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000698 PyObject *tzinfo, PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000699{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000700 PyDateTime_Time *self;
701 char aware = tzinfo != Py_None;
Tim Petersb0c854d2003-05-17 15:57:00 +0000702
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000703 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
704 if (self != NULL) {
705 self->hastzinfo = aware;
706 self->hashcode = -1;
707 TIME_SET_HOUR(self, hour);
708 TIME_SET_MINUTE(self, minute);
709 TIME_SET_SECOND(self, second);
710 TIME_SET_MICROSECOND(self, usecond);
711 if (aware) {
712 Py_INCREF(tzinfo);
713 self->tzinfo = tzinfo;
714 }
715 }
716 return (PyObject *)self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000717}
718
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000719#define new_time(hh, mm, ss, us, tzinfo) \
720 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000721
722/* Create a timedelta instance. Normalize the members iff normalize is
723 * true. Passing false is a speed optimization, if you know for sure
724 * that seconds and microseconds are already in their proper ranges. In any
725 * case, raises OverflowError and returns NULL if the normalized days is out
726 * of range).
727 */
728static PyObject *
729new_delta_ex(int days, int seconds, int microseconds, int normalize,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000730 PyTypeObject *type)
Tim Petersb0c854d2003-05-17 15:57:00 +0000731{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000732 PyDateTime_Delta *self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000733
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000734 if (normalize)
735 normalize_d_s_us(&days, &seconds, &microseconds);
736 assert(0 <= seconds && seconds < 24*3600);
737 assert(0 <= microseconds && microseconds < 1000000);
Tim Petersb0c854d2003-05-17 15:57:00 +0000738
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000739 if (check_delta_day_range(days) < 0)
740 return NULL;
Tim Petersb0c854d2003-05-17 15:57:00 +0000741
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000742 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
743 if (self != NULL) {
744 self->hashcode = -1;
745 SET_TD_DAYS(self, days);
746 SET_TD_SECONDS(self, seconds);
747 SET_TD_MICROSECONDS(self, microseconds);
748 }
749 return (PyObject *) self;
Tim Petersb0c854d2003-05-17 15:57:00 +0000750}
751
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000752#define new_delta(d, s, us, normalize) \
753 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +0000754
755/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000756 * tzinfo helpers.
757 */
758
Tim Peters855fe882002-12-22 03:43:39 +0000759/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
760 * raise TypeError and return -1.
761 */
762static int
763check_tzinfo_subclass(PyObject *p)
764{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000765 if (p == Py_None || PyTZInfo_Check(p))
766 return 0;
767 PyErr_Format(PyExc_TypeError,
768 "tzinfo argument must be None or of a tzinfo subclass, "
769 "not type '%s'",
770 Py_TYPE(p)->tp_name);
771 return -1;
Tim Peters855fe882002-12-22 03:43:39 +0000772}
773
Tim Petersbad8ff02002-12-30 20:52:32 +0000774/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000775 * If tzinfo is None, returns None.
776 */
777static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000778call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000779{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000780 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000781
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000782 assert(tzinfo && methname && tzinfoarg);
783 assert(check_tzinfo_subclass(tzinfo) >= 0);
784 if (tzinfo == Py_None) {
785 result = Py_None;
786 Py_INCREF(result);
787 }
788 else
789 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
790 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000791}
792
Tim Peters2a799bf2002-12-16 20:18:38 +0000793/* If self has a tzinfo member, return a BORROWED reference to it. Else
794 * return NULL, which is NOT AN ERROR. There are no error returns here,
795 * and the caller must not decref the result.
796 */
797static PyObject *
798get_tzinfo_member(PyObject *self)
799{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000800 PyObject *tzinfo = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +0000801
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000802 if (PyDateTime_Check(self) && HASTZINFO(self))
803 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
804 else if (PyTime_Check(self) && HASTZINFO(self))
805 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000806
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000807 return tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000808}
809
Tim Petersbad8ff02002-12-30 20:52:32 +0000810/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000811 * result. tzinfo must be an instance of the tzinfo class. If the method
812 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000813 * return None or timedelta, TypeError is raised and this returns -1. If it
814 * returnsa timedelta and the value is out of range or isn't a whole number
815 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000816 * Else *none is set to 0 and the integer method result is returned.
817 */
818static int
819call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000820 int *none)
Tim Peters2a799bf2002-12-16 20:18:38 +0000821{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000822 PyObject *u;
823 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000824
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000825 assert(tzinfo != NULL);
826 assert(PyTZInfo_Check(tzinfo));
827 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000828
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000829 *none = 0;
830 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
831 if (u == NULL)
832 return -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000833
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000834 else if (u == Py_None) {
835 result = 0;
836 *none = 1;
837 }
838 else if (PyDelta_Check(u)) {
839 const int days = GET_TD_DAYS(u);
840 if (days < -1 || days > 0)
841 result = 24*60; /* trigger ValueError below */
842 else {
843 /* next line can't overflow because we know days
844 * is -1 or 0 now
845 */
846 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
847 result = divmod(ss, 60, &ss);
848 if (ss || GET_TD_MICROSECONDS(u)) {
849 PyErr_Format(PyExc_ValueError,
850 "tzinfo.%s() must return a "
851 "whole number of minutes",
852 name);
853 result = -1;
854 }
855 }
856 }
857 else {
858 PyErr_Format(PyExc_TypeError,
859 "tzinfo.%s() must return None or "
860 "timedelta, not '%s'",
861 name, Py_TYPE(u)->tp_name);
862 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000863
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000864 Py_DECREF(u);
865 if (result < -1439 || result > 1439) {
866 PyErr_Format(PyExc_ValueError,
867 "tzinfo.%s() returned %d; must be in "
868 "-1439 .. 1439",
869 name, result);
870 result = -1;
871 }
872 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000873}
874
875/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
876 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
877 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000878 * doesn't return None or timedelta, TypeError is raised and this returns -1.
879 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
880 * # of minutes), ValueError is raised and this returns -1. Else *none is
881 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000882 */
883static int
884call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
885{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000886 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000887}
888
Tim Petersbad8ff02002-12-30 20:52:32 +0000889/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
890 */
Tim Peters855fe882002-12-22 03:43:39 +0000891static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000892offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000893 PyObject *result;
Tim Peters855fe882002-12-22 03:43:39 +0000894
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000895 assert(tzinfo && name && tzinfoarg);
896 if (tzinfo == Py_None) {
897 result = Py_None;
898 Py_INCREF(result);
899 }
900 else {
901 int none;
902 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
903 &none);
904 if (offset < 0 && PyErr_Occurred())
905 return NULL;
906 if (none) {
907 result = Py_None;
908 Py_INCREF(result);
909 }
910 else
911 result = new_delta(0, offset * 60, 0, 1);
912 }
913 return result;
Tim Peters855fe882002-12-22 03:43:39 +0000914}
915
Tim Peters2a799bf2002-12-16 20:18:38 +0000916/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
917 * result. tzinfo must be an instance of the tzinfo class. If dst()
918 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000919 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000920 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000921 * ValueError is raised and this returns -1. Else *none is set to 0 and
922 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000923 */
924static int
925call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
926{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000927 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000928}
929
Tim Petersbad8ff02002-12-30 20:52:32 +0000930/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000931 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000932 * tzname() doesn't return None or a string, TypeError is raised and this
Guido van Rossume3d1d412007-05-23 21:24:35 +0000933 * returns NULL. If the result is a string, we ensure it is a Unicode
934 * string.
Tim Peters2a799bf2002-12-16 20:18:38 +0000935 */
936static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000937call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000938{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000939 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000940
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000941 assert(tzinfo != NULL);
942 assert(check_tzinfo_subclass(tzinfo) >= 0);
943 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000944
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000945 if (tzinfo == Py_None) {
946 result = Py_None;
947 Py_INCREF(result);
948 }
949 else
950 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000951
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000952 if (result != NULL && result != Py_None) {
953 if (!PyUnicode_Check(result)) {
954 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
955 "return None or a string, not '%s'",
956 Py_TYPE(result)->tp_name);
957 Py_DECREF(result);
958 result = NULL;
959 }
960 else if (!PyUnicode_Check(result)) {
961 PyObject *temp = PyUnicode_FromObject(result);
962 Py_DECREF(result);
963 result = temp;
964 }
965 }
966 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000967}
968
969typedef enum {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000970 /* an exception has been set; the caller should pass it on */
971 OFFSET_ERROR,
Tim Peters2a799bf2002-12-16 20:18:38 +0000972
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000973 /* type isn't date, datetime, or time subclass */
974 OFFSET_UNKNOWN,
Tim Peters2a799bf2002-12-16 20:18:38 +0000975
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000976 /* date,
977 * datetime with !hastzinfo
978 * datetime with None tzinfo,
979 * datetime where utcoffset() returns None
980 * time with !hastzinfo
981 * time with None tzinfo,
982 * time where utcoffset() returns None
983 */
984 OFFSET_NAIVE,
Tim Peters2a799bf2002-12-16 20:18:38 +0000985
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000986 /* time or datetime where utcoffset() doesn't return None */
987 OFFSET_AWARE
Tim Peters2a799bf2002-12-16 20:18:38 +0000988} naivety;
989
Tim Peters14b69412002-12-22 18:10:22 +0000990/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000991 * the "naivety" typedef for details. If the type is aware, *offset is set
992 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000993 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000994 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000995 */
996static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000997classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000998{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000999 int none;
1000 PyObject *tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +00001001
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001002 assert(tzinfoarg != NULL);
1003 *offset = 0;
1004 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
1005 if (tzinfo == Py_None)
1006 return OFFSET_NAIVE;
1007 if (tzinfo == NULL) {
1008 /* note that a datetime passes the PyDate_Check test */
1009 return (PyTime_Check(op) || PyDate_Check(op)) ?
1010 OFFSET_NAIVE : OFFSET_UNKNOWN;
1011 }
1012 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1013 if (*offset == -1 && PyErr_Occurred())
1014 return OFFSET_ERROR;
1015 return none ? OFFSET_NAIVE : OFFSET_AWARE;
Tim Peters2a799bf2002-12-16 20:18:38 +00001016}
1017
Tim Peters00237032002-12-27 02:21:51 +00001018/* Classify two objects as to whether they're naive or offset-aware.
1019 * This isn't quite the same as calling classify_utcoffset() twice: for
1020 * binary operations (comparison and subtraction), we generally want to
1021 * ignore the tzinfo members if they're identical. This is by design,
1022 * so that results match "naive" expectations when mixing objects from a
1023 * single timezone. So in that case, this sets both offsets to 0 and
1024 * both naiveties to OFFSET_NAIVE.
1025 * The function returns 0 if everything's OK, and -1 on error.
1026 */
1027static int
1028classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001029 PyObject *tzinfoarg1,
1030 PyObject *o2, int *offset2, naivety *n2,
1031 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001032{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001033 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1034 *offset1 = *offset2 = 0;
1035 *n1 = *n2 = OFFSET_NAIVE;
1036 }
1037 else {
1038 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1039 if (*n1 == OFFSET_ERROR)
1040 return -1;
1041 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1042 if (*n2 == OFFSET_ERROR)
1043 return -1;
1044 }
1045 return 0;
Tim Peters00237032002-12-27 02:21:51 +00001046}
1047
Tim Peters2a799bf2002-12-16 20:18:38 +00001048/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1049 * stuff
1050 * ", tzinfo=" + repr(tzinfo)
1051 * before the closing ")".
1052 */
1053static PyObject *
1054append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1055{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001056 PyObject *temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001057
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001058 assert(PyUnicode_Check(repr));
1059 assert(tzinfo);
1060 if (tzinfo == Py_None)
1061 return repr;
1062 /* Get rid of the trailing ')'. */
1063 assert(PyUnicode_AS_UNICODE(repr)[PyUnicode_GET_SIZE(repr)-1] == ')');
1064 temp = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(repr),
1065 PyUnicode_GET_SIZE(repr) - 1);
1066 Py_DECREF(repr);
1067 if (temp == NULL)
1068 return NULL;
1069 repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1070 Py_DECREF(temp);
1071 return repr;
Tim Peters2a799bf2002-12-16 20:18:38 +00001072}
1073
1074/* ---------------------------------------------------------------------------
1075 * String format helpers.
1076 */
1077
1078static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001079format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001080{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001081 static const char *DayNames[] = {
1082 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1083 };
1084 static const char *MonthNames[] = {
1085 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1086 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1087 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001088
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001089 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001090
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001091 return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1092 DayNames[wday], MonthNames[GET_MONTH(date)-1],
1093 GET_DAY(date), hours, minutes, seconds,
1094 GET_YEAR(date));
Tim Peters2a799bf2002-12-16 20:18:38 +00001095}
1096
1097/* Add an hours & minutes UTC offset string to buf. buf has no more than
1098 * buflen bytes remaining. The UTC offset is gotten by calling
1099 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1100 * *buf, and that's all. Else the returned value is checked for sanity (an
1101 * integer in range), and if that's OK it's converted to an hours & minutes
1102 * string of the form
1103 * sign HH sep MM
1104 * Returns 0 if everything is OK. If the return value from utcoffset() is
1105 * bogus, an appropriate exception is set and -1 is returned.
1106 */
1107static int
Tim Peters328fff72002-12-20 01:31:27 +00001108format_utcoffset(char *buf, size_t buflen, const char *sep,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001109 PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001110{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001111 int offset;
1112 int hours;
1113 int minutes;
1114 char sign;
1115 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00001116
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001117 assert(buflen >= 1);
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001118
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001119 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1120 if (offset == -1 && PyErr_Occurred())
1121 return -1;
1122 if (none) {
1123 *buf = '\0';
1124 return 0;
1125 }
1126 sign = '+';
1127 if (offset < 0) {
1128 sign = '-';
1129 offset = - offset;
1130 }
1131 hours = divmod(offset, 60, &minutes);
1132 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1133 return 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001134}
1135
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001136static PyObject *
1137make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1138{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001139 PyObject *temp;
1140 PyObject *tzinfo = get_tzinfo_member(object);
1141 PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1142 if (Zreplacement == NULL)
1143 return NULL;
1144 if (tzinfo == Py_None || tzinfo == NULL)
1145 return Zreplacement;
Neal Norwitzaea70e02007-08-12 04:32:26 +00001146
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001147 assert(tzinfoarg != NULL);
1148 temp = call_tzname(tzinfo, tzinfoarg);
1149 if (temp == NULL)
1150 goto Error;
1151 if (temp == Py_None) {
1152 Py_DECREF(temp);
1153 return Zreplacement;
1154 }
Neal Norwitzaea70e02007-08-12 04:32:26 +00001155
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001156 assert(PyUnicode_Check(temp));
1157 /* Since the tzname is getting stuffed into the
1158 * format, we have to double any % signs so that
1159 * strftime doesn't treat them as format codes.
1160 */
1161 Py_DECREF(Zreplacement);
1162 Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
1163 Py_DECREF(temp);
1164 if (Zreplacement == NULL)
1165 return NULL;
1166 if (!PyUnicode_Check(Zreplacement)) {
1167 PyErr_SetString(PyExc_TypeError,
1168 "tzname.replace() did not return a string");
1169 goto Error;
1170 }
1171 return Zreplacement;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001172
1173 Error:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001174 Py_DECREF(Zreplacement);
1175 return NULL;
Guido van Rossumd8595fe2007-05-23 21:36:49 +00001176}
1177
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001178static PyObject *
1179make_freplacement(PyObject *object)
1180{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001181 char freplacement[64];
1182 if (PyTime_Check(object))
1183 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1184 else if (PyDateTime_Check(object))
1185 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1186 else
1187 sprintf(freplacement, "%06d", 0);
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001188
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001189 return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001190}
1191
Tim Peters2a799bf2002-12-16 20:18:38 +00001192/* I sure don't want to reproduce the strftime code from the time module,
1193 * so this imports the module and calls it. All the hair is due to
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001194 * giving special meanings to the %z, %Z and %f format codes via a
1195 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001196 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1197 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001198 */
1199static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001200wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001201 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001202{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001203 PyObject *result = NULL; /* guilty until proved innocent */
Tim Peters2a799bf2002-12-16 20:18:38 +00001204
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001205 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1206 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1207 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001208
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001209 const char *pin; /* pointer to next char in input format */
1210 Py_ssize_t flen; /* length of input format */
1211 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001212
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001213 PyObject *newfmt = NULL; /* py string, the output format */
1214 char *pnew; /* pointer to available byte in output format */
1215 size_t totalnew; /* number bytes total in output format buffer,
1216 exclusive of trailing \0 */
1217 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001218
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001219 const char *ptoappend; /* ptr to string to append to output buffer */
1220 Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001221
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001222 assert(object && format && timetuple);
1223 assert(PyUnicode_Check(format));
1224 /* Convert the input format to a C string and size */
1225 pin = _PyUnicode_AsStringAndSize(format, &flen);
1226 if (!pin)
1227 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001228
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001229 /* Give up if the year is before 1900.
1230 * Python strftime() plays games with the year, and different
1231 * games depending on whether envar PYTHON2K is set. This makes
1232 * years before 1900 a nightmare, even if the platform strftime
1233 * supports them (and not all do).
1234 * We could get a lot farther here by avoiding Python's strftime
1235 * wrapper and calling the C strftime() directly, but that isn't
1236 * an option in the Python implementation of this module.
1237 */
1238 {
1239 long year;
1240 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1241 if (pyyear == NULL) return NULL;
1242 assert(PyLong_Check(pyyear));
1243 year = PyLong_AsLong(pyyear);
1244 Py_DECREF(pyyear);
1245 if (year < 1900) {
1246 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1247 "1900; the datetime strftime() "
1248 "methods require year >= 1900",
1249 year);
1250 return NULL;
1251 }
1252 }
Tim Petersd6844152002-12-22 20:58:42 +00001253
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001254 /* Scan the input format, looking for %z/%Z/%f escapes, building
1255 * a new format. Since computing the replacements for those codes
1256 * is expensive, don't unless they're actually used.
1257 */
1258 if (flen > INT_MAX - 1) {
1259 PyErr_NoMemory();
1260 goto Done;
1261 }
Amaury Forgeot d'Arc9c74b142008-06-18 00:47:36 +00001262
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001263 totalnew = flen + 1; /* realistic if no %z/%Z */
1264 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1265 if (newfmt == NULL) goto Done;
1266 pnew = PyBytes_AsString(newfmt);
1267 usednew = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001268
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001269 while ((ch = *pin++) != '\0') {
1270 if (ch != '%') {
1271 ptoappend = pin - 1;
1272 ntoappend = 1;
1273 }
1274 else if ((ch = *pin++) == '\0') {
1275 /* There's a lone trailing %; doesn't make sense. */
1276 PyErr_SetString(PyExc_ValueError, "strftime format "
1277 "ends with raw %");
1278 goto Done;
1279 }
1280 /* A % has been seen and ch is the character after it. */
1281 else if (ch == 'z') {
1282 if (zreplacement == NULL) {
1283 /* format utcoffset */
1284 char buf[100];
1285 PyObject *tzinfo = get_tzinfo_member(object);
1286 zreplacement = PyBytes_FromStringAndSize("", 0);
1287 if (zreplacement == NULL) goto Done;
1288 if (tzinfo != Py_None && tzinfo != NULL) {
1289 assert(tzinfoarg != NULL);
1290 if (format_utcoffset(buf,
1291 sizeof(buf),
1292 "",
1293 tzinfo,
1294 tzinfoarg) < 0)
1295 goto Done;
1296 Py_DECREF(zreplacement);
1297 zreplacement =
1298 PyBytes_FromStringAndSize(buf,
1299 strlen(buf));
1300 if (zreplacement == NULL)
1301 goto Done;
1302 }
1303 }
1304 assert(zreplacement != NULL);
1305 ptoappend = PyBytes_AS_STRING(zreplacement);
1306 ntoappend = PyBytes_GET_SIZE(zreplacement);
1307 }
1308 else if (ch == 'Z') {
1309 /* format tzname */
1310 if (Zreplacement == NULL) {
1311 Zreplacement = make_Zreplacement(object,
1312 tzinfoarg);
1313 if (Zreplacement == NULL)
1314 goto Done;
1315 }
1316 assert(Zreplacement != NULL);
1317 assert(PyUnicode_Check(Zreplacement));
1318 ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
1319 &ntoappend);
1320 ntoappend = Py_SIZE(Zreplacement);
1321 }
1322 else if (ch == 'f') {
1323 /* format microseconds */
1324 if (freplacement == NULL) {
1325 freplacement = make_freplacement(object);
1326 if (freplacement == NULL)
1327 goto Done;
1328 }
1329 assert(freplacement != NULL);
1330 assert(PyBytes_Check(freplacement));
1331 ptoappend = PyBytes_AS_STRING(freplacement);
1332 ntoappend = PyBytes_GET_SIZE(freplacement);
1333 }
1334 else {
1335 /* percent followed by neither z nor Z */
1336 ptoappend = pin - 2;
1337 ntoappend = 2;
1338 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001339
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001340 /* Append the ntoappend chars starting at ptoappend to
1341 * the new format.
1342 */
1343 if (ntoappend == 0)
1344 continue;
1345 assert(ptoappend != NULL);
1346 assert(ntoappend > 0);
1347 while (usednew + ntoappend > totalnew) {
1348 size_t bigger = totalnew << 1;
1349 if ((bigger >> 1) != totalnew) { /* overflow */
1350 PyErr_NoMemory();
1351 goto Done;
1352 }
1353 if (_PyBytes_Resize(&newfmt, bigger) < 0)
1354 goto Done;
1355 totalnew = bigger;
1356 pnew = PyBytes_AsString(newfmt) + usednew;
1357 }
1358 memcpy(pnew, ptoappend, ntoappend);
1359 pnew += ntoappend;
1360 usednew += ntoappend;
1361 assert(usednew <= totalnew);
1362 } /* end while() */
Tim Peters2a799bf2002-12-16 20:18:38 +00001363
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001364 if (_PyBytes_Resize(&newfmt, usednew) < 0)
1365 goto Done;
1366 {
1367 PyObject *format;
1368 PyObject *time = PyImport_ImportModuleNoBlock("time");
1369 if (time == NULL)
1370 goto Done;
1371 format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1372 if (format != NULL) {
1373 result = PyObject_CallMethod(time, "strftime", "OO",
1374 format, timetuple);
1375 Py_DECREF(format);
1376 }
1377 Py_DECREF(time);
1378 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001379 Done:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001380 Py_XDECREF(freplacement);
1381 Py_XDECREF(zreplacement);
1382 Py_XDECREF(Zreplacement);
1383 Py_XDECREF(newfmt);
1384 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001385}
1386
Tim Peters2a799bf2002-12-16 20:18:38 +00001387/* ---------------------------------------------------------------------------
1388 * Wrap functions from the time module. These aren't directly available
1389 * from C. Perhaps they should be.
1390 */
1391
1392/* Call time.time() and return its result (a Python float). */
1393static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001394time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001395{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001396 PyObject *result = NULL;
1397 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001398
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001399 if (time != NULL) {
1400 result = PyObject_CallMethod(time, "time", "()");
1401 Py_DECREF(time);
1402 }
1403 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001404}
1405
1406/* Build a time.struct_time. The weekday and day number are automatically
1407 * computed from the y,m,d args.
1408 */
1409static PyObject *
1410build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1411{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001412 PyObject *time;
1413 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001414
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001415 time = PyImport_ImportModuleNoBlock("time");
1416 if (time != NULL) {
1417 result = PyObject_CallMethod(time, "struct_time",
1418 "((iiiiiiiii))",
1419 y, m, d,
1420 hh, mm, ss,
1421 weekday(y, m, d),
1422 days_before_month(y, m) + d,
1423 dstflag);
1424 Py_DECREF(time);
1425 }
1426 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001427}
1428
1429/* ---------------------------------------------------------------------------
1430 * Miscellaneous helpers.
1431 */
1432
Mark Dickinsone94c6792009-02-02 20:36:42 +00001433/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
Tim Peters2a799bf2002-12-16 20:18:38 +00001434 * The comparisons here all most naturally compute a cmp()-like result.
1435 * This little helper turns that into a bool result for rich comparisons.
1436 */
1437static PyObject *
1438diff_to_bool(int diff, int op)
1439{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001440 PyObject *result;
1441 int istrue;
Tim Peters2a799bf2002-12-16 20:18:38 +00001442
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001443 switch (op) {
1444 case Py_EQ: istrue = diff == 0; break;
1445 case Py_NE: istrue = diff != 0; break;
1446 case Py_LE: istrue = diff <= 0; break;
1447 case Py_GE: istrue = diff >= 0; break;
1448 case Py_LT: istrue = diff < 0; break;
1449 case Py_GT: istrue = diff > 0; break;
1450 default:
1451 assert(! "op unknown");
1452 istrue = 0; /* To shut up compiler */
1453 }
1454 result = istrue ? Py_True : Py_False;
1455 Py_INCREF(result);
1456 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001457}
1458
Tim Peters07534a62003-02-07 22:50:28 +00001459/* Raises a "can't compare" TypeError and returns NULL. */
1460static PyObject *
1461cmperror(PyObject *a, PyObject *b)
1462{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001463 PyErr_Format(PyExc_TypeError,
1464 "can't compare %s to %s",
1465 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1466 return NULL;
Tim Peters07534a62003-02-07 22:50:28 +00001467}
1468
Tim Peters2a799bf2002-12-16 20:18:38 +00001469/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001470 * Cached Python objects; these are set by the module init function.
1471 */
1472
1473/* Conversion factors. */
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001474static PyObject *us_per_us = NULL; /* 1 */
1475static PyObject *us_per_ms = NULL; /* 1000 */
1476static PyObject *us_per_second = NULL; /* 1000000 */
1477static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1478static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1479static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1480static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
Tim Peters2a799bf2002-12-16 20:18:38 +00001481static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1482
Tim Peters2a799bf2002-12-16 20:18:38 +00001483/* ---------------------------------------------------------------------------
1484 * Class implementations.
1485 */
1486
1487/*
1488 * PyDateTime_Delta implementation.
1489 */
1490
1491/* Convert a timedelta to a number of us,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001492 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
Tim Peters2a799bf2002-12-16 20:18:38 +00001493 * as a Python int or long.
1494 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1495 * due to ubiquitous overflow possibilities.
1496 */
1497static PyObject *
1498delta_to_microseconds(PyDateTime_Delta *self)
1499{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001500 PyObject *x1 = NULL;
1501 PyObject *x2 = NULL;
1502 PyObject *x3 = NULL;
1503 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001504
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001505 x1 = PyLong_FromLong(GET_TD_DAYS(self));
1506 if (x1 == NULL)
1507 goto Done;
1508 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1509 if (x2 == NULL)
1510 goto Done;
1511 Py_DECREF(x1);
1512 x1 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001513
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001514 /* x2 has days in seconds */
1515 x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1516 if (x1 == NULL)
1517 goto Done;
1518 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1519 if (x3 == NULL)
1520 goto Done;
1521 Py_DECREF(x1);
1522 Py_DECREF(x2);
1523 x1 = x2 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001524
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001525 /* x3 has days+seconds in seconds */
1526 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1527 if (x1 == NULL)
1528 goto Done;
1529 Py_DECREF(x3);
1530 x3 = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001531
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001532 /* x1 has days+seconds in us */
1533 x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1534 if (x2 == NULL)
1535 goto Done;
1536 result = PyNumber_Add(x1, x2);
Tim Peters2a799bf2002-12-16 20:18:38 +00001537
1538Done:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001539 Py_XDECREF(x1);
1540 Py_XDECREF(x2);
1541 Py_XDECREF(x3);
1542 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001543}
1544
1545/* Convert a number of us (as a Python int or long) to a timedelta.
1546 */
1547static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001548microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001549{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001550 int us;
1551 int s;
1552 int d;
1553 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001554
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001555 PyObject *tuple = NULL;
1556 PyObject *num = NULL;
1557 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001558
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001559 tuple = PyNumber_Divmod(pyus, us_per_second);
1560 if (tuple == NULL)
1561 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001562
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001563 num = PyTuple_GetItem(tuple, 1); /* us */
1564 if (num == NULL)
1565 goto Done;
1566 temp = PyLong_AsLong(num);
1567 num = NULL;
1568 if (temp == -1 && PyErr_Occurred())
1569 goto Done;
1570 assert(0 <= temp && temp < 1000000);
1571 us = (int)temp;
1572 if (us < 0) {
1573 /* The divisor was positive, so this must be an error. */
1574 assert(PyErr_Occurred());
1575 goto Done;
1576 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001577
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001578 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1579 if (num == NULL)
1580 goto Done;
1581 Py_INCREF(num);
1582 Py_DECREF(tuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001583
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001584 tuple = PyNumber_Divmod(num, seconds_per_day);
1585 if (tuple == NULL)
1586 goto Done;
1587 Py_DECREF(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001588
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001589 num = PyTuple_GetItem(tuple, 1); /* seconds */
1590 if (num == NULL)
1591 goto Done;
1592 temp = PyLong_AsLong(num);
1593 num = NULL;
1594 if (temp == -1 && PyErr_Occurred())
1595 goto Done;
1596 assert(0 <= temp && temp < 24*3600);
1597 s = (int)temp;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001598
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001599 if (s < 0) {
1600 /* The divisor was positive, so this must be an error. */
1601 assert(PyErr_Occurred());
1602 goto Done;
1603 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001604
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001605 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1606 if (num == NULL)
1607 goto Done;
1608 Py_INCREF(num);
1609 temp = PyLong_AsLong(num);
1610 if (temp == -1 && PyErr_Occurred())
1611 goto Done;
1612 d = (int)temp;
1613 if ((long)d != temp) {
1614 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1615 "large to fit in a C int");
1616 goto Done;
1617 }
1618 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001619
1620Done:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001621 Py_XDECREF(tuple);
1622 Py_XDECREF(num);
1623 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001624}
1625
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001626#define microseconds_to_delta(pymicros) \
1627 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
Tim Petersb0c854d2003-05-17 15:57:00 +00001628
Tim Peters2a799bf2002-12-16 20:18:38 +00001629static PyObject *
1630multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1631{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001632 PyObject *pyus_in;
1633 PyObject *pyus_out;
1634 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001635
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001636 pyus_in = delta_to_microseconds(delta);
1637 if (pyus_in == NULL)
1638 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001639
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001640 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1641 Py_DECREF(pyus_in);
1642 if (pyus_out == NULL)
1643 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001644
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001645 result = microseconds_to_delta(pyus_out);
1646 Py_DECREF(pyus_out);
1647 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001648}
1649
1650static PyObject *
1651divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1652{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001653 PyObject *pyus_in;
1654 PyObject *pyus_out;
1655 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001656
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001657 pyus_in = delta_to_microseconds(delta);
1658 if (pyus_in == NULL)
1659 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001660
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001661 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1662 Py_DECREF(pyus_in);
1663 if (pyus_out == NULL)
1664 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001665
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001666 result = microseconds_to_delta(pyus_out);
1667 Py_DECREF(pyus_out);
1668 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001669}
1670
1671static PyObject *
1672delta_add(PyObject *left, PyObject *right)
1673{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001674 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001675
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001676 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1677 /* delta + delta */
1678 /* The C-level additions can't overflow because of the
1679 * invariant bounds.
1680 */
1681 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1682 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1683 int microseconds = GET_TD_MICROSECONDS(left) +
1684 GET_TD_MICROSECONDS(right);
1685 result = new_delta(days, seconds, microseconds, 1);
1686 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001687
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001688 if (result == Py_NotImplemented)
1689 Py_INCREF(result);
1690 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001691}
1692
1693static PyObject *
1694delta_negative(PyDateTime_Delta *self)
1695{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001696 return new_delta(-GET_TD_DAYS(self),
1697 -GET_TD_SECONDS(self),
1698 -GET_TD_MICROSECONDS(self),
1699 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001700}
1701
1702static PyObject *
1703delta_positive(PyDateTime_Delta *self)
1704{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001705 /* Could optimize this (by returning self) if this isn't a
1706 * subclass -- but who uses unary + ? Approximately nobody.
1707 */
1708 return new_delta(GET_TD_DAYS(self),
1709 GET_TD_SECONDS(self),
1710 GET_TD_MICROSECONDS(self),
1711 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001712}
1713
1714static PyObject *
1715delta_abs(PyDateTime_Delta *self)
1716{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001717 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001718
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001719 assert(GET_TD_MICROSECONDS(self) >= 0);
1720 assert(GET_TD_SECONDS(self) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00001721
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001722 if (GET_TD_DAYS(self) < 0)
1723 result = delta_negative(self);
1724 else
1725 result = delta_positive(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00001726
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001727 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001728}
1729
1730static PyObject *
1731delta_subtract(PyObject *left, PyObject *right)
1732{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001733 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001734
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001735 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1736 /* delta - delta */
1737 PyObject *minus_right = PyNumber_Negative(right);
1738 if (minus_right) {
1739 result = delta_add(left, minus_right);
1740 Py_DECREF(minus_right);
1741 }
1742 else
1743 result = NULL;
1744 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001745
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001746 if (result == Py_NotImplemented)
1747 Py_INCREF(result);
1748 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001749}
1750
Tim Peters2a799bf2002-12-16 20:18:38 +00001751static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00001752delta_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00001753{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001754 if (PyDelta_Check(other)) {
1755 int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1756 if (diff == 0) {
1757 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1758 if (diff == 0)
1759 diff = GET_TD_MICROSECONDS(self) -
1760 GET_TD_MICROSECONDS(other);
1761 }
1762 return diff_to_bool(diff, op);
1763 }
1764 else {
1765 Py_INCREF(Py_NotImplemented);
1766 return Py_NotImplemented;
1767 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001768}
1769
1770static PyObject *delta_getstate(PyDateTime_Delta *self);
1771
1772static long
1773delta_hash(PyDateTime_Delta *self)
1774{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001775 if (self->hashcode == -1) {
1776 PyObject *temp = delta_getstate(self);
1777 if (temp != NULL) {
1778 self->hashcode = PyObject_Hash(temp);
1779 Py_DECREF(temp);
1780 }
1781 }
1782 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00001783}
1784
1785static PyObject *
1786delta_multiply(PyObject *left, PyObject *right)
1787{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001788 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001789
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001790 if (PyDelta_Check(left)) {
1791 /* delta * ??? */
1792 if (PyLong_Check(right))
1793 result = multiply_int_timedelta(right,
1794 (PyDateTime_Delta *) left);
1795 }
1796 else if (PyLong_Check(left))
1797 result = multiply_int_timedelta(left,
1798 (PyDateTime_Delta *) right);
Tim Peters2a799bf2002-12-16 20:18:38 +00001799
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001800 if (result == Py_NotImplemented)
1801 Py_INCREF(result);
1802 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001803}
1804
1805static PyObject *
1806delta_divide(PyObject *left, PyObject *right)
1807{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001808 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00001809
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001810 if (PyDelta_Check(left)) {
1811 /* delta * ??? */
1812 if (PyLong_Check(right))
1813 result = divide_timedelta_int(
1814 (PyDateTime_Delta *)left,
1815 right);
1816 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001817
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001818 if (result == Py_NotImplemented)
1819 Py_INCREF(result);
1820 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00001821}
1822
1823/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1824 * timedelta constructor. sofar is the # of microseconds accounted for
1825 * so far, and there are factor microseconds per current unit, the number
1826 * of which is given by num. num * factor is added to sofar in a
1827 * numerically careful way, and that's the result. Any fractional
1828 * microseconds left over (this can happen if num is a float type) are
1829 * added into *leftover.
1830 * Note that there are many ways this can give an error (NULL) return.
1831 */
1832static PyObject *
1833accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1834 double *leftover)
1835{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001836 PyObject *prod;
1837 PyObject *sum;
Tim Peters2a799bf2002-12-16 20:18:38 +00001838
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001839 assert(num != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001840
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001841 if (PyLong_Check(num)) {
1842 prod = PyNumber_Multiply(num, factor);
1843 if (prod == NULL)
1844 return NULL;
1845 sum = PyNumber_Add(sofar, prod);
1846 Py_DECREF(prod);
1847 return sum;
1848 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001849
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001850 if (PyFloat_Check(num)) {
1851 double dnum;
1852 double fracpart;
1853 double intpart;
1854 PyObject *x;
1855 PyObject *y;
Tim Peters2a799bf2002-12-16 20:18:38 +00001856
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001857 /* The Plan: decompose num into an integer part and a
1858 * fractional part, num = intpart + fracpart.
1859 * Then num * factor ==
1860 * intpart * factor + fracpart * factor
1861 * and the LHS can be computed exactly in long arithmetic.
1862 * The RHS is again broken into an int part and frac part.
1863 * and the frac part is added into *leftover.
1864 */
1865 dnum = PyFloat_AsDouble(num);
1866 if (dnum == -1.0 && PyErr_Occurred())
1867 return NULL;
1868 fracpart = modf(dnum, &intpart);
1869 x = PyLong_FromDouble(intpart);
1870 if (x == NULL)
1871 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001872
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001873 prod = PyNumber_Multiply(x, factor);
1874 Py_DECREF(x);
1875 if (prod == NULL)
1876 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001877
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001878 sum = PyNumber_Add(sofar, prod);
1879 Py_DECREF(prod);
1880 if (sum == NULL)
1881 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001882
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001883 if (fracpart == 0.0)
1884 return sum;
1885 /* So far we've lost no information. Dealing with the
1886 * fractional part requires float arithmetic, and may
1887 * lose a little info.
1888 */
1889 assert(PyLong_Check(factor));
1890 dnum = PyLong_AsDouble(factor);
Tim Peters2a799bf2002-12-16 20:18:38 +00001891
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001892 dnum *= fracpart;
1893 fracpart = modf(dnum, &intpart);
1894 x = PyLong_FromDouble(intpart);
1895 if (x == NULL) {
1896 Py_DECREF(sum);
1897 return NULL;
1898 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001899
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001900 y = PyNumber_Add(sum, x);
1901 Py_DECREF(sum);
1902 Py_DECREF(x);
1903 *leftover += fracpart;
1904 return y;
1905 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001906
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001907 PyErr_Format(PyExc_TypeError,
1908 "unsupported type for timedelta %s component: %s",
1909 tag, Py_TYPE(num)->tp_name);
1910 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001911}
1912
1913static PyObject *
1914delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1915{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001916 PyObject *self = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001917
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001918 /* Argument objects. */
1919 PyObject *day = NULL;
1920 PyObject *second = NULL;
1921 PyObject *us = NULL;
1922 PyObject *ms = NULL;
1923 PyObject *minute = NULL;
1924 PyObject *hour = NULL;
1925 PyObject *week = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001926
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001927 PyObject *x = NULL; /* running sum of microseconds */
1928 PyObject *y = NULL; /* temp sum of microseconds */
1929 double leftover_us = 0.0;
Tim Peters2a799bf2002-12-16 20:18:38 +00001930
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001931 static char *keywords[] = {
1932 "days", "seconds", "microseconds", "milliseconds",
1933 "minutes", "hours", "weeks", NULL
1934 };
Tim Peters2a799bf2002-12-16 20:18:38 +00001935
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001936 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1937 keywords,
1938 &day, &second, &us,
1939 &ms, &minute, &hour, &week) == 0)
1940 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001941
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001942 x = PyLong_FromLong(0);
1943 if (x == NULL)
1944 goto Done;
Tim Peters2a799bf2002-12-16 20:18:38 +00001945
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001946#define CLEANUP \
1947 Py_DECREF(x); \
1948 x = y; \
1949 if (x == NULL) \
1950 goto Done
Tim Peters2a799bf2002-12-16 20:18:38 +00001951
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001952 if (us) {
1953 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1954 CLEANUP;
1955 }
1956 if (ms) {
1957 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1958 CLEANUP;
1959 }
1960 if (second) {
1961 y = accum("seconds", x, second, us_per_second, &leftover_us);
1962 CLEANUP;
1963 }
1964 if (minute) {
1965 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1966 CLEANUP;
1967 }
1968 if (hour) {
1969 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1970 CLEANUP;
1971 }
1972 if (day) {
1973 y = accum("days", x, day, us_per_day, &leftover_us);
1974 CLEANUP;
1975 }
1976 if (week) {
1977 y = accum("weeks", x, week, us_per_week, &leftover_us);
1978 CLEANUP;
1979 }
1980 if (leftover_us) {
1981 /* Round to nearest whole # of us, and add into x. */
1982 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1983 if (temp == NULL) {
1984 Py_DECREF(x);
1985 goto Done;
1986 }
1987 y = PyNumber_Add(x, temp);
1988 Py_DECREF(temp);
1989 CLEANUP;
1990 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001991
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001992 self = microseconds_to_delta_ex(x, type);
1993 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00001994Done:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00001995 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00001996
1997#undef CLEANUP
1998}
1999
2000static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00002001delta_bool(PyDateTime_Delta *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002002{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002003 return (GET_TD_DAYS(self) != 0
2004 || GET_TD_SECONDS(self) != 0
2005 || GET_TD_MICROSECONDS(self) != 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002006}
2007
2008static PyObject *
2009delta_repr(PyDateTime_Delta *self)
2010{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002011 if (GET_TD_MICROSECONDS(self) != 0)
2012 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2013 Py_TYPE(self)->tp_name,
2014 GET_TD_DAYS(self),
2015 GET_TD_SECONDS(self),
2016 GET_TD_MICROSECONDS(self));
2017 if (GET_TD_SECONDS(self) != 0)
2018 return PyUnicode_FromFormat("%s(%d, %d)",
2019 Py_TYPE(self)->tp_name,
2020 GET_TD_DAYS(self),
2021 GET_TD_SECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002022
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002023 return PyUnicode_FromFormat("%s(%d)",
2024 Py_TYPE(self)->tp_name,
2025 GET_TD_DAYS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002026}
2027
2028static PyObject *
2029delta_str(PyDateTime_Delta *self)
2030{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002031 int us = GET_TD_MICROSECONDS(self);
2032 int seconds = GET_TD_SECONDS(self);
2033 int minutes = divmod(seconds, 60, &seconds);
2034 int hours = divmod(minutes, 60, &minutes);
2035 int days = GET_TD_DAYS(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002036
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002037 if (days) {
2038 if (us)
2039 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2040 days, (days == 1 || days == -1) ? "" : "s",
2041 hours, minutes, seconds, us);
2042 else
2043 return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2044 days, (days == 1 || days == -1) ? "" : "s",
2045 hours, minutes, seconds);
2046 } else {
2047 if (us)
2048 return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2049 hours, minutes, seconds, us);
2050 else
2051 return PyUnicode_FromFormat("%d:%02d:%02d",
2052 hours, minutes, seconds);
2053 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002054
Tim Peters2a799bf2002-12-16 20:18:38 +00002055}
2056
Tim Peters371935f2003-02-01 01:52:50 +00002057/* Pickle support, a simple use of __reduce__. */
2058
Tim Petersb57f8f02003-02-01 02:54:15 +00002059/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002060static PyObject *
2061delta_getstate(PyDateTime_Delta *self)
2062{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002063 return Py_BuildValue("iii", GET_TD_DAYS(self),
2064 GET_TD_SECONDS(self),
2065 GET_TD_MICROSECONDS(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002066}
2067
Tim Peters2a799bf2002-12-16 20:18:38 +00002068static PyObject *
2069delta_reduce(PyDateTime_Delta* self)
2070{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002071 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002072}
2073
2074#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2075
2076static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002077
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002078 {"days", T_INT, OFFSET(days), READONLY,
2079 PyDoc_STR("Number of days.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002080
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002081 {"seconds", T_INT, OFFSET(seconds), READONLY,
2082 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002083
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002084 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2085 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2086 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002087};
2088
2089static PyMethodDef delta_methods[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002090 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2091 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002092
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002093 {NULL, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00002094};
2095
2096static char delta_doc[] =
2097PyDoc_STR("Difference between two datetime values.");
2098
2099static PyNumberMethods delta_as_number = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002100 delta_add, /* nb_add */
2101 delta_subtract, /* nb_subtract */
2102 delta_multiply, /* nb_multiply */
2103 0, /* nb_remainder */
2104 0, /* nb_divmod */
2105 0, /* nb_power */
2106 (unaryfunc)delta_negative, /* nb_negative */
2107 (unaryfunc)delta_positive, /* nb_positive */
2108 (unaryfunc)delta_abs, /* nb_absolute */
2109 (inquiry)delta_bool, /* nb_bool */
2110 0, /*nb_invert*/
2111 0, /*nb_lshift*/
2112 0, /*nb_rshift*/
2113 0, /*nb_and*/
2114 0, /*nb_xor*/
2115 0, /*nb_or*/
2116 0, /*nb_int*/
2117 0, /*nb_reserved*/
2118 0, /*nb_float*/
2119 0, /*nb_inplace_add*/
2120 0, /*nb_inplace_subtract*/
2121 0, /*nb_inplace_multiply*/
2122 0, /*nb_inplace_remainder*/
2123 0, /*nb_inplace_power*/
2124 0, /*nb_inplace_lshift*/
2125 0, /*nb_inplace_rshift*/
2126 0, /*nb_inplace_and*/
2127 0, /*nb_inplace_xor*/
2128 0, /*nb_inplace_or*/
2129 delta_divide, /* nb_floor_divide */
2130 0, /* nb_true_divide */
2131 0, /* nb_inplace_floor_divide */
2132 0, /* nb_inplace_true_divide */
Tim Peters2a799bf2002-12-16 20:18:38 +00002133};
2134
2135static PyTypeObject PyDateTime_DeltaType = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002136 PyVarObject_HEAD_INIT(NULL, 0)
2137 "datetime.timedelta", /* tp_name */
2138 sizeof(PyDateTime_Delta), /* tp_basicsize */
2139 0, /* tp_itemsize */
2140 0, /* tp_dealloc */
2141 0, /* tp_print */
2142 0, /* tp_getattr */
2143 0, /* tp_setattr */
2144 0, /* tp_reserved */
2145 (reprfunc)delta_repr, /* tp_repr */
2146 &delta_as_number, /* tp_as_number */
2147 0, /* tp_as_sequence */
2148 0, /* tp_as_mapping */
2149 (hashfunc)delta_hash, /* tp_hash */
2150 0, /* tp_call */
2151 (reprfunc)delta_str, /* tp_str */
2152 PyObject_GenericGetAttr, /* tp_getattro */
2153 0, /* tp_setattro */
2154 0, /* tp_as_buffer */
2155 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2156 delta_doc, /* tp_doc */
2157 0, /* tp_traverse */
2158 0, /* tp_clear */
2159 delta_richcompare, /* tp_richcompare */
2160 0, /* tp_weaklistoffset */
2161 0, /* tp_iter */
2162 0, /* tp_iternext */
2163 delta_methods, /* tp_methods */
2164 delta_members, /* tp_members */
2165 0, /* tp_getset */
2166 0, /* tp_base */
2167 0, /* tp_dict */
2168 0, /* tp_descr_get */
2169 0, /* tp_descr_set */
2170 0, /* tp_dictoffset */
2171 0, /* tp_init */
2172 0, /* tp_alloc */
2173 delta_new, /* tp_new */
2174 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002175};
2176
2177/*
2178 * PyDateTime_Date implementation.
2179 */
2180
2181/* Accessor properties. */
2182
2183static PyObject *
2184date_year(PyDateTime_Date *self, void *unused)
2185{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002186 return PyLong_FromLong(GET_YEAR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002187}
2188
2189static PyObject *
2190date_month(PyDateTime_Date *self, void *unused)
2191{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002192 return PyLong_FromLong(GET_MONTH(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002193}
2194
2195static PyObject *
2196date_day(PyDateTime_Date *self, void *unused)
2197{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002198 return PyLong_FromLong(GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002199}
2200
2201static PyGetSetDef date_getset[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002202 {"year", (getter)date_year},
2203 {"month", (getter)date_month},
2204 {"day", (getter)date_day},
2205 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002206};
2207
2208/* Constructors. */
2209
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002210static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002211
Tim Peters2a799bf2002-12-16 20:18:38 +00002212static PyObject *
2213date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2214{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002215 PyObject *self = NULL;
2216 PyObject *state;
2217 int year;
2218 int month;
2219 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002220
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002221 /* Check for invocation from pickle with __getstate__ state */
2222 if (PyTuple_GET_SIZE(args) == 1 &&
2223 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2224 PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2225 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2226 {
2227 PyDateTime_Date *me;
Tim Peters70533e22003-02-01 04:40:04 +00002228
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002229 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2230 if (me != NULL) {
2231 char *pdata = PyBytes_AS_STRING(state);
2232 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2233 me->hashcode = -1;
2234 }
2235 return (PyObject *)me;
2236 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002237
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002238 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2239 &year, &month, &day)) {
2240 if (check_date_args(year, month, day) < 0)
2241 return NULL;
2242 self = new_date_ex(year, month, day, type);
2243 }
2244 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00002245}
2246
2247/* Return new date from localtime(t). */
2248static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002249date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002250{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002251 struct tm *tm;
2252 time_t t;
2253 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002254
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002255 t = _PyTime_DoubleToTimet(ts);
2256 if (t == (time_t)-1 && PyErr_Occurred())
2257 return NULL;
2258 tm = localtime(&t);
2259 if (tm)
2260 result = PyObject_CallFunction(cls, "iii",
2261 tm->tm_year + 1900,
2262 tm->tm_mon + 1,
2263 tm->tm_mday);
2264 else
2265 PyErr_SetString(PyExc_ValueError,
2266 "timestamp out of range for "
2267 "platform localtime() function");
2268 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002269}
2270
2271/* Return new date from current time.
2272 * We say this is equivalent to fromtimestamp(time.time()), and the
2273 * only way to be sure of that is to *call* time.time(). That's not
2274 * generally the same as calling C's time.
2275 */
2276static PyObject *
2277date_today(PyObject *cls, PyObject *dummy)
2278{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002279 PyObject *time;
2280 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002281
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002282 time = time_time();
2283 if (time == NULL)
2284 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002285
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002286 /* Note well: today() is a class method, so this may not call
2287 * date.fromtimestamp. For example, it may call
2288 * datetime.fromtimestamp. That's why we need all the accuracy
2289 * time.time() delivers; if someone were gonzo about optimization,
2290 * date.today() could get away with plain C time().
2291 */
2292 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2293 Py_DECREF(time);
2294 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002295}
2296
2297/* Return new date from given timestamp (Python timestamp -- a double). */
2298static PyObject *
2299date_fromtimestamp(PyObject *cls, PyObject *args)
2300{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002301 double timestamp;
2302 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002303
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002304 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2305 result = date_local_from_time_t(cls, timestamp);
2306 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002307}
2308
2309/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2310 * the ordinal is out of range.
2311 */
2312static PyObject *
2313date_fromordinal(PyObject *cls, PyObject *args)
2314{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002315 PyObject *result = NULL;
2316 int ordinal;
Tim Peters2a799bf2002-12-16 20:18:38 +00002317
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002318 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2319 int year;
2320 int month;
2321 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002322
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002323 if (ordinal < 1)
2324 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2325 ">= 1");
2326 else {
2327 ord_to_ymd(ordinal, &year, &month, &day);
2328 result = PyObject_CallFunction(cls, "iii",
2329 year, month, day);
2330 }
2331 }
2332 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002333}
2334
2335/*
2336 * Date arithmetic.
2337 */
2338
2339/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2340 * instead.
2341 */
2342static PyObject *
2343add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2344{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002345 PyObject *result = NULL;
2346 int year = GET_YEAR(date);
2347 int month = GET_MONTH(date);
2348 int deltadays = GET_TD_DAYS(delta);
2349 /* C-level overflow is impossible because |deltadays| < 1e9. */
2350 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
Tim Peters2a799bf2002-12-16 20:18:38 +00002351
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002352 if (normalize_date(&year, &month, &day) >= 0)
2353 result = new_date(year, month, day);
2354 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002355}
2356
2357static PyObject *
2358date_add(PyObject *left, PyObject *right)
2359{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002360 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2361 Py_INCREF(Py_NotImplemented);
2362 return Py_NotImplemented;
2363 }
2364 if (PyDate_Check(left)) {
2365 /* date + ??? */
2366 if (PyDelta_Check(right))
2367 /* date + delta */
2368 return add_date_timedelta((PyDateTime_Date *) left,
2369 (PyDateTime_Delta *) right,
2370 0);
2371 }
2372 else {
2373 /* ??? + date
2374 * 'right' must be one of us, or we wouldn't have been called
2375 */
2376 if (PyDelta_Check(left))
2377 /* delta + date */
2378 return add_date_timedelta((PyDateTime_Date *) right,
2379 (PyDateTime_Delta *) left,
2380 0);
2381 }
2382 Py_INCREF(Py_NotImplemented);
2383 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002384}
2385
2386static PyObject *
2387date_subtract(PyObject *left, PyObject *right)
2388{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002389 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2390 Py_INCREF(Py_NotImplemented);
2391 return Py_NotImplemented;
2392 }
2393 if (PyDate_Check(left)) {
2394 if (PyDate_Check(right)) {
2395 /* date - date */
2396 int left_ord = ymd_to_ord(GET_YEAR(left),
2397 GET_MONTH(left),
2398 GET_DAY(left));
2399 int right_ord = ymd_to_ord(GET_YEAR(right),
2400 GET_MONTH(right),
2401 GET_DAY(right));
2402 return new_delta(left_ord - right_ord, 0, 0, 0);
2403 }
2404 if (PyDelta_Check(right)) {
2405 /* date - delta */
2406 return add_date_timedelta((PyDateTime_Date *) left,
2407 (PyDateTime_Delta *) right,
2408 1);
2409 }
2410 }
2411 Py_INCREF(Py_NotImplemented);
2412 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002413}
2414
2415
2416/* Various ways to turn a date into a string. */
2417
2418static PyObject *
2419date_repr(PyDateTime_Date *self)
2420{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002421 return PyUnicode_FromFormat("%s(%d, %d, %d)",
2422 Py_TYPE(self)->tp_name,
2423 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002424}
2425
2426static PyObject *
2427date_isoformat(PyDateTime_Date *self)
2428{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002429 return PyUnicode_FromFormat("%04d-%02d-%02d",
2430 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002431}
2432
Tim Peterse2df5ff2003-05-02 18:39:55 +00002433/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002434static PyObject *
2435date_str(PyDateTime_Date *self)
2436{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002437 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters2a799bf2002-12-16 20:18:38 +00002438}
2439
2440
2441static PyObject *
2442date_ctime(PyDateTime_Date *self)
2443{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002444 return format_ctime(self, 0, 0, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00002445}
2446
2447static PyObject *
2448date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2449{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002450 /* This method can be inherited, and needs to call the
2451 * timetuple() method appropriate to self's class.
2452 */
2453 PyObject *result;
2454 PyObject *tuple;
2455 PyObject *format;
2456 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002457
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002458 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2459 &format))
2460 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002461
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002462 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2463 if (tuple == NULL)
2464 return NULL;
2465 result = wrap_strftime((PyObject *)self, format, tuple,
2466 (PyObject *)self);
2467 Py_DECREF(tuple);
2468 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002469}
2470
Eric Smith1ba31142007-09-11 18:06:02 +00002471static PyObject *
2472date_format(PyDateTime_Date *self, PyObject *args)
2473{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002474 PyObject *format;
Eric Smith1ba31142007-09-11 18:06:02 +00002475
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002476 if (!PyArg_ParseTuple(args, "U:__format__", &format))
2477 return NULL;
Eric Smith1ba31142007-09-11 18:06:02 +00002478
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002479 /* if the format is zero length, return str(self) */
2480 if (PyUnicode_GetSize(format) == 0)
2481 return PyObject_Str((PyObject *)self);
Eric Smith1ba31142007-09-11 18:06:02 +00002482
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002483 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
Eric Smith1ba31142007-09-11 18:06:02 +00002484}
2485
Tim Peters2a799bf2002-12-16 20:18:38 +00002486/* ISO methods. */
2487
2488static PyObject *
2489date_isoweekday(PyDateTime_Date *self)
2490{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002491 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002492
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002493 return PyLong_FromLong(dow + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002494}
2495
2496static PyObject *
2497date_isocalendar(PyDateTime_Date *self)
2498{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002499 int year = GET_YEAR(self);
2500 int week1_monday = iso_week1_monday(year);
2501 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2502 int week;
2503 int day;
Tim Peters2a799bf2002-12-16 20:18:38 +00002504
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002505 week = divmod(today - week1_monday, 7, &day);
2506 if (week < 0) {
2507 --year;
2508 week1_monday = iso_week1_monday(year);
2509 week = divmod(today - week1_monday, 7, &day);
2510 }
2511 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2512 ++year;
2513 week = 0;
2514 }
2515 return Py_BuildValue("iii", year, week + 1, day + 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002516}
2517
2518/* Miscellaneous methods. */
2519
Tim Peters2a799bf2002-12-16 20:18:38 +00002520static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00002521date_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters2a799bf2002-12-16 20:18:38 +00002522{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002523 if (PyDate_Check(other)) {
2524 int diff = memcmp(((PyDateTime_Date *)self)->data,
2525 ((PyDateTime_Date *)other)->data,
2526 _PyDateTime_DATE_DATASIZE);
2527 return diff_to_bool(diff, op);
2528 }
2529 else {
2530 Py_INCREF(Py_NotImplemented);
2531 return Py_NotImplemented;
2532 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002533}
2534
2535static PyObject *
2536date_timetuple(PyDateTime_Date *self)
2537{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002538 return build_struct_time(GET_YEAR(self),
2539 GET_MONTH(self),
2540 GET_DAY(self),
2541 0, 0, 0, -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00002542}
2543
Tim Peters12bf3392002-12-24 05:41:27 +00002544static PyObject *
2545date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2546{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002547 PyObject *clone;
2548 PyObject *tuple;
2549 int year = GET_YEAR(self);
2550 int month = GET_MONTH(self);
2551 int day = GET_DAY(self);
Tim Peters12bf3392002-12-24 05:41:27 +00002552
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002553 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2554 &year, &month, &day))
2555 return NULL;
2556 tuple = Py_BuildValue("iii", year, month, day);
2557 if (tuple == NULL)
2558 return NULL;
2559 clone = date_new(Py_TYPE(self), tuple, NULL);
2560 Py_DECREF(tuple);
2561 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00002562}
2563
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002564/*
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002565 Borrowed from stringobject.c, originally it was string_hash()
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002566*/
2567static long
2568generic_hash(unsigned char *data, int len)
2569{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002570 register unsigned char *p;
2571 register long x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002572
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002573 p = (unsigned char *) data;
2574 x = *p << 7;
2575 while (--len >= 0)
2576 x = (1000003*x) ^ *p++;
2577 x ^= len;
2578 if (x == -1)
2579 x = -2;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002580
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002581 return x;
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002582}
2583
2584
2585static PyObject *date_getstate(PyDateTime_Date *self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002586
2587static long
2588date_hash(PyDateTime_Date *self)
2589{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002590 if (self->hashcode == -1)
2591 self->hashcode = generic_hash(
2592 (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
Guido van Rossum254348e2007-11-21 19:29:53 +00002593
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002594 return self->hashcode;
Tim Peters2a799bf2002-12-16 20:18:38 +00002595}
2596
2597static PyObject *
2598date_toordinal(PyDateTime_Date *self)
2599{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002600 return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2601 GET_DAY(self)));
Tim Peters2a799bf2002-12-16 20:18:38 +00002602}
2603
2604static PyObject *
2605date_weekday(PyDateTime_Date *self)
2606{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002607 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002608
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002609 return PyLong_FromLong(dow);
Tim Peters2a799bf2002-12-16 20:18:38 +00002610}
2611
Tim Peters371935f2003-02-01 01:52:50 +00002612/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002613
Tim Petersb57f8f02003-02-01 02:54:15 +00002614/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002615static PyObject *
Guido van Rossumfd53fd62007-08-24 04:05:13 +00002616date_getstate(PyDateTime_Date *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002617{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002618 PyObject* field;
2619 field = PyBytes_FromStringAndSize((char*)self->data,
2620 _PyDateTime_DATE_DATASIZE);
2621 return Py_BuildValue("(N)", field);
Tim Peters2a799bf2002-12-16 20:18:38 +00002622}
2623
2624static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002625date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002626{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002627 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002628}
2629
2630static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002631
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002632 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002633
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002634 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2635 METH_CLASS,
2636 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2637 "time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002638
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002639 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2640 METH_CLASS,
2641 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2642 "ordinal.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002643
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002644 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2645 PyDoc_STR("Current date or datetime: same as "
2646 "self.__class__.fromtimestamp(time.time()).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002647
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002648 /* Instance methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00002649
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002650 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2651 PyDoc_STR("Return ctime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002652
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002653 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2654 PyDoc_STR("format -> strftime() style string.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002655
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002656 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2657 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00002658
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002659 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2660 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002661
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002662 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2663 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2664 "weekday.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002665
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002666 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2667 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002668
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002669 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2670 PyDoc_STR("Return the day of the week represented by the date.\n"
2671 "Monday == 1 ... Sunday == 7")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002672
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002673 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2674 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2675 "1 is day 1.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002676
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002677 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2678 PyDoc_STR("Return the day of the week represented by the date.\n"
2679 "Monday == 0 ... Sunday == 6")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002680
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002681 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2682 PyDoc_STR("Return date with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00002683
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002684 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2685 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002686
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002687 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002688};
2689
2690static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002691PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002692
2693static PyNumberMethods date_as_number = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002694 date_add, /* nb_add */
2695 date_subtract, /* nb_subtract */
2696 0, /* nb_multiply */
2697 0, /* nb_remainder */
2698 0, /* nb_divmod */
2699 0, /* nb_power */
2700 0, /* nb_negative */
2701 0, /* nb_positive */
2702 0, /* nb_absolute */
2703 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00002704};
2705
2706static PyTypeObject PyDateTime_DateType = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002707 PyVarObject_HEAD_INIT(NULL, 0)
2708 "datetime.date", /* tp_name */
2709 sizeof(PyDateTime_Date), /* tp_basicsize */
2710 0, /* tp_itemsize */
2711 0, /* tp_dealloc */
2712 0, /* tp_print */
2713 0, /* tp_getattr */
2714 0, /* tp_setattr */
2715 0, /* tp_reserved */
2716 (reprfunc)date_repr, /* tp_repr */
2717 &date_as_number, /* tp_as_number */
2718 0, /* tp_as_sequence */
2719 0, /* tp_as_mapping */
2720 (hashfunc)date_hash, /* tp_hash */
2721 0, /* tp_call */
2722 (reprfunc)date_str, /* tp_str */
2723 PyObject_GenericGetAttr, /* tp_getattro */
2724 0, /* tp_setattro */
2725 0, /* tp_as_buffer */
2726 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2727 date_doc, /* tp_doc */
2728 0, /* tp_traverse */
2729 0, /* tp_clear */
2730 date_richcompare, /* tp_richcompare */
2731 0, /* tp_weaklistoffset */
2732 0, /* tp_iter */
2733 0, /* tp_iternext */
2734 date_methods, /* tp_methods */
2735 0, /* tp_members */
2736 date_getset, /* tp_getset */
2737 0, /* tp_base */
2738 0, /* tp_dict */
2739 0, /* tp_descr_get */
2740 0, /* tp_descr_set */
2741 0, /* tp_dictoffset */
2742 0, /* tp_init */
2743 0, /* tp_alloc */
2744 date_new, /* tp_new */
2745 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002746};
2747
2748/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002749 * PyDateTime_TZInfo implementation.
2750 */
2751
2752/* This is a pure abstract base class, so doesn't do anything beyond
2753 * raising NotImplemented exceptions. Real tzinfo classes need
2754 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002755 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002756 * be subclasses of this tzinfo class, which is easy and quick to check).
2757 *
2758 * Note: For reasons having to do with pickling of subclasses, we have
2759 * to allow tzinfo objects to be instantiated. This wasn't an issue
2760 * in the Python implementation (__init__() could raise NotImplementedError
2761 * there without ill effect), but doing so in the C implementation hit a
2762 * brick wall.
2763 */
2764
2765static PyObject *
2766tzinfo_nogo(const char* methodname)
2767{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002768 PyErr_Format(PyExc_NotImplementedError,
2769 "a tzinfo subclass must implement %s()",
2770 methodname);
2771 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002772}
2773
2774/* Methods. A subclass must implement these. */
2775
Tim Peters52dcce22003-01-23 16:36:11 +00002776static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002777tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2778{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002779 return tzinfo_nogo("tzname");
Tim Peters2a799bf2002-12-16 20:18:38 +00002780}
2781
Tim Peters52dcce22003-01-23 16:36:11 +00002782static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002783tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2784{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002785 return tzinfo_nogo("utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00002786}
2787
Tim Peters52dcce22003-01-23 16:36:11 +00002788static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002789tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2790{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002791 return tzinfo_nogo("dst");
Tim Peters2a799bf2002-12-16 20:18:38 +00002792}
2793
Tim Peters52dcce22003-01-23 16:36:11 +00002794static PyObject *
2795tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2796{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002797 int y, m, d, hh, mm, ss, us;
Tim Peters52dcce22003-01-23 16:36:11 +00002798
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002799 PyObject *result;
2800 int off, dst;
2801 int none;
2802 int delta;
Tim Peters52dcce22003-01-23 16:36:11 +00002803
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002804 if (! PyDateTime_Check(dt)) {
2805 PyErr_SetString(PyExc_TypeError,
2806 "fromutc: argument must be a datetime");
2807 return NULL;
2808 }
2809 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2810 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2811 "is not self");
2812 return NULL;
2813 }
Tim Peters52dcce22003-01-23 16:36:11 +00002814
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002815 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2816 if (off == -1 && PyErr_Occurred())
2817 return NULL;
2818 if (none) {
2819 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2820 "utcoffset() result required");
2821 return NULL;
2822 }
Tim Peters52dcce22003-01-23 16:36:11 +00002823
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002824 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2825 if (dst == -1 && PyErr_Occurred())
2826 return NULL;
2827 if (none) {
2828 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2829 "dst() result required");
2830 return NULL;
2831 }
Tim Peters52dcce22003-01-23 16:36:11 +00002832
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002833 y = GET_YEAR(dt);
2834 m = GET_MONTH(dt);
2835 d = GET_DAY(dt);
2836 hh = DATE_GET_HOUR(dt);
2837 mm = DATE_GET_MINUTE(dt);
2838 ss = DATE_GET_SECOND(dt);
2839 us = DATE_GET_MICROSECOND(dt);
Tim Peters52dcce22003-01-23 16:36:11 +00002840
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002841 delta = off - dst;
2842 mm += delta;
2843 if ((mm < 0 || mm >= 60) &&
2844 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2845 return NULL;
2846 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2847 if (result == NULL)
2848 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002849
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002850 dst = call_dst(dt->tzinfo, result, &none);
2851 if (dst == -1 && PyErr_Occurred())
2852 goto Fail;
2853 if (none)
2854 goto Inconsistent;
2855 if (dst == 0)
2856 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002857
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002858 mm += dst;
2859 if ((mm < 0 || mm >= 60) &&
2860 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2861 goto Fail;
2862 Py_DECREF(result);
2863 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2864 return result;
Tim Peters52dcce22003-01-23 16:36:11 +00002865
2866Inconsistent:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002867 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2868 "inconsistent results; cannot convert");
Tim Peters52dcce22003-01-23 16:36:11 +00002869
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002870 /* fall thru to failure */
Tim Peters52dcce22003-01-23 16:36:11 +00002871Fail:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002872 Py_DECREF(result);
2873 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002874}
2875
Tim Peters2a799bf2002-12-16 20:18:38 +00002876/*
2877 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002878 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002879 */
2880
Guido van Rossum177e41a2003-01-30 22:06:23 +00002881static PyObject *
2882tzinfo_reduce(PyObject *self)
2883{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002884 PyObject *args, *state, *tmp;
2885 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002886
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002887 tmp = PyTuple_New(0);
2888 if (tmp == NULL)
2889 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002890
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002891 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2892 if (getinitargs != NULL) {
2893 args = PyObject_CallObject(getinitargs, tmp);
2894 Py_DECREF(getinitargs);
2895 if (args == NULL) {
2896 Py_DECREF(tmp);
2897 return NULL;
2898 }
2899 }
2900 else {
2901 PyErr_Clear();
2902 args = tmp;
2903 Py_INCREF(args);
2904 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002905
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002906 getstate = PyObject_GetAttrString(self, "__getstate__");
2907 if (getstate != NULL) {
2908 state = PyObject_CallObject(getstate, tmp);
2909 Py_DECREF(getstate);
2910 if (state == NULL) {
2911 Py_DECREF(args);
2912 Py_DECREF(tmp);
2913 return NULL;
2914 }
2915 }
2916 else {
2917 PyObject **dictptr;
2918 PyErr_Clear();
2919 state = Py_None;
2920 dictptr = _PyObject_GetDictPtr(self);
2921 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2922 state = *dictptr;
2923 Py_INCREF(state);
2924 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002925
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002926 Py_DECREF(tmp);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002927
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002928 if (state == Py_None) {
2929 Py_DECREF(state);
2930 return Py_BuildValue("(ON)", Py_TYPE(self), args);
2931 }
2932 else
2933 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002934}
Tim Peters2a799bf2002-12-16 20:18:38 +00002935
2936static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002937
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002938 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2939 PyDoc_STR("datetime -> string name of time zone.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002940
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002941 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2942 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2943 "west of UTC).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002944
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002945 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2946 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00002947
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002948 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2949 PyDoc_STR("datetime in UTC -> datetime in local time.")},
Tim Peters52dcce22003-01-23 16:36:11 +00002950
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002951 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2952 PyDoc_STR("-> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002953
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002954 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00002955};
2956
2957static char tzinfo_doc[] =
2958PyDoc_STR("Abstract base class for time zone info objects.");
2959
Neal Norwitz227b5332006-03-22 09:28:35 +00002960static PyTypeObject PyDateTime_TZInfoType = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00002961 PyVarObject_HEAD_INIT(NULL, 0)
2962 "datetime.tzinfo", /* tp_name */
2963 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2964 0, /* tp_itemsize */
2965 0, /* tp_dealloc */
2966 0, /* tp_print */
2967 0, /* tp_getattr */
2968 0, /* tp_setattr */
2969 0, /* tp_reserved */
2970 0, /* tp_repr */
2971 0, /* tp_as_number */
2972 0, /* tp_as_sequence */
2973 0, /* tp_as_mapping */
2974 0, /* tp_hash */
2975 0, /* tp_call */
2976 0, /* tp_str */
2977 PyObject_GenericGetAttr, /* tp_getattro */
2978 0, /* tp_setattro */
2979 0, /* tp_as_buffer */
2980 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2981 tzinfo_doc, /* tp_doc */
2982 0, /* tp_traverse */
2983 0, /* tp_clear */
2984 0, /* tp_richcompare */
2985 0, /* tp_weaklistoffset */
2986 0, /* tp_iter */
2987 0, /* tp_iternext */
2988 tzinfo_methods, /* tp_methods */
2989 0, /* tp_members */
2990 0, /* tp_getset */
2991 0, /* tp_base */
2992 0, /* tp_dict */
2993 0, /* tp_descr_get */
2994 0, /* tp_descr_set */
2995 0, /* tp_dictoffset */
2996 0, /* tp_init */
2997 0, /* tp_alloc */
2998 PyType_GenericNew, /* tp_new */
2999 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003000};
3001
3002/*
Tim Peters37f39822003-01-10 03:49:02 +00003003 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003004 */
3005
Tim Peters37f39822003-01-10 03:49:02 +00003006/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003007 */
3008
3009static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003010time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003011{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003012 return PyLong_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003013}
3014
Tim Peters37f39822003-01-10 03:49:02 +00003015static PyObject *
3016time_minute(PyDateTime_Time *self, void *unused)
3017{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003018 return PyLong_FromLong(TIME_GET_MINUTE(self));
Tim Peters37f39822003-01-10 03:49:02 +00003019}
3020
3021/* The name time_second conflicted with some platform header file. */
3022static PyObject *
3023py_time_second(PyDateTime_Time *self, void *unused)
3024{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003025 return PyLong_FromLong(TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003026}
3027
3028static PyObject *
3029time_microsecond(PyDateTime_Time *self, void *unused)
3030{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003031 return PyLong_FromLong(TIME_GET_MICROSECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003032}
3033
3034static PyObject *
3035time_tzinfo(PyDateTime_Time *self, void *unused)
3036{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003037 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3038 Py_INCREF(result);
3039 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003040}
3041
3042static PyGetSetDef time_getset[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003043 {"hour", (getter)time_hour},
3044 {"minute", (getter)time_minute},
3045 {"second", (getter)py_time_second},
3046 {"microsecond", (getter)time_microsecond},
3047 {"tzinfo", (getter)time_tzinfo},
3048 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003049};
3050
3051/*
3052 * Constructors.
3053 */
3054
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003055static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003056 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003057
Tim Peters2a799bf2002-12-16 20:18:38 +00003058static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003059time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003060{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003061 PyObject *self = NULL;
3062 PyObject *state;
3063 int hour = 0;
3064 int minute = 0;
3065 int second = 0;
3066 int usecond = 0;
3067 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003068
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003069 /* Check for invocation from pickle with __getstate__ state */
3070 if (PyTuple_GET_SIZE(args) >= 1 &&
3071 PyTuple_GET_SIZE(args) <= 2 &&
3072 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3073 PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3074 ((unsigned char) (PyBytes_AS_STRING(state)[0])) < 24)
3075 {
3076 PyDateTime_Time *me;
3077 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003078
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003079 if (PyTuple_GET_SIZE(args) == 2) {
3080 tzinfo = PyTuple_GET_ITEM(args, 1);
3081 if (check_tzinfo_subclass(tzinfo) < 0) {
3082 PyErr_SetString(PyExc_TypeError, "bad "
3083 "tzinfo state arg");
3084 return NULL;
3085 }
3086 }
3087 aware = (char)(tzinfo != Py_None);
3088 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3089 if (me != NULL) {
3090 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003091
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003092 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3093 me->hashcode = -1;
3094 me->hastzinfo = aware;
3095 if (aware) {
3096 Py_INCREF(tzinfo);
3097 me->tzinfo = tzinfo;
3098 }
3099 }
3100 return (PyObject *)me;
3101 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003102
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003103 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3104 &hour, &minute, &second, &usecond,
3105 &tzinfo)) {
3106 if (check_time_args(hour, minute, second, usecond) < 0)
3107 return NULL;
3108 if (check_tzinfo_subclass(tzinfo) < 0)
3109 return NULL;
3110 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3111 type);
3112 }
3113 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003114}
3115
3116/*
3117 * Destructor.
3118 */
3119
3120static void
Tim Peters37f39822003-01-10 03:49:02 +00003121time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003122{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003123 if (HASTZINFO(self)) {
3124 Py_XDECREF(self->tzinfo);
3125 }
3126 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003127}
3128
3129/*
Tim Peters855fe882002-12-22 03:43:39 +00003130 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003131 */
3132
Tim Peters2a799bf2002-12-16 20:18:38 +00003133/* These are all METH_NOARGS, so don't need to check the arglist. */
3134static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003135time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003136 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3137 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003138}
3139
3140static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003141time_dst(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003142 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3143 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003144}
3145
3146static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003147time_tzname(PyDateTime_Time *self, PyObject *unused) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003148 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3149 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003150}
3151
3152/*
Tim Peters37f39822003-01-10 03:49:02 +00003153 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003154 */
3155
3156static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003157time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003158{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003159 const char *type_name = Py_TYPE(self)->tp_name;
3160 int h = TIME_GET_HOUR(self);
3161 int m = TIME_GET_MINUTE(self);
3162 int s = TIME_GET_SECOND(self);
3163 int us = TIME_GET_MICROSECOND(self);
3164 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003165
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003166 if (us)
3167 result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3168 type_name, h, m, s, us);
3169 else if (s)
3170 result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3171 type_name, h, m, s);
3172 else
3173 result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3174 if (result != NULL && HASTZINFO(self))
3175 result = append_keyword_tzinfo(result, self->tzinfo);
3176 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003177}
3178
Tim Peters37f39822003-01-10 03:49:02 +00003179static PyObject *
3180time_str(PyDateTime_Time *self)
3181{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003182 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
Tim Peters37f39822003-01-10 03:49:02 +00003183}
Tim Peters2a799bf2002-12-16 20:18:38 +00003184
3185static PyObject *
Thomas Wouterscf297e42007-02-23 15:07:44 +00003186time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003187{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003188 char buf[100];
3189 PyObject *result;
3190 int us = TIME_GET_MICROSECOND(self);;
Tim Peters2a799bf2002-12-16 20:18:38 +00003191
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003192 if (us)
3193 result = PyUnicode_FromFormat("%02d:%02d:%02d.%06d",
3194 TIME_GET_HOUR(self),
3195 TIME_GET_MINUTE(self),
3196 TIME_GET_SECOND(self),
3197 us);
3198 else
3199 result = PyUnicode_FromFormat("%02d:%02d:%02d",
3200 TIME_GET_HOUR(self),
3201 TIME_GET_MINUTE(self),
3202 TIME_GET_SECOND(self));
Tim Peters37f39822003-01-10 03:49:02 +00003203
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003204 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3205 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003206
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003207 /* We need to append the UTC offset. */
3208 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3209 Py_None) < 0) {
3210 Py_DECREF(result);
3211 return NULL;
3212 }
3213 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3214 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003215}
3216
Tim Peters37f39822003-01-10 03:49:02 +00003217static PyObject *
3218time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3219{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003220 PyObject *result;
3221 PyObject *tuple;
3222 PyObject *format;
3223 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003224
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003225 if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3226 &format))
3227 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003228
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003229 /* Python's strftime does insane things with the year part of the
3230 * timetuple. The year is forced to (the otherwise nonsensical)
3231 * 1900 to worm around that.
3232 */
3233 tuple = Py_BuildValue("iiiiiiiii",
3234 1900, 1, 1, /* year, month, day */
3235 TIME_GET_HOUR(self),
3236 TIME_GET_MINUTE(self),
3237 TIME_GET_SECOND(self),
3238 0, 1, -1); /* weekday, daynum, dst */
3239 if (tuple == NULL)
3240 return NULL;
3241 assert(PyTuple_Size(tuple) == 9);
3242 result = wrap_strftime((PyObject *)self, format, tuple,
3243 Py_None);
3244 Py_DECREF(tuple);
3245 return result;
Tim Peters37f39822003-01-10 03:49:02 +00003246}
Tim Peters2a799bf2002-12-16 20:18:38 +00003247
3248/*
3249 * Miscellaneous methods.
3250 */
3251
Tim Peters37f39822003-01-10 03:49:02 +00003252static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00003253time_richcompare(PyObject *self, PyObject *other, int op)
Tim Peters37f39822003-01-10 03:49:02 +00003254{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003255 int diff;
3256 naivety n1, n2;
3257 int offset1, offset2;
Tim Peters37f39822003-01-10 03:49:02 +00003258
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003259 if (! PyTime_Check(other)) {
3260 Py_INCREF(Py_NotImplemented);
3261 return Py_NotImplemented;
3262 }
3263 if (classify_two_utcoffsets(self, &offset1, &n1, Py_None,
3264 other, &offset2, &n2, Py_None) < 0)
3265 return NULL;
3266 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3267 /* If they're both naive, or both aware and have the same offsets,
3268 * we get off cheap. Note that if they're both naive, offset1 ==
3269 * offset2 == 0 at this point.
3270 */
3271 if (n1 == n2 && offset1 == offset2) {
3272 diff = memcmp(((PyDateTime_Time *)self)->data,
3273 ((PyDateTime_Time *)other)->data,
3274 _PyDateTime_TIME_DATASIZE);
3275 return diff_to_bool(diff, op);
3276 }
Tim Peters37f39822003-01-10 03:49:02 +00003277
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003278 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3279 assert(offset1 != offset2); /* else last "if" handled it */
3280 /* Convert everything except microseconds to seconds. These
3281 * can't overflow (no more than the # of seconds in 2 days).
3282 */
3283 offset1 = TIME_GET_HOUR(self) * 3600 +
3284 (TIME_GET_MINUTE(self) - offset1) * 60 +
3285 TIME_GET_SECOND(self);
3286 offset2 = TIME_GET_HOUR(other) * 3600 +
3287 (TIME_GET_MINUTE(other) - offset2) * 60 +
3288 TIME_GET_SECOND(other);
3289 diff = offset1 - offset2;
3290 if (diff == 0)
3291 diff = TIME_GET_MICROSECOND(self) -
3292 TIME_GET_MICROSECOND(other);
3293 return diff_to_bool(diff, op);
3294 }
Tim Peters37f39822003-01-10 03:49:02 +00003295
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003296 assert(n1 != n2);
3297 PyErr_SetString(PyExc_TypeError,
3298 "can't compare offset-naive and "
3299 "offset-aware times");
3300 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003301}
3302
3303static long
3304time_hash(PyDateTime_Time *self)
3305{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003306 if (self->hashcode == -1) {
3307 naivety n;
3308 int offset;
3309 PyObject *temp;
Tim Peters37f39822003-01-10 03:49:02 +00003310
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003311 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3312 assert(n != OFFSET_UNKNOWN);
3313 if (n == OFFSET_ERROR)
3314 return -1;
Tim Peters37f39822003-01-10 03:49:02 +00003315
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003316 /* Reduce this to a hash of another object. */
3317 if (offset == 0) {
3318 self->hashcode = generic_hash(
3319 (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3320 return self->hashcode;
3321 }
3322 else {
3323 int hour;
3324 int minute;
Tim Peters37f39822003-01-10 03:49:02 +00003325
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003326 assert(n == OFFSET_AWARE);
3327 assert(HASTZINFO(self));
3328 hour = divmod(TIME_GET_HOUR(self) * 60 +
3329 TIME_GET_MINUTE(self) - offset,
3330 60,
3331 &minute);
3332 if (0 <= hour && hour < 24)
3333 temp = new_time(hour, minute,
3334 TIME_GET_SECOND(self),
3335 TIME_GET_MICROSECOND(self),
3336 Py_None);
3337 else
3338 temp = Py_BuildValue("iiii",
3339 hour, minute,
3340 TIME_GET_SECOND(self),
3341 TIME_GET_MICROSECOND(self));
3342 }
3343 if (temp != NULL) {
3344 self->hashcode = PyObject_Hash(temp);
3345 Py_DECREF(temp);
3346 }
3347 }
3348 return self->hashcode;
Tim Peters37f39822003-01-10 03:49:02 +00003349}
Tim Peters2a799bf2002-12-16 20:18:38 +00003350
Tim Peters12bf3392002-12-24 05:41:27 +00003351static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003352time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003353{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003354 PyObject *clone;
3355 PyObject *tuple;
3356 int hh = TIME_GET_HOUR(self);
3357 int mm = TIME_GET_MINUTE(self);
3358 int ss = TIME_GET_SECOND(self);
3359 int us = TIME_GET_MICROSECOND(self);
3360 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003361
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003362 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3363 time_kws,
3364 &hh, &mm, &ss, &us, &tzinfo))
3365 return NULL;
3366 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3367 if (tuple == NULL)
3368 return NULL;
3369 clone = time_new(Py_TYPE(self), tuple, NULL);
3370 Py_DECREF(tuple);
3371 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00003372}
3373
Tim Peters2a799bf2002-12-16 20:18:38 +00003374static int
Jack Diederich4dafcc42006-11-28 19:15:13 +00003375time_bool(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003376{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003377 int offset;
3378 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00003379
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003380 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3381 /* Since utcoffset is in whole minutes, nothing can
3382 * alter the conclusion that this is nonzero.
3383 */
3384 return 1;
3385 }
3386 offset = 0;
3387 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3388 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3389 if (offset == -1 && PyErr_Occurred())
3390 return -1;
3391 }
3392 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00003393}
3394
Tim Peters371935f2003-02-01 01:52:50 +00003395/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003396
Tim Peters33e0f382003-01-10 02:05:14 +00003397/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003398 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3399 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003400 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003401 */
3402static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003403time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003404{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003405 PyObject *basestate;
3406 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003407
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003408 basestate = PyBytes_FromStringAndSize((char *)self->data,
3409 _PyDateTime_TIME_DATASIZE);
3410 if (basestate != NULL) {
3411 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3412 result = PyTuple_Pack(1, basestate);
3413 else
3414 result = PyTuple_Pack(2, basestate, self->tzinfo);
3415 Py_DECREF(basestate);
3416 }
3417 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003418}
3419
3420static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003421time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003422{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003423 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003424}
3425
Tim Peters37f39822003-01-10 03:49:02 +00003426static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003427
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003428 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3429 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3430 "[+HH:MM].")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003431
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003432 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3433 PyDoc_STR("format -> strftime() style string.")},
Tim Peters37f39822003-01-10 03:49:02 +00003434
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003435 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3436 PyDoc_STR("Formats self with strftime.")},
Eric Smith1ba31142007-09-11 18:06:02 +00003437
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003438 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3439 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003440
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003441 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3442 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003443
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003444 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3445 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00003446
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003447 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3448 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003449
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003450 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3451 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003452
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003453 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003454};
3455
Tim Peters37f39822003-01-10 03:49:02 +00003456static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003457PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3458\n\
3459All arguments are optional. tzinfo may be None, or an instance of\n\
3460a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003461
Tim Peters37f39822003-01-10 03:49:02 +00003462static PyNumberMethods time_as_number = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003463 0, /* nb_add */
3464 0, /* nb_subtract */
3465 0, /* nb_multiply */
3466 0, /* nb_remainder */
3467 0, /* nb_divmod */
3468 0, /* nb_power */
3469 0, /* nb_negative */
3470 0, /* nb_positive */
3471 0, /* nb_absolute */
3472 (inquiry)time_bool, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00003473};
3474
Neal Norwitz227b5332006-03-22 09:28:35 +00003475static PyTypeObject PyDateTime_TimeType = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003476 PyVarObject_HEAD_INIT(NULL, 0)
3477 "datetime.time", /* tp_name */
3478 sizeof(PyDateTime_Time), /* tp_basicsize */
3479 0, /* tp_itemsize */
3480 (destructor)time_dealloc, /* tp_dealloc */
3481 0, /* tp_print */
3482 0, /* tp_getattr */
3483 0, /* tp_setattr */
3484 0, /* tp_reserved */
3485 (reprfunc)time_repr, /* tp_repr */
3486 &time_as_number, /* tp_as_number */
3487 0, /* tp_as_sequence */
3488 0, /* tp_as_mapping */
3489 (hashfunc)time_hash, /* tp_hash */
3490 0, /* tp_call */
3491 (reprfunc)time_str, /* tp_str */
3492 PyObject_GenericGetAttr, /* tp_getattro */
3493 0, /* tp_setattro */
3494 0, /* tp_as_buffer */
3495 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3496 time_doc, /* tp_doc */
3497 0, /* tp_traverse */
3498 0, /* tp_clear */
3499 time_richcompare, /* tp_richcompare */
3500 0, /* tp_weaklistoffset */
3501 0, /* tp_iter */
3502 0, /* tp_iternext */
3503 time_methods, /* tp_methods */
3504 0, /* tp_members */
3505 time_getset, /* tp_getset */
3506 0, /* tp_base */
3507 0, /* tp_dict */
3508 0, /* tp_descr_get */
3509 0, /* tp_descr_set */
3510 0, /* tp_dictoffset */
3511 0, /* tp_init */
3512 time_alloc, /* tp_alloc */
3513 time_new, /* tp_new */
3514 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003515};
3516
3517/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003518 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003519 */
3520
Tim Petersa9bc1682003-01-11 03:39:11 +00003521/* Accessor properties. Properties for day, month, and year are inherited
3522 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003523 */
3524
3525static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003526datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003527{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003528 return PyLong_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003529}
3530
Tim Petersa9bc1682003-01-11 03:39:11 +00003531static PyObject *
3532datetime_minute(PyDateTime_DateTime *self, void *unused)
3533{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003534 return PyLong_FromLong(DATE_GET_MINUTE(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003535}
3536
3537static PyObject *
3538datetime_second(PyDateTime_DateTime *self, void *unused)
3539{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003540 return PyLong_FromLong(DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003541}
3542
3543static PyObject *
3544datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3545{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003546 return PyLong_FromLong(DATE_GET_MICROSECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00003547}
3548
3549static PyObject *
3550datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3551{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003552 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3553 Py_INCREF(result);
3554 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003555}
3556
3557static PyGetSetDef datetime_getset[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003558 {"hour", (getter)datetime_hour},
3559 {"minute", (getter)datetime_minute},
3560 {"second", (getter)datetime_second},
3561 {"microsecond", (getter)datetime_microsecond},
3562 {"tzinfo", (getter)datetime_tzinfo},
3563 {NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003564};
3565
3566/*
3567 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003568 */
3569
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003570static char *datetime_kws[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003571 "year", "month", "day", "hour", "minute", "second",
3572 "microsecond", "tzinfo", NULL
Tim Peters12bf3392002-12-24 05:41:27 +00003573};
3574
Tim Peters2a799bf2002-12-16 20:18:38 +00003575static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003576datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003577{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003578 PyObject *self = NULL;
3579 PyObject *state;
3580 int year;
3581 int month;
3582 int day;
3583 int hour = 0;
3584 int minute = 0;
3585 int second = 0;
3586 int usecond = 0;
3587 PyObject *tzinfo = Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00003588
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003589 /* Check for invocation from pickle with __getstate__ state */
3590 if (PyTuple_GET_SIZE(args) >= 1 &&
3591 PyTuple_GET_SIZE(args) <= 2 &&
3592 PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3593 PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3594 MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
3595 {
3596 PyDateTime_DateTime *me;
3597 char aware;
Tim Peters70533e22003-02-01 04:40:04 +00003598
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003599 if (PyTuple_GET_SIZE(args) == 2) {
3600 tzinfo = PyTuple_GET_ITEM(args, 1);
3601 if (check_tzinfo_subclass(tzinfo) < 0) {
3602 PyErr_SetString(PyExc_TypeError, "bad "
3603 "tzinfo state arg");
3604 return NULL;
3605 }
3606 }
3607 aware = (char)(tzinfo != Py_None);
3608 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3609 if (me != NULL) {
3610 char *pdata = PyBytes_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003611
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003612 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3613 me->hashcode = -1;
3614 me->hastzinfo = aware;
3615 if (aware) {
3616 Py_INCREF(tzinfo);
3617 me->tzinfo = tzinfo;
3618 }
3619 }
3620 return (PyObject *)me;
3621 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00003622
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003623 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3624 &year, &month, &day, &hour, &minute,
3625 &second, &usecond, &tzinfo)) {
3626 if (check_date_args(year, month, day) < 0)
3627 return NULL;
3628 if (check_time_args(hour, minute, second, usecond) < 0)
3629 return NULL;
3630 if (check_tzinfo_subclass(tzinfo) < 0)
3631 return NULL;
3632 self = new_datetime_ex(year, month, day,
3633 hour, minute, second, usecond,
3634 tzinfo, type);
3635 }
3636 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003637}
3638
Tim Petersa9bc1682003-01-11 03:39:11 +00003639/* TM_FUNC is the shared type of localtime() and gmtime(). */
3640typedef struct tm *(*TM_FUNC)(const time_t *timer);
3641
3642/* Internal helper.
3643 * Build datetime from a time_t and a distinct count of microseconds.
3644 * Pass localtime or gmtime for f, to control the interpretation of timet.
3645 */
3646static PyObject *
3647datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003648 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00003649{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003650 struct tm *tm;
3651 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003652
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003653 tm = f(&timet);
3654 if (tm) {
3655 /* The platform localtime/gmtime may insert leap seconds,
3656 * indicated by tm->tm_sec > 59. We don't care about them,
3657 * except to the extent that passing them on to the datetime
3658 * constructor would raise ValueError for a reason that
3659 * made no sense to the user.
3660 */
3661 if (tm->tm_sec > 59)
3662 tm->tm_sec = 59;
3663 result = PyObject_CallFunction(cls, "iiiiiiiO",
3664 tm->tm_year + 1900,
3665 tm->tm_mon + 1,
3666 tm->tm_mday,
3667 tm->tm_hour,
3668 tm->tm_min,
3669 tm->tm_sec,
3670 us,
3671 tzinfo);
3672 }
3673 else
3674 PyErr_SetString(PyExc_ValueError,
3675 "timestamp out of range for "
3676 "platform localtime()/gmtime() function");
3677 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003678}
3679
3680/* Internal helper.
3681 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3682 * to control the interpretation of the timestamp. Since a double doesn't
3683 * have enough bits to cover a datetime's full range of precision, it's
3684 * better to call datetime_from_timet_and_us provided you have a way
3685 * to get that much precision (e.g., C time() isn't good enough).
3686 */
3687static PyObject *
3688datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003689 PyObject *tzinfo)
Tim Petersa9bc1682003-01-11 03:39:11 +00003690{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003691 time_t timet;
3692 double fraction;
3693 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00003694
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003695 timet = _PyTime_DoubleToTimet(timestamp);
3696 if (timet == (time_t)-1 && PyErr_Occurred())
3697 return NULL;
3698 fraction = timestamp - (double)timet;
3699 us = (int)round_to_long(fraction * 1e6);
3700 if (us < 0) {
3701 /* Truncation towards zero is not what we wanted
3702 for negative numbers (Python's mod semantics) */
3703 timet -= 1;
3704 us += 1000000;
3705 }
3706 /* If timestamp is less than one microsecond smaller than a
3707 * full second, round up. Otherwise, ValueErrors are raised
3708 * for some floats. */
3709 if (us == 1000000) {
3710 timet += 1;
3711 us = 0;
3712 }
3713 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003714}
3715
3716/* Internal helper.
3717 * Build most accurate possible datetime for current time. Pass localtime or
3718 * gmtime for f as appropriate.
3719 */
3720static PyObject *
3721datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3722{
3723#ifdef HAVE_GETTIMEOFDAY
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003724 struct timeval t;
Tim Petersa9bc1682003-01-11 03:39:11 +00003725
3726#ifdef GETTIMEOFDAY_NO_TZ
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003727 gettimeofday(&t);
Tim Petersa9bc1682003-01-11 03:39:11 +00003728#else
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003729 gettimeofday(&t, (struct timezone *)NULL);
Tim Petersa9bc1682003-01-11 03:39:11 +00003730#endif
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003731 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3732 tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003733
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003734#else /* ! HAVE_GETTIMEOFDAY */
3735 /* No flavor of gettimeofday exists on this platform. Python's
3736 * time.time() does a lot of other platform tricks to get the
3737 * best time it can on the platform, and we're not going to do
3738 * better than that (if we could, the better code would belong
3739 * in time.time()!) We're limited by the precision of a double,
3740 * though.
3741 */
3742 PyObject *time;
3743 double dtime;
Tim Petersa9bc1682003-01-11 03:39:11 +00003744
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003745 time = time_time();
3746 if (time == NULL)
3747 return NULL;
3748 dtime = PyFloat_AsDouble(time);
3749 Py_DECREF(time);
3750 if (dtime == -1.0 && PyErr_Occurred())
3751 return NULL;
3752 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3753#endif /* ! HAVE_GETTIMEOFDAY */
Tim Petersa9bc1682003-01-11 03:39:11 +00003754}
3755
Tim Peters2a799bf2002-12-16 20:18:38 +00003756/* Return best possible local time -- this isn't constrained by the
3757 * precision of a timestamp.
3758 */
3759static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003760datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003761{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003762 PyObject *self;
3763 PyObject *tzinfo = Py_None;
3764 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003765
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003766 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3767 &tzinfo))
3768 return NULL;
3769 if (check_tzinfo_subclass(tzinfo) < 0)
3770 return NULL;
Tim Peters10cadce2003-01-23 19:58:02 +00003771
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003772 self = datetime_best_possible(cls,
3773 tzinfo == Py_None ? localtime : gmtime,
3774 tzinfo);
3775 if (self != NULL && tzinfo != Py_None) {
3776 /* Convert UTC to tzinfo's zone. */
3777 PyObject *temp = self;
3778 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3779 Py_DECREF(temp);
3780 }
3781 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003782}
3783
Tim Petersa9bc1682003-01-11 03:39:11 +00003784/* Return best possible UTC time -- this isn't constrained by the
3785 * precision of a timestamp.
3786 */
3787static PyObject *
3788datetime_utcnow(PyObject *cls, PyObject *dummy)
3789{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003790 return datetime_best_possible(cls, gmtime, Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00003791}
3792
Tim Peters2a799bf2002-12-16 20:18:38 +00003793/* Return new local datetime from timestamp (Python timestamp -- a double). */
3794static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003795datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003796{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003797 PyObject *self;
3798 double timestamp;
3799 PyObject *tzinfo = Py_None;
3800 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003801
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003802 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3803 keywords, &timestamp, &tzinfo))
3804 return NULL;
3805 if (check_tzinfo_subclass(tzinfo) < 0)
3806 return NULL;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003807
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003808 self = datetime_from_timestamp(cls,
3809 tzinfo == Py_None ? localtime : gmtime,
3810 timestamp,
3811 tzinfo);
3812 if (self != NULL && tzinfo != Py_None) {
3813 /* Convert UTC to tzinfo's zone. */
3814 PyObject *temp = self;
3815 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3816 Py_DECREF(temp);
3817 }
3818 return self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003819}
3820
Tim Petersa9bc1682003-01-11 03:39:11 +00003821/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3822static PyObject *
3823datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3824{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003825 double timestamp;
3826 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003827
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003828 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3829 result = datetime_from_timestamp(cls, gmtime, timestamp,
3830 Py_None);
3831 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003832}
3833
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003834/* Return new datetime from time.strptime(). */
3835static PyObject *
3836datetime_strptime(PyObject *cls, PyObject *args)
3837{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003838 static PyObject *module = NULL;
3839 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3840 const Py_UNICODE *string, *format;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003841
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003842 if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
3843 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003844
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003845 if (module == NULL &&
3846 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3847 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003848
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003849 /* _strptime._strptime returns a two-element tuple. The first
3850 element is a time.struct_time object. The second is the
3851 microseconds (which are not defined for time.struct_time). */
3852 obj = PyObject_CallMethod(module, "_strptime", "uu", string, format);
3853 if (obj != NULL) {
3854 int i, good_timetuple = 1;
3855 long int ia[7];
3856 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3857 st = PySequence_GetItem(obj, 0);
3858 frac = PySequence_GetItem(obj, 1);
3859 if (st == NULL || frac == NULL)
3860 good_timetuple = 0;
3861 /* copy y/m/d/h/m/s values out of the
3862 time.struct_time */
3863 if (good_timetuple &&
3864 PySequence_Check(st) &&
3865 PySequence_Size(st) >= 6) {
3866 for (i=0; i < 6; i++) {
3867 PyObject *p = PySequence_GetItem(st, i);
3868 if (p == NULL) {
3869 good_timetuple = 0;
3870 break;
3871 }
3872 if (PyLong_Check(p))
3873 ia[i] = PyLong_AsLong(p);
3874 else
3875 good_timetuple = 0;
3876 Py_DECREF(p);
3877 }
3878/* if (PyLong_CheckExact(p)) {
3879 ia[i] = PyLong_AsLongAndOverflow(p, &overflow);
3880 if (overflow)
3881 good_timetuple = 0;
3882 }
3883 else
3884 good_timetuple = 0;
3885 Py_DECREF(p);
3886*/ }
3887 else
3888 good_timetuple = 0;
3889 /* follow that up with a little dose of microseconds */
3890 if (PyLong_Check(frac))
3891 ia[6] = PyLong_AsLong(frac);
3892 else
3893 good_timetuple = 0;
3894 }
3895 else
3896 good_timetuple = 0;
3897 if (good_timetuple)
3898 result = PyObject_CallFunction(cls, "iiiiiii",
3899 ia[0], ia[1], ia[2],
3900 ia[3], ia[4], ia[5],
3901 ia[6]);
3902 else
3903 PyErr_SetString(PyExc_ValueError,
3904 "unexpected value from _strptime._strptime");
3905 }
3906 Py_XDECREF(obj);
3907 Py_XDECREF(st);
3908 Py_XDECREF(frac);
3909 return result;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003910}
3911
Tim Petersa9bc1682003-01-11 03:39:11 +00003912/* Return new datetime from date/datetime and time arguments. */
3913static PyObject *
3914datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3915{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003916 static char *keywords[] = {"date", "time", NULL};
3917 PyObject *date;
3918 PyObject *time;
3919 PyObject *result = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003920
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003921 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3922 &PyDateTime_DateType, &date,
3923 &PyDateTime_TimeType, &time)) {
3924 PyObject *tzinfo = Py_None;
Tim Petersa9bc1682003-01-11 03:39:11 +00003925
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003926 if (HASTZINFO(time))
3927 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3928 result = PyObject_CallFunction(cls, "iiiiiiiO",
3929 GET_YEAR(date),
3930 GET_MONTH(date),
3931 GET_DAY(date),
3932 TIME_GET_HOUR(time),
3933 TIME_GET_MINUTE(time),
3934 TIME_GET_SECOND(time),
3935 TIME_GET_MICROSECOND(time),
3936 tzinfo);
3937 }
3938 return result;
Tim Petersa9bc1682003-01-11 03:39:11 +00003939}
Tim Peters2a799bf2002-12-16 20:18:38 +00003940
3941/*
3942 * Destructor.
3943 */
3944
3945static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003946datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003947{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003948 if (HASTZINFO(self)) {
3949 Py_XDECREF(self->tzinfo);
3950 }
3951 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003952}
3953
3954/*
3955 * Indirect access to tzinfo methods.
3956 */
3957
Tim Peters2a799bf2002-12-16 20:18:38 +00003958/* These are all METH_NOARGS, so don't need to check the arglist. */
3959static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003960datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003961 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3962 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003963}
3964
3965static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003966datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003967 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3968 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003969}
3970
3971static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003972datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003973 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3974 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003975}
3976
3977/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003978 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003979 */
3980
Tim Petersa9bc1682003-01-11 03:39:11 +00003981/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3982 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003983 */
3984static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003985add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003986 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003987{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00003988 /* Note that the C-level additions can't overflow, because of
3989 * invariant bounds on the member values.
3990 */
3991 int year = GET_YEAR(date);
3992 int month = GET_MONTH(date);
3993 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3994 int hour = DATE_GET_HOUR(date);
3995 int minute = DATE_GET_MINUTE(date);
3996 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3997 int microsecond = DATE_GET_MICROSECOND(date) +
3998 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003999
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004000 assert(factor == 1 || factor == -1);
4001 if (normalize_datetime(&year, &month, &day,
4002 &hour, &minute, &second, &microsecond) < 0)
4003 return NULL;
4004 else
4005 return new_datetime(year, month, day,
4006 hour, minute, second, microsecond,
4007 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004008}
4009
4010static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004011datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004012{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004013 if (PyDateTime_Check(left)) {
4014 /* datetime + ??? */
4015 if (PyDelta_Check(right))
4016 /* datetime + delta */
4017 return add_datetime_timedelta(
4018 (PyDateTime_DateTime *)left,
4019 (PyDateTime_Delta *)right,
4020 1);
4021 }
4022 else if (PyDelta_Check(left)) {
4023 /* delta + datetime */
4024 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4025 (PyDateTime_Delta *) left,
4026 1);
4027 }
4028 Py_INCREF(Py_NotImplemented);
4029 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004030}
4031
4032static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004033datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004034{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004035 PyObject *result = Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004036
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004037 if (PyDateTime_Check(left)) {
4038 /* datetime - ??? */
4039 if (PyDateTime_Check(right)) {
4040 /* datetime - datetime */
4041 naivety n1, n2;
4042 int offset1, offset2;
4043 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004044
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004045 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4046 right, &offset2, &n2,
4047 right) < 0)
4048 return NULL;
4049 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4050 if (n1 != n2) {
4051 PyErr_SetString(PyExc_TypeError,
4052 "can't subtract offset-naive and "
4053 "offset-aware datetimes");
4054 return NULL;
4055 }
4056 delta_d = ymd_to_ord(GET_YEAR(left),
4057 GET_MONTH(left),
4058 GET_DAY(left)) -
4059 ymd_to_ord(GET_YEAR(right),
4060 GET_MONTH(right),
4061 GET_DAY(right));
4062 /* These can't overflow, since the values are
4063 * normalized. At most this gives the number of
4064 * seconds in one day.
4065 */
4066 delta_s = (DATE_GET_HOUR(left) -
4067 DATE_GET_HOUR(right)) * 3600 +
4068 (DATE_GET_MINUTE(left) -
4069 DATE_GET_MINUTE(right)) * 60 +
4070 (DATE_GET_SECOND(left) -
4071 DATE_GET_SECOND(right));
4072 delta_us = DATE_GET_MICROSECOND(left) -
4073 DATE_GET_MICROSECOND(right);
4074 /* (left - offset1) - (right - offset2) =
4075 * (left - right) + (offset2 - offset1)
4076 */
4077 delta_s += (offset2 - offset1) * 60;
4078 result = new_delta(delta_d, delta_s, delta_us, 1);
4079 }
4080 else if (PyDelta_Check(right)) {
4081 /* datetime - delta */
4082 result = add_datetime_timedelta(
4083 (PyDateTime_DateTime *)left,
4084 (PyDateTime_Delta *)right,
4085 -1);
4086 }
4087 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004088
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004089 if (result == Py_NotImplemented)
4090 Py_INCREF(result);
4091 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004092}
4093
4094/* Various ways to turn a datetime into a string. */
4095
4096static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004097datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004098{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004099 const char *type_name = Py_TYPE(self)->tp_name;
4100 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004101
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004102 if (DATE_GET_MICROSECOND(self)) {
4103 baserepr = PyUnicode_FromFormat(
4104 "%s(%d, %d, %d, %d, %d, %d, %d)",
4105 type_name,
4106 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4107 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4108 DATE_GET_SECOND(self),
4109 DATE_GET_MICROSECOND(self));
4110 }
4111 else if (DATE_GET_SECOND(self)) {
4112 baserepr = PyUnicode_FromFormat(
4113 "%s(%d, %d, %d, %d, %d, %d)",
4114 type_name,
4115 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4116 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4117 DATE_GET_SECOND(self));
4118 }
4119 else {
4120 baserepr = PyUnicode_FromFormat(
4121 "%s(%d, %d, %d, %d, %d)",
4122 type_name,
4123 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4124 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4125 }
4126 if (baserepr == NULL || ! HASTZINFO(self))
4127 return baserepr;
4128 return append_keyword_tzinfo(baserepr, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004129}
4130
Tim Petersa9bc1682003-01-11 03:39:11 +00004131static PyObject *
4132datetime_str(PyDateTime_DateTime *self)
4133{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004134 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
Tim Petersa9bc1682003-01-11 03:39:11 +00004135}
Tim Peters2a799bf2002-12-16 20:18:38 +00004136
4137static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004138datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004139{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004140 int sep = 'T';
4141 static char *keywords[] = {"sep", NULL};
4142 char buffer[100];
4143 PyObject *result;
4144 int us = DATE_GET_MICROSECOND(self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004145
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004146 if (!PyArg_ParseTupleAndKeywords(args, kw, "|C:isoformat", keywords, &sep))
4147 return NULL;
4148 if (us)
4149 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d.%06d",
4150 GET_YEAR(self), GET_MONTH(self),
4151 GET_DAY(self), (int)sep,
4152 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4153 DATE_GET_SECOND(self), us);
4154 else
4155 result = PyUnicode_FromFormat("%04d-%02d-%02d%c%02d:%02d:%02d",
4156 GET_YEAR(self), GET_MONTH(self),
4157 GET_DAY(self), (int)sep,
4158 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4159 DATE_GET_SECOND(self));
Walter Dörwaldbafa1372007-05-31 17:50:48 +00004160
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004161 if (!result || !HASTZINFO(self))
4162 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004163
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004164 /* We need to append the UTC offset. */
4165 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4166 (PyObject *)self) < 0) {
4167 Py_DECREF(result);
4168 return NULL;
4169 }
4170 PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4171 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004172}
4173
Tim Petersa9bc1682003-01-11 03:39:11 +00004174static PyObject *
4175datetime_ctime(PyDateTime_DateTime *self)
4176{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004177 return format_ctime((PyDateTime_Date *)self,
4178 DATE_GET_HOUR(self),
4179 DATE_GET_MINUTE(self),
4180 DATE_GET_SECOND(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004181}
4182
Tim Peters2a799bf2002-12-16 20:18:38 +00004183/* Miscellaneous methods. */
4184
Tim Petersa9bc1682003-01-11 03:39:11 +00004185static PyObject *
Guido van Rossum19960592006-08-24 17:29:38 +00004186datetime_richcompare(PyObject *self, PyObject *other, int op)
Tim Petersa9bc1682003-01-11 03:39:11 +00004187{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004188 int diff;
4189 naivety n1, n2;
4190 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004191
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004192 if (! PyDateTime_Check(other)) {
4193 if (PyDate_Check(other)) {
4194 /* Prevent invocation of date_richcompare. We want to
4195 return NotImplemented here to give the other object
4196 a chance. But since DateTime is a subclass of
4197 Date, if the other object is a Date, it would
4198 compute an ordering based on the date part alone,
4199 and we don't want that. So force unequal or
4200 uncomparable here in that case. */
4201 if (op == Py_EQ)
4202 Py_RETURN_FALSE;
4203 if (op == Py_NE)
4204 Py_RETURN_TRUE;
4205 return cmperror(self, other);
4206 }
4207 Py_INCREF(Py_NotImplemented);
4208 return Py_NotImplemented;
4209 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004210
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004211 if (classify_two_utcoffsets(self, &offset1, &n1, self,
4212 other, &offset2, &n2, other) < 0)
4213 return NULL;
4214 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4215 /* If they're both naive, or both aware and have the same offsets,
4216 * we get off cheap. Note that if they're both naive, offset1 ==
4217 * offset2 == 0 at this point.
4218 */
4219 if (n1 == n2 && offset1 == offset2) {
4220 diff = memcmp(((PyDateTime_DateTime *)self)->data,
4221 ((PyDateTime_DateTime *)other)->data,
4222 _PyDateTime_DATETIME_DATASIZE);
4223 return diff_to_bool(diff, op);
4224 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004225
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004226 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4227 PyDateTime_Delta *delta;
Tim Petersa9bc1682003-01-11 03:39:11 +00004228
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004229 assert(offset1 != offset2); /* else last "if" handled it */
4230 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4231 other);
4232 if (delta == NULL)
4233 return NULL;
4234 diff = GET_TD_DAYS(delta);
4235 if (diff == 0)
4236 diff = GET_TD_SECONDS(delta) |
4237 GET_TD_MICROSECONDS(delta);
4238 Py_DECREF(delta);
4239 return diff_to_bool(diff, op);
4240 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004241
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004242 assert(n1 != n2);
4243 PyErr_SetString(PyExc_TypeError,
4244 "can't compare offset-naive and "
4245 "offset-aware datetimes");
4246 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004247}
4248
4249static long
4250datetime_hash(PyDateTime_DateTime *self)
4251{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004252 if (self->hashcode == -1) {
4253 naivety n;
4254 int offset;
4255 PyObject *temp;
Tim Petersa9bc1682003-01-11 03:39:11 +00004256
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004257 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4258 &offset);
4259 assert(n != OFFSET_UNKNOWN);
4260 if (n == OFFSET_ERROR)
4261 return -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004262
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004263 /* Reduce this to a hash of another object. */
4264 if (n == OFFSET_NAIVE) {
4265 self->hashcode = generic_hash(
4266 (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
4267 return self->hashcode;
4268 }
4269 else {
4270 int days;
4271 int seconds;
Tim Petersa9bc1682003-01-11 03:39:11 +00004272
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004273 assert(n == OFFSET_AWARE);
4274 assert(HASTZINFO(self));
4275 days = ymd_to_ord(GET_YEAR(self),
4276 GET_MONTH(self),
4277 GET_DAY(self));
4278 seconds = DATE_GET_HOUR(self) * 3600 +
4279 (DATE_GET_MINUTE(self) - offset) * 60 +
4280 DATE_GET_SECOND(self);
4281 temp = new_delta(days,
4282 seconds,
4283 DATE_GET_MICROSECOND(self),
4284 1);
4285 }
4286 if (temp != NULL) {
4287 self->hashcode = PyObject_Hash(temp);
4288 Py_DECREF(temp);
4289 }
4290 }
4291 return self->hashcode;
Tim Petersa9bc1682003-01-11 03:39:11 +00004292}
Tim Peters2a799bf2002-12-16 20:18:38 +00004293
4294static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004295datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004296{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004297 PyObject *clone;
4298 PyObject *tuple;
4299 int y = GET_YEAR(self);
4300 int m = GET_MONTH(self);
4301 int d = GET_DAY(self);
4302 int hh = DATE_GET_HOUR(self);
4303 int mm = DATE_GET_MINUTE(self);
4304 int ss = DATE_GET_SECOND(self);
4305 int us = DATE_GET_MICROSECOND(self);
4306 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004307
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004308 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4309 datetime_kws,
4310 &y, &m, &d, &hh, &mm, &ss, &us,
4311 &tzinfo))
4312 return NULL;
4313 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4314 if (tuple == NULL)
4315 return NULL;
4316 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4317 Py_DECREF(tuple);
4318 return clone;
Tim Peters12bf3392002-12-24 05:41:27 +00004319}
4320
4321static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004322datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004323{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004324 int y, m, d, hh, mm, ss, us;
4325 PyObject *result;
4326 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004327
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004328 PyObject *tzinfo;
4329 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004330
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004331 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4332 &PyDateTime_TZInfoType, &tzinfo))
4333 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004334
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004335 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4336 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004337
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004338 /* Conversion to self's own time zone is a NOP. */
4339 if (self->tzinfo == tzinfo) {
4340 Py_INCREF(self);
4341 return (PyObject *)self;
4342 }
Tim Peters521fc152002-12-31 17:36:56 +00004343
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004344 /* Convert self to UTC. */
4345 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4346 if (offset == -1 && PyErr_Occurred())
4347 return NULL;
4348 if (none)
4349 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004350
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004351 y = GET_YEAR(self);
4352 m = GET_MONTH(self);
4353 d = GET_DAY(self);
4354 hh = DATE_GET_HOUR(self);
4355 mm = DATE_GET_MINUTE(self);
4356 ss = DATE_GET_SECOND(self);
4357 us = DATE_GET_MICROSECOND(self);
Tim Peters52dcce22003-01-23 16:36:11 +00004358
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004359 mm -= offset;
4360 if ((mm < 0 || mm >= 60) &&
4361 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4362 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00004363
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004364 /* Attach new tzinfo and let fromutc() do the rest. */
4365 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4366 if (result != NULL) {
4367 PyObject *temp = result;
Tim Peters52dcce22003-01-23 16:36:11 +00004368
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004369 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4370 Py_DECREF(temp);
4371 }
4372 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004373
Tim Peters52dcce22003-01-23 16:36:11 +00004374NeedAware:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004375 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4376 "a naive datetime");
4377 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004378}
4379
4380static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004381datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004382{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004383 int dstflag = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004384
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004385 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4386 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004387
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004388 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4389 if (dstflag == -1 && PyErr_Occurred())
4390 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004391
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004392 if (none)
4393 dstflag = -1;
4394 else if (dstflag != 0)
4395 dstflag = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00004396
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004397 }
4398 return build_struct_time(GET_YEAR(self),
4399 GET_MONTH(self),
4400 GET_DAY(self),
4401 DATE_GET_HOUR(self),
4402 DATE_GET_MINUTE(self),
4403 DATE_GET_SECOND(self),
4404 dstflag);
Tim Peters2a799bf2002-12-16 20:18:38 +00004405}
4406
4407static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004408datetime_getdate(PyDateTime_DateTime *self)
4409{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004410 return new_date(GET_YEAR(self),
4411 GET_MONTH(self),
4412 GET_DAY(self));
Tim Petersa9bc1682003-01-11 03:39:11 +00004413}
4414
4415static PyObject *
4416datetime_gettime(PyDateTime_DateTime *self)
4417{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004418 return new_time(DATE_GET_HOUR(self),
4419 DATE_GET_MINUTE(self),
4420 DATE_GET_SECOND(self),
4421 DATE_GET_MICROSECOND(self),
4422 Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004423}
4424
4425static PyObject *
4426datetime_gettimetz(PyDateTime_DateTime *self)
4427{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004428 return new_time(DATE_GET_HOUR(self),
4429 DATE_GET_MINUTE(self),
4430 DATE_GET_SECOND(self),
4431 DATE_GET_MICROSECOND(self),
4432 HASTZINFO(self) ? self->tzinfo : Py_None);
Tim Petersa9bc1682003-01-11 03:39:11 +00004433}
4434
4435static PyObject *
4436datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004437{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004438 int y = GET_YEAR(self);
4439 int m = GET_MONTH(self);
4440 int d = GET_DAY(self);
4441 int hh = DATE_GET_HOUR(self);
4442 int mm = DATE_GET_MINUTE(self);
4443 int ss = DATE_GET_SECOND(self);
4444 int us = 0; /* microseconds are ignored in a timetuple */
4445 int offset = 0;
Tim Peters2a799bf2002-12-16 20:18:38 +00004446
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004447 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4448 int none;
Tim Peters2a799bf2002-12-16 20:18:38 +00004449
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004450 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4451 if (offset == -1 && PyErr_Occurred())
4452 return NULL;
4453 }
4454 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4455 * 0 in a UTC timetuple regardless of what dst() says.
4456 */
4457 if (offset) {
4458 /* Subtract offset minutes & normalize. */
4459 int stat;
Tim Peters2a799bf2002-12-16 20:18:38 +00004460
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004461 mm -= offset;
4462 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4463 if (stat < 0) {
4464 /* At the edges, it's possible we overflowed
4465 * beyond MINYEAR or MAXYEAR.
4466 */
4467 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4468 PyErr_Clear();
4469 else
4470 return NULL;
4471 }
4472 }
4473 return build_struct_time(y, m, d, hh, mm, ss, 0);
Tim Peters2a799bf2002-12-16 20:18:38 +00004474}
4475
Tim Peters371935f2003-02-01 01:52:50 +00004476/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004477
Tim Petersa9bc1682003-01-11 03:39:11 +00004478/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004479 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4480 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004481 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004482 */
4483static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004484datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004485{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004486 PyObject *basestate;
4487 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004488
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004489 basestate = PyBytes_FromStringAndSize((char *)self->data,
4490 _PyDateTime_DATETIME_DATASIZE);
4491 if (basestate != NULL) {
4492 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4493 result = PyTuple_Pack(1, basestate);
4494 else
4495 result = PyTuple_Pack(2, basestate, self->tzinfo);
4496 Py_DECREF(basestate);
4497 }
4498 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004499}
4500
4501static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004502datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004503{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004504 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004505}
4506
Tim Petersa9bc1682003-01-11 03:39:11 +00004507static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004508
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004509 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004510
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004511 {"now", (PyCFunction)datetime_now,
4512 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4513 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004514
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004515 {"utcnow", (PyCFunction)datetime_utcnow,
4516 METH_NOARGS | METH_CLASS,
4517 PyDoc_STR("Return a new datetime representing UTC day and time.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004518
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004519 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4520 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4521 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004522
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004523 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4524 METH_VARARGS | METH_CLASS,
4525 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4526 "(like time.time()).")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004527
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004528 {"strptime", (PyCFunction)datetime_strptime,
4529 METH_VARARGS | METH_CLASS,
4530 PyDoc_STR("string, format -> new datetime parsed from a string "
4531 "(like time.strptime()).")},
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004532
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004533 {"combine", (PyCFunction)datetime_combine,
4534 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4535 PyDoc_STR("date, time -> datetime with same date and time fields")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004536
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004537 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004538
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004539 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4540 PyDoc_STR("Return date object with same year, month and day.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004541
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004542 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4543 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004544
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004545 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4546 PyDoc_STR("Return time object with same time and tzinfo.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004547
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004548 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4549 PyDoc_STR("Return ctime() style string.")},
Tim Petersa9bc1682003-01-11 03:39:11 +00004550
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004551 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4552 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004553
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004554 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4555 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004556
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004557 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4558 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4559 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4560 "sep is used to separate the year from the time, and "
4561 "defaults to 'T'.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004562
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004563 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4564 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004565
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004566 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4567 PyDoc_STR("Return self.tzinfo.tzname(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004568
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004569 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4570 PyDoc_STR("Return self.tzinfo.dst(self).")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004571
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004572 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4573 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004574
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004575 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4576 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
Tim Peters80475bb2002-12-25 07:40:55 +00004577
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004578 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4579 PyDoc_STR("__reduce__() -> (cls, state)")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004580
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004581 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004582};
4583
Tim Petersa9bc1682003-01-11 03:39:11 +00004584static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004585PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4586\n\
4587The year, month and day arguments are required. tzinfo may be None, or an\n\
4588instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004589
Tim Petersa9bc1682003-01-11 03:39:11 +00004590static PyNumberMethods datetime_as_number = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004591 datetime_add, /* nb_add */
4592 datetime_subtract, /* nb_subtract */
4593 0, /* nb_multiply */
4594 0, /* nb_remainder */
4595 0, /* nb_divmod */
4596 0, /* nb_power */
4597 0, /* nb_negative */
4598 0, /* nb_positive */
4599 0, /* nb_absolute */
4600 0, /* nb_bool */
Tim Peters2a799bf2002-12-16 20:18:38 +00004601};
4602
Neal Norwitz227b5332006-03-22 09:28:35 +00004603static PyTypeObject PyDateTime_DateTimeType = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004604 PyVarObject_HEAD_INIT(NULL, 0)
4605 "datetime.datetime", /* tp_name */
4606 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4607 0, /* tp_itemsize */
4608 (destructor)datetime_dealloc, /* tp_dealloc */
4609 0, /* tp_print */
4610 0, /* tp_getattr */
4611 0, /* tp_setattr */
4612 0, /* tp_reserved */
4613 (reprfunc)datetime_repr, /* tp_repr */
4614 &datetime_as_number, /* tp_as_number */
4615 0, /* tp_as_sequence */
4616 0, /* tp_as_mapping */
4617 (hashfunc)datetime_hash, /* tp_hash */
4618 0, /* tp_call */
4619 (reprfunc)datetime_str, /* tp_str */
4620 PyObject_GenericGetAttr, /* tp_getattro */
4621 0, /* tp_setattro */
4622 0, /* tp_as_buffer */
4623 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4624 datetime_doc, /* tp_doc */
4625 0, /* tp_traverse */
4626 0, /* tp_clear */
4627 datetime_richcompare, /* tp_richcompare */
4628 0, /* tp_weaklistoffset */
4629 0, /* tp_iter */
4630 0, /* tp_iternext */
4631 datetime_methods, /* tp_methods */
4632 0, /* tp_members */
4633 datetime_getset, /* tp_getset */
4634 &PyDateTime_DateType, /* tp_base */
4635 0, /* tp_dict */
4636 0, /* tp_descr_get */
4637 0, /* tp_descr_set */
4638 0, /* tp_dictoffset */
4639 0, /* tp_init */
4640 datetime_alloc, /* tp_alloc */
4641 datetime_new, /* tp_new */
4642 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004643};
4644
4645/* ---------------------------------------------------------------------------
4646 * Module methods and initialization.
4647 */
4648
4649static PyMethodDef module_methods[] = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004650 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00004651};
4652
Tim Peters9ddf40b2004-06-20 22:41:32 +00004653/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4654 * datetime.h.
4655 */
4656static PyDateTime_CAPI CAPI = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004657 &PyDateTime_DateType,
4658 &PyDateTime_DateTimeType,
4659 &PyDateTime_TimeType,
4660 &PyDateTime_DeltaType,
4661 &PyDateTime_TZInfoType,
4662 new_date_ex,
4663 new_datetime_ex,
4664 new_time_ex,
4665 new_delta_ex,
4666 datetime_fromtimestamp,
4667 date_fromtimestamp
Tim Peters9ddf40b2004-06-20 22:41:32 +00004668};
4669
4670
Martin v. Löwis1a214512008-06-11 05:26:20 +00004671
4672static struct PyModuleDef datetimemodule = {
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004673 PyModuleDef_HEAD_INIT,
4674 "datetime",
4675 "Fast implementation of the datetime type.",
4676 -1,
4677 module_methods,
4678 NULL,
4679 NULL,
4680 NULL,
4681 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00004682};
4683
Tim Peters2a799bf2002-12-16 20:18:38 +00004684PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00004685PyInit_datetime(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00004686{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004687 PyObject *m; /* a module object */
4688 PyObject *d; /* its dict */
4689 PyObject *x;
Tim Peters2a799bf2002-12-16 20:18:38 +00004690
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004691 m = PyModule_Create(&datetimemodule);
4692 if (m == NULL)
4693 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004694
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004695 if (PyType_Ready(&PyDateTime_DateType) < 0)
4696 return NULL;
4697 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4698 return NULL;
4699 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4700 return NULL;
4701 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4702 return NULL;
4703 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4704 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004705
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004706 /* timedelta values */
4707 d = PyDateTime_DeltaType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004708
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004709 x = new_delta(0, 0, 1, 0);
4710 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4711 return NULL;
4712 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004713
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004714 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4715 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4716 return NULL;
4717 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004718
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004719 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4720 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4721 return NULL;
4722 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004723
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004724 /* date values */
4725 d = PyDateTime_DateType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004726
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004727 x = new_date(1, 1, 1);
4728 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4729 return NULL;
4730 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004731
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004732 x = new_date(MAXYEAR, 12, 31);
4733 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4734 return NULL;
4735 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004736
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004737 x = new_delta(1, 0, 0, 0);
4738 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4739 return NULL;
4740 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004741
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004742 /* time values */
4743 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004744
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004745 x = new_time(0, 0, 0, 0, Py_None);
4746 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4747 return NULL;
4748 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004749
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004750 x = new_time(23, 59, 59, 999999, Py_None);
4751 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4752 return NULL;
4753 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004754
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004755 x = new_delta(0, 0, 1, 0);
4756 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4757 return NULL;
4758 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004759
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004760 /* datetime values */
4761 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004762
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004763 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4764 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4765 return NULL;
4766 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004767
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004768 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4769 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4770 return NULL;
4771 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004772
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004773 x = new_delta(0, 0, 1, 0);
4774 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4775 return NULL;
4776 Py_DECREF(x);
Tim Peters2a799bf2002-12-16 20:18:38 +00004777
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004778 /* module initialization */
4779 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4780 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
Tim Peters2a799bf2002-12-16 20:18:38 +00004781
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004782 Py_INCREF(&PyDateTime_DateType);
4783 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004784
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004785 Py_INCREF(&PyDateTime_DateTimeType);
4786 PyModule_AddObject(m, "datetime",
4787 (PyObject *)&PyDateTime_DateTimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00004788
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004789 Py_INCREF(&PyDateTime_TimeType);
4790 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
Tim Petersa9bc1682003-01-11 03:39:11 +00004791
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004792 Py_INCREF(&PyDateTime_DeltaType);
4793 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004794
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004795 Py_INCREF(&PyDateTime_TZInfoType);
4796 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004797
Benjamin Petersonb173f782009-05-05 22:31:58 +00004798 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
4799 if (x == NULL)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004800 return NULL;
Benjamin Petersonb173f782009-05-05 22:31:58 +00004801 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00004802
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004803 /* A 4-year cycle has an extra leap day over what we'd get from
4804 * pasting together 4 single years.
4805 */
4806 assert(DI4Y == 4 * 365 + 1);
4807 assert(DI4Y == days_before_year(4+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004808
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004809 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4810 * get from pasting together 4 100-year cycles.
4811 */
4812 assert(DI400Y == 4 * DI100Y + 1);
4813 assert(DI400Y == days_before_year(400+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004814
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004815 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4816 * pasting together 25 4-year cycles.
4817 */
4818 assert(DI100Y == 25 * DI4Y - 1);
4819 assert(DI100Y == days_before_year(100+1));
Tim Peters2a799bf2002-12-16 20:18:38 +00004820
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004821 us_per_us = PyLong_FromLong(1);
4822 us_per_ms = PyLong_FromLong(1000);
4823 us_per_second = PyLong_FromLong(1000000);
4824 us_per_minute = PyLong_FromLong(60000000);
4825 seconds_per_day = PyLong_FromLong(24 * 3600);
4826 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4827 us_per_minute == NULL || seconds_per_day == NULL)
4828 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00004829
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004830 /* The rest are too big for 32-bit ints, but even
4831 * us_per_week fits in 40 bits, so doubles should be exact.
4832 */
4833 us_per_hour = PyLong_FromDouble(3600000000.0);
4834 us_per_day = PyLong_FromDouble(86400000000.0);
4835 us_per_week = PyLong_FromDouble(604800000000.0);
4836 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4837 return NULL;
4838 return m;
Tim Peters2a799bf2002-12-16 20:18:38 +00004839}
Tim Petersf3615152003-01-01 21:51:37 +00004840
4841/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004842Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004843 x.n = x stripped of its timezone -- its naive time.
4844 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004845 return None
Tim Petersf3615152003-01-01 21:51:37 +00004846 x.d = x.dst(), and assuming that doesn't raise an exception or
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004847 return None
Tim Petersf3615152003-01-01 21:51:37 +00004848 x.s = x's standard offset, x.o - x.d
4849
4850Now some derived rules, where k is a duration (timedelta).
4851
48521. x.o = x.s + x.d
4853 This follows from the definition of x.s.
4854
Tim Petersc5dc4da2003-01-02 17:55:03 +000048552. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004856 This is actually a requirement, an assumption we need to make about
4857 sane tzinfo classes.
4858
48593. The naive UTC time corresponding to x is x.n - x.o.
4860 This is again a requirement for a sane tzinfo class.
4861
48624. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004863 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004864
Tim Petersc5dc4da2003-01-02 17:55:03 +000048655. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004866 Again follows from how arithmetic is defined.
4867
Tim Peters8bb5ad22003-01-24 02:44:45 +00004868Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004869(meaning that the various tzinfo methods exist, and don't blow up or return
4870None when called).
4871
Tim Petersa9bc1682003-01-11 03:39:11 +00004872The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004873x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004874
4875By #3, we want
4876
Tim Peters8bb5ad22003-01-24 02:44:45 +00004877 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004878
4879The algorithm starts by attaching tz to x.n, and calling that y. So
4880x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4881becomes true; in effect, we want to solve [2] for k:
4882
Tim Peters8bb5ad22003-01-24 02:44:45 +00004883 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004884
4885By #1, this is the same as
4886
Tim Peters8bb5ad22003-01-24 02:44:45 +00004887 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004888
4889By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4890Substituting that into [3],
4891
Tim Peters8bb5ad22003-01-24 02:44:45 +00004892 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4893 k - (y+k).s - (y+k).d = 0; rearranging,
4894 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4895 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004896
Tim Peters8bb5ad22003-01-24 02:44:45 +00004897On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4898approximate k by ignoring the (y+k).d term at first. Note that k can't be
4899very large, since all offset-returning methods return a duration of magnitude
4900less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4901be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004902
4903In any case, the new value is
4904
Tim Peters8bb5ad22003-01-24 02:44:45 +00004905 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004906
Tim Peters8bb5ad22003-01-24 02:44:45 +00004907It's helpful to step back at look at [4] from a higher level: it's simply
4908mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004909
4910At this point, if
4911
Tim Peters8bb5ad22003-01-24 02:44:45 +00004912 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004913
4914we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004915at the start of daylight time. Picture US Eastern for concreteness. The wall
4916time 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 +00004917sense then. The docs ask that an Eastern tzinfo class consider such a time to
4918be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4919on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004920the only spelling that makes sense on the local wall clock.
4921
Tim Petersc5dc4da2003-01-02 17:55:03 +00004922In fact, if [5] holds at this point, we do have the standard-time spelling,
4923but that takes a bit of proof. We first prove a stronger result. What's the
4924difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004925
Tim Peters8bb5ad22003-01-24 02:44:45 +00004926 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004927
Tim Petersc5dc4da2003-01-02 17:55:03 +00004928Now
4929 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004930 (y + y.s).n = by #5
4931 y.n + y.s = since y.n = x.n
4932 x.n + y.s = since z and y are have the same tzinfo member,
4933 y.s = z.s by #2
4934 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004935
Tim Petersc5dc4da2003-01-02 17:55:03 +00004936Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004937
Tim Petersc5dc4da2003-01-02 17:55:03 +00004938 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004939 x.n - ((x.n + z.s) - z.o) = expanding
4940 x.n - x.n - z.s + z.o = cancelling
4941 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004942 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004943
Tim Petersc5dc4da2003-01-02 17:55:03 +00004944So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004945
Tim Petersc5dc4da2003-01-02 17:55:03 +00004946If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004947spelling we wanted in the endcase described above. We're done. Contrarily,
4948if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004949
Tim Petersc5dc4da2003-01-02 17:55:03 +00004950If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4951add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00004952local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004953
Tim Petersc5dc4da2003-01-02 17:55:03 +00004954Let
Tim Petersf3615152003-01-01 21:51:37 +00004955
Tim Peters4fede1a2003-01-04 00:26:59 +00004956 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004957
Tim Peters4fede1a2003-01-04 00:26:59 +00004958and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004959
Tim Peters8bb5ad22003-01-24 02:44:45 +00004960 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004961
Tim Peters8bb5ad22003-01-24 02:44:45 +00004962If so, we're done. If not, the tzinfo class is insane, according to the
4963assumptions we've made. This also requires a bit of proof. As before, let's
4964compute the difference between the LHS and RHS of [8] (and skipping some of
4965the justifications for the kinds of substitutions we've done several times
4966already):
Tim Peters4fede1a2003-01-04 00:26:59 +00004967
Tim Peters8bb5ad22003-01-24 02:44:45 +00004968 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00004969 x.n - (z.n + diff - z'.o) = replacing diff via [6]
4970 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
4971 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
4972 - z.n + z.n - z.o + z'.o = cancel z.n
4973 - z.o + z'.o = #1 twice
4974 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4975 z'.d - z.d
Tim Peters4fede1a2003-01-04 00:26:59 +00004976
4977So 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 +00004978we've found the UTC-equivalent so are done. In fact, we stop with [7] and
4979return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00004980
Tim Peters8bb5ad22003-01-24 02:44:45 +00004981How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
4982a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
4983would have to change the result dst() returns: we start in DST, and moving
4984a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00004985
Tim Peters8bb5ad22003-01-24 02:44:45 +00004986There isn't a sane case where this can happen. The closest it gets is at
4987the end of DST, where there's an hour in UTC with no spelling in a hybrid
4988tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
4989that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
4990UTC) because the docs insist on that, but 0:MM is taken as being in daylight
4991time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
4992clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
4993standard time. Since that's what the local clock *does*, we want to map both
4994UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00004995in local time, but so it goes -- it's the way the local clock works.
4996
Tim Peters8bb5ad22003-01-24 02:44:45 +00004997When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4998so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4999z' = 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 +00005000(correctly) concludes that z' is not UTC-equivalent to x.
5001
5002Because we know z.d said z was in daylight time (else [5] would have held and
5003we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005004and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005005return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5006but the reasoning doesn't depend on the example -- it depends on there being
5007two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005008z' must be in standard time, and is the spelling we want in this case.
5009
5010Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5011concerned (because it takes z' as being in standard time rather than the
5012daylight time we intend here), but returning it gives the real-life "local
5013clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5014tz.
5015
5016When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5017the 1:MM standard time spelling we want.
5018
5019So how can this break? One of the assumptions must be violated. Two
5020possibilities:
5021
50221) [2] effectively says that y.s is invariant across all y belong to a given
5023 time zone. This isn't true if, for political reasons or continental drift,
5024 a region decides to change its base offset from UTC.
5025
50262) There may be versions of "double daylight" time where the tail end of
5027 the analysis gives up a step too early. I haven't thought about that
5028 enough to say.
5029
5030In any case, it's clear that the default fromutc() is strong enough to handle
5031"almost all" time zones: so long as the standard offset is invariant, it
5032doesn't matter if daylight time transition points change from year to year, or
5033if daylight time is skipped in some years; it doesn't matter how large or
5034small dst() may get within its bounds; and it doesn't even matter if some
5035perverse time zone returns a negative dst()). So a breaking case must be
5036pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005037--------------------------------------------------------------------------- */