blob: 36793382fe5c82b8145e5647d3f345c0bfd42820 [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
11#include "datetime.h"
12
13/* We require that C int be at least 32 bits, and use int virtually
14 * everywhere. In just a few cases we use a temp long, where a Python
15 * API returns a C long. In such cases, we have to ensure that the
16 * final result fits in a C int (this can be an issue on 64-bit boxes).
17 */
18#if SIZEOF_INT < 4
19# error "datetime.c requires that C int have at least 32 bits"
20#endif
21
22#define MINYEAR 1
23#define MAXYEAR 9999
24
25/* Nine decimal digits is easy to communicate, and leaves enough room
26 * so that two delta days can be added w/o fear of overflowing a signed
27 * 32-bit int, and with plenty of room left over to absorb any possible
28 * carries from adding seconds.
29 */
30#define MAX_DELTA_DAYS 999999999
31
32/* Rename the long macros in datetime.h to more reasonable short names. */
33#define GET_YEAR PyDateTime_GET_YEAR
34#define GET_MONTH PyDateTime_GET_MONTH
35#define GET_DAY PyDateTime_GET_DAY
36#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
37#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
38#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
39#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
40
41/* Date accessors for date and datetime. */
42#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
43 ((o)->data[1] = ((v) & 0x00ff)))
44#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
45#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
46
47/* Date/Time accessors for datetime. */
48#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
49#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
50#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
51#define DATE_SET_MICROSECOND(o, v) \
52 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
53 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
54 ((o)->data[9] = ((v) & 0x0000ff)))
55
56/* Time accessors for time. */
57#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
58#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
59#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
60#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
61#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
62#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
63#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
64#define TIME_SET_MICROSECOND(o, v) \
65 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
66 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
67 ((o)->data[5] = ((v) & 0x0000ff)))
68
69/* Delta accessors for timedelta. */
70#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
71#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
72#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
73
74#define SET_TD_DAYS(o, v) ((o)->days = (v))
75#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
76#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
77
Tim Petersa032d2e2003-01-11 00:15:54 +000078/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
79 * p->hastzinfo.
80 */
81#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
82
Tim Peters2a799bf2002-12-16 20:18:38 +000083/* Forward declarations. */
84static PyTypeObject PyDateTime_DateType;
85static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +000086static PyTypeObject PyDateTime_DeltaType;
87static PyTypeObject PyDateTime_TimeType;
88static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +000089
90/* ---------------------------------------------------------------------------
91 * Math utilities.
92 */
93
94/* k = i+j overflows iff k differs in sign from both inputs,
95 * iff k^i has sign bit set and k^j has sign bit set,
96 * iff (k^i)&(k^j) has sign bit set.
97 */
98#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
99 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
100
101/* Compute Python divmod(x, y), returning the quotient and storing the
102 * remainder into *r. The quotient is the floor of x/y, and that's
103 * the real point of this. C will probably truncate instead (C99
104 * requires truncation; C89 left it implementation-defined).
105 * Simplification: we *require* that y > 0 here. That's appropriate
106 * for all the uses made of it. This simplifies the code and makes
107 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
108 * overflow case).
109 */
110static int
111divmod(int x, int y, int *r)
112{
113 int quo;
114
115 assert(y > 0);
116 quo = x / y;
117 *r = x - quo * y;
118 if (*r < 0) {
119 --quo;
120 *r += y;
121 }
122 assert(0 <= *r && *r < y);
123 return quo;
124}
125
Tim Peters5d644dd2003-01-02 16:32:54 +0000126/* Round a double to the nearest long. |x| must be small enough to fit
127 * in a C long; this is not checked.
128 */
129static long
130round_to_long(double x)
131{
132 if (x >= 0.0)
133 x = floor(x + 0.5);
134 else
135 x = ceil(x - 0.5);
136 return (long)x;
137}
138
Tim Peters2a799bf2002-12-16 20:18:38 +0000139/* ---------------------------------------------------------------------------
140 * General calendrical helper functions
141 */
142
143/* For each month ordinal in 1..12, the number of days in that month,
144 * and the number of days before that month in the same year. These
145 * are correct for non-leap years only.
146 */
147static int _days_in_month[] = {
148 0, /* unused; this vector uses 1-based indexing */
149 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
150};
151
152static int _days_before_month[] = {
153 0, /* unused; this vector uses 1-based indexing */
154 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
155};
156
157/* year -> 1 if leap year, else 0. */
158static int
159is_leap(int year)
160{
161 /* Cast year to unsigned. The result is the same either way, but
162 * C can generate faster code for unsigned mod than for signed
163 * mod (especially for % 4 -- a good compiler should just grab
164 * the last 2 bits when the LHS is unsigned).
165 */
166 const unsigned int ayear = (unsigned int)year;
167 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
168}
169
170/* year, month -> number of days in that month in that year */
171static int
172days_in_month(int year, int month)
173{
174 assert(month >= 1);
175 assert(month <= 12);
176 if (month == 2 && is_leap(year))
177 return 29;
178 else
179 return _days_in_month[month];
180}
181
182/* year, month -> number of days in year preceeding first day of month */
183static int
184days_before_month(int year, int month)
185{
186 int days;
187
188 assert(month >= 1);
189 assert(month <= 12);
190 days = _days_before_month[month];
191 if (month > 2 && is_leap(year))
192 ++days;
193 return days;
194}
195
196/* year -> number of days before January 1st of year. Remember that we
197 * start with year 1, so days_before_year(1) == 0.
198 */
199static int
200days_before_year(int year)
201{
202 int y = year - 1;
203 /* This is incorrect if year <= 0; we really want the floor
204 * here. But so long as MINYEAR is 1, the smallest year this
205 * can see is 0 (this can happen in some normalization endcases),
206 * so we'll just special-case that.
207 */
208 assert (year >= 0);
209 if (y >= 0)
210 return y*365 + y/4 - y/100 + y/400;
211 else {
212 assert(y == -1);
213 return -366;
214 }
215}
216
217/* Number of days in 4, 100, and 400 year cycles. That these have
218 * the correct values is asserted in the module init function.
219 */
220#define DI4Y 1461 /* days_before_year(5); days in 4 years */
221#define DI100Y 36524 /* days_before_year(101); days in 100 years */
222#define DI400Y 146097 /* days_before_year(401); days in 400 years */
223
224/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
225static void
226ord_to_ymd(int ordinal, int *year, int *month, int *day)
227{
228 int n, n1, n4, n100, n400, leapyear, preceding;
229
230 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
231 * leap years repeats exactly every 400 years. The basic strategy is
232 * to find the closest 400-year boundary at or before ordinal, then
233 * work with the offset from that boundary to ordinal. Life is much
234 * clearer if we subtract 1 from ordinal first -- then the values
235 * of ordinal at 400-year boundaries are exactly those divisible
236 * by DI400Y:
237 *
238 * D M Y n n-1
239 * -- --- ---- ---------- ----------------
240 * 31 Dec -400 -DI400Y -DI400Y -1
241 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
242 * ...
243 * 30 Dec 000 -1 -2
244 * 31 Dec 000 0 -1
245 * 1 Jan 001 1 0 400-year boundary
246 * 2 Jan 001 2 1
247 * 3 Jan 001 3 2
248 * ...
249 * 31 Dec 400 DI400Y DI400Y -1
250 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
251 */
252 assert(ordinal >= 1);
253 --ordinal;
254 n400 = ordinal / DI400Y;
255 n = ordinal % DI400Y;
256 *year = n400 * 400 + 1;
257
258 /* Now n is the (non-negative) offset, in days, from January 1 of
259 * year, to the desired date. Now compute how many 100-year cycles
260 * precede n.
261 * Note that it's possible for n100 to equal 4! In that case 4 full
262 * 100-year cycles precede the desired day, which implies the
263 * desired day is December 31 at the end of a 400-year cycle.
264 */
265 n100 = n / DI100Y;
266 n = n % DI100Y;
267
268 /* Now compute how many 4-year cycles precede it. */
269 n4 = n / DI4Y;
270 n = n % DI4Y;
271
272 /* And now how many single years. Again n1 can be 4, and again
273 * meaning that the desired day is December 31 at the end of the
274 * 4-year cycle.
275 */
276 n1 = n / 365;
277 n = n % 365;
278
279 *year += n100 * 100 + n4 * 4 + n1;
280 if (n1 == 4 || n100 == 4) {
281 assert(n == 0);
282 *year -= 1;
283 *month = 12;
284 *day = 31;
285 return;
286 }
287
288 /* Now the year is correct, and n is the offset from January 1. We
289 * find the month via an estimate that's either exact or one too
290 * large.
291 */
292 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
293 assert(leapyear == is_leap(*year));
294 *month = (n + 50) >> 5;
295 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
296 if (preceding > n) {
297 /* estimate is too large */
298 *month -= 1;
299 preceding -= days_in_month(*year, *month);
300 }
301 n -= preceding;
302 assert(0 <= n);
303 assert(n < days_in_month(*year, *month));
304
305 *day = n + 1;
306}
307
308/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
309static int
310ymd_to_ord(int year, int month, int day)
311{
312 return days_before_year(year) + days_before_month(year, month) + day;
313}
314
315/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
316static int
317weekday(int year, int month, int day)
318{
319 return (ymd_to_ord(year, month, day) + 6) % 7;
320}
321
322/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
323 * first calendar week containing a Thursday.
324 */
325static int
326iso_week1_monday(int year)
327{
328 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
329 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
330 int first_weekday = (first_day + 6) % 7;
331 /* ordinal of closest Monday at or before 1/1 */
332 int week1_monday = first_day - first_weekday;
333
334 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
335 week1_monday += 7;
336 return week1_monday;
337}
338
339/* ---------------------------------------------------------------------------
340 * Range checkers.
341 */
342
343/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
344 * If not, raise OverflowError and return -1.
345 */
346static int
347check_delta_day_range(int days)
348{
349 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
350 return 0;
351 PyErr_Format(PyExc_OverflowError,
352 "days=%d; must have magnitude <= %d",
Guido van Rossumbd43e912002-12-16 20:34:55 +0000353 days, MAX_DELTA_DAYS);
Tim Peters2a799bf2002-12-16 20:18:38 +0000354 return -1;
355}
356
357/* Check that date arguments are in range. Return 0 if they are. If they
358 * aren't, raise ValueError and return -1.
359 */
360static int
361check_date_args(int year, int month, int day)
362{
363
364 if (year < MINYEAR || year > MAXYEAR) {
365 PyErr_SetString(PyExc_ValueError,
366 "year is out of range");
367 return -1;
368 }
369 if (month < 1 || month > 12) {
370 PyErr_SetString(PyExc_ValueError,
371 "month must be in 1..12");
372 return -1;
373 }
374 if (day < 1 || day > days_in_month(year, month)) {
375 PyErr_SetString(PyExc_ValueError,
376 "day is out of range for month");
377 return -1;
378 }
379 return 0;
380}
381
382/* Check that time arguments are in range. Return 0 if they are. If they
383 * aren't, raise ValueError and return -1.
384 */
385static int
386check_time_args(int h, int m, int s, int us)
387{
388 if (h < 0 || h > 23) {
389 PyErr_SetString(PyExc_ValueError,
390 "hour must be in 0..23");
391 return -1;
392 }
393 if (m < 0 || m > 59) {
394 PyErr_SetString(PyExc_ValueError,
395 "minute must be in 0..59");
396 return -1;
397 }
398 if (s < 0 || s > 59) {
399 PyErr_SetString(PyExc_ValueError,
400 "second must be in 0..59");
401 return -1;
402 }
403 if (us < 0 || us > 999999) {
404 PyErr_SetString(PyExc_ValueError,
405 "microsecond must be in 0..999999");
406 return -1;
407 }
408 return 0;
409}
410
411/* ---------------------------------------------------------------------------
412 * Normalization utilities.
413 */
414
415/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
416 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
417 * at least factor, enough of *lo is converted into "hi" units so that
418 * 0 <= *lo < factor. The input values must be such that int overflow
419 * is impossible.
420 */
421static void
422normalize_pair(int *hi, int *lo, int factor)
423{
424 assert(factor > 0);
425 assert(lo != hi);
426 if (*lo < 0 || *lo >= factor) {
427 const int num_hi = divmod(*lo, factor, lo);
428 const int new_hi = *hi + num_hi;
429 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
430 *hi = new_hi;
431 }
432 assert(0 <= *lo && *lo < factor);
433}
434
435/* Fiddle days (d), seconds (s), and microseconds (us) so that
436 * 0 <= *s < 24*3600
437 * 0 <= *us < 1000000
438 * The input values must be such that the internals don't overflow.
439 * The way this routine is used, we don't get close.
440 */
441static void
442normalize_d_s_us(int *d, int *s, int *us)
443{
444 if (*us < 0 || *us >= 1000000) {
445 normalize_pair(s, us, 1000000);
446 /* |s| can't be bigger than about
447 * |original s| + |original us|/1000000 now.
448 */
449
450 }
451 if (*s < 0 || *s >= 24*3600) {
452 normalize_pair(d, s, 24*3600);
453 /* |d| can't be bigger than about
454 * |original d| +
455 * (|original s| + |original us|/1000000) / (24*3600) now.
456 */
457 }
458 assert(0 <= *s && *s < 24*3600);
459 assert(0 <= *us && *us < 1000000);
460}
461
462/* Fiddle years (y), months (m), and days (d) so that
463 * 1 <= *m <= 12
464 * 1 <= *d <= days_in_month(*y, *m)
465 * The input values must be such that the internals don't overflow.
466 * The way this routine is used, we don't get close.
467 */
468static void
469normalize_y_m_d(int *y, int *m, int *d)
470{
471 int dim; /* # of days in month */
472
473 /* This gets muddy: the proper range for day can't be determined
474 * without knowing the correct month and year, but if day is, e.g.,
475 * plus or minus a million, the current month and year values make
476 * no sense (and may also be out of bounds themselves).
477 * Saying 12 months == 1 year should be non-controversial.
478 */
479 if (*m < 1 || *m > 12) {
480 --*m;
481 normalize_pair(y, m, 12);
482 ++*m;
483 /* |y| can't be bigger than about
484 * |original y| + |original m|/12 now.
485 */
486 }
487 assert(1 <= *m && *m <= 12);
488
489 /* Now only day can be out of bounds (year may also be out of bounds
490 * for a datetime object, but we don't care about that here).
491 * If day is out of bounds, what to do is arguable, but at least the
492 * method here is principled and explainable.
493 */
494 dim = days_in_month(*y, *m);
495 if (*d < 1 || *d > dim) {
496 /* Move day-1 days from the first of the month. First try to
497 * get off cheap if we're only one day out of range
498 * (adjustments for timezone alone can't be worse than that).
499 */
500 if (*d == 0) {
501 --*m;
502 if (*m > 0)
503 *d = days_in_month(*y, *m);
504 else {
505 --*y;
506 *m = 12;
507 *d = 31;
508 }
509 }
510 else if (*d == dim + 1) {
511 /* move forward a day */
512 ++*m;
513 *d = 1;
514 if (*m > 12) {
515 *m = 1;
516 ++*y;
517 }
518 }
519 else {
520 int ordinal = ymd_to_ord(*y, *m, 1) +
521 *d - 1;
522 ord_to_ymd(ordinal, y, m, d);
523 }
524 }
525 assert(*m > 0);
526 assert(*d > 0);
527}
528
529/* Fiddle out-of-bounds months and days so that the result makes some kind
530 * of sense. The parameters are both inputs and outputs. Returns < 0 on
531 * failure, where failure means the adjusted year is out of bounds.
532 */
533static int
534normalize_date(int *year, int *month, int *day)
535{
536 int result;
537
538 normalize_y_m_d(year, month, day);
539 if (MINYEAR <= *year && *year <= MAXYEAR)
540 result = 0;
541 else {
542 PyErr_SetString(PyExc_OverflowError,
543 "date value out of range");
544 result = -1;
545 }
546 return result;
547}
548
549/* Force all the datetime fields into range. The parameters are both
550 * inputs and outputs. Returns < 0 on error.
551 */
552static int
553normalize_datetime(int *year, int *month, int *day,
554 int *hour, int *minute, int *second,
555 int *microsecond)
556{
557 normalize_pair(second, microsecond, 1000000);
558 normalize_pair(minute, second, 60);
559 normalize_pair(hour, minute, 60);
560 normalize_pair(day, hour, 24);
561 return normalize_date(year, month, day);
562}
563
564/* ---------------------------------------------------------------------------
565 * tzinfo helpers.
566 */
567
Tim Peters855fe882002-12-22 03:43:39 +0000568/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
569 * raise TypeError and return -1.
570 */
571static int
572check_tzinfo_subclass(PyObject *p)
573{
574 if (p == Py_None || PyTZInfo_Check(p))
575 return 0;
576 PyErr_Format(PyExc_TypeError,
577 "tzinfo argument must be None or of a tzinfo subclass, "
578 "not type '%s'",
579 p->ob_type->tp_name);
580 return -1;
581}
582
Tim Petersbad8ff02002-12-30 20:52:32 +0000583/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000584 * If tzinfo is None, returns None.
585 */
586static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000587call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000588{
589 PyObject *result;
590
Tim Petersbad8ff02002-12-30 20:52:32 +0000591 assert(tzinfo && methname && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000592 assert(check_tzinfo_subclass(tzinfo) >= 0);
593 if (tzinfo == Py_None) {
594 result = Py_None;
595 Py_INCREF(result);
596 }
597 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000598 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000599 return result;
600}
601
Tim Peters2a799bf2002-12-16 20:18:38 +0000602/* If self has a tzinfo member, return a BORROWED reference to it. Else
603 * return NULL, which is NOT AN ERROR. There are no error returns here,
604 * and the caller must not decref the result.
605 */
606static PyObject *
607get_tzinfo_member(PyObject *self)
608{
609 PyObject *tzinfo = NULL;
610
Tim Petersa9bc1682003-01-11 03:39:11 +0000611 if (PyDateTime_Check(self) && HASTZINFO(self))
612 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
Tim Petersa032d2e2003-01-11 00:15:54 +0000613 else if (PyTime_Check(self) && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +0000614 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000615
616 return tzinfo;
617}
618
Tim Petersbad8ff02002-12-30 20:52:32 +0000619/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000620 * result. tzinfo must be an instance of the tzinfo class. If the method
621 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000622 * return None or timedelta, TypeError is raised and this returns -1. If it
623 * returnsa timedelta and the value is out of range or isn't a whole number
624 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000625 * Else *none is set to 0 and the integer method result is returned.
626 */
627static int
628call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
629 int *none)
630{
631 PyObject *u;
Tim Peters397301e2003-01-02 21:28:08 +0000632 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000633
634 assert(tzinfo != NULL);
635 assert(PyTZInfo_Check(tzinfo));
636 assert(tzinfoarg != NULL);
637
638 *none = 0;
Tim Petersbad8ff02002-12-30 20:52:32 +0000639 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000640 if (u == NULL)
641 return -1;
642
Tim Peters27362852002-12-23 16:17:39 +0000643 else if (u == Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +0000644 result = 0;
645 *none = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000646 }
Tim Peters855fe882002-12-22 03:43:39 +0000647 else if (PyDelta_Check(u)) {
648 const int days = GET_TD_DAYS(u);
649 if (days < -1 || days > 0)
650 result = 24*60; /* trigger ValueError below */
651 else {
652 /* next line can't overflow because we know days
653 * is -1 or 0 now
654 */
655 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
656 result = divmod(ss, 60, &ss);
657 if (ss || GET_TD_MICROSECONDS(u)) {
658 PyErr_Format(PyExc_ValueError,
659 "tzinfo.%s() must return a "
660 "whole number of minutes",
661 name);
662 result = -1;
Tim Peters855fe882002-12-22 03:43:39 +0000663 }
664 }
665 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000666 else {
667 PyErr_Format(PyExc_TypeError,
Tim Peters397301e2003-01-02 21:28:08 +0000668 "tzinfo.%s() must return None or "
Tim Peters855fe882002-12-22 03:43:39 +0000669 "timedelta, not '%s'",
670 name, u->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000671 }
672
Tim Peters2a799bf2002-12-16 20:18:38 +0000673 Py_DECREF(u);
674 if (result < -1439 || result > 1439) {
675 PyErr_Format(PyExc_ValueError,
Neal Norwitz506a2242003-01-04 01:02:25 +0000676 "tzinfo.%s() returned %d; must be in "
Tim Peters2a799bf2002-12-16 20:18:38 +0000677 "-1439 .. 1439",
678 name, result);
679 result = -1;
680 }
Tim Peters397301e2003-01-02 21:28:08 +0000681 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000682}
683
684/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
685 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
686 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000687 * doesn't return None or timedelta, TypeError is raised and this returns -1.
688 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
689 * # of minutes), ValueError is raised and this returns -1. Else *none is
690 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000691 */
692static int
693call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
694{
695 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
696}
697
Tim Peters855fe882002-12-22 03:43:39 +0000698static PyObject *new_delta(int d, int sec, int usec, int normalize);
699
Tim Petersbad8ff02002-12-30 20:52:32 +0000700/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
701 */
Tim Peters855fe882002-12-22 03:43:39 +0000702static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000703offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Tim Peters855fe882002-12-22 03:43:39 +0000704 PyObject *result;
705
Tim Petersbad8ff02002-12-30 20:52:32 +0000706 assert(tzinfo && name && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000707 if (tzinfo == Py_None) {
708 result = Py_None;
709 Py_INCREF(result);
710 }
711 else {
712 int none;
Tim Petersbad8ff02002-12-30 20:52:32 +0000713 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
714 &none);
Tim Peters855fe882002-12-22 03:43:39 +0000715 if (offset < 0 && PyErr_Occurred())
716 return NULL;
717 if (none) {
718 result = Py_None;
719 Py_INCREF(result);
720 }
721 else
722 result = new_delta(0, offset * 60, 0, 1);
723 }
724 return result;
725}
726
Tim Peters2a799bf2002-12-16 20:18:38 +0000727/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
728 * result. tzinfo must be an instance of the tzinfo class. If dst()
729 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000730 & doesn't return None or timedelta, TypeError is raised and this
731 * returns -1. If dst() returns an invalid timedelta for for a UTC offset,
732 * ValueError is raised and this returns -1. Else *none is set to 0 and
733 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000734 */
735static int
736call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
737{
738 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
739}
740
Tim Petersbad8ff02002-12-30 20:52:32 +0000741/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000742 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000743 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000744 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000745 */
746static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000747call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000748{
749 PyObject *result;
750
751 assert(tzinfo != NULL);
Tim Peters855fe882002-12-22 03:43:39 +0000752 assert(check_tzinfo_subclass(tzinfo) >= 0);
Tim Petersbad8ff02002-12-30 20:52:32 +0000753 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000754
Tim Peters855fe882002-12-22 03:43:39 +0000755 if (tzinfo == Py_None) {
756 result = Py_None;
757 Py_INCREF(result);
758 }
759 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000760 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000761
762 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
763 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
Tim Peters2a799bf2002-12-16 20:18:38 +0000764 "return None or a string, not '%s'",
765 result->ob_type->tp_name);
766 Py_DECREF(result);
767 result = NULL;
768 }
769 return result;
770}
771
772typedef enum {
773 /* an exception has been set; the caller should pass it on */
774 OFFSET_ERROR,
775
Tim Petersa9bc1682003-01-11 03:39:11 +0000776 /* type isn't date, datetime, or time subclass */
Tim Peters2a799bf2002-12-16 20:18:38 +0000777 OFFSET_UNKNOWN,
778
779 /* date,
Tim Petersa9bc1682003-01-11 03:39:11 +0000780 * datetime with !hastzinfo
781 * datetime with None tzinfo,
782 * datetime where utcoffset() returns None
Tim Peters37f39822003-01-10 03:49:02 +0000783 * time with !hastzinfo
784 * time with None tzinfo,
785 * time where utcoffset() returns None
Tim Peters2a799bf2002-12-16 20:18:38 +0000786 */
787 OFFSET_NAIVE,
788
Tim Petersa9bc1682003-01-11 03:39:11 +0000789 /* time or datetime where utcoffset() doesn't return None */
Tim Peters2a799bf2002-12-16 20:18:38 +0000790 OFFSET_AWARE,
791} naivety;
792
Tim Peters14b69412002-12-22 18:10:22 +0000793/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000794 * the "naivety" typedef for details. If the type is aware, *offset is set
795 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000796 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000797 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000798 */
799static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000800classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000801{
802 int none;
803 PyObject *tzinfo;
804
Tim Peterse39a80c2002-12-30 21:28:52 +0000805 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000806 *offset = 0;
Tim Peters14b69412002-12-22 18:10:22 +0000807 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
Tim Peters2a799bf2002-12-16 20:18:38 +0000808 if (tzinfo == Py_None)
809 return OFFSET_NAIVE;
Tim Peters14b69412002-12-22 18:10:22 +0000810 if (tzinfo == NULL) {
811 /* note that a datetime passes the PyDate_Check test */
812 return (PyTime_Check(op) || PyDate_Check(op)) ?
813 OFFSET_NAIVE : OFFSET_UNKNOWN;
814 }
Tim Peterse39a80c2002-12-30 21:28:52 +0000815 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000816 if (*offset == -1 && PyErr_Occurred())
817 return OFFSET_ERROR;
818 return none ? OFFSET_NAIVE : OFFSET_AWARE;
819}
820
Tim Peters00237032002-12-27 02:21:51 +0000821/* Classify two objects as to whether they're naive or offset-aware.
822 * This isn't quite the same as calling classify_utcoffset() twice: for
823 * binary operations (comparison and subtraction), we generally want to
824 * ignore the tzinfo members if they're identical. This is by design,
825 * so that results match "naive" expectations when mixing objects from a
826 * single timezone. So in that case, this sets both offsets to 0 and
827 * both naiveties to OFFSET_NAIVE.
828 * The function returns 0 if everything's OK, and -1 on error.
829 */
830static int
831classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Tim Peterse39a80c2002-12-30 21:28:52 +0000832 PyObject *tzinfoarg1,
833 PyObject *o2, int *offset2, naivety *n2,
834 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +0000835{
836 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
837 *offset1 = *offset2 = 0;
838 *n1 = *n2 = OFFSET_NAIVE;
839 }
840 else {
Tim Peterse39a80c2002-12-30 21:28:52 +0000841 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
Tim Peters00237032002-12-27 02:21:51 +0000842 if (*n1 == OFFSET_ERROR)
843 return -1;
Tim Peterse39a80c2002-12-30 21:28:52 +0000844 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
Tim Peters00237032002-12-27 02:21:51 +0000845 if (*n2 == OFFSET_ERROR)
846 return -1;
847 }
848 return 0;
849}
850
Tim Peters2a799bf2002-12-16 20:18:38 +0000851/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
852 * stuff
853 * ", tzinfo=" + repr(tzinfo)
854 * before the closing ")".
855 */
856static PyObject *
857append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
858{
859 PyObject *temp;
860
861 assert(PyString_Check(repr));
862 assert(tzinfo);
863 if (tzinfo == Py_None)
864 return repr;
865 /* Get rid of the trailing ')'. */
866 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
867 temp = PyString_FromStringAndSize(PyString_AsString(repr),
868 PyString_Size(repr) - 1);
869 Py_DECREF(repr);
870 if (temp == NULL)
871 return NULL;
872 repr = temp;
873
874 /* Append ", tzinfo=". */
875 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
876
877 /* Append repr(tzinfo). */
878 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
879
880 /* Add a closing paren. */
881 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
882 return repr;
883}
884
885/* ---------------------------------------------------------------------------
886 * String format helpers.
887 */
888
889static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +0000890format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000891{
892 static char *DayNames[] = {
893 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
894 };
895 static char *MonthNames[] = {
896 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
897 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
898 };
899
900 char buffer[128];
901 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
902
903 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
904 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
905 GET_DAY(date), hours, minutes, seconds,
906 GET_YEAR(date));
907 return PyString_FromString(buffer);
908}
909
910/* Add an hours & minutes UTC offset string to buf. buf has no more than
911 * buflen bytes remaining. The UTC offset is gotten by calling
912 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
913 * *buf, and that's all. Else the returned value is checked for sanity (an
914 * integer in range), and if that's OK it's converted to an hours & minutes
915 * string of the form
916 * sign HH sep MM
917 * Returns 0 if everything is OK. If the return value from utcoffset() is
918 * bogus, an appropriate exception is set and -1 is returned.
919 */
920static int
Tim Peters328fff72002-12-20 01:31:27 +0000921format_utcoffset(char *buf, size_t buflen, const char *sep,
Tim Peters2a799bf2002-12-16 20:18:38 +0000922 PyObject *tzinfo, PyObject *tzinfoarg)
923{
924 int offset;
925 int hours;
926 int minutes;
927 char sign;
928 int none;
929
930 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
931 if (offset == -1 && PyErr_Occurred())
932 return -1;
933 if (none) {
934 *buf = '\0';
935 return 0;
936 }
937 sign = '+';
938 if (offset < 0) {
939 sign = '-';
940 offset = - offset;
941 }
942 hours = divmod(offset, 60, &minutes);
943 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
944 return 0;
945}
946
947/* I sure don't want to reproduce the strftime code from the time module,
948 * so this imports the module and calls it. All the hair is due to
949 * giving special meanings to the %z and %Z format codes via a preprocessing
950 * step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +0000951 * tzinfoarg is the argument to pass to the object's tzinfo method, if
952 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +0000953 */
954static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000955wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
956 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000957{
958 PyObject *result = NULL; /* guilty until proved innocent */
959
960 PyObject *zreplacement = NULL; /* py string, replacement for %z */
961 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
962
963 char *pin; /* pointer to next char in input format */
964 char ch; /* next char in input format */
965
966 PyObject *newfmt = NULL; /* py string, the output format */
967 char *pnew; /* pointer to available byte in output format */
968 char totalnew; /* number bytes total in output format buffer,
969 exclusive of trailing \0 */
970 char usednew; /* number bytes used so far in output format buffer */
971
972 char *ptoappend; /* pointer to string to append to output buffer */
973 int ntoappend; /* # of bytes to append to output buffer */
974
Tim Peters2a799bf2002-12-16 20:18:38 +0000975 assert(object && format && timetuple);
976 assert(PyString_Check(format));
977
Tim Petersd6844152002-12-22 20:58:42 +0000978 /* Give up if the year is before 1900.
979 * Python strftime() plays games with the year, and different
980 * games depending on whether envar PYTHON2K is set. This makes
981 * years before 1900 a nightmare, even if the platform strftime
982 * supports them (and not all do).
983 * We could get a lot farther here by avoiding Python's strftime
984 * wrapper and calling the C strftime() directly, but that isn't
985 * an option in the Python implementation of this module.
986 */
987 {
988 long year;
989 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
990 if (pyyear == NULL) return NULL;
991 assert(PyInt_Check(pyyear));
992 year = PyInt_AsLong(pyyear);
993 Py_DECREF(pyyear);
994 if (year < 1900) {
995 PyErr_Format(PyExc_ValueError, "year=%ld is before "
996 "1900; the datetime strftime() "
997 "methods require year >= 1900",
998 year);
999 return NULL;
1000 }
1001 }
1002
Tim Peters2a799bf2002-12-16 20:18:38 +00001003 /* Scan the input format, looking for %z and %Z escapes, building
Tim Peters328fff72002-12-20 01:31:27 +00001004 * a new format. Since computing the replacements for those codes
1005 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +00001006 */
1007 totalnew = PyString_Size(format); /* realistic if no %z/%Z */
1008 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1009 if (newfmt == NULL) goto Done;
1010 pnew = PyString_AsString(newfmt);
1011 usednew = 0;
1012
1013 pin = PyString_AsString(format);
1014 while ((ch = *pin++) != '\0') {
1015 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +00001016 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001017 ntoappend = 1;
1018 }
1019 else if ((ch = *pin++) == '\0') {
1020 /* There's a lone trailing %; doesn't make sense. */
1021 PyErr_SetString(PyExc_ValueError, "strftime format "
1022 "ends with raw %");
1023 goto Done;
1024 }
1025 /* A % has been seen and ch is the character after it. */
1026 else if (ch == 'z') {
1027 if (zreplacement == NULL) {
1028 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +00001029 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +00001030 PyObject *tzinfo = get_tzinfo_member(object);
1031 zreplacement = PyString_FromString("");
1032 if (zreplacement == NULL) goto Done;
1033 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001034 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001035 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001036 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001037 "",
1038 tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00001039 tzinfoarg) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001040 goto Done;
1041 Py_DECREF(zreplacement);
1042 zreplacement = PyString_FromString(buf);
1043 if (zreplacement == NULL) goto Done;
1044 }
1045 }
1046 assert(zreplacement != NULL);
1047 ptoappend = PyString_AsString(zreplacement);
1048 ntoappend = PyString_Size(zreplacement);
1049 }
1050 else if (ch == 'Z') {
1051 /* format tzname */
1052 if (Zreplacement == NULL) {
1053 PyObject *tzinfo = get_tzinfo_member(object);
1054 Zreplacement = PyString_FromString("");
1055 if (Zreplacement == NULL) goto Done;
1056 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001057 PyObject *temp;
1058 assert(tzinfoarg != NULL);
1059 temp = call_tzname(tzinfo, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001060 if (temp == NULL) goto Done;
1061 if (temp != Py_None) {
1062 assert(PyString_Check(temp));
1063 /* Since the tzname is getting
1064 * stuffed into the format, we
1065 * have to double any % signs
1066 * so that strftime doesn't
1067 * treat them as format codes.
1068 */
1069 Py_DECREF(Zreplacement);
1070 Zreplacement = PyObject_CallMethod(
1071 temp, "replace",
1072 "ss", "%", "%%");
1073 Py_DECREF(temp);
1074 if (Zreplacement == NULL)
1075 goto Done;
1076 }
1077 else
1078 Py_DECREF(temp);
1079 }
1080 }
1081 assert(Zreplacement != NULL);
1082 ptoappend = PyString_AsString(Zreplacement);
1083 ntoappend = PyString_Size(Zreplacement);
1084 }
1085 else {
Tim Peters328fff72002-12-20 01:31:27 +00001086 /* percent followed by neither z nor Z */
1087 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001088 ntoappend = 2;
1089 }
1090
1091 /* Append the ntoappend chars starting at ptoappend to
1092 * the new format.
1093 */
1094 assert(ntoappend >= 0);
1095 if (ntoappend == 0)
1096 continue;
1097 while (usednew + ntoappend > totalnew) {
1098 int bigger = totalnew << 1;
1099 if ((bigger >> 1) != totalnew) { /* overflow */
1100 PyErr_NoMemory();
1101 goto Done;
1102 }
1103 if (_PyString_Resize(&newfmt, bigger) < 0)
1104 goto Done;
1105 totalnew = bigger;
1106 pnew = PyString_AsString(newfmt) + usednew;
1107 }
1108 memcpy(pnew, ptoappend, ntoappend);
1109 pnew += ntoappend;
1110 usednew += ntoappend;
1111 assert(usednew <= totalnew);
1112 } /* end while() */
1113
1114 if (_PyString_Resize(&newfmt, usednew) < 0)
1115 goto Done;
1116 {
1117 PyObject *time = PyImport_ImportModule("time");
1118 if (time == NULL)
1119 goto Done;
1120 result = PyObject_CallMethod(time, "strftime", "OO",
1121 newfmt, timetuple);
1122 Py_DECREF(time);
1123 }
1124 Done:
1125 Py_XDECREF(zreplacement);
1126 Py_XDECREF(Zreplacement);
1127 Py_XDECREF(newfmt);
1128 return result;
1129}
1130
1131static char *
1132isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1133{
1134 int x;
1135 x = PyOS_snprintf(buffer, bufflen,
1136 "%04d-%02d-%02d",
1137 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1138 return buffer + x;
1139}
1140
1141static void
1142isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1143{
1144 int us = DATE_GET_MICROSECOND(dt);
1145
1146 PyOS_snprintf(buffer, bufflen,
1147 "%02d:%02d:%02d", /* 8 characters */
1148 DATE_GET_HOUR(dt),
1149 DATE_GET_MINUTE(dt),
1150 DATE_GET_SECOND(dt));
1151 if (us)
1152 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1153}
1154
1155/* ---------------------------------------------------------------------------
1156 * Wrap functions from the time module. These aren't directly available
1157 * from C. Perhaps they should be.
1158 */
1159
1160/* Call time.time() and return its result (a Python float). */
1161static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001162time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001163{
1164 PyObject *result = NULL;
1165 PyObject *time = PyImport_ImportModule("time");
1166
1167 if (time != NULL) {
1168 result = PyObject_CallMethod(time, "time", "()");
1169 Py_DECREF(time);
1170 }
1171 return result;
1172}
1173
1174/* Build a time.struct_time. The weekday and day number are automatically
1175 * computed from the y,m,d args.
1176 */
1177static PyObject *
1178build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1179{
1180 PyObject *time;
1181 PyObject *result = NULL;
1182
1183 time = PyImport_ImportModule("time");
1184 if (time != NULL) {
1185 result = PyObject_CallMethod(time, "struct_time",
1186 "((iiiiiiiii))",
1187 y, m, d,
1188 hh, mm, ss,
1189 weekday(y, m, d),
1190 days_before_month(y, m) + d,
1191 dstflag);
1192 Py_DECREF(time);
1193 }
1194 return result;
1195}
1196
1197/* ---------------------------------------------------------------------------
1198 * Miscellaneous helpers.
1199 */
1200
1201/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1202 * The comparisons here all most naturally compute a cmp()-like result.
1203 * This little helper turns that into a bool result for rich comparisons.
1204 */
1205static PyObject *
1206diff_to_bool(int diff, int op)
1207{
1208 PyObject *result;
1209 int istrue;
1210
1211 switch (op) {
1212 case Py_EQ: istrue = diff == 0; break;
1213 case Py_NE: istrue = diff != 0; break;
1214 case Py_LE: istrue = diff <= 0; break;
1215 case Py_GE: istrue = diff >= 0; break;
1216 case Py_LT: istrue = diff < 0; break;
1217 case Py_GT: istrue = diff > 0; break;
1218 default:
1219 assert(! "op unknown");
1220 istrue = 0; /* To shut up compiler */
1221 }
1222 result = istrue ? Py_True : Py_False;
1223 Py_INCREF(result);
1224 return result;
1225}
1226
Tim Peters07534a62003-02-07 22:50:28 +00001227/* Raises a "can't compare" TypeError and returns NULL. */
1228static PyObject *
1229cmperror(PyObject *a, PyObject *b)
1230{
1231 PyErr_Format(PyExc_TypeError,
1232 "can't compare %s to %s",
1233 a->ob_type->tp_name, b->ob_type->tp_name);
1234 return NULL;
1235}
1236
Tim Peters2a799bf2002-12-16 20:18:38 +00001237/* ---------------------------------------------------------------------------
Tim Petersa98924a2003-05-17 05:55:19 +00001238 * Basic object allocation: tp_alloc implementatiosn. These allocate
1239 * Python objects of the right size and type, and do the Python object-
1240 * initialization bit. If there's not enough memory, they return NULL after
1241 * setting MemoryError. All data members remain uninitialized trash.
1242 *
1243 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
1244 * member is needed. This is ugly.
Tim Peters70533e22003-02-01 04:40:04 +00001245 */
Tim Peters70533e22003-02-01 04:40:04 +00001246
Tim Petersa98924a2003-05-17 05:55:19 +00001247static PyObject *
1248time_alloc(PyTypeObject *type, int aware)
1249{
1250 PyObject *self;
1251
1252 self = (PyObject *)
Tim Peters70533e22003-02-01 04:40:04 +00001253 PyObject_MALLOC(aware ?
1254 sizeof(PyDateTime_Time) :
1255 sizeof(_PyDateTime_BaseTime));
1256 if (self == NULL)
Tim Petersa98924a2003-05-17 05:55:19 +00001257 return (PyObject *)PyErr_NoMemory();
1258 PyObject_INIT(self, type);
Tim Peters70533e22003-02-01 04:40:04 +00001259 return self;
1260}
1261
Tim Petersa98924a2003-05-17 05:55:19 +00001262static PyObject *
1263datetime_alloc(PyTypeObject *type, int aware)
Tim Peters70533e22003-02-01 04:40:04 +00001264{
Tim Petersa98924a2003-05-17 05:55:19 +00001265 PyObject *self;
Tim Peters70533e22003-02-01 04:40:04 +00001266
Tim Petersa98924a2003-05-17 05:55:19 +00001267 self = (PyObject *)
Tim Peters70533e22003-02-01 04:40:04 +00001268 PyObject_MALLOC(aware ?
1269 sizeof(PyDateTime_DateTime) :
1270 sizeof(_PyDateTime_BaseDateTime));
1271 if (self == NULL)
Tim Petersa98924a2003-05-17 05:55:19 +00001272 return (PyObject *)PyErr_NoMemory();
1273 PyObject_INIT(self, type);
Tim Peters70533e22003-02-01 04:40:04 +00001274 return self;
1275}
1276
1277/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001278 * Helpers for setting object fields. These work on pointers to the
1279 * appropriate base class.
1280 */
1281
Tim Petersa9bc1682003-01-11 03:39:11 +00001282/* For date and datetime. */
Tim Peters2a799bf2002-12-16 20:18:38 +00001283static void
1284set_date_fields(PyDateTime_Date *self, int y, int m, int d)
1285{
1286 self->hashcode = -1;
1287 SET_YEAR(self, y);
1288 SET_MONTH(self, m);
1289 SET_DAY(self, d);
1290}
1291
Tim Peters2a799bf2002-12-16 20:18:38 +00001292/* ---------------------------------------------------------------------------
1293 * Create various objects, mostly without range checking.
1294 */
1295
1296/* Create a date instance with no range checking. */
1297static PyObject *
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00001298new_date_ex(int year, int month, int day, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001299{
1300 PyDateTime_Date *self;
1301
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00001302 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
Tim Peters2a799bf2002-12-16 20:18:38 +00001303 if (self != NULL)
1304 set_date_fields(self, year, month, day);
1305 return (PyObject *) self;
1306}
1307
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00001308#define new_date(year, month, day) \
Tim Petersa98924a2003-05-17 05:55:19 +00001309 new_date_ex(year, month, day, &PyDateTime_DateType)
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00001310
Tim Peters2a799bf2002-12-16 20:18:38 +00001311/* Create a datetime instance with no range checking. */
1312static PyObject *
Tim Petersa98924a2003-05-17 05:55:19 +00001313new_datetime_ex(int year, int month, int day, int hour, int minute,
1314 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001315{
1316 PyDateTime_DateTime *self;
Tim Petersa9bc1682003-01-11 03:39:11 +00001317 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001318
Tim Petersa98924a2003-05-17 05:55:19 +00001319 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
Tim Peters70533e22003-02-01 04:40:04 +00001320 if (self != NULL) {
1321 self->hastzinfo = aware;
1322 set_date_fields((PyDateTime_Date *)self, year, month, day);
1323 DATE_SET_HOUR(self, hour);
1324 DATE_SET_MINUTE(self, minute);
1325 DATE_SET_SECOND(self, second);
1326 DATE_SET_MICROSECOND(self, usecond);
1327 if (aware) {
1328 Py_INCREF(tzinfo);
1329 self->tzinfo = tzinfo;
1330 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001331 }
Tim Peters70533e22003-02-01 04:40:04 +00001332 return (PyObject *)self;
Tim Peters2a799bf2002-12-16 20:18:38 +00001333}
1334
Tim Petersa98924a2003-05-17 05:55:19 +00001335#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
1336 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
1337 &PyDateTime_DateTimeType)
1338
Tim Peters2a799bf2002-12-16 20:18:38 +00001339/* Create a time instance with no range checking. */
1340static PyObject *
Tim Petersa98924a2003-05-17 05:55:19 +00001341new_time_ex(int hour, int minute, int second, int usecond,
1342 PyObject *tzinfo, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001343{
1344 PyDateTime_Time *self;
Tim Peters37f39822003-01-10 03:49:02 +00001345 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001346
Tim Petersa98924a2003-05-17 05:55:19 +00001347 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
Tim Peters70533e22003-02-01 04:40:04 +00001348 if (self != NULL) {
1349 self->hastzinfo = aware;
1350 self->hashcode = -1;
1351 TIME_SET_HOUR(self, hour);
1352 TIME_SET_MINUTE(self, minute);
1353 TIME_SET_SECOND(self, second);
1354 TIME_SET_MICROSECOND(self, usecond);
1355 if (aware) {
1356 Py_INCREF(tzinfo);
1357 self->tzinfo = tzinfo;
1358 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001359 }
Tim Peters70533e22003-02-01 04:40:04 +00001360 return (PyObject *)self;
Tim Peters2a799bf2002-12-16 20:18:38 +00001361}
1362
Tim Petersa98924a2003-05-17 05:55:19 +00001363#define new_time(hh, mm, ss, us, tzinfo) \
1364 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
1365
Tim Peters2a799bf2002-12-16 20:18:38 +00001366/* Create a timedelta instance. Normalize the members iff normalize is
1367 * true. Passing false is a speed optimization, if you know for sure
1368 * that seconds and microseconds are already in their proper ranges. In any
1369 * case, raises OverflowError and returns NULL if the normalized days is out
1370 * of range).
1371 */
1372static PyObject *
1373new_delta(int days, int seconds, int microseconds, int normalize)
1374{
1375 PyDateTime_Delta *self;
1376
1377 if (normalize)
1378 normalize_d_s_us(&days, &seconds, &microseconds);
1379 assert(0 <= seconds && seconds < 24*3600);
1380 assert(0 <= microseconds && microseconds < 1000000);
1381
1382 if (check_delta_day_range(days) < 0)
1383 return NULL;
1384
1385 self = PyObject_New(PyDateTime_Delta, &PyDateTime_DeltaType);
1386 if (self != NULL) {
1387 self->hashcode = -1;
1388 SET_TD_DAYS(self, days);
1389 SET_TD_SECONDS(self, seconds);
1390 SET_TD_MICROSECONDS(self, microseconds);
1391 }
1392 return (PyObject *) self;
1393}
1394
1395
1396/* ---------------------------------------------------------------------------
1397 * Cached Python objects; these are set by the module init function.
1398 */
1399
1400/* Conversion factors. */
1401static PyObject *us_per_us = NULL; /* 1 */
1402static PyObject *us_per_ms = NULL; /* 1000 */
1403static PyObject *us_per_second = NULL; /* 1000000 */
1404static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1405static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1406static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1407static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1408static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1409
Tim Peters2a799bf2002-12-16 20:18:38 +00001410/* ---------------------------------------------------------------------------
1411 * Class implementations.
1412 */
1413
1414/*
1415 * PyDateTime_Delta implementation.
1416 */
1417
1418/* Convert a timedelta to a number of us,
1419 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1420 * as a Python int or long.
1421 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1422 * due to ubiquitous overflow possibilities.
1423 */
1424static PyObject *
1425delta_to_microseconds(PyDateTime_Delta *self)
1426{
1427 PyObject *x1 = NULL;
1428 PyObject *x2 = NULL;
1429 PyObject *x3 = NULL;
1430 PyObject *result = NULL;
1431
1432 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1433 if (x1 == NULL)
1434 goto Done;
1435 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1436 if (x2 == NULL)
1437 goto Done;
1438 Py_DECREF(x1);
1439 x1 = NULL;
1440
1441 /* x2 has days in seconds */
1442 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1443 if (x1 == NULL)
1444 goto Done;
1445 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1446 if (x3 == NULL)
1447 goto Done;
1448 Py_DECREF(x1);
1449 Py_DECREF(x2);
1450 x1 = x2 = NULL;
1451
1452 /* x3 has days+seconds in seconds */
1453 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1454 if (x1 == NULL)
1455 goto Done;
1456 Py_DECREF(x3);
1457 x3 = NULL;
1458
1459 /* x1 has days+seconds in us */
1460 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1461 if (x2 == NULL)
1462 goto Done;
1463 result = PyNumber_Add(x1, x2);
1464
1465Done:
1466 Py_XDECREF(x1);
1467 Py_XDECREF(x2);
1468 Py_XDECREF(x3);
1469 return result;
1470}
1471
1472/* Convert a number of us (as a Python int or long) to a timedelta.
1473 */
1474static PyObject *
1475microseconds_to_delta(PyObject *pyus)
1476{
1477 int us;
1478 int s;
1479 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001480 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001481
1482 PyObject *tuple = NULL;
1483 PyObject *num = NULL;
1484 PyObject *result = NULL;
1485
1486 tuple = PyNumber_Divmod(pyus, us_per_second);
1487 if (tuple == NULL)
1488 goto Done;
1489
1490 num = PyTuple_GetItem(tuple, 1); /* us */
1491 if (num == NULL)
1492 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001493 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001494 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001495 if (temp == -1 && PyErr_Occurred())
1496 goto Done;
1497 assert(0 <= temp && temp < 1000000);
1498 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001499 if (us < 0) {
1500 /* The divisor was positive, so this must be an error. */
1501 assert(PyErr_Occurred());
1502 goto Done;
1503 }
1504
1505 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1506 if (num == NULL)
1507 goto Done;
1508 Py_INCREF(num);
1509 Py_DECREF(tuple);
1510
1511 tuple = PyNumber_Divmod(num, seconds_per_day);
1512 if (tuple == NULL)
1513 goto Done;
1514 Py_DECREF(num);
1515
1516 num = PyTuple_GetItem(tuple, 1); /* seconds */
1517 if (num == NULL)
1518 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001519 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001520 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001521 if (temp == -1 && PyErr_Occurred())
1522 goto Done;
1523 assert(0 <= temp && temp < 24*3600);
1524 s = (int)temp;
1525
Tim Peters2a799bf2002-12-16 20:18:38 +00001526 if (s < 0) {
1527 /* The divisor was positive, so this must be an error. */
1528 assert(PyErr_Occurred());
1529 goto Done;
1530 }
1531
1532 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1533 if (num == NULL)
1534 goto Done;
1535 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001536 temp = PyLong_AsLong(num);
1537 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001538 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001539 d = (int)temp;
1540 if ((long)d != temp) {
1541 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1542 "large to fit in a C int");
1543 goto Done;
1544 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001545 result = new_delta(d, s, us, 0);
1546
1547Done:
1548 Py_XDECREF(tuple);
1549 Py_XDECREF(num);
1550 return result;
1551}
1552
1553static PyObject *
1554multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1555{
1556 PyObject *pyus_in;
1557 PyObject *pyus_out;
1558 PyObject *result;
1559
1560 pyus_in = delta_to_microseconds(delta);
1561 if (pyus_in == NULL)
1562 return NULL;
1563
1564 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1565 Py_DECREF(pyus_in);
1566 if (pyus_out == NULL)
1567 return NULL;
1568
1569 result = microseconds_to_delta(pyus_out);
1570 Py_DECREF(pyus_out);
1571 return result;
1572}
1573
1574static PyObject *
1575divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1576{
1577 PyObject *pyus_in;
1578 PyObject *pyus_out;
1579 PyObject *result;
1580
1581 pyus_in = delta_to_microseconds(delta);
1582 if (pyus_in == NULL)
1583 return NULL;
1584
1585 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1586 Py_DECREF(pyus_in);
1587 if (pyus_out == NULL)
1588 return NULL;
1589
1590 result = microseconds_to_delta(pyus_out);
1591 Py_DECREF(pyus_out);
1592 return result;
1593}
1594
1595static PyObject *
1596delta_add(PyObject *left, PyObject *right)
1597{
1598 PyObject *result = Py_NotImplemented;
1599
1600 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1601 /* delta + delta */
1602 /* The C-level additions can't overflow because of the
1603 * invariant bounds.
1604 */
1605 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1606 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1607 int microseconds = GET_TD_MICROSECONDS(left) +
1608 GET_TD_MICROSECONDS(right);
1609 result = new_delta(days, seconds, microseconds, 1);
1610 }
1611
1612 if (result == Py_NotImplemented)
1613 Py_INCREF(result);
1614 return result;
1615}
1616
1617static PyObject *
1618delta_negative(PyDateTime_Delta *self)
1619{
1620 return new_delta(-GET_TD_DAYS(self),
1621 -GET_TD_SECONDS(self),
1622 -GET_TD_MICROSECONDS(self),
1623 1);
1624}
1625
1626static PyObject *
1627delta_positive(PyDateTime_Delta *self)
1628{
1629 /* Could optimize this (by returning self) if this isn't a
1630 * subclass -- but who uses unary + ? Approximately nobody.
1631 */
1632 return new_delta(GET_TD_DAYS(self),
1633 GET_TD_SECONDS(self),
1634 GET_TD_MICROSECONDS(self),
1635 0);
1636}
1637
1638static PyObject *
1639delta_abs(PyDateTime_Delta *self)
1640{
1641 PyObject *result;
1642
1643 assert(GET_TD_MICROSECONDS(self) >= 0);
1644 assert(GET_TD_SECONDS(self) >= 0);
1645
1646 if (GET_TD_DAYS(self) < 0)
1647 result = delta_negative(self);
1648 else
1649 result = delta_positive(self);
1650
1651 return result;
1652}
1653
1654static PyObject *
1655delta_subtract(PyObject *left, PyObject *right)
1656{
1657 PyObject *result = Py_NotImplemented;
1658
1659 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1660 /* delta - delta */
1661 PyObject *minus_right = PyNumber_Negative(right);
1662 if (minus_right) {
1663 result = delta_add(left, minus_right);
1664 Py_DECREF(minus_right);
1665 }
1666 else
1667 result = NULL;
1668 }
1669
1670 if (result == Py_NotImplemented)
1671 Py_INCREF(result);
1672 return result;
1673}
1674
1675/* This is more natural as a tp_compare, but doesn't work then: for whatever
1676 * reason, Python's try_3way_compare ignores tp_compare unless
1677 * PyInstance_Check returns true, but these aren't old-style classes.
1678 */
1679static PyObject *
1680delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1681{
Tim Peters07534a62003-02-07 22:50:28 +00001682 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001683
Tim Petersaa7d8492003-02-08 03:28:59 +00001684 if (PyDelta_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00001685 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1686 if (diff == 0) {
1687 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1688 if (diff == 0)
1689 diff = GET_TD_MICROSECONDS(self) -
1690 GET_TD_MICROSECONDS(other);
1691 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001692 }
Tim Peters07534a62003-02-07 22:50:28 +00001693 else if (op == Py_EQ || op == Py_NE)
1694 diff = 1; /* any non-zero value will do */
1695
1696 else /* stop this from falling back to address comparison */
1697 return cmperror((PyObject *)self, other);
1698
Tim Peters2a799bf2002-12-16 20:18:38 +00001699 return diff_to_bool(diff, op);
1700}
1701
1702static PyObject *delta_getstate(PyDateTime_Delta *self);
1703
1704static long
1705delta_hash(PyDateTime_Delta *self)
1706{
1707 if (self->hashcode == -1) {
1708 PyObject *temp = delta_getstate(self);
1709 if (temp != NULL) {
1710 self->hashcode = PyObject_Hash(temp);
1711 Py_DECREF(temp);
1712 }
1713 }
1714 return self->hashcode;
1715}
1716
1717static PyObject *
1718delta_multiply(PyObject *left, PyObject *right)
1719{
1720 PyObject *result = Py_NotImplemented;
1721
1722 if (PyDelta_Check(left)) {
1723 /* delta * ??? */
1724 if (PyInt_Check(right) || PyLong_Check(right))
1725 result = multiply_int_timedelta(right,
1726 (PyDateTime_Delta *) left);
1727 }
1728 else if (PyInt_Check(left) || PyLong_Check(left))
1729 result = multiply_int_timedelta(left,
1730 (PyDateTime_Delta *) right);
1731
1732 if (result == Py_NotImplemented)
1733 Py_INCREF(result);
1734 return result;
1735}
1736
1737static PyObject *
1738delta_divide(PyObject *left, PyObject *right)
1739{
1740 PyObject *result = Py_NotImplemented;
1741
1742 if (PyDelta_Check(left)) {
1743 /* delta * ??? */
1744 if (PyInt_Check(right) || PyLong_Check(right))
1745 result = divide_timedelta_int(
1746 (PyDateTime_Delta *)left,
1747 right);
1748 }
1749
1750 if (result == Py_NotImplemented)
1751 Py_INCREF(result);
1752 return result;
1753}
1754
1755/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1756 * timedelta constructor. sofar is the # of microseconds accounted for
1757 * so far, and there are factor microseconds per current unit, the number
1758 * of which is given by num. num * factor is added to sofar in a
1759 * numerically careful way, and that's the result. Any fractional
1760 * microseconds left over (this can happen if num is a float type) are
1761 * added into *leftover.
1762 * Note that there are many ways this can give an error (NULL) return.
1763 */
1764static PyObject *
1765accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1766 double *leftover)
1767{
1768 PyObject *prod;
1769 PyObject *sum;
1770
1771 assert(num != NULL);
1772
1773 if (PyInt_Check(num) || PyLong_Check(num)) {
1774 prod = PyNumber_Multiply(num, factor);
1775 if (prod == NULL)
1776 return NULL;
1777 sum = PyNumber_Add(sofar, prod);
1778 Py_DECREF(prod);
1779 return sum;
1780 }
1781
1782 if (PyFloat_Check(num)) {
1783 double dnum;
1784 double fracpart;
1785 double intpart;
1786 PyObject *x;
1787 PyObject *y;
1788
1789 /* The Plan: decompose num into an integer part and a
1790 * fractional part, num = intpart + fracpart.
1791 * Then num * factor ==
1792 * intpart * factor + fracpart * factor
1793 * and the LHS can be computed exactly in long arithmetic.
1794 * The RHS is again broken into an int part and frac part.
1795 * and the frac part is added into *leftover.
1796 */
1797 dnum = PyFloat_AsDouble(num);
1798 if (dnum == -1.0 && PyErr_Occurred())
1799 return NULL;
1800 fracpart = modf(dnum, &intpart);
1801 x = PyLong_FromDouble(intpart);
1802 if (x == NULL)
1803 return NULL;
1804
1805 prod = PyNumber_Multiply(x, factor);
1806 Py_DECREF(x);
1807 if (prod == NULL)
1808 return NULL;
1809
1810 sum = PyNumber_Add(sofar, prod);
1811 Py_DECREF(prod);
1812 if (sum == NULL)
1813 return NULL;
1814
1815 if (fracpart == 0.0)
1816 return sum;
1817 /* So far we've lost no information. Dealing with the
1818 * fractional part requires float arithmetic, and may
1819 * lose a little info.
1820 */
1821 assert(PyInt_Check(factor) || PyLong_Check(factor));
1822 if (PyInt_Check(factor))
1823 dnum = (double)PyInt_AsLong(factor);
1824 else
1825 dnum = PyLong_AsDouble(factor);
1826
1827 dnum *= fracpart;
1828 fracpart = modf(dnum, &intpart);
1829 x = PyLong_FromDouble(intpart);
1830 if (x == NULL) {
1831 Py_DECREF(sum);
1832 return NULL;
1833 }
1834
1835 y = PyNumber_Add(sum, x);
1836 Py_DECREF(sum);
1837 Py_DECREF(x);
1838 *leftover += fracpart;
1839 return y;
1840 }
1841
1842 PyErr_Format(PyExc_TypeError,
1843 "unsupported type for timedelta %s component: %s",
1844 tag, num->ob_type->tp_name);
1845 return NULL;
1846}
1847
1848static PyObject *
1849delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1850{
1851 PyObject *self = NULL;
1852
1853 /* Argument objects. */
1854 PyObject *day = NULL;
1855 PyObject *second = NULL;
1856 PyObject *us = NULL;
1857 PyObject *ms = NULL;
1858 PyObject *minute = NULL;
1859 PyObject *hour = NULL;
1860 PyObject *week = NULL;
1861
1862 PyObject *x = NULL; /* running sum of microseconds */
1863 PyObject *y = NULL; /* temp sum of microseconds */
1864 double leftover_us = 0.0;
1865
1866 static char *keywords[] = {
1867 "days", "seconds", "microseconds", "milliseconds",
1868 "minutes", "hours", "weeks", NULL
1869 };
1870
1871 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1872 keywords,
1873 &day, &second, &us,
1874 &ms, &minute, &hour, &week) == 0)
1875 goto Done;
1876
1877 x = PyInt_FromLong(0);
1878 if (x == NULL)
1879 goto Done;
1880
1881#define CLEANUP \
1882 Py_DECREF(x); \
1883 x = y; \
1884 if (x == NULL) \
1885 goto Done
1886
1887 if (us) {
1888 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1889 CLEANUP;
1890 }
1891 if (ms) {
1892 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1893 CLEANUP;
1894 }
1895 if (second) {
1896 y = accum("seconds", x, second, us_per_second, &leftover_us);
1897 CLEANUP;
1898 }
1899 if (minute) {
1900 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1901 CLEANUP;
1902 }
1903 if (hour) {
1904 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1905 CLEANUP;
1906 }
1907 if (day) {
1908 y = accum("days", x, day, us_per_day, &leftover_us);
1909 CLEANUP;
1910 }
1911 if (week) {
1912 y = accum("weeks", x, week, us_per_week, &leftover_us);
1913 CLEANUP;
1914 }
1915 if (leftover_us) {
1916 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001917 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001918 if (temp == NULL) {
1919 Py_DECREF(x);
1920 goto Done;
1921 }
1922 y = PyNumber_Add(x, temp);
1923 Py_DECREF(temp);
1924 CLEANUP;
1925 }
1926
1927 self = microseconds_to_delta(x);
1928 Py_DECREF(x);
1929Done:
1930 return self;
1931
1932#undef CLEANUP
1933}
1934
1935static int
1936delta_nonzero(PyDateTime_Delta *self)
1937{
1938 return (GET_TD_DAYS(self) != 0
1939 || GET_TD_SECONDS(self) != 0
1940 || GET_TD_MICROSECONDS(self) != 0);
1941}
1942
1943static PyObject *
1944delta_repr(PyDateTime_Delta *self)
1945{
1946 if (GET_TD_MICROSECONDS(self) != 0)
1947 return PyString_FromFormat("%s(%d, %d, %d)",
1948 self->ob_type->tp_name,
1949 GET_TD_DAYS(self),
1950 GET_TD_SECONDS(self),
1951 GET_TD_MICROSECONDS(self));
1952 if (GET_TD_SECONDS(self) != 0)
1953 return PyString_FromFormat("%s(%d, %d)",
1954 self->ob_type->tp_name,
1955 GET_TD_DAYS(self),
1956 GET_TD_SECONDS(self));
1957
1958 return PyString_FromFormat("%s(%d)",
1959 self->ob_type->tp_name,
1960 GET_TD_DAYS(self));
1961}
1962
1963static PyObject *
1964delta_str(PyDateTime_Delta *self)
1965{
1966 int days = GET_TD_DAYS(self);
1967 int seconds = GET_TD_SECONDS(self);
1968 int us = GET_TD_MICROSECONDS(self);
1969 int hours;
1970 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001971 char buf[100];
1972 char *pbuf = buf;
1973 size_t buflen = sizeof(buf);
1974 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001975
1976 minutes = divmod(seconds, 60, &seconds);
1977 hours = divmod(minutes, 60, &minutes);
1978
1979 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00001980 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
1981 (days == 1 || days == -1) ? "" : "s");
1982 if (n < 0 || (size_t)n >= buflen)
1983 goto Fail;
1984 pbuf += n;
1985 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001986 }
1987
Tim Petersba873472002-12-18 20:19:21 +00001988 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
1989 hours, minutes, seconds);
1990 if (n < 0 || (size_t)n >= buflen)
1991 goto Fail;
1992 pbuf += n;
1993 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001994
1995 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00001996 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
1997 if (n < 0 || (size_t)n >= buflen)
1998 goto Fail;
1999 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002000 }
2001
Tim Petersba873472002-12-18 20:19:21 +00002002 return PyString_FromStringAndSize(buf, pbuf - buf);
2003
2004 Fail:
2005 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2006 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002007}
2008
Tim Peters371935f2003-02-01 01:52:50 +00002009/* Pickle support, a simple use of __reduce__. */
2010
Tim Petersb57f8f02003-02-01 02:54:15 +00002011/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002012static PyObject *
2013delta_getstate(PyDateTime_Delta *self)
2014{
2015 return Py_BuildValue("iii", GET_TD_DAYS(self),
2016 GET_TD_SECONDS(self),
2017 GET_TD_MICROSECONDS(self));
2018}
2019
Tim Peters2a799bf2002-12-16 20:18:38 +00002020static PyObject *
2021delta_reduce(PyDateTime_Delta* self)
2022{
Tim Peters8a60c222003-02-01 01:47:29 +00002023 return Py_BuildValue("ON", self->ob_type, delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002024}
2025
2026#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2027
2028static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002029
Neal Norwitzdfb80862002-12-19 02:30:56 +00002030 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002031 PyDoc_STR("Number of days.")},
2032
Neal Norwitzdfb80862002-12-19 02:30:56 +00002033 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002034 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2035
Neal Norwitzdfb80862002-12-19 02:30:56 +00002036 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002037 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2038 {NULL}
2039};
2040
2041static PyMethodDef delta_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002042 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2043 PyDoc_STR("__reduce__() -> (cls, state)")},
2044
Tim Peters2a799bf2002-12-16 20:18:38 +00002045 {NULL, NULL},
2046};
2047
2048static char delta_doc[] =
2049PyDoc_STR("Difference between two datetime values.");
2050
2051static PyNumberMethods delta_as_number = {
2052 delta_add, /* nb_add */
2053 delta_subtract, /* nb_subtract */
2054 delta_multiply, /* nb_multiply */
2055 delta_divide, /* nb_divide */
2056 0, /* nb_remainder */
2057 0, /* nb_divmod */
2058 0, /* nb_power */
2059 (unaryfunc)delta_negative, /* nb_negative */
2060 (unaryfunc)delta_positive, /* nb_positive */
2061 (unaryfunc)delta_abs, /* nb_absolute */
2062 (inquiry)delta_nonzero, /* nb_nonzero */
2063 0, /*nb_invert*/
2064 0, /*nb_lshift*/
2065 0, /*nb_rshift*/
2066 0, /*nb_and*/
2067 0, /*nb_xor*/
2068 0, /*nb_or*/
2069 0, /*nb_coerce*/
2070 0, /*nb_int*/
2071 0, /*nb_long*/
2072 0, /*nb_float*/
2073 0, /*nb_oct*/
2074 0, /*nb_hex*/
2075 0, /*nb_inplace_add*/
2076 0, /*nb_inplace_subtract*/
2077 0, /*nb_inplace_multiply*/
2078 0, /*nb_inplace_divide*/
2079 0, /*nb_inplace_remainder*/
2080 0, /*nb_inplace_power*/
2081 0, /*nb_inplace_lshift*/
2082 0, /*nb_inplace_rshift*/
2083 0, /*nb_inplace_and*/
2084 0, /*nb_inplace_xor*/
2085 0, /*nb_inplace_or*/
2086 delta_divide, /* nb_floor_divide */
2087 0, /* nb_true_divide */
2088 0, /* nb_inplace_floor_divide */
2089 0, /* nb_inplace_true_divide */
2090};
2091
2092static PyTypeObject PyDateTime_DeltaType = {
2093 PyObject_HEAD_INIT(NULL)
2094 0, /* ob_size */
2095 "datetime.timedelta", /* tp_name */
2096 sizeof(PyDateTime_Delta), /* tp_basicsize */
2097 0, /* tp_itemsize */
2098 0, /* tp_dealloc */
2099 0, /* tp_print */
2100 0, /* tp_getattr */
2101 0, /* tp_setattr */
2102 0, /* tp_compare */
2103 (reprfunc)delta_repr, /* tp_repr */
2104 &delta_as_number, /* tp_as_number */
2105 0, /* tp_as_sequence */
2106 0, /* tp_as_mapping */
2107 (hashfunc)delta_hash, /* tp_hash */
2108 0, /* tp_call */
2109 (reprfunc)delta_str, /* tp_str */
2110 PyObject_GenericGetAttr, /* tp_getattro */
2111 0, /* tp_setattro */
2112 0, /* tp_as_buffer */
2113 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
2114 delta_doc, /* tp_doc */
2115 0, /* tp_traverse */
2116 0, /* tp_clear */
2117 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2118 0, /* tp_weaklistoffset */
2119 0, /* tp_iter */
2120 0, /* tp_iternext */
2121 delta_methods, /* tp_methods */
2122 delta_members, /* tp_members */
2123 0, /* tp_getset */
2124 0, /* tp_base */
2125 0, /* tp_dict */
2126 0, /* tp_descr_get */
2127 0, /* tp_descr_set */
2128 0, /* tp_dictoffset */
2129 0, /* tp_init */
2130 0, /* tp_alloc */
2131 delta_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002132 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002133};
2134
2135/*
2136 * PyDateTime_Date implementation.
2137 */
2138
2139/* Accessor properties. */
2140
2141static PyObject *
2142date_year(PyDateTime_Date *self, void *unused)
2143{
2144 return PyInt_FromLong(GET_YEAR(self));
2145}
2146
2147static PyObject *
2148date_month(PyDateTime_Date *self, void *unused)
2149{
2150 return PyInt_FromLong(GET_MONTH(self));
2151}
2152
2153static PyObject *
2154date_day(PyDateTime_Date *self, void *unused)
2155{
2156 return PyInt_FromLong(GET_DAY(self));
2157}
2158
2159static PyGetSetDef date_getset[] = {
2160 {"year", (getter)date_year},
2161 {"month", (getter)date_month},
2162 {"day", (getter)date_day},
2163 {NULL}
2164};
2165
2166/* Constructors. */
2167
Tim Peters12bf3392002-12-24 05:41:27 +00002168static char *date_kws[] = {"year", "month", "day", NULL};
2169
Tim Peters2a799bf2002-12-16 20:18:38 +00002170static PyObject *
2171date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2172{
2173 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002174 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002175 int year;
2176 int month;
2177 int day;
2178
Guido van Rossum177e41a2003-01-30 22:06:23 +00002179 /* Check for invocation from pickle with __getstate__ state */
2180 if (PyTuple_GET_SIZE(args) == 1 &&
Tim Peters70533e22003-02-01 04:40:04 +00002181 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2182 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00002183 {
Tim Peters70533e22003-02-01 04:40:04 +00002184 PyDateTime_Date *me;
2185
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002186 me = PyObject_New(PyDateTime_Date, type);
Tim Peters70533e22003-02-01 04:40:04 +00002187 if (me != NULL) {
2188 char *pdata = PyString_AS_STRING(state);
2189 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2190 me->hashcode = -1;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002191 }
Tim Peters70533e22003-02-01 04:40:04 +00002192 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002193 }
2194
Tim Peters12bf3392002-12-24 05:41:27 +00002195 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002196 &year, &month, &day)) {
2197 if (check_date_args(year, month, day) < 0)
2198 return NULL;
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002199 self = new_date_ex(year, month, day, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00002200 }
2201 return self;
2202}
2203
2204/* Return new date from localtime(t). */
2205static PyObject *
2206date_local_from_time_t(PyObject *cls, time_t t)
2207{
2208 struct tm *tm;
2209 PyObject *result = NULL;
2210
2211 tm = localtime(&t);
2212 if (tm)
2213 result = PyObject_CallFunction(cls, "iii",
2214 tm->tm_year + 1900,
2215 tm->tm_mon + 1,
2216 tm->tm_mday);
2217 else
2218 PyErr_SetString(PyExc_ValueError,
2219 "timestamp out of range for "
2220 "platform localtime() function");
2221 return result;
2222}
2223
2224/* Return new date from current time.
2225 * We say this is equivalent to fromtimestamp(time.time()), and the
2226 * only way to be sure of that is to *call* time.time(). That's not
2227 * generally the same as calling C's time.
2228 */
2229static PyObject *
2230date_today(PyObject *cls, PyObject *dummy)
2231{
2232 PyObject *time;
2233 PyObject *result;
2234
2235 time = time_time();
2236 if (time == NULL)
2237 return NULL;
2238
2239 /* Note well: today() is a class method, so this may not call
2240 * date.fromtimestamp. For example, it may call
2241 * datetime.fromtimestamp. That's why we need all the accuracy
2242 * time.time() delivers; if someone were gonzo about optimization,
2243 * date.today() could get away with plain C time().
2244 */
2245 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2246 Py_DECREF(time);
2247 return result;
2248}
2249
2250/* Return new date from given timestamp (Python timestamp -- a double). */
2251static PyObject *
2252date_fromtimestamp(PyObject *cls, PyObject *args)
2253{
2254 double timestamp;
2255 PyObject *result = NULL;
2256
2257 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2258 result = date_local_from_time_t(cls, (time_t)timestamp);
2259 return result;
2260}
2261
2262/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2263 * the ordinal is out of range.
2264 */
2265static PyObject *
2266date_fromordinal(PyObject *cls, PyObject *args)
2267{
2268 PyObject *result = NULL;
2269 int ordinal;
2270
2271 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2272 int year;
2273 int month;
2274 int day;
2275
2276 if (ordinal < 1)
2277 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2278 ">= 1");
2279 else {
2280 ord_to_ymd(ordinal, &year, &month, &day);
2281 result = PyObject_CallFunction(cls, "iii",
2282 year, month, day);
2283 }
2284 }
2285 return result;
2286}
2287
2288/*
2289 * Date arithmetic.
2290 */
2291
2292/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2293 * instead.
2294 */
2295static PyObject *
2296add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2297{
2298 PyObject *result = NULL;
2299 int year = GET_YEAR(date);
2300 int month = GET_MONTH(date);
2301 int deltadays = GET_TD_DAYS(delta);
2302 /* C-level overflow is impossible because |deltadays| < 1e9. */
2303 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2304
2305 if (normalize_date(&year, &month, &day) >= 0)
2306 result = new_date(year, month, day);
2307 return result;
2308}
2309
2310static PyObject *
2311date_add(PyObject *left, PyObject *right)
2312{
2313 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2314 Py_INCREF(Py_NotImplemented);
2315 return Py_NotImplemented;
2316 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002317 if (PyDate_Check(left)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002318 /* date + ??? */
2319 if (PyDelta_Check(right))
2320 /* date + delta */
2321 return add_date_timedelta((PyDateTime_Date *) left,
2322 (PyDateTime_Delta *) right,
2323 0);
2324 }
2325 else {
2326 /* ??? + date
2327 * 'right' must be one of us, or we wouldn't have been called
2328 */
2329 if (PyDelta_Check(left))
2330 /* delta + date */
2331 return add_date_timedelta((PyDateTime_Date *) right,
2332 (PyDateTime_Delta *) left,
2333 0);
2334 }
2335 Py_INCREF(Py_NotImplemented);
2336 return Py_NotImplemented;
2337}
2338
2339static PyObject *
2340date_subtract(PyObject *left, PyObject *right)
2341{
2342 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2343 Py_INCREF(Py_NotImplemented);
2344 return Py_NotImplemented;
2345 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002346 if (PyDate_Check(left)) {
2347 if (PyDate_Check(right)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002348 /* date - date */
2349 int left_ord = ymd_to_ord(GET_YEAR(left),
2350 GET_MONTH(left),
2351 GET_DAY(left));
2352 int right_ord = ymd_to_ord(GET_YEAR(right),
2353 GET_MONTH(right),
2354 GET_DAY(right));
2355 return new_delta(left_ord - right_ord, 0, 0, 0);
2356 }
2357 if (PyDelta_Check(right)) {
2358 /* date - delta */
2359 return add_date_timedelta((PyDateTime_Date *) left,
2360 (PyDateTime_Delta *) right,
2361 1);
2362 }
2363 }
2364 Py_INCREF(Py_NotImplemented);
2365 return Py_NotImplemented;
2366}
2367
2368
2369/* Various ways to turn a date into a string. */
2370
2371static PyObject *
2372date_repr(PyDateTime_Date *self)
2373{
2374 char buffer[1028];
2375 char *typename;
2376
2377 typename = self->ob_type->tp_name;
2378 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2379 typename,
2380 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2381
2382 return PyString_FromString(buffer);
2383}
2384
2385static PyObject *
2386date_isoformat(PyDateTime_Date *self)
2387{
2388 char buffer[128];
2389
2390 isoformat_date(self, buffer, sizeof(buffer));
2391 return PyString_FromString(buffer);
2392}
2393
Tim Peterse2df5ff2003-05-02 18:39:55 +00002394/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002395static PyObject *
2396date_str(PyDateTime_Date *self)
2397{
2398 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2399}
2400
2401
2402static PyObject *
2403date_ctime(PyDateTime_Date *self)
2404{
2405 return format_ctime(self, 0, 0, 0);
2406}
2407
2408static PyObject *
2409date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2410{
2411 /* This method can be inherited, and needs to call the
2412 * timetuple() method appropriate to self's class.
2413 */
2414 PyObject *result;
2415 PyObject *format;
2416 PyObject *tuple;
2417 static char *keywords[] = {"format", NULL};
2418
2419 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2420 &PyString_Type, &format))
2421 return NULL;
2422
2423 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2424 if (tuple == NULL)
2425 return NULL;
Tim Petersbad8ff02002-12-30 20:52:32 +00002426 result = wrap_strftime((PyObject *)self, format, tuple,
2427 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002428 Py_DECREF(tuple);
2429 return result;
2430}
2431
2432/* ISO methods. */
2433
2434static PyObject *
2435date_isoweekday(PyDateTime_Date *self)
2436{
2437 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2438
2439 return PyInt_FromLong(dow + 1);
2440}
2441
2442static PyObject *
2443date_isocalendar(PyDateTime_Date *self)
2444{
2445 int year = GET_YEAR(self);
2446 int week1_monday = iso_week1_monday(year);
2447 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2448 int week;
2449 int day;
2450
2451 week = divmod(today - week1_monday, 7, &day);
2452 if (week < 0) {
2453 --year;
2454 week1_monday = iso_week1_monday(year);
2455 week = divmod(today - week1_monday, 7, &day);
2456 }
2457 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2458 ++year;
2459 week = 0;
2460 }
2461 return Py_BuildValue("iii", year, week + 1, day + 1);
2462}
2463
2464/* Miscellaneous methods. */
2465
2466/* This is more natural as a tp_compare, but doesn't work then: for whatever
2467 * reason, Python's try_3way_compare ignores tp_compare unless
2468 * PyInstance_Check returns true, but these aren't old-style classes.
2469 */
2470static PyObject *
2471date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2472{
Tim Peters07534a62003-02-07 22:50:28 +00002473 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002474
Tim Peters07534a62003-02-07 22:50:28 +00002475 if (PyDate_Check(other))
2476 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2477 _PyDateTime_DATE_DATASIZE);
2478
2479 else if (PyObject_HasAttrString(other, "timetuple")) {
2480 /* A hook for other kinds of date objects. */
2481 Py_INCREF(Py_NotImplemented);
2482 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002483 }
Tim Peters07534a62003-02-07 22:50:28 +00002484 else if (op == Py_EQ || op == Py_NE)
2485 diff = 1; /* any non-zero value will do */
2486
2487 else /* stop this from falling back to address comparison */
2488 return cmperror((PyObject *)self, other);
2489
Tim Peters2a799bf2002-12-16 20:18:38 +00002490 return diff_to_bool(diff, op);
2491}
2492
2493static PyObject *
2494date_timetuple(PyDateTime_Date *self)
2495{
2496 return build_struct_time(GET_YEAR(self),
2497 GET_MONTH(self),
2498 GET_DAY(self),
2499 0, 0, 0, -1);
2500}
2501
Tim Peters12bf3392002-12-24 05:41:27 +00002502static PyObject *
2503date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2504{
2505 PyObject *clone;
2506 PyObject *tuple;
2507 int year = GET_YEAR(self);
2508 int month = GET_MONTH(self);
2509 int day = GET_DAY(self);
2510
2511 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2512 &year, &month, &day))
2513 return NULL;
2514 tuple = Py_BuildValue("iii", year, month, day);
2515 if (tuple == NULL)
2516 return NULL;
2517 clone = date_new(self->ob_type, tuple, NULL);
2518 Py_DECREF(tuple);
2519 return clone;
2520}
2521
Tim Peters2a799bf2002-12-16 20:18:38 +00002522static PyObject *date_getstate(PyDateTime_Date *self);
2523
2524static long
2525date_hash(PyDateTime_Date *self)
2526{
2527 if (self->hashcode == -1) {
2528 PyObject *temp = date_getstate(self);
2529 if (temp != NULL) {
2530 self->hashcode = PyObject_Hash(temp);
2531 Py_DECREF(temp);
2532 }
2533 }
2534 return self->hashcode;
2535}
2536
2537static PyObject *
2538date_toordinal(PyDateTime_Date *self)
2539{
2540 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2541 GET_DAY(self)));
2542}
2543
2544static PyObject *
2545date_weekday(PyDateTime_Date *self)
2546{
2547 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2548
2549 return PyInt_FromLong(dow);
2550}
2551
Tim Peters371935f2003-02-01 01:52:50 +00002552/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002553
Tim Petersb57f8f02003-02-01 02:54:15 +00002554/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002555static PyObject *
2556date_getstate(PyDateTime_Date *self)
2557{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002558 return Py_BuildValue(
2559 "(N)",
2560 PyString_FromStringAndSize((char *)self->data,
2561 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002562}
2563
2564static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002565date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002566{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002567 return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002568}
2569
2570static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002571
Tim Peters2a799bf2002-12-16 20:18:38 +00002572 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002573
Tim Peters2a799bf2002-12-16 20:18:38 +00002574 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2575 METH_CLASS,
2576 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2577 "time.time()).")},
2578
2579 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2580 METH_CLASS,
2581 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2582 "ordinal.")},
2583
2584 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2585 PyDoc_STR("Current date or datetime: same as "
2586 "self.__class__.fromtimestamp(time.time()).")},
2587
2588 /* Instance methods: */
2589
2590 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2591 PyDoc_STR("Return ctime() style string.")},
2592
2593 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2594 PyDoc_STR("format -> strftime() style string.")},
2595
2596 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2597 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2598
2599 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2600 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2601 "weekday.")},
2602
2603 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2604 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2605
2606 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2607 PyDoc_STR("Return the day of the week represented by the date.\n"
2608 "Monday == 1 ... Sunday == 7")},
2609
2610 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2611 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2612 "1 is day 1.")},
2613
2614 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2615 PyDoc_STR("Return the day of the week represented by the date.\n"
2616 "Monday == 0 ... Sunday == 6")},
2617
Tim Peters12bf3392002-12-24 05:41:27 +00002618 {"replace", (PyCFunction)date_replace, METH_KEYWORDS,
2619 PyDoc_STR("Return date with new specified fields.")},
2620
Guido van Rossum177e41a2003-01-30 22:06:23 +00002621 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2622 PyDoc_STR("__reduce__() -> (cls, state)")},
2623
Tim Peters2a799bf2002-12-16 20:18:38 +00002624 {NULL, NULL}
2625};
2626
2627static char date_doc[] =
2628PyDoc_STR("Basic date type.");
2629
2630static PyNumberMethods date_as_number = {
2631 date_add, /* nb_add */
2632 date_subtract, /* nb_subtract */
2633 0, /* nb_multiply */
2634 0, /* nb_divide */
2635 0, /* nb_remainder */
2636 0, /* nb_divmod */
2637 0, /* nb_power */
2638 0, /* nb_negative */
2639 0, /* nb_positive */
2640 0, /* nb_absolute */
2641 0, /* nb_nonzero */
2642};
2643
2644static PyTypeObject PyDateTime_DateType = {
2645 PyObject_HEAD_INIT(NULL)
2646 0, /* ob_size */
2647 "datetime.date", /* tp_name */
2648 sizeof(PyDateTime_Date), /* tp_basicsize */
2649 0, /* tp_itemsize */
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002650 0, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00002651 0, /* tp_print */
2652 0, /* tp_getattr */
2653 0, /* tp_setattr */
2654 0, /* tp_compare */
2655 (reprfunc)date_repr, /* tp_repr */
2656 &date_as_number, /* tp_as_number */
2657 0, /* tp_as_sequence */
2658 0, /* tp_as_mapping */
2659 (hashfunc)date_hash, /* tp_hash */
2660 0, /* tp_call */
2661 (reprfunc)date_str, /* tp_str */
2662 PyObject_GenericGetAttr, /* tp_getattro */
2663 0, /* tp_setattro */
2664 0, /* tp_as_buffer */
2665 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2666 Py_TPFLAGS_BASETYPE, /* tp_flags */
2667 date_doc, /* tp_doc */
2668 0, /* tp_traverse */
2669 0, /* tp_clear */
2670 (richcmpfunc)date_richcompare, /* tp_richcompare */
2671 0, /* tp_weaklistoffset */
2672 0, /* tp_iter */
2673 0, /* tp_iternext */
2674 date_methods, /* tp_methods */
2675 0, /* tp_members */
2676 date_getset, /* tp_getset */
2677 0, /* tp_base */
2678 0, /* tp_dict */
2679 0, /* tp_descr_get */
2680 0, /* tp_descr_set */
2681 0, /* tp_dictoffset */
2682 0, /* tp_init */
2683 0, /* tp_alloc */
2684 date_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002685 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002686};
2687
2688/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002689 * PyDateTime_TZInfo implementation.
2690 */
2691
2692/* This is a pure abstract base class, so doesn't do anything beyond
2693 * raising NotImplemented exceptions. Real tzinfo classes need
2694 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002695 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002696 * be subclasses of this tzinfo class, which is easy and quick to check).
2697 *
2698 * Note: For reasons having to do with pickling of subclasses, we have
2699 * to allow tzinfo objects to be instantiated. This wasn't an issue
2700 * in the Python implementation (__init__() could raise NotImplementedError
2701 * there without ill effect), but doing so in the C implementation hit a
2702 * brick wall.
2703 */
2704
2705static PyObject *
2706tzinfo_nogo(const char* methodname)
2707{
2708 PyErr_Format(PyExc_NotImplementedError,
2709 "a tzinfo subclass must implement %s()",
2710 methodname);
2711 return NULL;
2712}
2713
2714/* Methods. A subclass must implement these. */
2715
Tim Peters52dcce22003-01-23 16:36:11 +00002716static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002717tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2718{
2719 return tzinfo_nogo("tzname");
2720}
2721
Tim Peters52dcce22003-01-23 16:36:11 +00002722static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002723tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2724{
2725 return tzinfo_nogo("utcoffset");
2726}
2727
Tim Peters52dcce22003-01-23 16:36:11 +00002728static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002729tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2730{
2731 return tzinfo_nogo("dst");
2732}
2733
Tim Peters52dcce22003-01-23 16:36:11 +00002734static PyObject *
2735tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2736{
2737 int y, m, d, hh, mm, ss, us;
2738
2739 PyObject *result;
2740 int off, dst;
2741 int none;
2742 int delta;
2743
2744 if (! PyDateTime_Check(dt)) {
2745 PyErr_SetString(PyExc_TypeError,
2746 "fromutc: argument must be a datetime");
2747 return NULL;
2748 }
2749 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2750 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2751 "is not self");
2752 return NULL;
2753 }
2754
2755 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2756 if (off == -1 && PyErr_Occurred())
2757 return NULL;
2758 if (none) {
2759 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2760 "utcoffset() result required");
2761 return NULL;
2762 }
2763
2764 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2765 if (dst == -1 && PyErr_Occurred())
2766 return NULL;
2767 if (none) {
2768 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2769 "dst() result required");
2770 return NULL;
2771 }
2772
2773 y = GET_YEAR(dt);
2774 m = GET_MONTH(dt);
2775 d = GET_DAY(dt);
2776 hh = DATE_GET_HOUR(dt);
2777 mm = DATE_GET_MINUTE(dt);
2778 ss = DATE_GET_SECOND(dt);
2779 us = DATE_GET_MICROSECOND(dt);
2780
2781 delta = off - dst;
2782 mm += delta;
2783 if ((mm < 0 || mm >= 60) &&
2784 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002785 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002786 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2787 if (result == NULL)
2788 return result;
2789
2790 dst = call_dst(dt->tzinfo, result, &none);
2791 if (dst == -1 && PyErr_Occurred())
2792 goto Fail;
2793 if (none)
2794 goto Inconsistent;
2795 if (dst == 0)
2796 return result;
2797
2798 mm += dst;
2799 if ((mm < 0 || mm >= 60) &&
2800 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2801 goto Fail;
2802 Py_DECREF(result);
2803 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2804 return result;
2805
2806Inconsistent:
2807 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2808 "inconsistent results; cannot convert");
2809
2810 /* fall thru to failure */
2811Fail:
2812 Py_DECREF(result);
2813 return NULL;
2814}
2815
Tim Peters2a799bf2002-12-16 20:18:38 +00002816/*
2817 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002818 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002819 */
2820
Guido van Rossum177e41a2003-01-30 22:06:23 +00002821static PyObject *
2822tzinfo_reduce(PyObject *self)
2823{
2824 PyObject *args, *state, *tmp;
2825 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002826
Guido van Rossum177e41a2003-01-30 22:06:23 +00002827 tmp = PyTuple_New(0);
2828 if (tmp == NULL)
2829 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002830
Guido van Rossum177e41a2003-01-30 22:06:23 +00002831 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2832 if (getinitargs != NULL) {
2833 args = PyObject_CallObject(getinitargs, tmp);
2834 Py_DECREF(getinitargs);
2835 if (args == NULL) {
2836 Py_DECREF(tmp);
2837 return NULL;
2838 }
2839 }
2840 else {
2841 PyErr_Clear();
2842 args = tmp;
2843 Py_INCREF(args);
2844 }
2845
2846 getstate = PyObject_GetAttrString(self, "__getstate__");
2847 if (getstate != NULL) {
2848 state = PyObject_CallObject(getstate, tmp);
2849 Py_DECREF(getstate);
2850 if (state == NULL) {
2851 Py_DECREF(args);
2852 Py_DECREF(tmp);
2853 return NULL;
2854 }
2855 }
2856 else {
2857 PyObject **dictptr;
2858 PyErr_Clear();
2859 state = Py_None;
2860 dictptr = _PyObject_GetDictPtr(self);
2861 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2862 state = *dictptr;
2863 Py_INCREF(state);
2864 }
2865
2866 Py_DECREF(tmp);
2867
2868 if (state == Py_None) {
2869 Py_DECREF(state);
2870 return Py_BuildValue("(ON)", self->ob_type, args);
2871 }
2872 else
2873 return Py_BuildValue("(ONN)", self->ob_type, args, state);
2874}
Tim Peters2a799bf2002-12-16 20:18:38 +00002875
2876static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002877
Tim Peters2a799bf2002-12-16 20:18:38 +00002878 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2879 PyDoc_STR("datetime -> string name of time zone.")},
2880
2881 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2882 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2883 "west of UTC).")},
2884
2885 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2886 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2887
Tim Peters52dcce22003-01-23 16:36:11 +00002888 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2889 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2890
Guido van Rossum177e41a2003-01-30 22:06:23 +00002891 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2892 PyDoc_STR("-> (cls, state)")},
2893
Tim Peters2a799bf2002-12-16 20:18:38 +00002894 {NULL, NULL}
2895};
2896
2897static char tzinfo_doc[] =
2898PyDoc_STR("Abstract base class for time zone info objects.");
2899
Neal Norwitzce3d34d2003-02-04 20:45:17 +00002900statichere PyTypeObject PyDateTime_TZInfoType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00002901 PyObject_HEAD_INIT(NULL)
2902 0, /* ob_size */
2903 "datetime.tzinfo", /* tp_name */
2904 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2905 0, /* tp_itemsize */
2906 0, /* tp_dealloc */
2907 0, /* tp_print */
2908 0, /* tp_getattr */
2909 0, /* tp_setattr */
2910 0, /* tp_compare */
2911 0, /* tp_repr */
2912 0, /* tp_as_number */
2913 0, /* tp_as_sequence */
2914 0, /* tp_as_mapping */
2915 0, /* tp_hash */
2916 0, /* tp_call */
2917 0, /* tp_str */
2918 PyObject_GenericGetAttr, /* tp_getattro */
2919 0, /* tp_setattro */
2920 0, /* tp_as_buffer */
2921 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2922 Py_TPFLAGS_BASETYPE, /* tp_flags */
2923 tzinfo_doc, /* tp_doc */
2924 0, /* tp_traverse */
2925 0, /* tp_clear */
2926 0, /* tp_richcompare */
2927 0, /* tp_weaklistoffset */
2928 0, /* tp_iter */
2929 0, /* tp_iternext */
2930 tzinfo_methods, /* tp_methods */
2931 0, /* tp_members */
2932 0, /* tp_getset */
2933 0, /* tp_base */
2934 0, /* tp_dict */
2935 0, /* tp_descr_get */
2936 0, /* tp_descr_set */
2937 0, /* tp_dictoffset */
2938 0, /* tp_init */
2939 0, /* tp_alloc */
2940 PyType_GenericNew, /* tp_new */
2941 0, /* tp_free */
2942};
2943
2944/*
Tim Peters37f39822003-01-10 03:49:02 +00002945 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00002946 */
2947
Tim Peters37f39822003-01-10 03:49:02 +00002948/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00002949 */
2950
2951static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002952time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00002953{
Tim Peters37f39822003-01-10 03:49:02 +00002954 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002955}
2956
Tim Peters37f39822003-01-10 03:49:02 +00002957static PyObject *
2958time_minute(PyDateTime_Time *self, void *unused)
2959{
2960 return PyInt_FromLong(TIME_GET_MINUTE(self));
2961}
2962
2963/* The name time_second conflicted with some platform header file. */
2964static PyObject *
2965py_time_second(PyDateTime_Time *self, void *unused)
2966{
2967 return PyInt_FromLong(TIME_GET_SECOND(self));
2968}
2969
2970static PyObject *
2971time_microsecond(PyDateTime_Time *self, void *unused)
2972{
2973 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
2974}
2975
2976static PyObject *
2977time_tzinfo(PyDateTime_Time *self, void *unused)
2978{
Tim Petersa032d2e2003-01-11 00:15:54 +00002979 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00002980 Py_INCREF(result);
2981 return result;
2982}
2983
2984static PyGetSetDef time_getset[] = {
2985 {"hour", (getter)time_hour},
2986 {"minute", (getter)time_minute},
2987 {"second", (getter)py_time_second},
2988 {"microsecond", (getter)time_microsecond},
2989 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00002990 {NULL}
2991};
2992
2993/*
2994 * Constructors.
2995 */
2996
Tim Peters37f39822003-01-10 03:49:02 +00002997static char *time_kws[] = {"hour", "minute", "second", "microsecond",
2998 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002999
Tim Peters2a799bf2002-12-16 20:18:38 +00003000static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003001time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003002{
3003 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003004 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003005 int hour = 0;
3006 int minute = 0;
3007 int second = 0;
3008 int usecond = 0;
3009 PyObject *tzinfo = Py_None;
3010
Guido van Rossum177e41a2003-01-30 22:06:23 +00003011 /* Check for invocation from pickle with __getstate__ state */
3012 if (PyTuple_GET_SIZE(args) >= 1 &&
3013 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00003014 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3015 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003016 {
Tim Peters70533e22003-02-01 04:40:04 +00003017 PyDateTime_Time *me;
3018 char aware;
3019
3020 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003021 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003022 if (check_tzinfo_subclass(tzinfo) < 0) {
3023 PyErr_SetString(PyExc_TypeError, "bad "
3024 "tzinfo state arg");
3025 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003026 }
3027 }
Tim Peters70533e22003-02-01 04:40:04 +00003028 aware = (char)(tzinfo != Py_None);
Tim Petersa98924a2003-05-17 05:55:19 +00003029 me = (PyDateTime_Time *) time_alloc(&PyDateTime_TimeType,
3030 aware);
Tim Peters70533e22003-02-01 04:40:04 +00003031 if (me != NULL) {
3032 char *pdata = PyString_AS_STRING(state);
3033
3034 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3035 me->hashcode = -1;
3036 me->hastzinfo = aware;
3037 if (aware) {
3038 Py_INCREF(tzinfo);
3039 me->tzinfo = tzinfo;
3040 }
3041 }
3042 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003043 }
3044
Tim Peters37f39822003-01-10 03:49:02 +00003045 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003046 &hour, &minute, &second, &usecond,
3047 &tzinfo)) {
3048 if (check_time_args(hour, minute, second, usecond) < 0)
3049 return NULL;
3050 if (check_tzinfo_subclass(tzinfo) < 0)
3051 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003052 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3053 type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003054 }
3055 return self;
3056}
3057
3058/*
3059 * Destructor.
3060 */
3061
3062static void
Tim Peters37f39822003-01-10 03:49:02 +00003063time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003064{
Tim Petersa032d2e2003-01-11 00:15:54 +00003065 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003066 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003067 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003068 self->ob_type->tp_free((PyObject *)self);
3069}
3070
3071/*
Tim Peters855fe882002-12-22 03:43:39 +00003072 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003073 */
3074
Tim Peters2a799bf2002-12-16 20:18:38 +00003075/* These are all METH_NOARGS, so don't need to check the arglist. */
3076static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003077time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003078 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003079 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003080}
3081
3082static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003083time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003084 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003085 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003086}
3087
3088static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003089time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003090 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003091 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003092}
3093
3094/*
Tim Peters37f39822003-01-10 03:49:02 +00003095 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003096 */
3097
3098static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003099time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003100{
Tim Peters37f39822003-01-10 03:49:02 +00003101 char buffer[100];
3102 char *typename = self->ob_type->tp_name;
3103 int h = TIME_GET_HOUR(self);
3104 int m = TIME_GET_MINUTE(self);
3105 int s = TIME_GET_SECOND(self);
3106 int us = TIME_GET_MICROSECOND(self);
3107 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003108
Tim Peters37f39822003-01-10 03:49:02 +00003109 if (us)
3110 PyOS_snprintf(buffer, sizeof(buffer),
3111 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3112 else if (s)
3113 PyOS_snprintf(buffer, sizeof(buffer),
3114 "%s(%d, %d, %d)", typename, h, m, s);
3115 else
3116 PyOS_snprintf(buffer, sizeof(buffer),
3117 "%s(%d, %d)", typename, h, m);
3118 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003119 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003120 result = append_keyword_tzinfo(result, self->tzinfo);
3121 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003122}
3123
Tim Peters37f39822003-01-10 03:49:02 +00003124static PyObject *
3125time_str(PyDateTime_Time *self)
3126{
3127 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3128}
Tim Peters2a799bf2002-12-16 20:18:38 +00003129
3130static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003131time_isoformat(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003132{
3133 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003134 PyObject *result;
3135 /* Reuse the time format code from the datetime type. */
3136 PyDateTime_DateTime datetime;
3137 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003138
Tim Peters37f39822003-01-10 03:49:02 +00003139 /* Copy over just the time bytes. */
3140 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3141 self->data,
3142 _PyDateTime_TIME_DATASIZE);
3143
3144 isoformat_time(pdatetime, buf, sizeof(buf));
3145 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003146 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003147 return result;
3148
3149 /* We need to append the UTC offset. */
3150 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003151 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003152 Py_DECREF(result);
3153 return NULL;
3154 }
3155 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3156 return result;
3157}
3158
Tim Peters37f39822003-01-10 03:49:02 +00003159static PyObject *
3160time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3161{
3162 PyObject *result;
3163 PyObject *format;
3164 PyObject *tuple;
3165 static char *keywords[] = {"format", NULL};
3166
3167 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3168 &PyString_Type, &format))
3169 return NULL;
3170
3171 /* Python's strftime does insane things with the year part of the
3172 * timetuple. The year is forced to (the otherwise nonsensical)
3173 * 1900 to worm around that.
3174 */
3175 tuple = Py_BuildValue("iiiiiiiii",
3176 1900, 0, 0, /* year, month, day */
3177 TIME_GET_HOUR(self),
3178 TIME_GET_MINUTE(self),
3179 TIME_GET_SECOND(self),
3180 0, 0, -1); /* weekday, daynum, dst */
3181 if (tuple == NULL)
3182 return NULL;
3183 assert(PyTuple_Size(tuple) == 9);
3184 result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
3185 Py_DECREF(tuple);
3186 return result;
3187}
Tim Peters2a799bf2002-12-16 20:18:38 +00003188
3189/*
3190 * Miscellaneous methods.
3191 */
3192
Tim Peters37f39822003-01-10 03:49:02 +00003193/* This is more natural as a tp_compare, but doesn't work then: for whatever
3194 * reason, Python's try_3way_compare ignores tp_compare unless
3195 * PyInstance_Check returns true, but these aren't old-style classes.
3196 */
3197static PyObject *
3198time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3199{
3200 int diff;
3201 naivety n1, n2;
3202 int offset1, offset2;
3203
3204 if (! PyTime_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00003205 if (op == Py_EQ || op == Py_NE) {
3206 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3207 Py_INCREF(result);
3208 return result;
3209 }
Tim Peters37f39822003-01-10 03:49:02 +00003210 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00003211 return cmperror((PyObject *)self, other);
Tim Peters37f39822003-01-10 03:49:02 +00003212 }
3213 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3214 other, &offset2, &n2, Py_None) < 0)
3215 return NULL;
3216 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3217 /* If they're both naive, or both aware and have the same offsets,
3218 * we get off cheap. Note that if they're both naive, offset1 ==
3219 * offset2 == 0 at this point.
3220 */
3221 if (n1 == n2 && offset1 == offset2) {
3222 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3223 _PyDateTime_TIME_DATASIZE);
3224 return diff_to_bool(diff, op);
3225 }
3226
3227 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3228 assert(offset1 != offset2); /* else last "if" handled it */
3229 /* Convert everything except microseconds to seconds. These
3230 * can't overflow (no more than the # of seconds in 2 days).
3231 */
3232 offset1 = TIME_GET_HOUR(self) * 3600 +
3233 (TIME_GET_MINUTE(self) - offset1) * 60 +
3234 TIME_GET_SECOND(self);
3235 offset2 = TIME_GET_HOUR(other) * 3600 +
3236 (TIME_GET_MINUTE(other) - offset2) * 60 +
3237 TIME_GET_SECOND(other);
3238 diff = offset1 - offset2;
3239 if (diff == 0)
3240 diff = TIME_GET_MICROSECOND(self) -
3241 TIME_GET_MICROSECOND(other);
3242 return diff_to_bool(diff, op);
3243 }
3244
3245 assert(n1 != n2);
3246 PyErr_SetString(PyExc_TypeError,
3247 "can't compare offset-naive and "
3248 "offset-aware times");
3249 return NULL;
3250}
3251
3252static long
3253time_hash(PyDateTime_Time *self)
3254{
3255 if (self->hashcode == -1) {
3256 naivety n;
3257 int offset;
3258 PyObject *temp;
3259
3260 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3261 assert(n != OFFSET_UNKNOWN);
3262 if (n == OFFSET_ERROR)
3263 return -1;
3264
3265 /* Reduce this to a hash of another object. */
3266 if (offset == 0)
3267 temp = PyString_FromStringAndSize((char *)self->data,
3268 _PyDateTime_TIME_DATASIZE);
3269 else {
3270 int hour;
3271 int minute;
3272
3273 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003274 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003275 hour = divmod(TIME_GET_HOUR(self) * 60 +
3276 TIME_GET_MINUTE(self) - offset,
3277 60,
3278 &minute);
3279 if (0 <= hour && hour < 24)
3280 temp = new_time(hour, minute,
3281 TIME_GET_SECOND(self),
3282 TIME_GET_MICROSECOND(self),
3283 Py_None);
3284 else
3285 temp = Py_BuildValue("iiii",
3286 hour, minute,
3287 TIME_GET_SECOND(self),
3288 TIME_GET_MICROSECOND(self));
3289 }
3290 if (temp != NULL) {
3291 self->hashcode = PyObject_Hash(temp);
3292 Py_DECREF(temp);
3293 }
3294 }
3295 return self->hashcode;
3296}
Tim Peters2a799bf2002-12-16 20:18:38 +00003297
Tim Peters12bf3392002-12-24 05:41:27 +00003298static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003299time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003300{
3301 PyObject *clone;
3302 PyObject *tuple;
3303 int hh = TIME_GET_HOUR(self);
3304 int mm = TIME_GET_MINUTE(self);
3305 int ss = TIME_GET_SECOND(self);
3306 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003307 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003308
3309 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003310 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003311 &hh, &mm, &ss, &us, &tzinfo))
3312 return NULL;
3313 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3314 if (tuple == NULL)
3315 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003316 clone = time_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003317 Py_DECREF(tuple);
3318 return clone;
3319}
3320
Tim Peters2a799bf2002-12-16 20:18:38 +00003321static int
Tim Peters37f39822003-01-10 03:49:02 +00003322time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003323{
3324 int offset;
3325 int none;
3326
3327 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3328 /* Since utcoffset is in whole minutes, nothing can
3329 * alter the conclusion that this is nonzero.
3330 */
3331 return 1;
3332 }
3333 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003334 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003335 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003336 if (offset == -1 && PyErr_Occurred())
3337 return -1;
3338 }
3339 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3340}
3341
Tim Peters371935f2003-02-01 01:52:50 +00003342/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003343
Tim Peters33e0f382003-01-10 02:05:14 +00003344/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003345 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3346 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003347 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003348 */
3349static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003350time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003351{
3352 PyObject *basestate;
3353 PyObject *result = NULL;
3354
Tim Peters33e0f382003-01-10 02:05:14 +00003355 basestate = PyString_FromStringAndSize((char *)self->data,
3356 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003357 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003358 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003359 result = Py_BuildValue("(O)", basestate);
3360 else
3361 result = Py_BuildValue("OO", basestate, self->tzinfo);
3362 Py_DECREF(basestate);
3363 }
3364 return result;
3365}
3366
3367static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003368time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003369{
Guido van Rossum177e41a2003-01-30 22:06:23 +00003370 return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003371}
3372
Tim Peters37f39822003-01-10 03:49:02 +00003373static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003374
Tim Peters37f39822003-01-10 03:49:02 +00003375 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003376 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3377 "[+HH:MM].")},
3378
Tim Peters37f39822003-01-10 03:49:02 +00003379 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3380 PyDoc_STR("format -> strftime() style string.")},
3381
3382 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003383 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3384
Tim Peters37f39822003-01-10 03:49:02 +00003385 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003386 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3387
Tim Peters37f39822003-01-10 03:49:02 +00003388 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003389 PyDoc_STR("Return self.tzinfo.dst(self).")},
3390
Tim Peters37f39822003-01-10 03:49:02 +00003391 {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
3392 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003393
Guido van Rossum177e41a2003-01-30 22:06:23 +00003394 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3395 PyDoc_STR("__reduce__() -> (cls, state)")},
3396
Tim Peters2a799bf2002-12-16 20:18:38 +00003397 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003398};
3399
Tim Peters37f39822003-01-10 03:49:02 +00003400static char time_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003401PyDoc_STR("Time type.");
3402
Tim Peters37f39822003-01-10 03:49:02 +00003403static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003404 0, /* nb_add */
3405 0, /* nb_subtract */
3406 0, /* nb_multiply */
3407 0, /* nb_divide */
3408 0, /* nb_remainder */
3409 0, /* nb_divmod */
3410 0, /* nb_power */
3411 0, /* nb_negative */
3412 0, /* nb_positive */
3413 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003414 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003415};
3416
Tim Peters37f39822003-01-10 03:49:02 +00003417statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003418 PyObject_HEAD_INIT(NULL)
3419 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003420 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003421 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003422 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003423 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003424 0, /* tp_print */
3425 0, /* tp_getattr */
3426 0, /* tp_setattr */
3427 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003428 (reprfunc)time_repr, /* tp_repr */
3429 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003430 0, /* tp_as_sequence */
3431 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003432 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003433 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003434 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003435 PyObject_GenericGetAttr, /* tp_getattro */
3436 0, /* tp_setattro */
3437 0, /* tp_as_buffer */
3438 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3439 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003440 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003441 0, /* tp_traverse */
3442 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003443 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003444 0, /* tp_weaklistoffset */
3445 0, /* tp_iter */
3446 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003447 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003448 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003449 time_getset, /* tp_getset */
3450 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003451 0, /* tp_dict */
3452 0, /* tp_descr_get */
3453 0, /* tp_descr_set */
3454 0, /* tp_dictoffset */
3455 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00003456 time_alloc, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003457 time_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00003458 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003459};
3460
3461/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003462 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003463 */
3464
Tim Petersa9bc1682003-01-11 03:39:11 +00003465/* Accessor properties. Properties for day, month, and year are inherited
3466 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003467 */
3468
3469static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003470datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003471{
Tim Petersa9bc1682003-01-11 03:39:11 +00003472 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003473}
3474
Tim Petersa9bc1682003-01-11 03:39:11 +00003475static PyObject *
3476datetime_minute(PyDateTime_DateTime *self, void *unused)
3477{
3478 return PyInt_FromLong(DATE_GET_MINUTE(self));
3479}
3480
3481static PyObject *
3482datetime_second(PyDateTime_DateTime *self, void *unused)
3483{
3484 return PyInt_FromLong(DATE_GET_SECOND(self));
3485}
3486
3487static PyObject *
3488datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3489{
3490 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3491}
3492
3493static PyObject *
3494datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3495{
3496 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3497 Py_INCREF(result);
3498 return result;
3499}
3500
3501static PyGetSetDef datetime_getset[] = {
3502 {"hour", (getter)datetime_hour},
3503 {"minute", (getter)datetime_minute},
3504 {"second", (getter)datetime_second},
3505 {"microsecond", (getter)datetime_microsecond},
3506 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003507 {NULL}
3508};
3509
3510/*
3511 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003512 */
3513
Tim Petersa9bc1682003-01-11 03:39:11 +00003514static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003515 "year", "month", "day", "hour", "minute", "second",
3516 "microsecond", "tzinfo", NULL
3517};
3518
Tim Peters2a799bf2002-12-16 20:18:38 +00003519static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003520datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003521{
3522 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003523 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003524 int year;
3525 int month;
3526 int day;
3527 int hour = 0;
3528 int minute = 0;
3529 int second = 0;
3530 int usecond = 0;
3531 PyObject *tzinfo = Py_None;
3532
Guido van Rossum177e41a2003-01-30 22:06:23 +00003533 /* Check for invocation from pickle with __getstate__ state */
3534 if (PyTuple_GET_SIZE(args) >= 1 &&
3535 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00003536 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3537 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003538 {
Tim Peters70533e22003-02-01 04:40:04 +00003539 PyDateTime_DateTime *me;
3540 char aware;
3541
3542 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003543 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003544 if (check_tzinfo_subclass(tzinfo) < 0) {
3545 PyErr_SetString(PyExc_TypeError, "bad "
3546 "tzinfo state arg");
3547 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003548 }
3549 }
Tim Peters70533e22003-02-01 04:40:04 +00003550 aware = (char)(tzinfo != Py_None);
Tim Petersa98924a2003-05-17 05:55:19 +00003551 me = (PyDateTime_DateTime *) datetime_alloc(
3552 &PyDateTime_DateTimeType,
3553 aware);
Tim Peters70533e22003-02-01 04:40:04 +00003554 if (me != NULL) {
3555 char *pdata = PyString_AS_STRING(state);
3556
3557 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3558 me->hashcode = -1;
3559 me->hastzinfo = aware;
3560 if (aware) {
3561 Py_INCREF(tzinfo);
3562 me->tzinfo = tzinfo;
3563 }
3564 }
3565 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003566 }
3567
Tim Petersa9bc1682003-01-11 03:39:11 +00003568 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003569 &year, &month, &day, &hour, &minute,
3570 &second, &usecond, &tzinfo)) {
3571 if (check_date_args(year, month, day) < 0)
3572 return NULL;
3573 if (check_time_args(hour, minute, second, usecond) < 0)
3574 return NULL;
3575 if (check_tzinfo_subclass(tzinfo) < 0)
3576 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003577 self = new_datetime_ex(year, month, day,
3578 hour, minute, second, usecond,
3579 tzinfo, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003580 }
3581 return self;
3582}
3583
Tim Petersa9bc1682003-01-11 03:39:11 +00003584/* TM_FUNC is the shared type of localtime() and gmtime(). */
3585typedef struct tm *(*TM_FUNC)(const time_t *timer);
3586
3587/* Internal helper.
3588 * Build datetime from a time_t and a distinct count of microseconds.
3589 * Pass localtime or gmtime for f, to control the interpretation of timet.
3590 */
3591static PyObject *
3592datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3593 PyObject *tzinfo)
3594{
3595 struct tm *tm;
3596 PyObject *result = NULL;
3597
3598 tm = f(&timet);
3599 if (tm) {
3600 /* The platform localtime/gmtime may insert leap seconds,
3601 * indicated by tm->tm_sec > 59. We don't care about them,
3602 * except to the extent that passing them on to the datetime
3603 * constructor would raise ValueError for a reason that
3604 * made no sense to the user.
3605 */
3606 if (tm->tm_sec > 59)
3607 tm->tm_sec = 59;
3608 result = PyObject_CallFunction(cls, "iiiiiiiO",
3609 tm->tm_year + 1900,
3610 tm->tm_mon + 1,
3611 tm->tm_mday,
3612 tm->tm_hour,
3613 tm->tm_min,
3614 tm->tm_sec,
3615 us,
3616 tzinfo);
3617 }
3618 else
3619 PyErr_SetString(PyExc_ValueError,
3620 "timestamp out of range for "
3621 "platform localtime()/gmtime() function");
3622 return result;
3623}
3624
3625/* Internal helper.
3626 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3627 * to control the interpretation of the timestamp. Since a double doesn't
3628 * have enough bits to cover a datetime's full range of precision, it's
3629 * better to call datetime_from_timet_and_us provided you have a way
3630 * to get that much precision (e.g., C time() isn't good enough).
3631 */
3632static PyObject *
3633datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3634 PyObject *tzinfo)
3635{
3636 time_t timet = (time_t)timestamp;
3637 double fraction = timestamp - (double)timet;
3638 int us = (int)round_to_long(fraction * 1e6);
3639
3640 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3641}
3642
3643/* Internal helper.
3644 * Build most accurate possible datetime for current time. Pass localtime or
3645 * gmtime for f as appropriate.
3646 */
3647static PyObject *
3648datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3649{
3650#ifdef HAVE_GETTIMEOFDAY
3651 struct timeval t;
3652
3653#ifdef GETTIMEOFDAY_NO_TZ
3654 gettimeofday(&t);
3655#else
3656 gettimeofday(&t, (struct timezone *)NULL);
3657#endif
3658 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3659 tzinfo);
3660
3661#else /* ! HAVE_GETTIMEOFDAY */
3662 /* No flavor of gettimeofday exists on this platform. Python's
3663 * time.time() does a lot of other platform tricks to get the
3664 * best time it can on the platform, and we're not going to do
3665 * better than that (if we could, the better code would belong
3666 * in time.time()!) We're limited by the precision of a double,
3667 * though.
3668 */
3669 PyObject *time;
3670 double dtime;
3671
3672 time = time_time();
3673 if (time == NULL)
3674 return NULL;
3675 dtime = PyFloat_AsDouble(time);
3676 Py_DECREF(time);
3677 if (dtime == -1.0 && PyErr_Occurred())
3678 return NULL;
3679 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3680#endif /* ! HAVE_GETTIMEOFDAY */
3681}
3682
Tim Peters2a799bf2002-12-16 20:18:38 +00003683/* Return best possible local time -- this isn't constrained by the
3684 * precision of a timestamp.
3685 */
3686static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003687datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003688{
Tim Peters10cadce2003-01-23 19:58:02 +00003689 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003690 PyObject *tzinfo = Py_None;
Tim Peters10cadce2003-01-23 19:58:02 +00003691 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003692
Tim Peters10cadce2003-01-23 19:58:02 +00003693 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3694 &tzinfo))
3695 return NULL;
3696 if (check_tzinfo_subclass(tzinfo) < 0)
3697 return NULL;
3698
3699 self = datetime_best_possible(cls,
3700 tzinfo == Py_None ? localtime : gmtime,
3701 tzinfo);
3702 if (self != NULL && tzinfo != Py_None) {
3703 /* Convert UTC to tzinfo's zone. */
3704 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003705 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003706 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003707 }
3708 return self;
3709}
3710
Tim Petersa9bc1682003-01-11 03:39:11 +00003711/* Return best possible UTC time -- this isn't constrained by the
3712 * precision of a timestamp.
3713 */
3714static PyObject *
3715datetime_utcnow(PyObject *cls, PyObject *dummy)
3716{
3717 return datetime_best_possible(cls, gmtime, Py_None);
3718}
3719
Tim Peters2a799bf2002-12-16 20:18:38 +00003720/* Return new local datetime from timestamp (Python timestamp -- a double). */
3721static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003722datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003723{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003724 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003725 double timestamp;
3726 PyObject *tzinfo = Py_None;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003727 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003728
Tim Peters2a44a8d2003-01-23 20:53:10 +00003729 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3730 keywords, &timestamp, &tzinfo))
3731 return NULL;
3732 if (check_tzinfo_subclass(tzinfo) < 0)
3733 return NULL;
3734
3735 self = datetime_from_timestamp(cls,
3736 tzinfo == Py_None ? localtime : gmtime,
3737 timestamp,
3738 tzinfo);
3739 if (self != NULL && tzinfo != Py_None) {
3740 /* Convert UTC to tzinfo's zone. */
3741 PyObject *temp = self;
3742 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3743 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003744 }
3745 return self;
3746}
3747
Tim Petersa9bc1682003-01-11 03:39:11 +00003748/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3749static PyObject *
3750datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3751{
3752 double timestamp;
3753 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003754
Tim Petersa9bc1682003-01-11 03:39:11 +00003755 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3756 result = datetime_from_timestamp(cls, gmtime, timestamp,
3757 Py_None);
3758 return result;
3759}
3760
3761/* Return new datetime from date/datetime and time arguments. */
3762static PyObject *
3763datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3764{
3765 static char *keywords[] = {"date", "time", NULL};
3766 PyObject *date;
3767 PyObject *time;
3768 PyObject *result = NULL;
3769
3770 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3771 &PyDateTime_DateType, &date,
3772 &PyDateTime_TimeType, &time)) {
3773 PyObject *tzinfo = Py_None;
3774
3775 if (HASTZINFO(time))
3776 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3777 result = PyObject_CallFunction(cls, "iiiiiiiO",
3778 GET_YEAR(date),
3779 GET_MONTH(date),
3780 GET_DAY(date),
3781 TIME_GET_HOUR(time),
3782 TIME_GET_MINUTE(time),
3783 TIME_GET_SECOND(time),
3784 TIME_GET_MICROSECOND(time),
3785 tzinfo);
3786 }
3787 return result;
3788}
Tim Peters2a799bf2002-12-16 20:18:38 +00003789
3790/*
3791 * Destructor.
3792 */
3793
3794static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003795datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003796{
Tim Petersa9bc1682003-01-11 03:39:11 +00003797 if (HASTZINFO(self)) {
3798 Py_XDECREF(self->tzinfo);
3799 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003800 self->ob_type->tp_free((PyObject *)self);
3801}
3802
3803/*
3804 * Indirect access to tzinfo methods.
3805 */
3806
Tim Peters2a799bf2002-12-16 20:18:38 +00003807/* These are all METH_NOARGS, so don't need to check the arglist. */
3808static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003809datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3810 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3811 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003812}
3813
3814static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003815datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3816 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3817 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003818}
3819
3820static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003821datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3822 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3823 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003824}
3825
3826/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003827 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003828 */
3829
Tim Petersa9bc1682003-01-11 03:39:11 +00003830/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3831 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003832 */
3833static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003834add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3835 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003836{
Tim Petersa9bc1682003-01-11 03:39:11 +00003837 /* Note that the C-level additions can't overflow, because of
3838 * invariant bounds on the member values.
3839 */
3840 int year = GET_YEAR(date);
3841 int month = GET_MONTH(date);
3842 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3843 int hour = DATE_GET_HOUR(date);
3844 int minute = DATE_GET_MINUTE(date);
3845 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3846 int microsecond = DATE_GET_MICROSECOND(date) +
3847 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003848
Tim Petersa9bc1682003-01-11 03:39:11 +00003849 assert(factor == 1 || factor == -1);
3850 if (normalize_datetime(&year, &month, &day,
3851 &hour, &minute, &second, &microsecond) < 0)
3852 return NULL;
3853 else
3854 return new_datetime(year, month, day,
3855 hour, minute, second, microsecond,
3856 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003857}
3858
3859static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003860datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003861{
Tim Petersa9bc1682003-01-11 03:39:11 +00003862 if (PyDateTime_Check(left)) {
3863 /* datetime + ??? */
3864 if (PyDelta_Check(right))
3865 /* datetime + delta */
3866 return add_datetime_timedelta(
3867 (PyDateTime_DateTime *)left,
3868 (PyDateTime_Delta *)right,
3869 1);
3870 }
3871 else if (PyDelta_Check(left)) {
3872 /* delta + datetime */
3873 return add_datetime_timedelta((PyDateTime_DateTime *) right,
3874 (PyDateTime_Delta *) left,
3875 1);
3876 }
3877 Py_INCREF(Py_NotImplemented);
3878 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00003879}
3880
3881static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003882datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003883{
3884 PyObject *result = Py_NotImplemented;
3885
3886 if (PyDateTime_Check(left)) {
3887 /* datetime - ??? */
3888 if (PyDateTime_Check(right)) {
3889 /* datetime - datetime */
3890 naivety n1, n2;
3891 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00003892 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00003893
Tim Peterse39a80c2002-12-30 21:28:52 +00003894 if (classify_two_utcoffsets(left, &offset1, &n1, left,
3895 right, &offset2, &n2,
3896 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00003897 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00003898 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00003899 if (n1 != n2) {
3900 PyErr_SetString(PyExc_TypeError,
3901 "can't subtract offset-naive and "
3902 "offset-aware datetimes");
3903 return NULL;
3904 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003905 delta_d = ymd_to_ord(GET_YEAR(left),
3906 GET_MONTH(left),
3907 GET_DAY(left)) -
3908 ymd_to_ord(GET_YEAR(right),
3909 GET_MONTH(right),
3910 GET_DAY(right));
3911 /* These can't overflow, since the values are
3912 * normalized. At most this gives the number of
3913 * seconds in one day.
3914 */
3915 delta_s = (DATE_GET_HOUR(left) -
3916 DATE_GET_HOUR(right)) * 3600 +
3917 (DATE_GET_MINUTE(left) -
3918 DATE_GET_MINUTE(right)) * 60 +
3919 (DATE_GET_SECOND(left) -
3920 DATE_GET_SECOND(right));
3921 delta_us = DATE_GET_MICROSECOND(left) -
3922 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00003923 /* (left - offset1) - (right - offset2) =
3924 * (left - right) + (offset2 - offset1)
3925 */
Tim Petersa9bc1682003-01-11 03:39:11 +00003926 delta_s += (offset2 - offset1) * 60;
3927 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003928 }
3929 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00003930 /* datetime - delta */
3931 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00003932 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00003933 (PyDateTime_Delta *)right,
3934 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003935 }
3936 }
3937
3938 if (result == Py_NotImplemented)
3939 Py_INCREF(result);
3940 return result;
3941}
3942
3943/* Various ways to turn a datetime into a string. */
3944
3945static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003946datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003947{
Tim Petersa9bc1682003-01-11 03:39:11 +00003948 char buffer[1000];
3949 char *typename = self->ob_type->tp_name;
3950 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003951
Tim Petersa9bc1682003-01-11 03:39:11 +00003952 if (DATE_GET_MICROSECOND(self)) {
3953 PyOS_snprintf(buffer, sizeof(buffer),
3954 "%s(%d, %d, %d, %d, %d, %d, %d)",
3955 typename,
3956 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3957 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3958 DATE_GET_SECOND(self),
3959 DATE_GET_MICROSECOND(self));
3960 }
3961 else if (DATE_GET_SECOND(self)) {
3962 PyOS_snprintf(buffer, sizeof(buffer),
3963 "%s(%d, %d, %d, %d, %d, %d)",
3964 typename,
3965 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3966 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3967 DATE_GET_SECOND(self));
3968 }
3969 else {
3970 PyOS_snprintf(buffer, sizeof(buffer),
3971 "%s(%d, %d, %d, %d, %d)",
3972 typename,
3973 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3974 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
3975 }
3976 baserepr = PyString_FromString(buffer);
3977 if (baserepr == NULL || ! HASTZINFO(self))
3978 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003979 return append_keyword_tzinfo(baserepr, self->tzinfo);
3980}
3981
Tim Petersa9bc1682003-01-11 03:39:11 +00003982static PyObject *
3983datetime_str(PyDateTime_DateTime *self)
3984{
3985 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
3986}
Tim Peters2a799bf2002-12-16 20:18:38 +00003987
3988static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003989datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003990{
Tim Petersa9bc1682003-01-11 03:39:11 +00003991 char sep = 'T';
3992 static char *keywords[] = {"sep", NULL};
3993 char buffer[100];
3994 char *cp;
3995 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003996
Tim Petersa9bc1682003-01-11 03:39:11 +00003997 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
3998 &sep))
3999 return NULL;
4000 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4001 assert(cp != NULL);
4002 *cp++ = sep;
4003 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4004 result = PyString_FromString(buffer);
4005 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00004006 return result;
4007
4008 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00004009 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00004010 (PyObject *)self) < 0) {
4011 Py_DECREF(result);
4012 return NULL;
4013 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004014 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00004015 return result;
4016}
4017
Tim Petersa9bc1682003-01-11 03:39:11 +00004018static PyObject *
4019datetime_ctime(PyDateTime_DateTime *self)
4020{
4021 return format_ctime((PyDateTime_Date *)self,
4022 DATE_GET_HOUR(self),
4023 DATE_GET_MINUTE(self),
4024 DATE_GET_SECOND(self));
4025}
4026
Tim Peters2a799bf2002-12-16 20:18:38 +00004027/* Miscellaneous methods. */
4028
Tim Petersa9bc1682003-01-11 03:39:11 +00004029/* This is more natural as a tp_compare, but doesn't work then: for whatever
4030 * reason, Python's try_3way_compare ignores tp_compare unless
4031 * PyInstance_Check returns true, but these aren't old-style classes.
4032 */
4033static PyObject *
4034datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4035{
4036 int diff;
4037 naivety n1, n2;
4038 int offset1, offset2;
4039
4040 if (! PyDateTime_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004041 if (PyObject_HasAttrString(other, "timetuple")) {
4042 /* A hook for other kinds of datetime objects. */
4043 Py_INCREF(Py_NotImplemented);
4044 return Py_NotImplemented;
4045 }
Tim Peters07534a62003-02-07 22:50:28 +00004046 if (op == Py_EQ || op == Py_NE) {
4047 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4048 Py_INCREF(result);
4049 return result;
4050 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004051 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00004052 return cmperror((PyObject *)self, other);
Tim Petersa9bc1682003-01-11 03:39:11 +00004053 }
4054
4055 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4056 (PyObject *)self,
4057 other, &offset2, &n2,
4058 other) < 0)
4059 return NULL;
4060 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4061 /* If they're both naive, or both aware and have the same offsets,
4062 * we get off cheap. Note that if they're both naive, offset1 ==
4063 * offset2 == 0 at this point.
4064 */
4065 if (n1 == n2 && offset1 == offset2) {
4066 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4067 _PyDateTime_DATETIME_DATASIZE);
4068 return diff_to_bool(diff, op);
4069 }
4070
4071 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4072 PyDateTime_Delta *delta;
4073
4074 assert(offset1 != offset2); /* else last "if" handled it */
4075 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4076 other);
4077 if (delta == NULL)
4078 return NULL;
4079 diff = GET_TD_DAYS(delta);
4080 if (diff == 0)
4081 diff = GET_TD_SECONDS(delta) |
4082 GET_TD_MICROSECONDS(delta);
4083 Py_DECREF(delta);
4084 return diff_to_bool(diff, op);
4085 }
4086
4087 assert(n1 != n2);
4088 PyErr_SetString(PyExc_TypeError,
4089 "can't compare offset-naive and "
4090 "offset-aware datetimes");
4091 return NULL;
4092}
4093
4094static long
4095datetime_hash(PyDateTime_DateTime *self)
4096{
4097 if (self->hashcode == -1) {
4098 naivety n;
4099 int offset;
4100 PyObject *temp;
4101
4102 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4103 &offset);
4104 assert(n != OFFSET_UNKNOWN);
4105 if (n == OFFSET_ERROR)
4106 return -1;
4107
4108 /* Reduce this to a hash of another object. */
4109 if (n == OFFSET_NAIVE)
4110 temp = PyString_FromStringAndSize(
4111 (char *)self->data,
4112 _PyDateTime_DATETIME_DATASIZE);
4113 else {
4114 int days;
4115 int seconds;
4116
4117 assert(n == OFFSET_AWARE);
4118 assert(HASTZINFO(self));
4119 days = ymd_to_ord(GET_YEAR(self),
4120 GET_MONTH(self),
4121 GET_DAY(self));
4122 seconds = DATE_GET_HOUR(self) * 3600 +
4123 (DATE_GET_MINUTE(self) - offset) * 60 +
4124 DATE_GET_SECOND(self);
4125 temp = new_delta(days,
4126 seconds,
4127 DATE_GET_MICROSECOND(self),
4128 1);
4129 }
4130 if (temp != NULL) {
4131 self->hashcode = PyObject_Hash(temp);
4132 Py_DECREF(temp);
4133 }
4134 }
4135 return self->hashcode;
4136}
Tim Peters2a799bf2002-12-16 20:18:38 +00004137
4138static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004139datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004140{
4141 PyObject *clone;
4142 PyObject *tuple;
4143 int y = GET_YEAR(self);
4144 int m = GET_MONTH(self);
4145 int d = GET_DAY(self);
4146 int hh = DATE_GET_HOUR(self);
4147 int mm = DATE_GET_MINUTE(self);
4148 int ss = DATE_GET_SECOND(self);
4149 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004150 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004151
4152 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004153 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004154 &y, &m, &d, &hh, &mm, &ss, &us,
4155 &tzinfo))
4156 return NULL;
4157 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4158 if (tuple == NULL)
4159 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004160 clone = datetime_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004161 Py_DECREF(tuple);
4162 return clone;
4163}
4164
4165static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004166datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004167{
Tim Peters52dcce22003-01-23 16:36:11 +00004168 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004169 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004170 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004171
Tim Peters80475bb2002-12-25 07:40:55 +00004172 PyObject *tzinfo;
4173 static char *keywords[] = {"tz", NULL};
4174
Tim Peters52dcce22003-01-23 16:36:11 +00004175 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4176 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004177 return NULL;
4178
Tim Peters52dcce22003-01-23 16:36:11 +00004179 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4180 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004181
Tim Peters52dcce22003-01-23 16:36:11 +00004182 /* Conversion to self's own time zone is a NOP. */
4183 if (self->tzinfo == tzinfo) {
4184 Py_INCREF(self);
4185 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004186 }
Tim Peters521fc152002-12-31 17:36:56 +00004187
Tim Peters52dcce22003-01-23 16:36:11 +00004188 /* Convert self to UTC. */
4189 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4190 if (offset == -1 && PyErr_Occurred())
4191 return NULL;
4192 if (none)
4193 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004194
Tim Peters52dcce22003-01-23 16:36:11 +00004195 y = GET_YEAR(self);
4196 m = GET_MONTH(self);
4197 d = GET_DAY(self);
4198 hh = DATE_GET_HOUR(self);
4199 mm = DATE_GET_MINUTE(self);
4200 ss = DATE_GET_SECOND(self);
4201 us = DATE_GET_MICROSECOND(self);
4202
4203 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004204 if ((mm < 0 || mm >= 60) &&
4205 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004206 return NULL;
4207
4208 /* Attach new tzinfo and let fromutc() do the rest. */
4209 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4210 if (result != NULL) {
4211 PyObject *temp = result;
4212
4213 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4214 Py_DECREF(temp);
4215 }
Tim Petersadf64202003-01-04 06:03:15 +00004216 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004217
Tim Peters52dcce22003-01-23 16:36:11 +00004218NeedAware:
4219 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4220 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004221 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004222}
4223
4224static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004225datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004226{
4227 int dstflag = -1;
4228
Tim Petersa9bc1682003-01-11 03:39:11 +00004229 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004230 int none;
4231
4232 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4233 if (dstflag == -1 && PyErr_Occurred())
4234 return NULL;
4235
4236 if (none)
4237 dstflag = -1;
4238 else if (dstflag != 0)
4239 dstflag = 1;
4240
4241 }
4242 return build_struct_time(GET_YEAR(self),
4243 GET_MONTH(self),
4244 GET_DAY(self),
4245 DATE_GET_HOUR(self),
4246 DATE_GET_MINUTE(self),
4247 DATE_GET_SECOND(self),
4248 dstflag);
4249}
4250
4251static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004252datetime_getdate(PyDateTime_DateTime *self)
4253{
4254 return new_date(GET_YEAR(self),
4255 GET_MONTH(self),
4256 GET_DAY(self));
4257}
4258
4259static PyObject *
4260datetime_gettime(PyDateTime_DateTime *self)
4261{
4262 return new_time(DATE_GET_HOUR(self),
4263 DATE_GET_MINUTE(self),
4264 DATE_GET_SECOND(self),
4265 DATE_GET_MICROSECOND(self),
4266 Py_None);
4267}
4268
4269static PyObject *
4270datetime_gettimetz(PyDateTime_DateTime *self)
4271{
4272 return new_time(DATE_GET_HOUR(self),
4273 DATE_GET_MINUTE(self),
4274 DATE_GET_SECOND(self),
4275 DATE_GET_MICROSECOND(self),
4276 HASTZINFO(self) ? self->tzinfo : Py_None);
4277}
4278
4279static PyObject *
4280datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004281{
4282 int y = GET_YEAR(self);
4283 int m = GET_MONTH(self);
4284 int d = GET_DAY(self);
4285 int hh = DATE_GET_HOUR(self);
4286 int mm = DATE_GET_MINUTE(self);
4287 int ss = DATE_GET_SECOND(self);
4288 int us = 0; /* microseconds are ignored in a timetuple */
4289 int offset = 0;
4290
Tim Petersa9bc1682003-01-11 03:39:11 +00004291 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004292 int none;
4293
4294 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4295 if (offset == -1 && PyErr_Occurred())
4296 return NULL;
4297 }
4298 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4299 * 0 in a UTC timetuple regardless of what dst() says.
4300 */
4301 if (offset) {
4302 /* Subtract offset minutes & normalize. */
4303 int stat;
4304
4305 mm -= offset;
4306 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4307 if (stat < 0) {
4308 /* At the edges, it's possible we overflowed
4309 * beyond MINYEAR or MAXYEAR.
4310 */
4311 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4312 PyErr_Clear();
4313 else
4314 return NULL;
4315 }
4316 }
4317 return build_struct_time(y, m, d, hh, mm, ss, 0);
4318}
4319
Tim Peters371935f2003-02-01 01:52:50 +00004320/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004321
Tim Petersa9bc1682003-01-11 03:39:11 +00004322/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004323 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4324 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004325 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004326 */
4327static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004328datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004329{
4330 PyObject *basestate;
4331 PyObject *result = NULL;
4332
Tim Peters33e0f382003-01-10 02:05:14 +00004333 basestate = PyString_FromStringAndSize((char *)self->data,
4334 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004335 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004336 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00004337 result = Py_BuildValue("(O)", basestate);
4338 else
4339 result = Py_BuildValue("OO", basestate, self->tzinfo);
4340 Py_DECREF(basestate);
4341 }
4342 return result;
4343}
4344
4345static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004346datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004347{
Guido van Rossum177e41a2003-01-30 22:06:23 +00004348 return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004349}
4350
Tim Petersa9bc1682003-01-11 03:39:11 +00004351static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004352
Tim Peters2a799bf2002-12-16 20:18:38 +00004353 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004354
Tim Petersa9bc1682003-01-11 03:39:11 +00004355 {"now", (PyCFunction)datetime_now,
Tim Peters2a799bf2002-12-16 20:18:38 +00004356 METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004357 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004358
Tim Petersa9bc1682003-01-11 03:39:11 +00004359 {"utcnow", (PyCFunction)datetime_utcnow,
4360 METH_NOARGS | METH_CLASS,
4361 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4362
4363 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Tim Peters2a799bf2002-12-16 20:18:38 +00004364 METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004365 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004366
Tim Petersa9bc1682003-01-11 03:39:11 +00004367 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4368 METH_VARARGS | METH_CLASS,
4369 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4370 "(like time.time()).")},
4371
4372 {"combine", (PyCFunction)datetime_combine,
4373 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4374 PyDoc_STR("date, time -> datetime with same date and time fields")},
4375
Tim Peters2a799bf2002-12-16 20:18:38 +00004376 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004377
Tim Petersa9bc1682003-01-11 03:39:11 +00004378 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4379 PyDoc_STR("Return date object with same year, month and day.")},
4380
4381 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4382 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4383
4384 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4385 PyDoc_STR("Return time object with same time and tzinfo.")},
4386
4387 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4388 PyDoc_STR("Return ctime() style string.")},
4389
4390 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004391 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4392
Tim Petersa9bc1682003-01-11 03:39:11 +00004393 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004394 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4395
Tim Petersa9bc1682003-01-11 03:39:11 +00004396 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004397 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4398 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4399 "sep is used to separate the year from the time, and "
4400 "defaults to 'T'.")},
4401
Tim Petersa9bc1682003-01-11 03:39:11 +00004402 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004403 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4404
Tim Petersa9bc1682003-01-11 03:39:11 +00004405 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004406 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4407
Tim Petersa9bc1682003-01-11 03:39:11 +00004408 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004409 PyDoc_STR("Return self.tzinfo.dst(self).")},
4410
Tim Petersa9bc1682003-01-11 03:39:11 +00004411 {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
4412 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004413
Tim Petersa9bc1682003-01-11 03:39:11 +00004414 {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004415 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4416
Guido van Rossum177e41a2003-01-30 22:06:23 +00004417 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4418 PyDoc_STR("__reduce__() -> (cls, state)")},
4419
Tim Peters2a799bf2002-12-16 20:18:38 +00004420 {NULL, NULL}
4421};
4422
Tim Petersa9bc1682003-01-11 03:39:11 +00004423static char datetime_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00004424PyDoc_STR("date/time type.");
4425
Tim Petersa9bc1682003-01-11 03:39:11 +00004426static PyNumberMethods datetime_as_number = {
4427 datetime_add, /* nb_add */
4428 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004429 0, /* nb_multiply */
4430 0, /* nb_divide */
4431 0, /* nb_remainder */
4432 0, /* nb_divmod */
4433 0, /* nb_power */
4434 0, /* nb_negative */
4435 0, /* nb_positive */
4436 0, /* nb_absolute */
4437 0, /* nb_nonzero */
4438};
4439
Tim Petersa9bc1682003-01-11 03:39:11 +00004440statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004441 PyObject_HEAD_INIT(NULL)
4442 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004443 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004444 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004445 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004446 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004447 0, /* tp_print */
4448 0, /* tp_getattr */
4449 0, /* tp_setattr */
4450 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004451 (reprfunc)datetime_repr, /* tp_repr */
4452 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004453 0, /* tp_as_sequence */
4454 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004455 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004456 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004457 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004458 PyObject_GenericGetAttr, /* tp_getattro */
4459 0, /* tp_setattro */
4460 0, /* tp_as_buffer */
4461 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4462 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004463 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004464 0, /* tp_traverse */
4465 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004466 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004467 0, /* tp_weaklistoffset */
4468 0, /* tp_iter */
4469 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004470 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004471 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004472 datetime_getset, /* tp_getset */
4473 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004474 0, /* tp_dict */
4475 0, /* tp_descr_get */
4476 0, /* tp_descr_set */
4477 0, /* tp_dictoffset */
4478 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00004479 datetime_alloc, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004480 datetime_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00004481 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004482};
4483
4484/* ---------------------------------------------------------------------------
4485 * Module methods and initialization.
4486 */
4487
4488static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004489 {NULL, NULL}
4490};
4491
4492PyMODINIT_FUNC
4493initdatetime(void)
4494{
4495 PyObject *m; /* a module object */
4496 PyObject *d; /* its dict */
4497 PyObject *x;
4498
Tim Peters2a799bf2002-12-16 20:18:38 +00004499 m = Py_InitModule3("datetime", module_methods,
4500 "Fast implementation of the datetime type.");
4501
4502 if (PyType_Ready(&PyDateTime_DateType) < 0)
4503 return;
4504 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4505 return;
4506 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4507 return;
4508 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4509 return;
4510 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4511 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004512
Tim Peters2a799bf2002-12-16 20:18:38 +00004513 /* timedelta values */
4514 d = PyDateTime_DeltaType.tp_dict;
4515
Tim Peters2a799bf2002-12-16 20:18:38 +00004516 x = new_delta(0, 0, 1, 0);
4517 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4518 return;
4519 Py_DECREF(x);
4520
4521 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4522 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4523 return;
4524 Py_DECREF(x);
4525
4526 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4527 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4528 return;
4529 Py_DECREF(x);
4530
4531 /* date values */
4532 d = PyDateTime_DateType.tp_dict;
4533
4534 x = new_date(1, 1, 1);
4535 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4536 return;
4537 Py_DECREF(x);
4538
4539 x = new_date(MAXYEAR, 12, 31);
4540 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4541 return;
4542 Py_DECREF(x);
4543
4544 x = new_delta(1, 0, 0, 0);
4545 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4546 return;
4547 Py_DECREF(x);
4548
Tim Peters37f39822003-01-10 03:49:02 +00004549 /* time values */
4550 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004551
Tim Peters37f39822003-01-10 03:49:02 +00004552 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004553 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4554 return;
4555 Py_DECREF(x);
4556
Tim Peters37f39822003-01-10 03:49:02 +00004557 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004558 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4559 return;
4560 Py_DECREF(x);
4561
4562 x = new_delta(0, 0, 1, 0);
4563 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4564 return;
4565 Py_DECREF(x);
4566
Tim Petersa9bc1682003-01-11 03:39:11 +00004567 /* datetime values */
4568 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004569
Tim Petersa9bc1682003-01-11 03:39:11 +00004570 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004571 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4572 return;
4573 Py_DECREF(x);
4574
Tim Petersa9bc1682003-01-11 03:39:11 +00004575 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004576 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4577 return;
4578 Py_DECREF(x);
4579
4580 x = new_delta(0, 0, 1, 0);
4581 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4582 return;
4583 Py_DECREF(x);
4584
Tim Peters2a799bf2002-12-16 20:18:38 +00004585 /* module initialization */
4586 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4587 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4588
4589 Py_INCREF(&PyDateTime_DateType);
4590 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4591
Tim Petersa9bc1682003-01-11 03:39:11 +00004592 Py_INCREF(&PyDateTime_DateTimeType);
4593 PyModule_AddObject(m, "datetime",
4594 (PyObject *)&PyDateTime_DateTimeType);
4595
4596 Py_INCREF(&PyDateTime_TimeType);
4597 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4598
Tim Peters2a799bf2002-12-16 20:18:38 +00004599 Py_INCREF(&PyDateTime_DeltaType);
4600 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4601
Tim Peters2a799bf2002-12-16 20:18:38 +00004602 Py_INCREF(&PyDateTime_TZInfoType);
4603 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4604
Tim Peters2a799bf2002-12-16 20:18:38 +00004605 /* A 4-year cycle has an extra leap day over what we'd get from
4606 * pasting together 4 single years.
4607 */
4608 assert(DI4Y == 4 * 365 + 1);
4609 assert(DI4Y == days_before_year(4+1));
4610
4611 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4612 * get from pasting together 4 100-year cycles.
4613 */
4614 assert(DI400Y == 4 * DI100Y + 1);
4615 assert(DI400Y == days_before_year(400+1));
4616
4617 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4618 * pasting together 25 4-year cycles.
4619 */
4620 assert(DI100Y == 25 * DI4Y - 1);
4621 assert(DI100Y == days_before_year(100+1));
4622
4623 us_per_us = PyInt_FromLong(1);
4624 us_per_ms = PyInt_FromLong(1000);
4625 us_per_second = PyInt_FromLong(1000000);
4626 us_per_minute = PyInt_FromLong(60000000);
4627 seconds_per_day = PyInt_FromLong(24 * 3600);
4628 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4629 us_per_minute == NULL || seconds_per_day == NULL)
4630 return;
4631
4632 /* The rest are too big for 32-bit ints, but even
4633 * us_per_week fits in 40 bits, so doubles should be exact.
4634 */
4635 us_per_hour = PyLong_FromDouble(3600000000.0);
4636 us_per_day = PyLong_FromDouble(86400000000.0);
4637 us_per_week = PyLong_FromDouble(604800000000.0);
4638 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4639 return;
4640}
Tim Petersf3615152003-01-01 21:51:37 +00004641
4642/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004643Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004644 x.n = x stripped of its timezone -- its naive time.
4645 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4646 return None
4647 x.d = x.dst(), and assuming that doesn't raise an exception or
4648 return None
4649 x.s = x's standard offset, x.o - x.d
4650
4651Now some derived rules, where k is a duration (timedelta).
4652
46531. x.o = x.s + x.d
4654 This follows from the definition of x.s.
4655
Tim Petersc5dc4da2003-01-02 17:55:03 +000046562. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004657 This is actually a requirement, an assumption we need to make about
4658 sane tzinfo classes.
4659
46603. The naive UTC time corresponding to x is x.n - x.o.
4661 This is again a requirement for a sane tzinfo class.
4662
46634. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004664 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004665
Tim Petersc5dc4da2003-01-02 17:55:03 +000046665. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004667 Again follows from how arithmetic is defined.
4668
Tim Peters8bb5ad22003-01-24 02:44:45 +00004669Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004670(meaning that the various tzinfo methods exist, and don't blow up or return
4671None when called).
4672
Tim Petersa9bc1682003-01-11 03:39:11 +00004673The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004674x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004675
4676By #3, we want
4677
Tim Peters8bb5ad22003-01-24 02:44:45 +00004678 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004679
4680The algorithm starts by attaching tz to x.n, and calling that y. So
4681x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4682becomes true; in effect, we want to solve [2] for k:
4683
Tim Peters8bb5ad22003-01-24 02:44:45 +00004684 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004685
4686By #1, this is the same as
4687
Tim Peters8bb5ad22003-01-24 02:44:45 +00004688 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004689
4690By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4691Substituting that into [3],
4692
Tim Peters8bb5ad22003-01-24 02:44:45 +00004693 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4694 k - (y+k).s - (y+k).d = 0; rearranging,
4695 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4696 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004697
Tim Peters8bb5ad22003-01-24 02:44:45 +00004698On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4699approximate k by ignoring the (y+k).d term at first. Note that k can't be
4700very large, since all offset-returning methods return a duration of magnitude
4701less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4702be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004703
4704In any case, the new value is
4705
Tim Peters8bb5ad22003-01-24 02:44:45 +00004706 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004707
Tim Peters8bb5ad22003-01-24 02:44:45 +00004708It's helpful to step back at look at [4] from a higher level: it's simply
4709mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004710
4711At this point, if
4712
Tim Peters8bb5ad22003-01-24 02:44:45 +00004713 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004714
4715we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004716at the start of daylight time. Picture US Eastern for concreteness. The wall
4717time 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 +00004718sense then. The docs ask that an Eastern tzinfo class consider such a time to
4719be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4720on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004721the only spelling that makes sense on the local wall clock.
4722
Tim Petersc5dc4da2003-01-02 17:55:03 +00004723In fact, if [5] holds at this point, we do have the standard-time spelling,
4724but that takes a bit of proof. We first prove a stronger result. What's the
4725difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004726
Tim Peters8bb5ad22003-01-24 02:44:45 +00004727 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004728
Tim Petersc5dc4da2003-01-02 17:55:03 +00004729Now
4730 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004731 (y + y.s).n = by #5
4732 y.n + y.s = since y.n = x.n
4733 x.n + y.s = since z and y are have the same tzinfo member,
4734 y.s = z.s by #2
4735 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004736
Tim Petersc5dc4da2003-01-02 17:55:03 +00004737Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004738
Tim Petersc5dc4da2003-01-02 17:55:03 +00004739 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004740 x.n - ((x.n + z.s) - z.o) = expanding
4741 x.n - x.n - z.s + z.o = cancelling
4742 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004743 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004744
Tim Petersc5dc4da2003-01-02 17:55:03 +00004745So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004746
Tim Petersc5dc4da2003-01-02 17:55:03 +00004747If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004748spelling we wanted in the endcase described above. We're done. Contrarily,
4749if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004750
Tim Petersc5dc4da2003-01-02 17:55:03 +00004751If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4752add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00004753local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004754
Tim Petersc5dc4da2003-01-02 17:55:03 +00004755Let
Tim Petersf3615152003-01-01 21:51:37 +00004756
Tim Peters4fede1a2003-01-04 00:26:59 +00004757 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004758
Tim Peters4fede1a2003-01-04 00:26:59 +00004759and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004760
Tim Peters8bb5ad22003-01-24 02:44:45 +00004761 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004762
Tim Peters8bb5ad22003-01-24 02:44:45 +00004763If so, we're done. If not, the tzinfo class is insane, according to the
4764assumptions we've made. This also requires a bit of proof. As before, let's
4765compute the difference between the LHS and RHS of [8] (and skipping some of
4766the justifications for the kinds of substitutions we've done several times
4767already):
Tim Peters4fede1a2003-01-04 00:26:59 +00004768
Tim Peters8bb5ad22003-01-24 02:44:45 +00004769 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
4770 x.n - (z.n + diff - z'.o) = replacing diff via [6]
4771 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
4772 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
4773 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00004774 - z.o + z'.o = #1 twice
4775 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4776 z'.d - z.d
4777
4778So 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 +00004779we've found the UTC-equivalent so are done. In fact, we stop with [7] and
4780return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00004781
Tim Peters8bb5ad22003-01-24 02:44:45 +00004782How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
4783a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
4784would have to change the result dst() returns: we start in DST, and moving
4785a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00004786
Tim Peters8bb5ad22003-01-24 02:44:45 +00004787There isn't a sane case where this can happen. The closest it gets is at
4788the end of DST, where there's an hour in UTC with no spelling in a hybrid
4789tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
4790that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
4791UTC) because the docs insist on that, but 0:MM is taken as being in daylight
4792time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
4793clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
4794standard time. Since that's what the local clock *does*, we want to map both
4795UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00004796in local time, but so it goes -- it's the way the local clock works.
4797
Tim Peters8bb5ad22003-01-24 02:44:45 +00004798When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4799so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4800z' = 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 +00004801(correctly) concludes that z' is not UTC-equivalent to x.
4802
4803Because we know z.d said z was in daylight time (else [5] would have held and
4804we would have stopped then), and we know z.d != z'.d (else [8] would have held
4805and we we have stopped then), and there are only 2 possible values dst() can
4806return in Eastern, it follows that z'.d must be 0 (which it is in the example,
4807but the reasoning doesn't depend on the example -- it depends on there being
4808two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00004809z' must be in standard time, and is the spelling we want in this case.
4810
4811Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
4812concerned (because it takes z' as being in standard time rather than the
4813daylight time we intend here), but returning it gives the real-life "local
4814clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
4815tz.
4816
4817When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
4818the 1:MM standard time spelling we want.
4819
4820So how can this break? One of the assumptions must be violated. Two
4821possibilities:
4822
48231) [2] effectively says that y.s is invariant across all y belong to a given
4824 time zone. This isn't true if, for political reasons or continental drift,
4825 a region decides to change its base offset from UTC.
4826
48272) There may be versions of "double daylight" time where the tail end of
4828 the analysis gives up a step too early. I haven't thought about that
4829 enough to say.
4830
4831In any case, it's clear that the default fromutc() is strong enough to handle
4832"almost all" time zones: so long as the standard offset is invariant, it
4833doesn't matter if daylight time transition points change from year to year, or
4834if daylight time is skipped in some years; it doesn't matter how large or
4835small dst() may get within its bounds; and it doesn't even matter if some
4836perverse time zone returns a negative dst()). So a breaking case must be
4837pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00004838--------------------------------------------------------------------------- */