blob: 73c17643a521c693cd8ebe4711547c64f17eb065 [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
78/* Forward declarations. */
79static PyTypeObject PyDateTime_DateType;
80static PyTypeObject PyDateTime_DateTimeType;
81static PyTypeObject PyDateTime_DateTimeTZType;
82static PyTypeObject PyDateTime_DeltaType;
83static PyTypeObject PyDateTime_TimeType;
84static PyTypeObject PyDateTime_TZInfoType;
85static PyTypeObject PyDateTime_TimeTZType;
86
87/* ---------------------------------------------------------------------------
88 * Math utilities.
89 */
90
91/* k = i+j overflows iff k differs in sign from both inputs,
92 * iff k^i has sign bit set and k^j has sign bit set,
93 * iff (k^i)&(k^j) has sign bit set.
94 */
95#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
96 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
97
98/* Compute Python divmod(x, y), returning the quotient and storing the
99 * remainder into *r. The quotient is the floor of x/y, and that's
100 * the real point of this. C will probably truncate instead (C99
101 * requires truncation; C89 left it implementation-defined).
102 * Simplification: we *require* that y > 0 here. That's appropriate
103 * for all the uses made of it. This simplifies the code and makes
104 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
105 * overflow case).
106 */
107static int
108divmod(int x, int y, int *r)
109{
110 int quo;
111
112 assert(y > 0);
113 quo = x / y;
114 *r = x - quo * y;
115 if (*r < 0) {
116 --quo;
117 *r += y;
118 }
119 assert(0 <= *r && *r < y);
120 return quo;
121}
122
123/* ---------------------------------------------------------------------------
124 * General calendrical helper functions
125 */
126
127/* For each month ordinal in 1..12, the number of days in that month,
128 * and the number of days before that month in the same year. These
129 * are correct for non-leap years only.
130 */
131static int _days_in_month[] = {
132 0, /* unused; this vector uses 1-based indexing */
133 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
134};
135
136static int _days_before_month[] = {
137 0, /* unused; this vector uses 1-based indexing */
138 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
139};
140
141/* year -> 1 if leap year, else 0. */
142static int
143is_leap(int year)
144{
145 /* Cast year to unsigned. The result is the same either way, but
146 * C can generate faster code for unsigned mod than for signed
147 * mod (especially for % 4 -- a good compiler should just grab
148 * the last 2 bits when the LHS is unsigned).
149 */
150 const unsigned int ayear = (unsigned int)year;
151 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
152}
153
154/* year, month -> number of days in that month in that year */
155static int
156days_in_month(int year, int month)
157{
158 assert(month >= 1);
159 assert(month <= 12);
160 if (month == 2 && is_leap(year))
161 return 29;
162 else
163 return _days_in_month[month];
164}
165
166/* year, month -> number of days in year preceeding first day of month */
167static int
168days_before_month(int year, int month)
169{
170 int days;
171
172 assert(month >= 1);
173 assert(month <= 12);
174 days = _days_before_month[month];
175 if (month > 2 && is_leap(year))
176 ++days;
177 return days;
178}
179
180/* year -> number of days before January 1st of year. Remember that we
181 * start with year 1, so days_before_year(1) == 0.
182 */
183static int
184days_before_year(int year)
185{
186 int y = year - 1;
187 /* This is incorrect if year <= 0; we really want the floor
188 * here. But so long as MINYEAR is 1, the smallest year this
189 * can see is 0 (this can happen in some normalization endcases),
190 * so we'll just special-case that.
191 */
192 assert (year >= 0);
193 if (y >= 0)
194 return y*365 + y/4 - y/100 + y/400;
195 else {
196 assert(y == -1);
197 return -366;
198 }
199}
200
201/* Number of days in 4, 100, and 400 year cycles. That these have
202 * the correct values is asserted in the module init function.
203 */
204#define DI4Y 1461 /* days_before_year(5); days in 4 years */
205#define DI100Y 36524 /* days_before_year(101); days in 100 years */
206#define DI400Y 146097 /* days_before_year(401); days in 400 years */
207
208/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
209static void
210ord_to_ymd(int ordinal, int *year, int *month, int *day)
211{
212 int n, n1, n4, n100, n400, leapyear, preceding;
213
214 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
215 * leap years repeats exactly every 400 years. The basic strategy is
216 * to find the closest 400-year boundary at or before ordinal, then
217 * work with the offset from that boundary to ordinal. Life is much
218 * clearer if we subtract 1 from ordinal first -- then the values
219 * of ordinal at 400-year boundaries are exactly those divisible
220 * by DI400Y:
221 *
222 * D M Y n n-1
223 * -- --- ---- ---------- ----------------
224 * 31 Dec -400 -DI400Y -DI400Y -1
225 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
226 * ...
227 * 30 Dec 000 -1 -2
228 * 31 Dec 000 0 -1
229 * 1 Jan 001 1 0 400-year boundary
230 * 2 Jan 001 2 1
231 * 3 Jan 001 3 2
232 * ...
233 * 31 Dec 400 DI400Y DI400Y -1
234 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
235 */
236 assert(ordinal >= 1);
237 --ordinal;
238 n400 = ordinal / DI400Y;
239 n = ordinal % DI400Y;
240 *year = n400 * 400 + 1;
241
242 /* Now n is the (non-negative) offset, in days, from January 1 of
243 * year, to the desired date. Now compute how many 100-year cycles
244 * precede n.
245 * Note that it's possible for n100 to equal 4! In that case 4 full
246 * 100-year cycles precede the desired day, which implies the
247 * desired day is December 31 at the end of a 400-year cycle.
248 */
249 n100 = n / DI100Y;
250 n = n % DI100Y;
251
252 /* Now compute how many 4-year cycles precede it. */
253 n4 = n / DI4Y;
254 n = n % DI4Y;
255
256 /* And now how many single years. Again n1 can be 4, and again
257 * meaning that the desired day is December 31 at the end of the
258 * 4-year cycle.
259 */
260 n1 = n / 365;
261 n = n % 365;
262
263 *year += n100 * 100 + n4 * 4 + n1;
264 if (n1 == 4 || n100 == 4) {
265 assert(n == 0);
266 *year -= 1;
267 *month = 12;
268 *day = 31;
269 return;
270 }
271
272 /* Now the year is correct, and n is the offset from January 1. We
273 * find the month via an estimate that's either exact or one too
274 * large.
275 */
276 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
277 assert(leapyear == is_leap(*year));
278 *month = (n + 50) >> 5;
279 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
280 if (preceding > n) {
281 /* estimate is too large */
282 *month -= 1;
283 preceding -= days_in_month(*year, *month);
284 }
285 n -= preceding;
286 assert(0 <= n);
287 assert(n < days_in_month(*year, *month));
288
289 *day = n + 1;
290}
291
292/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
293static int
294ymd_to_ord(int year, int month, int day)
295{
296 return days_before_year(year) + days_before_month(year, month) + day;
297}
298
299/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
300static int
301weekday(int year, int month, int day)
302{
303 return (ymd_to_ord(year, month, day) + 6) % 7;
304}
305
306/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
307 * first calendar week containing a Thursday.
308 */
309static int
310iso_week1_monday(int year)
311{
312 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
313 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
314 int first_weekday = (first_day + 6) % 7;
315 /* ordinal of closest Monday at or before 1/1 */
316 int week1_monday = first_day - first_weekday;
317
318 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
319 week1_monday += 7;
320 return week1_monday;
321}
322
323/* ---------------------------------------------------------------------------
324 * Range checkers.
325 */
326
327/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
328 * If not, raise OverflowError and return -1.
329 */
330static int
331check_delta_day_range(int days)
332{
333 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
334 return 0;
335 PyErr_Format(PyExc_OverflowError,
336 "days=%d; must have magnitude <= %d",
Guido van Rossumbd43e912002-12-16 20:34:55 +0000337 days, MAX_DELTA_DAYS);
Tim Peters2a799bf2002-12-16 20:18:38 +0000338 return -1;
339}
340
341/* Check that date arguments are in range. Return 0 if they are. If they
342 * aren't, raise ValueError and return -1.
343 */
344static int
345check_date_args(int year, int month, int day)
346{
347
348 if (year < MINYEAR || year > MAXYEAR) {
349 PyErr_SetString(PyExc_ValueError,
350 "year is out of range");
351 return -1;
352 }
353 if (month < 1 || month > 12) {
354 PyErr_SetString(PyExc_ValueError,
355 "month must be in 1..12");
356 return -1;
357 }
358 if (day < 1 || day > days_in_month(year, month)) {
359 PyErr_SetString(PyExc_ValueError,
360 "day is out of range for month");
361 return -1;
362 }
363 return 0;
364}
365
366/* Check that time arguments are in range. Return 0 if they are. If they
367 * aren't, raise ValueError and return -1.
368 */
369static int
370check_time_args(int h, int m, int s, int us)
371{
372 if (h < 0 || h > 23) {
373 PyErr_SetString(PyExc_ValueError,
374 "hour must be in 0..23");
375 return -1;
376 }
377 if (m < 0 || m > 59) {
378 PyErr_SetString(PyExc_ValueError,
379 "minute must be in 0..59");
380 return -1;
381 }
382 if (s < 0 || s > 59) {
383 PyErr_SetString(PyExc_ValueError,
384 "second must be in 0..59");
385 return -1;
386 }
387 if (us < 0 || us > 999999) {
388 PyErr_SetString(PyExc_ValueError,
389 "microsecond must be in 0..999999");
390 return -1;
391 }
392 return 0;
393}
394
395/* ---------------------------------------------------------------------------
396 * Normalization utilities.
397 */
398
399/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
400 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
401 * at least factor, enough of *lo is converted into "hi" units so that
402 * 0 <= *lo < factor. The input values must be such that int overflow
403 * is impossible.
404 */
405static void
406normalize_pair(int *hi, int *lo, int factor)
407{
408 assert(factor > 0);
409 assert(lo != hi);
410 if (*lo < 0 || *lo >= factor) {
411 const int num_hi = divmod(*lo, factor, lo);
412 const int new_hi = *hi + num_hi;
413 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
414 *hi = new_hi;
415 }
416 assert(0 <= *lo && *lo < factor);
417}
418
419/* Fiddle days (d), seconds (s), and microseconds (us) so that
420 * 0 <= *s < 24*3600
421 * 0 <= *us < 1000000
422 * The input values must be such that the internals don't overflow.
423 * The way this routine is used, we don't get close.
424 */
425static void
426normalize_d_s_us(int *d, int *s, int *us)
427{
428 if (*us < 0 || *us >= 1000000) {
429 normalize_pair(s, us, 1000000);
430 /* |s| can't be bigger than about
431 * |original s| + |original us|/1000000 now.
432 */
433
434 }
435 if (*s < 0 || *s >= 24*3600) {
436 normalize_pair(d, s, 24*3600);
437 /* |d| can't be bigger than about
438 * |original d| +
439 * (|original s| + |original us|/1000000) / (24*3600) now.
440 */
441 }
442 assert(0 <= *s && *s < 24*3600);
443 assert(0 <= *us && *us < 1000000);
444}
445
446/* Fiddle years (y), months (m), and days (d) so that
447 * 1 <= *m <= 12
448 * 1 <= *d <= days_in_month(*y, *m)
449 * The input values must be such that the internals don't overflow.
450 * The way this routine is used, we don't get close.
451 */
452static void
453normalize_y_m_d(int *y, int *m, int *d)
454{
455 int dim; /* # of days in month */
456
457 /* This gets muddy: the proper range for day can't be determined
458 * without knowing the correct month and year, but if day is, e.g.,
459 * plus or minus a million, the current month and year values make
460 * no sense (and may also be out of bounds themselves).
461 * Saying 12 months == 1 year should be non-controversial.
462 */
463 if (*m < 1 || *m > 12) {
464 --*m;
465 normalize_pair(y, m, 12);
466 ++*m;
467 /* |y| can't be bigger than about
468 * |original y| + |original m|/12 now.
469 */
470 }
471 assert(1 <= *m && *m <= 12);
472
473 /* Now only day can be out of bounds (year may also be out of bounds
474 * for a datetime object, but we don't care about that here).
475 * If day is out of bounds, what to do is arguable, but at least the
476 * method here is principled and explainable.
477 */
478 dim = days_in_month(*y, *m);
479 if (*d < 1 || *d > dim) {
480 /* Move day-1 days from the first of the month. First try to
481 * get off cheap if we're only one day out of range
482 * (adjustments for timezone alone can't be worse than that).
483 */
484 if (*d == 0) {
485 --*m;
486 if (*m > 0)
487 *d = days_in_month(*y, *m);
488 else {
489 --*y;
490 *m = 12;
491 *d = 31;
492 }
493 }
494 else if (*d == dim + 1) {
495 /* move forward a day */
496 ++*m;
497 *d = 1;
498 if (*m > 12) {
499 *m = 1;
500 ++*y;
501 }
502 }
503 else {
504 int ordinal = ymd_to_ord(*y, *m, 1) +
505 *d - 1;
506 ord_to_ymd(ordinal, y, m, d);
507 }
508 }
509 assert(*m > 0);
510 assert(*d > 0);
511}
512
513/* Fiddle out-of-bounds months and days so that the result makes some kind
514 * of sense. The parameters are both inputs and outputs. Returns < 0 on
515 * failure, where failure means the adjusted year is out of bounds.
516 */
517static int
518normalize_date(int *year, int *month, int *day)
519{
520 int result;
521
522 normalize_y_m_d(year, month, day);
523 if (MINYEAR <= *year && *year <= MAXYEAR)
524 result = 0;
525 else {
526 PyErr_SetString(PyExc_OverflowError,
527 "date value out of range");
528 result = -1;
529 }
530 return result;
531}
532
533/* Force all the datetime fields into range. The parameters are both
534 * inputs and outputs. Returns < 0 on error.
535 */
536static int
537normalize_datetime(int *year, int *month, int *day,
538 int *hour, int *minute, int *second,
539 int *microsecond)
540{
541 normalize_pair(second, microsecond, 1000000);
542 normalize_pair(minute, second, 60);
543 normalize_pair(hour, minute, 60);
544 normalize_pair(day, hour, 24);
545 return normalize_date(year, month, day);
546}
547
548/* ---------------------------------------------------------------------------
549 * tzinfo helpers.
550 */
551
Tim Peters855fe882002-12-22 03:43:39 +0000552/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
553 * raise TypeError and return -1.
554 */
555static int
556check_tzinfo_subclass(PyObject *p)
557{
558 if (p == Py_None || PyTZInfo_Check(p))
559 return 0;
560 PyErr_Format(PyExc_TypeError,
561 "tzinfo argument must be None or of a tzinfo subclass, "
562 "not type '%s'",
563 p->ob_type->tp_name);
564 return -1;
565}
566
567/* Return tzinfo.methname(self), without any checking of results.
568 * If tzinfo is None, returns None.
569 */
570static PyObject *
571call_tzinfo_method(PyObject *self, PyObject *tzinfo, char *methname)
572{
573 PyObject *result;
574
575 assert(self && tzinfo && methname);
576 assert(check_tzinfo_subclass(tzinfo) >= 0);
577 if (tzinfo == Py_None) {
578 result = Py_None;
579 Py_INCREF(result);
580 }
581 else
582 result = PyObject_CallMethod(tzinfo, methname, "O", self);
583 return result;
584}
585
Tim Peters2a799bf2002-12-16 20:18:38 +0000586/* If self has a tzinfo member, return a BORROWED reference to it. Else
587 * return NULL, which is NOT AN ERROR. There are no error returns here,
588 * and the caller must not decref the result.
589 */
590static PyObject *
591get_tzinfo_member(PyObject *self)
592{
593 PyObject *tzinfo = NULL;
594
595 if (PyDateTimeTZ_Check(self))
596 tzinfo = ((PyDateTime_DateTimeTZ *)self)->tzinfo;
597 else if (PyTimeTZ_Check(self))
598 tzinfo = ((PyDateTime_TimeTZ *)self)->tzinfo;
599
600 return tzinfo;
601}
602
Tim Peters2a799bf2002-12-16 20:18:38 +0000603/* Internal helper.
604 * Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
605 * result. tzinfo must be an instance of the tzinfo class. If the method
606 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters855fe882002-12-22 03:43:39 +0000607 * return a Python int or long or timedelta, TypeError is raised and this
608 * returns -1. If it returns an int or long, but is outside the valid
609 * range for a UTC minute offset, or it returns a timedelta and the value is
610 * out of range or isn't a whole number of minutes, ValueError is raised and
611 * this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000612 * Else *none is set to 0 and the integer method result is returned.
613 */
614static int
615call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
616 int *none)
617{
618 PyObject *u;
619 long result = -1; /* Py{Int,Long}_AsLong return long */
620
621 assert(tzinfo != NULL);
622 assert(PyTZInfo_Check(tzinfo));
623 assert(tzinfoarg != NULL);
624
625 *none = 0;
Tim Peters855fe882002-12-22 03:43:39 +0000626 u = call_tzinfo_method(tzinfoarg, tzinfo, name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000627 if (u == NULL)
628 return -1;
629
630 if (u == Py_None) {
631 result = 0;
632 *none = 1;
633 goto Done;
634 }
635
636 if (PyInt_Check(u))
637 result = PyInt_AS_LONG(u);
Tim Peters855fe882002-12-22 03:43:39 +0000638
Tim Peters2a799bf2002-12-16 20:18:38 +0000639 else if (PyLong_Check(u))
640 result = PyLong_AsLong(u);
Tim Peters855fe882002-12-22 03:43:39 +0000641
642 else if (PyDelta_Check(u)) {
643 const int days = GET_TD_DAYS(u);
644 if (days < -1 || days > 0)
645 result = 24*60; /* trigger ValueError below */
646 else {
647 /* next line can't overflow because we know days
648 * is -1 or 0 now
649 */
650 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
651 result = divmod(ss, 60, &ss);
652 if (ss || GET_TD_MICROSECONDS(u)) {
653 PyErr_Format(PyExc_ValueError,
654 "tzinfo.%s() must return a "
655 "whole number of minutes",
656 name);
657 result = -1;
658 goto Done;
659 }
660 }
661 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000662 else {
663 PyErr_Format(PyExc_TypeError,
Tim Peters855fe882002-12-22 03:43:39 +0000664 "tzinfo.%s() must return None, integer or "
665 "timedelta, not '%s'",
666 name, u->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000667 goto Done;
668 }
669
670Done:
671 Py_DECREF(u);
672 if (result < -1439 || result > 1439) {
673 PyErr_Format(PyExc_ValueError,
674 "tzinfo.%s() returned %ld; must be in "
675 "-1439 .. 1439",
676 name, result);
677 result = -1;
678 }
679 return (int)result;
680}
681
682/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
683 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
684 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
685 & doesn't return a Python int or long, TypeError is raised and this
686 * returns -1. If utcoffset() returns an int outside the legitimate range
687 * for a UTC offset, ValueError is raised and this returns -1. Else
688 * *none is set to 0 and the offset is returned.
689 */
690static int
691call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
692{
693 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
694}
695
Tim Peters855fe882002-12-22 03:43:39 +0000696static PyObject *new_delta(int d, int sec, int usec, int normalize);
697
698/* Call tzinfo.name(self) and return the offset as a timedelta or None. */
699static PyObject *
700offset_as_timedelta(PyObject *self, PyObject *tzinfo, char *name) {
701 PyObject *result;
702
703 if (tzinfo == Py_None) {
704 result = Py_None;
705 Py_INCREF(result);
706 }
707 else {
708 int none;
709 int offset = call_utc_tzinfo_method(tzinfo, name, self, &none);
710 if (offset < 0 && PyErr_Occurred())
711 return NULL;
712 if (none) {
713 result = Py_None;
714 Py_INCREF(result);
715 }
716 else
717 result = new_delta(0, offset * 60, 0, 1);
718 }
719 return result;
720}
721
Tim Peters2a799bf2002-12-16 20:18:38 +0000722/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
723 * result. tzinfo must be an instance of the tzinfo class. If dst()
724 * returns None, call_dst returns 0 and sets *none to 1. If dst()
725 & doesn't return a Python int or long, TypeError is raised and this
726 * returns -1. If dst() returns an int outside the legitimate range
727 * for a UTC offset, ValueError is raised and this returns -1. Else
728 * *none is set to 0 and the offset is returned.
729 */
730static int
731call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
732{
733 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
734}
735
Tim Peters855fe882002-12-22 03:43:39 +0000736/* Call tzinfo.tzname(self), and return the result. tzinfo must be
737 * an instance of the tzinfo class or None. If tzinfo isn't None, and
738 * tzname() doesn't return None ora string, TypeError is raised and this
739 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000740 */
741static PyObject *
Tim Peters855fe882002-12-22 03:43:39 +0000742call_tzname(PyObject *self, PyObject *tzinfo)
Tim Peters2a799bf2002-12-16 20:18:38 +0000743{
744 PyObject *result;
745
Tim Peters855fe882002-12-22 03:43:39 +0000746 assert(self != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000747 assert(tzinfo != NULL);
Tim Peters855fe882002-12-22 03:43:39 +0000748 assert(check_tzinfo_subclass(tzinfo) >= 0);
Tim Peters2a799bf2002-12-16 20:18:38 +0000749
Tim Peters855fe882002-12-22 03:43:39 +0000750 if (tzinfo == Py_None) {
751 result = Py_None;
752 Py_INCREF(result);
753 }
754 else
755 result = PyObject_CallMethod(tzinfo, "tzname", "O", self);
756
757 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
758 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
Tim Peters2a799bf2002-12-16 20:18:38 +0000759 "return None or a string, not '%s'",
760 result->ob_type->tp_name);
761 Py_DECREF(result);
762 result = NULL;
763 }
764 return result;
765}
766
767typedef enum {
768 /* an exception has been set; the caller should pass it on */
769 OFFSET_ERROR,
770
771 /* type isn't date, datetime, datetimetz subclass, time, or
772 * timetz subclass
773 */
774 OFFSET_UNKNOWN,
775
776 /* date,
777 * datetime,
778 * datetimetz with None tzinfo,
Tim Peters855fe882002-12-22 03:43:39 +0000779 * datetimetz where utcoffset() returns None
Tim Peters2a799bf2002-12-16 20:18:38 +0000780 * time,
781 * timetz with None tzinfo,
782 * timetz where utcoffset() returns None
783 */
784 OFFSET_NAIVE,
785
786 /* timetz where utcoffset() doesn't return None,
787 * datetimetz where utcoffset() doesn't return None
788 */
789 OFFSET_AWARE,
790} naivety;
791
Tim Peters14b69412002-12-22 18:10:22 +0000792/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000793 * the "naivety" typedef for details. If the type is aware, *offset is set
794 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000795 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peters2a799bf2002-12-16 20:18:38 +0000796 */
797static naivety
Tim Peters14b69412002-12-22 18:10:22 +0000798classify_utcoffset(PyObject *op, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000799{
800 int none;
801 PyObject *tzinfo;
802
803 *offset = 0;
Tim Peters14b69412002-12-22 18:10:22 +0000804 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
Tim Peters2a799bf2002-12-16 20:18:38 +0000805 if (tzinfo == Py_None)
806 return OFFSET_NAIVE;
Tim Peters14b69412002-12-22 18:10:22 +0000807 if (tzinfo == NULL) {
808 /* note that a datetime passes the PyDate_Check test */
809 return (PyTime_Check(op) || PyDate_Check(op)) ?
810 OFFSET_NAIVE : OFFSET_UNKNOWN;
811 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000812 *offset = call_utcoffset(tzinfo, op, &none);
813 if (*offset == -1 && PyErr_Occurred())
814 return OFFSET_ERROR;
815 return none ? OFFSET_NAIVE : OFFSET_AWARE;
816}
817
818/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
819 * stuff
820 * ", tzinfo=" + repr(tzinfo)
821 * before the closing ")".
822 */
823static PyObject *
824append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
825{
826 PyObject *temp;
827
828 assert(PyString_Check(repr));
829 assert(tzinfo);
830 if (tzinfo == Py_None)
831 return repr;
832 /* Get rid of the trailing ')'. */
833 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
834 temp = PyString_FromStringAndSize(PyString_AsString(repr),
835 PyString_Size(repr) - 1);
836 Py_DECREF(repr);
837 if (temp == NULL)
838 return NULL;
839 repr = temp;
840
841 /* Append ", tzinfo=". */
842 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
843
844 /* Append repr(tzinfo). */
845 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
846
847 /* Add a closing paren. */
848 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
849 return repr;
850}
851
852/* ---------------------------------------------------------------------------
853 * String format helpers.
854 */
855
856static PyObject *
857format_ctime(PyDateTime_Date *date,
858 int hours, int minutes, int seconds)
859{
860 static char *DayNames[] = {
861 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
862 };
863 static char *MonthNames[] = {
864 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
865 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
866 };
867
868 char buffer[128];
869 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
870
871 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
872 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
873 GET_DAY(date), hours, minutes, seconds,
874 GET_YEAR(date));
875 return PyString_FromString(buffer);
876}
877
878/* Add an hours & minutes UTC offset string to buf. buf has no more than
879 * buflen bytes remaining. The UTC offset is gotten by calling
880 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
881 * *buf, and that's all. Else the returned value is checked for sanity (an
882 * integer in range), and if that's OK it's converted to an hours & minutes
883 * string of the form
884 * sign HH sep MM
885 * Returns 0 if everything is OK. If the return value from utcoffset() is
886 * bogus, an appropriate exception is set and -1 is returned.
887 */
888static int
Tim Peters328fff72002-12-20 01:31:27 +0000889format_utcoffset(char *buf, size_t buflen, const char *sep,
Tim Peters2a799bf2002-12-16 20:18:38 +0000890 PyObject *tzinfo, PyObject *tzinfoarg)
891{
892 int offset;
893 int hours;
894 int minutes;
895 char sign;
896 int none;
897
898 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
899 if (offset == -1 && PyErr_Occurred())
900 return -1;
901 if (none) {
902 *buf = '\0';
903 return 0;
904 }
905 sign = '+';
906 if (offset < 0) {
907 sign = '-';
908 offset = - offset;
909 }
910 hours = divmod(offset, 60, &minutes);
911 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
912 return 0;
913}
914
915/* I sure don't want to reproduce the strftime code from the time module,
916 * so this imports the module and calls it. All the hair is due to
917 * giving special meanings to the %z and %Z format codes via a preprocessing
918 * step on the format string.
919 */
920static PyObject *
921wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple)
922{
923 PyObject *result = NULL; /* guilty until proved innocent */
924
925 PyObject *zreplacement = NULL; /* py string, replacement for %z */
926 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
927
928 char *pin; /* pointer to next char in input format */
929 char ch; /* next char in input format */
930
931 PyObject *newfmt = NULL; /* py string, the output format */
932 char *pnew; /* pointer to available byte in output format */
933 char totalnew; /* number bytes total in output format buffer,
934 exclusive of trailing \0 */
935 char usednew; /* number bytes used so far in output format buffer */
936
937 char *ptoappend; /* pointer to string to append to output buffer */
938 int ntoappend; /* # of bytes to append to output buffer */
939
Tim Peters2a799bf2002-12-16 20:18:38 +0000940 assert(object && format && timetuple);
941 assert(PyString_Check(format));
942
943 /* Scan the input format, looking for %z and %Z escapes, building
Tim Peters328fff72002-12-20 01:31:27 +0000944 * a new format. Since computing the replacements for those codes
945 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +0000946 */
947 totalnew = PyString_Size(format); /* realistic if no %z/%Z */
948 newfmt = PyString_FromStringAndSize(NULL, totalnew);
949 if (newfmt == NULL) goto Done;
950 pnew = PyString_AsString(newfmt);
951 usednew = 0;
952
953 pin = PyString_AsString(format);
954 while ((ch = *pin++) != '\0') {
955 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +0000956 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000957 ntoappend = 1;
958 }
959 else if ((ch = *pin++) == '\0') {
960 /* There's a lone trailing %; doesn't make sense. */
961 PyErr_SetString(PyExc_ValueError, "strftime format "
962 "ends with raw %");
963 goto Done;
964 }
965 /* A % has been seen and ch is the character after it. */
966 else if (ch == 'z') {
967 if (zreplacement == NULL) {
968 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +0000969 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +0000970 PyObject *tzinfo = get_tzinfo_member(object);
971 zreplacement = PyString_FromString("");
972 if (zreplacement == NULL) goto Done;
973 if (tzinfo != Py_None && tzinfo != NULL) {
974 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +0000975 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +0000976 "",
977 tzinfo,
978 object) < 0)
979 goto Done;
980 Py_DECREF(zreplacement);
981 zreplacement = PyString_FromString(buf);
982 if (zreplacement == NULL) goto Done;
983 }
984 }
985 assert(zreplacement != NULL);
986 ptoappend = PyString_AsString(zreplacement);
987 ntoappend = PyString_Size(zreplacement);
988 }
989 else if (ch == 'Z') {
990 /* format tzname */
991 if (Zreplacement == NULL) {
992 PyObject *tzinfo = get_tzinfo_member(object);
993 Zreplacement = PyString_FromString("");
994 if (Zreplacement == NULL) goto Done;
995 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Peters855fe882002-12-22 03:43:39 +0000996 PyObject *temp = call_tzname(object,
997 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +0000998 if (temp == NULL) goto Done;
999 if (temp != Py_None) {
1000 assert(PyString_Check(temp));
1001 /* Since the tzname is getting
1002 * stuffed into the format, we
1003 * have to double any % signs
1004 * so that strftime doesn't
1005 * treat them as format codes.
1006 */
1007 Py_DECREF(Zreplacement);
1008 Zreplacement = PyObject_CallMethod(
1009 temp, "replace",
1010 "ss", "%", "%%");
1011 Py_DECREF(temp);
1012 if (Zreplacement == NULL)
1013 goto Done;
1014 }
1015 else
1016 Py_DECREF(temp);
1017 }
1018 }
1019 assert(Zreplacement != NULL);
1020 ptoappend = PyString_AsString(Zreplacement);
1021 ntoappend = PyString_Size(Zreplacement);
1022 }
1023 else {
Tim Peters328fff72002-12-20 01:31:27 +00001024 /* percent followed by neither z nor Z */
1025 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001026 ntoappend = 2;
1027 }
1028
1029 /* Append the ntoappend chars starting at ptoappend to
1030 * the new format.
1031 */
1032 assert(ntoappend >= 0);
1033 if (ntoappend == 0)
1034 continue;
1035 while (usednew + ntoappend > totalnew) {
1036 int bigger = totalnew << 1;
1037 if ((bigger >> 1) != totalnew) { /* overflow */
1038 PyErr_NoMemory();
1039 goto Done;
1040 }
1041 if (_PyString_Resize(&newfmt, bigger) < 0)
1042 goto Done;
1043 totalnew = bigger;
1044 pnew = PyString_AsString(newfmt) + usednew;
1045 }
1046 memcpy(pnew, ptoappend, ntoappend);
1047 pnew += ntoappend;
1048 usednew += ntoappend;
1049 assert(usednew <= totalnew);
1050 } /* end while() */
1051
1052 if (_PyString_Resize(&newfmt, usednew) < 0)
1053 goto Done;
1054 {
1055 PyObject *time = PyImport_ImportModule("time");
1056 if (time == NULL)
1057 goto Done;
1058 result = PyObject_CallMethod(time, "strftime", "OO",
1059 newfmt, timetuple);
1060 Py_DECREF(time);
1061 }
1062 Done:
1063 Py_XDECREF(zreplacement);
1064 Py_XDECREF(Zreplacement);
1065 Py_XDECREF(newfmt);
1066 return result;
1067}
1068
1069static char *
1070isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1071{
1072 int x;
1073 x = PyOS_snprintf(buffer, bufflen,
1074 "%04d-%02d-%02d",
1075 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1076 return buffer + x;
1077}
1078
1079static void
1080isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1081{
1082 int us = DATE_GET_MICROSECOND(dt);
1083
1084 PyOS_snprintf(buffer, bufflen,
1085 "%02d:%02d:%02d", /* 8 characters */
1086 DATE_GET_HOUR(dt),
1087 DATE_GET_MINUTE(dt),
1088 DATE_GET_SECOND(dt));
1089 if (us)
1090 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1091}
1092
1093/* ---------------------------------------------------------------------------
1094 * Wrap functions from the time module. These aren't directly available
1095 * from C. Perhaps they should be.
1096 */
1097
1098/* Call time.time() and return its result (a Python float). */
1099static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001100time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001101{
1102 PyObject *result = NULL;
1103 PyObject *time = PyImport_ImportModule("time");
1104
1105 if (time != NULL) {
1106 result = PyObject_CallMethod(time, "time", "()");
1107 Py_DECREF(time);
1108 }
1109 return result;
1110}
1111
1112/* Build a time.struct_time. The weekday and day number are automatically
1113 * computed from the y,m,d args.
1114 */
1115static PyObject *
1116build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1117{
1118 PyObject *time;
1119 PyObject *result = NULL;
1120
1121 time = PyImport_ImportModule("time");
1122 if (time != NULL) {
1123 result = PyObject_CallMethod(time, "struct_time",
1124 "((iiiiiiiii))",
1125 y, m, d,
1126 hh, mm, ss,
1127 weekday(y, m, d),
1128 days_before_month(y, m) + d,
1129 dstflag);
1130 Py_DECREF(time);
1131 }
1132 return result;
1133}
1134
1135/* ---------------------------------------------------------------------------
1136 * Miscellaneous helpers.
1137 */
1138
1139/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1140 * The comparisons here all most naturally compute a cmp()-like result.
1141 * This little helper turns that into a bool result for rich comparisons.
1142 */
1143static PyObject *
1144diff_to_bool(int diff, int op)
1145{
1146 PyObject *result;
1147 int istrue;
1148
1149 switch (op) {
1150 case Py_EQ: istrue = diff == 0; break;
1151 case Py_NE: istrue = diff != 0; break;
1152 case Py_LE: istrue = diff <= 0; break;
1153 case Py_GE: istrue = diff >= 0; break;
1154 case Py_LT: istrue = diff < 0; break;
1155 case Py_GT: istrue = diff > 0; break;
1156 default:
1157 assert(! "op unknown");
1158 istrue = 0; /* To shut up compiler */
1159 }
1160 result = istrue ? Py_True : Py_False;
1161 Py_INCREF(result);
1162 return result;
1163}
1164
1165/* ---------------------------------------------------------------------------
1166 * Helpers for setting object fields. These work on pointers to the
1167 * appropriate base class.
1168 */
1169
1170/* For date, datetime and datetimetz. */
1171static void
1172set_date_fields(PyDateTime_Date *self, int y, int m, int d)
1173{
1174 self->hashcode = -1;
1175 SET_YEAR(self, y);
1176 SET_MONTH(self, m);
1177 SET_DAY(self, d);
1178}
1179
1180/* For datetime and datetimetz. */
1181static void
1182set_datetime_time_fields(PyDateTime_Date *self, int h, int m, int s, int us)
1183{
1184 DATE_SET_HOUR(self, h);
1185 DATE_SET_MINUTE(self, m);
1186 DATE_SET_SECOND(self, s);
1187 DATE_SET_MICROSECOND(self, us);
1188}
1189
1190/* For time and timetz. */
1191static void
1192set_time_fields(PyDateTime_Time *self, int h, int m, int s, int us)
1193{
1194 self->hashcode = -1;
1195 TIME_SET_HOUR(self, h);
1196 TIME_SET_MINUTE(self, m);
1197 TIME_SET_SECOND(self, s);
1198 TIME_SET_MICROSECOND(self, us);
1199}
1200
1201/* ---------------------------------------------------------------------------
1202 * Create various objects, mostly without range checking.
1203 */
1204
1205/* Create a date instance with no range checking. */
1206static PyObject *
1207new_date(int year, int month, int day)
1208{
1209 PyDateTime_Date *self;
1210
1211 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
1212 if (self != NULL)
1213 set_date_fields(self, year, month, day);
1214 return (PyObject *) self;
1215}
1216
1217/* Create a datetime instance with no range checking. */
1218static PyObject *
1219new_datetime(int year, int month, int day, int hour, int minute,
1220 int second, int usecond)
1221{
1222 PyDateTime_DateTime *self;
1223
1224 self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType);
1225 if (self != NULL) {
1226 set_date_fields((PyDateTime_Date *)self, year, month, day);
1227 set_datetime_time_fields((PyDateTime_Date *)self,
1228 hour, minute, second, usecond);
1229 }
1230 return (PyObject *) self;
1231}
1232
1233/* Create a datetimetz instance with no range checking. */
1234static PyObject *
1235new_datetimetz(int year, int month, int day, int hour, int minute,
1236 int second, int usecond, PyObject *tzinfo)
1237{
1238 PyDateTime_DateTimeTZ *self;
1239
1240 self = PyObject_New(PyDateTime_DateTimeTZ, &PyDateTime_DateTimeTZType);
1241 if (self != NULL) {
1242 set_date_fields((PyDateTime_Date *)self, year, month, day);
1243 set_datetime_time_fields((PyDateTime_Date *)self,
1244 hour, minute, second, usecond);
1245 Py_INCREF(tzinfo);
1246 self->tzinfo = tzinfo;
1247 }
1248 return (PyObject *) self;
1249}
1250
1251/* Create a time instance with no range checking. */
1252static PyObject *
1253new_time(int hour, int minute, int second, int usecond)
1254{
1255 PyDateTime_Time *self;
1256
1257 self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType);
1258 if (self != NULL)
1259 set_time_fields(self, hour, minute, second, usecond);
1260 return (PyObject *) self;
1261}
1262
1263/* Create a timetz instance with no range checking. */
1264static PyObject *
1265new_timetz(int hour, int minute, int second, int usecond, PyObject *tzinfo)
1266{
1267 PyDateTime_TimeTZ *self;
1268
1269 self = PyObject_New(PyDateTime_TimeTZ, &PyDateTime_TimeTZType);
1270 if (self != NULL) {
1271 set_time_fields((PyDateTime_Time *)self,
1272 hour, minute, second, usecond);
1273 Py_INCREF(tzinfo);
1274 self->tzinfo = tzinfo;
1275 }
1276 return (PyObject *) self;
1277}
1278
1279/* Create a timedelta instance. Normalize the members iff normalize is
1280 * true. Passing false is a speed optimization, if you know for sure
1281 * that seconds and microseconds are already in their proper ranges. In any
1282 * case, raises OverflowError and returns NULL if the normalized days is out
1283 * of range).
1284 */
1285static PyObject *
1286new_delta(int days, int seconds, int microseconds, int normalize)
1287{
1288 PyDateTime_Delta *self;
1289
1290 if (normalize)
1291 normalize_d_s_us(&days, &seconds, &microseconds);
1292 assert(0 <= seconds && seconds < 24*3600);
1293 assert(0 <= microseconds && microseconds < 1000000);
1294
1295 if (check_delta_day_range(days) < 0)
1296 return NULL;
1297
1298 self = PyObject_New(PyDateTime_Delta, &PyDateTime_DeltaType);
1299 if (self != NULL) {
1300 self->hashcode = -1;
1301 SET_TD_DAYS(self, days);
1302 SET_TD_SECONDS(self, seconds);
1303 SET_TD_MICROSECONDS(self, microseconds);
1304 }
1305 return (PyObject *) self;
1306}
1307
1308
1309/* ---------------------------------------------------------------------------
1310 * Cached Python objects; these are set by the module init function.
1311 */
1312
1313/* Conversion factors. */
1314static PyObject *us_per_us = NULL; /* 1 */
1315static PyObject *us_per_ms = NULL; /* 1000 */
1316static PyObject *us_per_second = NULL; /* 1000000 */
1317static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1318static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1319static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1320static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1321static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1322
1323/* Callables to support unpickling. */
1324static PyObject *date_unpickler_object = NULL;
1325static PyObject *datetime_unpickler_object = NULL;
1326static PyObject *datetimetz_unpickler_object = NULL;
1327static PyObject *tzinfo_unpickler_object = NULL;
1328static PyObject *time_unpickler_object = NULL;
1329static PyObject *timetz_unpickler_object = NULL;
1330
1331/* ---------------------------------------------------------------------------
1332 * Class implementations.
1333 */
1334
1335/*
1336 * PyDateTime_Delta implementation.
1337 */
1338
1339/* Convert a timedelta to a number of us,
1340 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1341 * as a Python int or long.
1342 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1343 * due to ubiquitous overflow possibilities.
1344 */
1345static PyObject *
1346delta_to_microseconds(PyDateTime_Delta *self)
1347{
1348 PyObject *x1 = NULL;
1349 PyObject *x2 = NULL;
1350 PyObject *x3 = NULL;
1351 PyObject *result = NULL;
1352
1353 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1354 if (x1 == NULL)
1355 goto Done;
1356 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1357 if (x2 == NULL)
1358 goto Done;
1359 Py_DECREF(x1);
1360 x1 = NULL;
1361
1362 /* x2 has days in seconds */
1363 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1364 if (x1 == NULL)
1365 goto Done;
1366 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1367 if (x3 == NULL)
1368 goto Done;
1369 Py_DECREF(x1);
1370 Py_DECREF(x2);
1371 x1 = x2 = NULL;
1372
1373 /* x3 has days+seconds in seconds */
1374 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1375 if (x1 == NULL)
1376 goto Done;
1377 Py_DECREF(x3);
1378 x3 = NULL;
1379
1380 /* x1 has days+seconds in us */
1381 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1382 if (x2 == NULL)
1383 goto Done;
1384 result = PyNumber_Add(x1, x2);
1385
1386Done:
1387 Py_XDECREF(x1);
1388 Py_XDECREF(x2);
1389 Py_XDECREF(x3);
1390 return result;
1391}
1392
1393/* Convert a number of us (as a Python int or long) to a timedelta.
1394 */
1395static PyObject *
1396microseconds_to_delta(PyObject *pyus)
1397{
1398 int us;
1399 int s;
1400 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001401 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001402
1403 PyObject *tuple = NULL;
1404 PyObject *num = NULL;
1405 PyObject *result = NULL;
1406
1407 tuple = PyNumber_Divmod(pyus, us_per_second);
1408 if (tuple == NULL)
1409 goto Done;
1410
1411 num = PyTuple_GetItem(tuple, 1); /* us */
1412 if (num == NULL)
1413 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001414 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001415 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001416 if (temp == -1 && PyErr_Occurred())
1417 goto Done;
1418 assert(0 <= temp && temp < 1000000);
1419 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001420 if (us < 0) {
1421 /* The divisor was positive, so this must be an error. */
1422 assert(PyErr_Occurred());
1423 goto Done;
1424 }
1425
1426 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1427 if (num == NULL)
1428 goto Done;
1429 Py_INCREF(num);
1430 Py_DECREF(tuple);
1431
1432 tuple = PyNumber_Divmod(num, seconds_per_day);
1433 if (tuple == NULL)
1434 goto Done;
1435 Py_DECREF(num);
1436
1437 num = PyTuple_GetItem(tuple, 1); /* seconds */
1438 if (num == NULL)
1439 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001440 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001441 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001442 if (temp == -1 && PyErr_Occurred())
1443 goto Done;
1444 assert(0 <= temp && temp < 24*3600);
1445 s = (int)temp;
1446
Tim Peters2a799bf2002-12-16 20:18:38 +00001447 if (s < 0) {
1448 /* The divisor was positive, so this must be an error. */
1449 assert(PyErr_Occurred());
1450 goto Done;
1451 }
1452
1453 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1454 if (num == NULL)
1455 goto Done;
1456 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001457 temp = PyLong_AsLong(num);
1458 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001459 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001460 d = (int)temp;
1461 if ((long)d != temp) {
1462 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1463 "large to fit in a C int");
1464 goto Done;
1465 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001466 result = new_delta(d, s, us, 0);
1467
1468Done:
1469 Py_XDECREF(tuple);
1470 Py_XDECREF(num);
1471 return result;
1472}
1473
1474static PyObject *
1475multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1476{
1477 PyObject *pyus_in;
1478 PyObject *pyus_out;
1479 PyObject *result;
1480
1481 pyus_in = delta_to_microseconds(delta);
1482 if (pyus_in == NULL)
1483 return NULL;
1484
1485 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1486 Py_DECREF(pyus_in);
1487 if (pyus_out == NULL)
1488 return NULL;
1489
1490 result = microseconds_to_delta(pyus_out);
1491 Py_DECREF(pyus_out);
1492 return result;
1493}
1494
1495static PyObject *
1496divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1497{
1498 PyObject *pyus_in;
1499 PyObject *pyus_out;
1500 PyObject *result;
1501
1502 pyus_in = delta_to_microseconds(delta);
1503 if (pyus_in == NULL)
1504 return NULL;
1505
1506 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1507 Py_DECREF(pyus_in);
1508 if (pyus_out == NULL)
1509 return NULL;
1510
1511 result = microseconds_to_delta(pyus_out);
1512 Py_DECREF(pyus_out);
1513 return result;
1514}
1515
1516static PyObject *
1517delta_add(PyObject *left, PyObject *right)
1518{
1519 PyObject *result = Py_NotImplemented;
1520
1521 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1522 /* delta + delta */
1523 /* The C-level additions can't overflow because of the
1524 * invariant bounds.
1525 */
1526 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1527 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1528 int microseconds = GET_TD_MICROSECONDS(left) +
1529 GET_TD_MICROSECONDS(right);
1530 result = new_delta(days, seconds, microseconds, 1);
1531 }
1532
1533 if (result == Py_NotImplemented)
1534 Py_INCREF(result);
1535 return result;
1536}
1537
1538static PyObject *
1539delta_negative(PyDateTime_Delta *self)
1540{
1541 return new_delta(-GET_TD_DAYS(self),
1542 -GET_TD_SECONDS(self),
1543 -GET_TD_MICROSECONDS(self),
1544 1);
1545}
1546
1547static PyObject *
1548delta_positive(PyDateTime_Delta *self)
1549{
1550 /* Could optimize this (by returning self) if this isn't a
1551 * subclass -- but who uses unary + ? Approximately nobody.
1552 */
1553 return new_delta(GET_TD_DAYS(self),
1554 GET_TD_SECONDS(self),
1555 GET_TD_MICROSECONDS(self),
1556 0);
1557}
1558
1559static PyObject *
1560delta_abs(PyDateTime_Delta *self)
1561{
1562 PyObject *result;
1563
1564 assert(GET_TD_MICROSECONDS(self) >= 0);
1565 assert(GET_TD_SECONDS(self) >= 0);
1566
1567 if (GET_TD_DAYS(self) < 0)
1568 result = delta_negative(self);
1569 else
1570 result = delta_positive(self);
1571
1572 return result;
1573}
1574
1575static PyObject *
1576delta_subtract(PyObject *left, PyObject *right)
1577{
1578 PyObject *result = Py_NotImplemented;
1579
1580 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1581 /* delta - delta */
1582 PyObject *minus_right = PyNumber_Negative(right);
1583 if (minus_right) {
1584 result = delta_add(left, minus_right);
1585 Py_DECREF(minus_right);
1586 }
1587 else
1588 result = NULL;
1589 }
1590
1591 if (result == Py_NotImplemented)
1592 Py_INCREF(result);
1593 return result;
1594}
1595
1596/* This is more natural as a tp_compare, but doesn't work then: for whatever
1597 * reason, Python's try_3way_compare ignores tp_compare unless
1598 * PyInstance_Check returns true, but these aren't old-style classes.
1599 */
1600static PyObject *
1601delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1602{
1603 int diff;
1604
1605 if (! PyDelta_CheckExact(other)) {
1606 PyErr_Format(PyExc_TypeError,
1607 "can't compare %s to %s instance",
1608 self->ob_type->tp_name, other->ob_type->tp_name);
1609 return NULL;
1610 }
1611 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1612 if (diff == 0) {
1613 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1614 if (diff == 0)
1615 diff = GET_TD_MICROSECONDS(self) -
1616 GET_TD_MICROSECONDS(other);
1617 }
1618 return diff_to_bool(diff, op);
1619}
1620
1621static PyObject *delta_getstate(PyDateTime_Delta *self);
1622
1623static long
1624delta_hash(PyDateTime_Delta *self)
1625{
1626 if (self->hashcode == -1) {
1627 PyObject *temp = delta_getstate(self);
1628 if (temp != NULL) {
1629 self->hashcode = PyObject_Hash(temp);
1630 Py_DECREF(temp);
1631 }
1632 }
1633 return self->hashcode;
1634}
1635
1636static PyObject *
1637delta_multiply(PyObject *left, PyObject *right)
1638{
1639 PyObject *result = Py_NotImplemented;
1640
1641 if (PyDelta_Check(left)) {
1642 /* delta * ??? */
1643 if (PyInt_Check(right) || PyLong_Check(right))
1644 result = multiply_int_timedelta(right,
1645 (PyDateTime_Delta *) left);
1646 }
1647 else if (PyInt_Check(left) || PyLong_Check(left))
1648 result = multiply_int_timedelta(left,
1649 (PyDateTime_Delta *) right);
1650
1651 if (result == Py_NotImplemented)
1652 Py_INCREF(result);
1653 return result;
1654}
1655
1656static PyObject *
1657delta_divide(PyObject *left, PyObject *right)
1658{
1659 PyObject *result = Py_NotImplemented;
1660
1661 if (PyDelta_Check(left)) {
1662 /* delta * ??? */
1663 if (PyInt_Check(right) || PyLong_Check(right))
1664 result = divide_timedelta_int(
1665 (PyDateTime_Delta *)left,
1666 right);
1667 }
1668
1669 if (result == Py_NotImplemented)
1670 Py_INCREF(result);
1671 return result;
1672}
1673
1674/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1675 * timedelta constructor. sofar is the # of microseconds accounted for
1676 * so far, and there are factor microseconds per current unit, the number
1677 * of which is given by num. num * factor is added to sofar in a
1678 * numerically careful way, and that's the result. Any fractional
1679 * microseconds left over (this can happen if num is a float type) are
1680 * added into *leftover.
1681 * Note that there are many ways this can give an error (NULL) return.
1682 */
1683static PyObject *
1684accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1685 double *leftover)
1686{
1687 PyObject *prod;
1688 PyObject *sum;
1689
1690 assert(num != NULL);
1691
1692 if (PyInt_Check(num) || PyLong_Check(num)) {
1693 prod = PyNumber_Multiply(num, factor);
1694 if (prod == NULL)
1695 return NULL;
1696 sum = PyNumber_Add(sofar, prod);
1697 Py_DECREF(prod);
1698 return sum;
1699 }
1700
1701 if (PyFloat_Check(num)) {
1702 double dnum;
1703 double fracpart;
1704 double intpart;
1705 PyObject *x;
1706 PyObject *y;
1707
1708 /* The Plan: decompose num into an integer part and a
1709 * fractional part, num = intpart + fracpart.
1710 * Then num * factor ==
1711 * intpart * factor + fracpart * factor
1712 * and the LHS can be computed exactly in long arithmetic.
1713 * The RHS is again broken into an int part and frac part.
1714 * and the frac part is added into *leftover.
1715 */
1716 dnum = PyFloat_AsDouble(num);
1717 if (dnum == -1.0 && PyErr_Occurred())
1718 return NULL;
1719 fracpart = modf(dnum, &intpart);
1720 x = PyLong_FromDouble(intpart);
1721 if (x == NULL)
1722 return NULL;
1723
1724 prod = PyNumber_Multiply(x, factor);
1725 Py_DECREF(x);
1726 if (prod == NULL)
1727 return NULL;
1728
1729 sum = PyNumber_Add(sofar, prod);
1730 Py_DECREF(prod);
1731 if (sum == NULL)
1732 return NULL;
1733
1734 if (fracpart == 0.0)
1735 return sum;
1736 /* So far we've lost no information. Dealing with the
1737 * fractional part requires float arithmetic, and may
1738 * lose a little info.
1739 */
1740 assert(PyInt_Check(factor) || PyLong_Check(factor));
1741 if (PyInt_Check(factor))
1742 dnum = (double)PyInt_AsLong(factor);
1743 else
1744 dnum = PyLong_AsDouble(factor);
1745
1746 dnum *= fracpart;
1747 fracpart = modf(dnum, &intpart);
1748 x = PyLong_FromDouble(intpart);
1749 if (x == NULL) {
1750 Py_DECREF(sum);
1751 return NULL;
1752 }
1753
1754 y = PyNumber_Add(sum, x);
1755 Py_DECREF(sum);
1756 Py_DECREF(x);
1757 *leftover += fracpart;
1758 return y;
1759 }
1760
1761 PyErr_Format(PyExc_TypeError,
1762 "unsupported type for timedelta %s component: %s",
1763 tag, num->ob_type->tp_name);
1764 return NULL;
1765}
1766
1767static PyObject *
1768delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1769{
1770 PyObject *self = NULL;
1771
1772 /* Argument objects. */
1773 PyObject *day = NULL;
1774 PyObject *second = NULL;
1775 PyObject *us = NULL;
1776 PyObject *ms = NULL;
1777 PyObject *minute = NULL;
1778 PyObject *hour = NULL;
1779 PyObject *week = NULL;
1780
1781 PyObject *x = NULL; /* running sum of microseconds */
1782 PyObject *y = NULL; /* temp sum of microseconds */
1783 double leftover_us = 0.0;
1784
1785 static char *keywords[] = {
1786 "days", "seconds", "microseconds", "milliseconds",
1787 "minutes", "hours", "weeks", NULL
1788 };
1789
1790 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1791 keywords,
1792 &day, &second, &us,
1793 &ms, &minute, &hour, &week) == 0)
1794 goto Done;
1795
1796 x = PyInt_FromLong(0);
1797 if (x == NULL)
1798 goto Done;
1799
1800#define CLEANUP \
1801 Py_DECREF(x); \
1802 x = y; \
1803 if (x == NULL) \
1804 goto Done
1805
1806 if (us) {
1807 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1808 CLEANUP;
1809 }
1810 if (ms) {
1811 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1812 CLEANUP;
1813 }
1814 if (second) {
1815 y = accum("seconds", x, second, us_per_second, &leftover_us);
1816 CLEANUP;
1817 }
1818 if (minute) {
1819 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1820 CLEANUP;
1821 }
1822 if (hour) {
1823 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1824 CLEANUP;
1825 }
1826 if (day) {
1827 y = accum("days", x, day, us_per_day, &leftover_us);
1828 CLEANUP;
1829 }
1830 if (week) {
1831 y = accum("weeks", x, week, us_per_week, &leftover_us);
1832 CLEANUP;
1833 }
1834 if (leftover_us) {
1835 /* Round to nearest whole # of us, and add into x. */
1836 PyObject *temp;
1837 if (leftover_us >= 0.0)
1838 leftover_us = floor(leftover_us + 0.5);
1839 else
1840 leftover_us = ceil(leftover_us - 0.5);
1841 temp = PyLong_FromDouble(leftover_us);
1842 if (temp == NULL) {
1843 Py_DECREF(x);
1844 goto Done;
1845 }
1846 y = PyNumber_Add(x, temp);
1847 Py_DECREF(temp);
1848 CLEANUP;
1849 }
1850
1851 self = microseconds_to_delta(x);
1852 Py_DECREF(x);
1853Done:
1854 return self;
1855
1856#undef CLEANUP
1857}
1858
1859static int
1860delta_nonzero(PyDateTime_Delta *self)
1861{
1862 return (GET_TD_DAYS(self) != 0
1863 || GET_TD_SECONDS(self) != 0
1864 || GET_TD_MICROSECONDS(self) != 0);
1865}
1866
1867static PyObject *
1868delta_repr(PyDateTime_Delta *self)
1869{
1870 if (GET_TD_MICROSECONDS(self) != 0)
1871 return PyString_FromFormat("%s(%d, %d, %d)",
1872 self->ob_type->tp_name,
1873 GET_TD_DAYS(self),
1874 GET_TD_SECONDS(self),
1875 GET_TD_MICROSECONDS(self));
1876 if (GET_TD_SECONDS(self) != 0)
1877 return PyString_FromFormat("%s(%d, %d)",
1878 self->ob_type->tp_name,
1879 GET_TD_DAYS(self),
1880 GET_TD_SECONDS(self));
1881
1882 return PyString_FromFormat("%s(%d)",
1883 self->ob_type->tp_name,
1884 GET_TD_DAYS(self));
1885}
1886
1887static PyObject *
1888delta_str(PyDateTime_Delta *self)
1889{
1890 int days = GET_TD_DAYS(self);
1891 int seconds = GET_TD_SECONDS(self);
1892 int us = GET_TD_MICROSECONDS(self);
1893 int hours;
1894 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001895 char buf[100];
1896 char *pbuf = buf;
1897 size_t buflen = sizeof(buf);
1898 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001899
1900 minutes = divmod(seconds, 60, &seconds);
1901 hours = divmod(minutes, 60, &minutes);
1902
1903 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00001904 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
1905 (days == 1 || days == -1) ? "" : "s");
1906 if (n < 0 || (size_t)n >= buflen)
1907 goto Fail;
1908 pbuf += n;
1909 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001910 }
1911
Tim Petersba873472002-12-18 20:19:21 +00001912 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
1913 hours, minutes, seconds);
1914 if (n < 0 || (size_t)n >= buflen)
1915 goto Fail;
1916 pbuf += n;
1917 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001918
1919 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00001920 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
1921 if (n < 0 || (size_t)n >= buflen)
1922 goto Fail;
1923 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001924 }
1925
Tim Petersba873472002-12-18 20:19:21 +00001926 return PyString_FromStringAndSize(buf, pbuf - buf);
1927
1928 Fail:
1929 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
1930 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001931}
1932
1933/* Pickle support. Quite a maze! While __getstate__/__setstate__ sufficed
1934 * in the Python implementation, the C implementation also requires
1935 * __reduce__, and a __safe_for_unpickling__ attr in the type object.
1936 */
1937static PyObject *
1938delta_getstate(PyDateTime_Delta *self)
1939{
1940 return Py_BuildValue("iii", GET_TD_DAYS(self),
1941 GET_TD_SECONDS(self),
1942 GET_TD_MICROSECONDS(self));
1943}
1944
1945static PyObject *
1946delta_setstate(PyDateTime_Delta *self, PyObject *state)
1947{
1948 int day;
1949 int second;
1950 int us;
1951
1952 if (!PyArg_ParseTuple(state, "iii:__setstate__", &day, &second, &us))
1953 return NULL;
1954
1955 self->hashcode = -1;
1956 SET_TD_DAYS(self, day);
1957 SET_TD_SECONDS(self, second);
1958 SET_TD_MICROSECONDS(self, us);
1959
1960 Py_INCREF(Py_None);
1961 return Py_None;
1962}
1963
1964static PyObject *
1965delta_reduce(PyDateTime_Delta* self)
1966{
1967 PyObject* result = NULL;
1968 PyObject* state = delta_getstate(self);
1969
1970 if (state != NULL) {
1971 /* The funky "()" in the format string creates an empty
1972 * tuple as the 2nd component of the result 3-tuple.
1973 */
1974 result = Py_BuildValue("O()O", self->ob_type, state);
1975 Py_DECREF(state);
1976 }
1977 return result;
1978}
1979
1980#define OFFSET(field) offsetof(PyDateTime_Delta, field)
1981
1982static PyMemberDef delta_members[] = {
Neal Norwitzdfb80862002-12-19 02:30:56 +00001983 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00001984 PyDoc_STR("Number of days.")},
1985
Neal Norwitzdfb80862002-12-19 02:30:56 +00001986 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00001987 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
1988
Neal Norwitzdfb80862002-12-19 02:30:56 +00001989 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00001990 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
1991 {NULL}
1992};
1993
1994static PyMethodDef delta_methods[] = {
1995 {"__setstate__", (PyCFunction)delta_setstate, METH_O,
1996 PyDoc_STR("__setstate__(state)")},
1997
1998 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
1999 PyDoc_STR("__setstate__(state)")},
2000
2001 {"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS,
2002 PyDoc_STR("__getstate__() -> state")},
2003 {NULL, NULL},
2004};
2005
2006static char delta_doc[] =
2007PyDoc_STR("Difference between two datetime values.");
2008
2009static PyNumberMethods delta_as_number = {
2010 delta_add, /* nb_add */
2011 delta_subtract, /* nb_subtract */
2012 delta_multiply, /* nb_multiply */
2013 delta_divide, /* nb_divide */
2014 0, /* nb_remainder */
2015 0, /* nb_divmod */
2016 0, /* nb_power */
2017 (unaryfunc)delta_negative, /* nb_negative */
2018 (unaryfunc)delta_positive, /* nb_positive */
2019 (unaryfunc)delta_abs, /* nb_absolute */
2020 (inquiry)delta_nonzero, /* nb_nonzero */
2021 0, /*nb_invert*/
2022 0, /*nb_lshift*/
2023 0, /*nb_rshift*/
2024 0, /*nb_and*/
2025 0, /*nb_xor*/
2026 0, /*nb_or*/
2027 0, /*nb_coerce*/
2028 0, /*nb_int*/
2029 0, /*nb_long*/
2030 0, /*nb_float*/
2031 0, /*nb_oct*/
2032 0, /*nb_hex*/
2033 0, /*nb_inplace_add*/
2034 0, /*nb_inplace_subtract*/
2035 0, /*nb_inplace_multiply*/
2036 0, /*nb_inplace_divide*/
2037 0, /*nb_inplace_remainder*/
2038 0, /*nb_inplace_power*/
2039 0, /*nb_inplace_lshift*/
2040 0, /*nb_inplace_rshift*/
2041 0, /*nb_inplace_and*/
2042 0, /*nb_inplace_xor*/
2043 0, /*nb_inplace_or*/
2044 delta_divide, /* nb_floor_divide */
2045 0, /* nb_true_divide */
2046 0, /* nb_inplace_floor_divide */
2047 0, /* nb_inplace_true_divide */
2048};
2049
2050static PyTypeObject PyDateTime_DeltaType = {
2051 PyObject_HEAD_INIT(NULL)
2052 0, /* ob_size */
2053 "datetime.timedelta", /* tp_name */
2054 sizeof(PyDateTime_Delta), /* tp_basicsize */
2055 0, /* tp_itemsize */
2056 0, /* tp_dealloc */
2057 0, /* tp_print */
2058 0, /* tp_getattr */
2059 0, /* tp_setattr */
2060 0, /* tp_compare */
2061 (reprfunc)delta_repr, /* tp_repr */
2062 &delta_as_number, /* tp_as_number */
2063 0, /* tp_as_sequence */
2064 0, /* tp_as_mapping */
2065 (hashfunc)delta_hash, /* tp_hash */
2066 0, /* tp_call */
2067 (reprfunc)delta_str, /* tp_str */
2068 PyObject_GenericGetAttr, /* tp_getattro */
2069 0, /* tp_setattro */
2070 0, /* tp_as_buffer */
2071 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
2072 delta_doc, /* tp_doc */
2073 0, /* tp_traverse */
2074 0, /* tp_clear */
2075 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2076 0, /* tp_weaklistoffset */
2077 0, /* tp_iter */
2078 0, /* tp_iternext */
2079 delta_methods, /* tp_methods */
2080 delta_members, /* tp_members */
2081 0, /* tp_getset */
2082 0, /* tp_base */
2083 0, /* tp_dict */
2084 0, /* tp_descr_get */
2085 0, /* tp_descr_set */
2086 0, /* tp_dictoffset */
2087 0, /* tp_init */
2088 0, /* tp_alloc */
2089 delta_new, /* tp_new */
2090 _PyObject_Del, /* tp_free */
2091};
2092
2093/*
2094 * PyDateTime_Date implementation.
2095 */
2096
2097/* Accessor properties. */
2098
2099static PyObject *
2100date_year(PyDateTime_Date *self, void *unused)
2101{
2102 return PyInt_FromLong(GET_YEAR(self));
2103}
2104
2105static PyObject *
2106date_month(PyDateTime_Date *self, void *unused)
2107{
2108 return PyInt_FromLong(GET_MONTH(self));
2109}
2110
2111static PyObject *
2112date_day(PyDateTime_Date *self, void *unused)
2113{
2114 return PyInt_FromLong(GET_DAY(self));
2115}
2116
2117static PyGetSetDef date_getset[] = {
2118 {"year", (getter)date_year},
2119 {"month", (getter)date_month},
2120 {"day", (getter)date_day},
2121 {NULL}
2122};
2123
2124/* Constructors. */
2125
2126static PyObject *
2127date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2128{
2129 PyObject *self = NULL;
2130 int year;
2131 int month;
2132 int day;
2133
2134 static char *keywords[] = {
2135 "year", "month", "day", NULL
2136 };
2137
2138 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", keywords,
2139 &year, &month, &day)) {
2140 if (check_date_args(year, month, day) < 0)
2141 return NULL;
2142 self = new_date(year, month, day);
2143 }
2144 return self;
2145}
2146
2147/* Return new date from localtime(t). */
2148static PyObject *
2149date_local_from_time_t(PyObject *cls, time_t t)
2150{
2151 struct tm *tm;
2152 PyObject *result = NULL;
2153
2154 tm = localtime(&t);
2155 if (tm)
2156 result = PyObject_CallFunction(cls, "iii",
2157 tm->tm_year + 1900,
2158 tm->tm_mon + 1,
2159 tm->tm_mday);
2160 else
2161 PyErr_SetString(PyExc_ValueError,
2162 "timestamp out of range for "
2163 "platform localtime() function");
2164 return result;
2165}
2166
2167/* Return new date from current time.
2168 * We say this is equivalent to fromtimestamp(time.time()), and the
2169 * only way to be sure of that is to *call* time.time(). That's not
2170 * generally the same as calling C's time.
2171 */
2172static PyObject *
2173date_today(PyObject *cls, PyObject *dummy)
2174{
2175 PyObject *time;
2176 PyObject *result;
2177
2178 time = time_time();
2179 if (time == NULL)
2180 return NULL;
2181
2182 /* Note well: today() is a class method, so this may not call
2183 * date.fromtimestamp. For example, it may call
2184 * datetime.fromtimestamp. That's why we need all the accuracy
2185 * time.time() delivers; if someone were gonzo about optimization,
2186 * date.today() could get away with plain C time().
2187 */
2188 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2189 Py_DECREF(time);
2190 return result;
2191}
2192
2193/* Return new date from given timestamp (Python timestamp -- a double). */
2194static PyObject *
2195date_fromtimestamp(PyObject *cls, PyObject *args)
2196{
2197 double timestamp;
2198 PyObject *result = NULL;
2199
2200 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2201 result = date_local_from_time_t(cls, (time_t)timestamp);
2202 return result;
2203}
2204
2205/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2206 * the ordinal is out of range.
2207 */
2208static PyObject *
2209date_fromordinal(PyObject *cls, PyObject *args)
2210{
2211 PyObject *result = NULL;
2212 int ordinal;
2213
2214 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2215 int year;
2216 int month;
2217 int day;
2218
2219 if (ordinal < 1)
2220 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2221 ">= 1");
2222 else {
2223 ord_to_ymd(ordinal, &year, &month, &day);
2224 result = PyObject_CallFunction(cls, "iii",
2225 year, month, day);
2226 }
2227 }
2228 return result;
2229}
2230
2231/*
2232 * Date arithmetic.
2233 */
2234
2235/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2236 * instead.
2237 */
2238static PyObject *
2239add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2240{
2241 PyObject *result = NULL;
2242 int year = GET_YEAR(date);
2243 int month = GET_MONTH(date);
2244 int deltadays = GET_TD_DAYS(delta);
2245 /* C-level overflow is impossible because |deltadays| < 1e9. */
2246 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2247
2248 if (normalize_date(&year, &month, &day) >= 0)
2249 result = new_date(year, month, day);
2250 return result;
2251}
2252
2253static PyObject *
2254date_add(PyObject *left, PyObject *right)
2255{
2256 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2257 Py_INCREF(Py_NotImplemented);
2258 return Py_NotImplemented;
2259 }
2260 if (PyDate_CheckExact(left)) {
2261 /* date + ??? */
2262 if (PyDelta_Check(right))
2263 /* date + delta */
2264 return add_date_timedelta((PyDateTime_Date *) left,
2265 (PyDateTime_Delta *) right,
2266 0);
2267 }
2268 else {
2269 /* ??? + date
2270 * 'right' must be one of us, or we wouldn't have been called
2271 */
2272 if (PyDelta_Check(left))
2273 /* delta + date */
2274 return add_date_timedelta((PyDateTime_Date *) right,
2275 (PyDateTime_Delta *) left,
2276 0);
2277 }
2278 Py_INCREF(Py_NotImplemented);
2279 return Py_NotImplemented;
2280}
2281
2282static PyObject *
2283date_subtract(PyObject *left, PyObject *right)
2284{
2285 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2286 Py_INCREF(Py_NotImplemented);
2287 return Py_NotImplemented;
2288 }
2289 if (PyDate_CheckExact(left)) {
2290 if (PyDate_CheckExact(right)) {
2291 /* date - date */
2292 int left_ord = ymd_to_ord(GET_YEAR(left),
2293 GET_MONTH(left),
2294 GET_DAY(left));
2295 int right_ord = ymd_to_ord(GET_YEAR(right),
2296 GET_MONTH(right),
2297 GET_DAY(right));
2298 return new_delta(left_ord - right_ord, 0, 0, 0);
2299 }
2300 if (PyDelta_Check(right)) {
2301 /* date - delta */
2302 return add_date_timedelta((PyDateTime_Date *) left,
2303 (PyDateTime_Delta *) right,
2304 1);
2305 }
2306 }
2307 Py_INCREF(Py_NotImplemented);
2308 return Py_NotImplemented;
2309}
2310
2311
2312/* Various ways to turn a date into a string. */
2313
2314static PyObject *
2315date_repr(PyDateTime_Date *self)
2316{
2317 char buffer[1028];
2318 char *typename;
2319
2320 typename = self->ob_type->tp_name;
2321 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2322 typename,
2323 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2324
2325 return PyString_FromString(buffer);
2326}
2327
2328static PyObject *
2329date_isoformat(PyDateTime_Date *self)
2330{
2331 char buffer[128];
2332
2333 isoformat_date(self, buffer, sizeof(buffer));
2334 return PyString_FromString(buffer);
2335}
2336
2337/* str() calls the appropriate isofomat() method. */
2338static PyObject *
2339date_str(PyDateTime_Date *self)
2340{
2341 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2342}
2343
2344
2345static PyObject *
2346date_ctime(PyDateTime_Date *self)
2347{
2348 return format_ctime(self, 0, 0, 0);
2349}
2350
2351static PyObject *
2352date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2353{
2354 /* This method can be inherited, and needs to call the
2355 * timetuple() method appropriate to self's class.
2356 */
2357 PyObject *result;
2358 PyObject *format;
2359 PyObject *tuple;
2360 static char *keywords[] = {"format", NULL};
2361
2362 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2363 &PyString_Type, &format))
2364 return NULL;
2365
2366 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2367 if (tuple == NULL)
2368 return NULL;
2369 result = wrap_strftime((PyObject *)self, format, tuple);
2370 Py_DECREF(tuple);
2371 return result;
2372}
2373
2374/* ISO methods. */
2375
2376static PyObject *
2377date_isoweekday(PyDateTime_Date *self)
2378{
2379 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2380
2381 return PyInt_FromLong(dow + 1);
2382}
2383
2384static PyObject *
2385date_isocalendar(PyDateTime_Date *self)
2386{
2387 int year = GET_YEAR(self);
2388 int week1_monday = iso_week1_monday(year);
2389 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2390 int week;
2391 int day;
2392
2393 week = divmod(today - week1_monday, 7, &day);
2394 if (week < 0) {
2395 --year;
2396 week1_monday = iso_week1_monday(year);
2397 week = divmod(today - week1_monday, 7, &day);
2398 }
2399 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2400 ++year;
2401 week = 0;
2402 }
2403 return Py_BuildValue("iii", year, week + 1, day + 1);
2404}
2405
2406/* Miscellaneous methods. */
2407
2408/* This is more natural as a tp_compare, but doesn't work then: for whatever
2409 * reason, Python's try_3way_compare ignores tp_compare unless
2410 * PyInstance_Check returns true, but these aren't old-style classes.
2411 */
2412static PyObject *
2413date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2414{
2415 int diff;
2416
2417 if (! PyDate_Check(other)) {
2418 PyErr_Format(PyExc_TypeError,
2419 "can't compare date to %s instance",
2420 other->ob_type->tp_name);
2421 return NULL;
2422 }
2423 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2424 _PyDateTime_DATE_DATASIZE);
2425 return diff_to_bool(diff, op);
2426}
2427
2428static PyObject *
2429date_timetuple(PyDateTime_Date *self)
2430{
2431 return build_struct_time(GET_YEAR(self),
2432 GET_MONTH(self),
2433 GET_DAY(self),
2434 0, 0, 0, -1);
2435}
2436
2437static PyObject *date_getstate(PyDateTime_Date *self);
2438
2439static long
2440date_hash(PyDateTime_Date *self)
2441{
2442 if (self->hashcode == -1) {
2443 PyObject *temp = date_getstate(self);
2444 if (temp != NULL) {
2445 self->hashcode = PyObject_Hash(temp);
2446 Py_DECREF(temp);
2447 }
2448 }
2449 return self->hashcode;
2450}
2451
2452static PyObject *
2453date_toordinal(PyDateTime_Date *self)
2454{
2455 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2456 GET_DAY(self)));
2457}
2458
2459static PyObject *
2460date_weekday(PyDateTime_Date *self)
2461{
2462 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2463
2464 return PyInt_FromLong(dow);
2465}
2466
2467/* Pickle support. Quite a maze! */
2468
2469static PyObject *
2470date_getstate(PyDateTime_Date *self)
2471{
2472 return PyString_FromStringAndSize(self->data,
2473 _PyDateTime_DATE_DATASIZE);
2474}
2475
2476static PyObject *
2477date_setstate(PyDateTime_Date *self, PyObject *state)
2478{
2479 const int len = PyString_Size(state);
2480 unsigned char *pdata = (unsigned char*)PyString_AsString(state);
2481
2482 if (! PyString_Check(state) ||
2483 len != _PyDateTime_DATE_DATASIZE) {
2484 PyErr_SetString(PyExc_TypeError,
2485 "bad argument to date.__setstate__");
2486 return NULL;
2487 }
2488 memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE);
2489 self->hashcode = -1;
2490
2491 Py_INCREF(Py_None);
2492 return Py_None;
2493}
2494
2495/* XXX This seems a ridiculously inefficient way to pickle a short string. */
2496static PyObject *
2497date_pickler(PyObject *module, PyDateTime_Date *date)
2498{
2499 PyObject *state;
2500 PyObject *result = NULL;
2501
2502 if (! PyDate_CheckExact(date)) {
2503 PyErr_Format(PyExc_TypeError,
2504 "bad type passed to date pickler: %s",
2505 date->ob_type->tp_name);
2506 return NULL;
2507 }
2508 state = date_getstate(date);
2509 if (state) {
2510 result = Py_BuildValue("O(O)", date_unpickler_object, state);
2511 Py_DECREF(state);
2512 }
2513 return result;
2514}
2515
2516static PyObject *
2517date_unpickler(PyObject *module, PyObject *arg)
2518{
2519 PyDateTime_Date *self;
2520
2521 if (! PyString_CheckExact(arg)) {
2522 PyErr_Format(PyExc_TypeError,
2523 "bad type passed to date unpickler: %s",
2524 arg->ob_type->tp_name);
2525 return NULL;
2526 }
2527 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
2528 if (self != NULL) {
2529 PyObject *res = date_setstate(self, arg);
2530 if (res == NULL) {
2531 Py_DECREF(self);
2532 return NULL;
2533 }
2534 Py_DECREF(res);
2535 }
2536 return (PyObject *)self;
2537}
2538
2539static PyMethodDef date_methods[] = {
2540 /* Class methods: */
2541 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2542 METH_CLASS,
2543 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2544 "time.time()).")},
2545
2546 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2547 METH_CLASS,
2548 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2549 "ordinal.")},
2550
2551 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2552 PyDoc_STR("Current date or datetime: same as "
2553 "self.__class__.fromtimestamp(time.time()).")},
2554
2555 /* Instance methods: */
2556
2557 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2558 PyDoc_STR("Return ctime() style string.")},
2559
2560 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2561 PyDoc_STR("format -> strftime() style string.")},
2562
2563 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2564 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2565
2566 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2567 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2568 "weekday.")},
2569
2570 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2571 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2572
2573 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2574 PyDoc_STR("Return the day of the week represented by the date.\n"
2575 "Monday == 1 ... Sunday == 7")},
2576
2577 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2578 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2579 "1 is day 1.")},
2580
2581 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2582 PyDoc_STR("Return the day of the week represented by the date.\n"
2583 "Monday == 0 ... Sunday == 6")},
2584
2585 {"__setstate__", (PyCFunction)date_setstate, METH_O,
2586 PyDoc_STR("__setstate__(state)")},
2587
2588 {"__getstate__", (PyCFunction)date_getstate, METH_NOARGS,
2589 PyDoc_STR("__getstate__() -> state")},
2590
2591 {NULL, NULL}
2592};
2593
2594static char date_doc[] =
2595PyDoc_STR("Basic date type.");
2596
2597static PyNumberMethods date_as_number = {
2598 date_add, /* nb_add */
2599 date_subtract, /* nb_subtract */
2600 0, /* nb_multiply */
2601 0, /* nb_divide */
2602 0, /* nb_remainder */
2603 0, /* nb_divmod */
2604 0, /* nb_power */
2605 0, /* nb_negative */
2606 0, /* nb_positive */
2607 0, /* nb_absolute */
2608 0, /* nb_nonzero */
2609};
2610
2611static PyTypeObject PyDateTime_DateType = {
2612 PyObject_HEAD_INIT(NULL)
2613 0, /* ob_size */
2614 "datetime.date", /* tp_name */
2615 sizeof(PyDateTime_Date), /* tp_basicsize */
2616 0, /* tp_itemsize */
2617 (destructor)PyObject_Del, /* tp_dealloc */
2618 0, /* tp_print */
2619 0, /* tp_getattr */
2620 0, /* tp_setattr */
2621 0, /* tp_compare */
2622 (reprfunc)date_repr, /* tp_repr */
2623 &date_as_number, /* tp_as_number */
2624 0, /* tp_as_sequence */
2625 0, /* tp_as_mapping */
2626 (hashfunc)date_hash, /* tp_hash */
2627 0, /* tp_call */
2628 (reprfunc)date_str, /* tp_str */
2629 PyObject_GenericGetAttr, /* tp_getattro */
2630 0, /* tp_setattro */
2631 0, /* tp_as_buffer */
2632 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2633 Py_TPFLAGS_BASETYPE, /* tp_flags */
2634 date_doc, /* tp_doc */
2635 0, /* tp_traverse */
2636 0, /* tp_clear */
2637 (richcmpfunc)date_richcompare, /* tp_richcompare */
2638 0, /* tp_weaklistoffset */
2639 0, /* tp_iter */
2640 0, /* tp_iternext */
2641 date_methods, /* tp_methods */
2642 0, /* tp_members */
2643 date_getset, /* tp_getset */
2644 0, /* tp_base */
2645 0, /* tp_dict */
2646 0, /* tp_descr_get */
2647 0, /* tp_descr_set */
2648 0, /* tp_dictoffset */
2649 0, /* tp_init */
2650 0, /* tp_alloc */
2651 date_new, /* tp_new */
2652 _PyObject_Del, /* tp_free */
2653};
2654
2655/*
2656 * PyDateTime_DateTime implementation.
2657 */
2658
2659/* Accessor properties. */
2660
2661static PyObject *
2662datetime_hour(PyDateTime_DateTime *self, void *unused)
2663{
2664 return PyInt_FromLong(DATE_GET_HOUR(self));
2665}
2666
2667static PyObject *
2668datetime_minute(PyDateTime_DateTime *self, void *unused)
2669{
2670 return PyInt_FromLong(DATE_GET_MINUTE(self));
2671}
2672
2673static PyObject *
2674datetime_second(PyDateTime_DateTime *self, void *unused)
2675{
2676 return PyInt_FromLong(DATE_GET_SECOND(self));
2677}
2678
2679static PyObject *
2680datetime_microsecond(PyDateTime_DateTime *self, void *unused)
2681{
2682 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
2683}
2684
2685static PyGetSetDef datetime_getset[] = {
2686 {"hour", (getter)datetime_hour},
2687 {"minute", (getter)datetime_minute},
2688 {"second", (getter)datetime_second},
2689 {"microsecond", (getter)datetime_microsecond},
2690 {NULL}
2691};
2692
2693/* Constructors. */
2694
2695static PyObject *
2696datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2697{
2698 PyObject *self = NULL;
2699 int year;
2700 int month;
2701 int day;
2702 int hour = 0;
2703 int minute = 0;
2704 int second = 0;
2705 int usecond = 0;
2706
2707 static char *keywords[] = {
2708 "year", "month", "day", "hour", "minute", "second",
2709 "microsecond", NULL
2710 };
2711
2712 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiii", keywords,
2713 &year, &month, &day, &hour, &minute,
2714 &second, &usecond)) {
2715 if (check_date_args(year, month, day) < 0)
2716 return NULL;
2717 if (check_time_args(hour, minute, second, usecond) < 0)
2718 return NULL;
2719 self = new_datetime(year, month, day,
2720 hour, minute, second, usecond);
2721 }
2722 return self;
2723}
2724
2725
2726/* TM_FUNC is the shared type of localtime() and gmtime(). */
2727typedef struct tm *(*TM_FUNC)(const time_t *timer);
2728
2729/* Internal helper.
2730 * Build datetime from a time_t and a distinct count of microseconds.
2731 * Pass localtime or gmtime for f, to control the interpretation of timet.
2732 */
2733static PyObject *
2734datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us)
2735{
2736 struct tm *tm;
2737 PyObject *result = NULL;
2738
2739 tm = f(&timet);
2740 if (tm)
2741 result = PyObject_CallFunction(cls, "iiiiiii",
2742 tm->tm_year + 1900,
2743 tm->tm_mon + 1,
2744 tm->tm_mday,
2745 tm->tm_hour,
2746 tm->tm_min,
2747 tm->tm_sec,
2748 us);
2749 else
2750 PyErr_SetString(PyExc_ValueError,
2751 "timestamp out of range for "
2752 "platform localtime()/gmtime() function");
2753 return result;
2754}
2755
2756/* Internal helper.
2757 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
2758 * to control the interpretation of the timestamp. Since a double doesn't
2759 * have enough bits to cover a datetime's full range of precision, it's
2760 * better to call datetime_from_timet_and_us provided you have a way
2761 * to get that much precision (e.g., C time() isn't good enough).
2762 */
2763static PyObject *
2764datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp)
2765{
2766 time_t timet = (time_t)timestamp;
2767 int us = (int)((timestamp - (double)timet) * 1e6);
2768
2769 return datetime_from_timet_and_us(cls, f, timet, us);
2770}
2771
2772/* Internal helper.
2773 * Build most accurate possible datetime for current time. Pass localtime or
2774 * gmtime for f as appropriate.
2775 */
2776static PyObject *
2777datetime_best_possible(PyObject *cls, TM_FUNC f)
2778{
2779#ifdef HAVE_GETTIMEOFDAY
2780 struct timeval t;
2781
2782#ifdef GETTIMEOFDAY_NO_TZ
2783 gettimeofday(&t);
2784#else
2785 gettimeofday(&t, (struct timezone *)NULL);
2786#endif
2787 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec);
2788
2789#else /* ! HAVE_GETTIMEOFDAY */
2790 /* No flavor of gettimeofday exists on this platform. Python's
2791 * time.time() does a lot of other platform tricks to get the
2792 * best time it can on the platform, and we're not going to do
2793 * better than that (if we could, the better code would belong
2794 * in time.time()!) We're limited by the precision of a double,
2795 * though.
2796 */
2797 PyObject *time;
2798 double dtime;
2799
2800 time = time_time();
2801 if (time == NULL)
2802 return NULL;
2803 dtime = PyFloat_AsDouble(time);
2804 Py_DECREF(time);
2805 if (dtime == -1.0 && PyErr_Occurred())
2806 return NULL;
2807 return datetime_from_timestamp(cls, f, dtime);
2808#endif /* ! HAVE_GETTIMEOFDAY */
2809}
2810
2811/* Return new local datetime from timestamp (Python timestamp -- a double). */
2812static PyObject *
2813datetime_fromtimestamp(PyObject *cls, PyObject *args)
2814{
2815 double timestamp;
2816 PyObject *result = NULL;
2817
2818 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2819 result = datetime_from_timestamp(cls, localtime, timestamp);
2820 return result;
2821}
2822
2823/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
2824static PyObject *
2825datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
2826{
2827 double timestamp;
2828 PyObject *result = NULL;
2829
2830 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
2831 result = datetime_from_timestamp(cls, gmtime, timestamp);
2832 return result;
2833}
2834
2835/* Return best possible local time -- this isn't constrained by the
2836 * precision of a timestamp.
2837 */
2838static PyObject *
2839datetime_now(PyObject *cls, PyObject *dummy)
2840{
2841 return datetime_best_possible(cls, localtime);
2842}
2843
2844/* Return best possible UTC time -- this isn't constrained by the
2845 * precision of a timestamp.
2846 */
2847static PyObject *
2848datetime_utcnow(PyObject *cls, PyObject *dummy)
2849{
2850 return datetime_best_possible(cls, gmtime);
2851}
2852
2853/* Return new datetime or datetimetz from date/datetime/datetimetz and
2854 * time/timetz arguments.
2855 */
2856static PyObject *
2857datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
2858{
2859 static char *keywords[] = {"date", "time", NULL};
2860 PyObject *date;
2861 PyObject *time;
2862 PyObject *result = NULL;
2863
2864 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
2865 &PyDateTime_DateType, &date,
2866 &PyDateTime_TimeType, &time))
2867 result = PyObject_CallFunction(cls, "iiiiiii",
2868 GET_YEAR(date),
2869 GET_MONTH(date),
2870 GET_DAY(date),
2871 TIME_GET_HOUR(time),
2872 TIME_GET_MINUTE(time),
2873 TIME_GET_SECOND(time),
2874 TIME_GET_MICROSECOND(time));
2875 if (result && PyTimeTZ_Check(time) && PyDateTimeTZ_Check(result)) {
2876 /* Copy the tzinfo field. */
2877 PyObject *tzinfo = ((PyDateTime_TimeTZ *)time)->tzinfo;
2878 Py_INCREF(tzinfo);
2879 Py_DECREF(((PyDateTime_DateTimeTZ *)result)->tzinfo);
2880 ((PyDateTime_DateTimeTZ *)result)->tzinfo = tzinfo;
2881 }
2882 return result;
2883}
2884
2885/* datetime arithmetic. */
2886
2887static PyObject *
2888add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta)
2889{
2890 /* Note that the C-level additions can't overflow, because of
2891 * invariant bounds on the member values.
2892 */
2893 int year = GET_YEAR(date);
2894 int month = GET_MONTH(date);
2895 int day = GET_DAY(date) + GET_TD_DAYS(delta);
2896 int hour = DATE_GET_HOUR(date);
2897 int minute = DATE_GET_MINUTE(date);
2898 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta);
2899 int microsecond = DATE_GET_MICROSECOND(date) +
2900 GET_TD_MICROSECONDS(delta);
2901
2902 if (normalize_datetime(&year, &month, &day,
2903 &hour, &minute, &second, &microsecond) < 0)
2904 return NULL;
2905 else
2906 return new_datetime(year, month, day,
2907 hour, minute, second, microsecond);
2908}
2909
2910static PyObject *
2911sub_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta)
2912{
2913 /* Note that the C-level subtractions can't overflow, because of
2914 * invariant bounds on the member values.
2915 */
2916 int year = GET_YEAR(date);
2917 int month = GET_MONTH(date);
2918 int day = GET_DAY(date) - GET_TD_DAYS(delta);
2919 int hour = DATE_GET_HOUR(date);
2920 int minute = DATE_GET_MINUTE(date);
2921 int second = DATE_GET_SECOND(date) - GET_TD_SECONDS(delta);
2922 int microsecond = DATE_GET_MICROSECOND(date) -
2923 GET_TD_MICROSECONDS(delta);
2924
2925 if (normalize_datetime(&year, &month, &day,
2926 &hour, &minute, &second, &microsecond) < 0)
2927 return NULL;
2928 else
2929 return new_datetime(year, month, day,
2930 hour, minute, second, microsecond);
2931}
2932
2933static PyObject *
2934sub_datetime_datetime(PyDateTime_DateTime *left, PyDateTime_DateTime *right)
2935{
2936 int days1 = ymd_to_ord(GET_YEAR(left), GET_MONTH(left), GET_DAY(left));
2937 int days2 = ymd_to_ord(GET_YEAR(right),
2938 GET_MONTH(right),
2939 GET_DAY(right));
2940 /* These can't overflow, since the values are normalized. At most
2941 * this gives the number of seconds in one day.
2942 */
2943 int delta_s = (DATE_GET_HOUR(left) - DATE_GET_HOUR(right)) * 3600 +
2944 (DATE_GET_MINUTE(left) - DATE_GET_MINUTE(right)) * 60 +
2945 DATE_GET_SECOND(left) - DATE_GET_SECOND(right);
2946 int delta_us = DATE_GET_MICROSECOND(left) -
2947 DATE_GET_MICROSECOND(right);
2948
2949 return new_delta(days1 - days2, delta_s, delta_us, 1);
2950}
2951
2952static PyObject *
2953datetime_add(PyObject *left, PyObject *right)
2954{
2955 if (PyDateTime_Check(left)) {
2956 /* datetime + ??? */
2957 if (PyDelta_Check(right))
2958 /* datetime + delta */
2959 return add_datetime_timedelta(
2960 (PyDateTime_DateTime *)left,
2961 (PyDateTime_Delta *)right);
2962 }
2963 else if (PyDelta_Check(left)) {
2964 /* delta + datetime */
2965 return add_datetime_timedelta((PyDateTime_DateTime *) right,
2966 (PyDateTime_Delta *) left);
2967 }
2968 Py_INCREF(Py_NotImplemented);
2969 return Py_NotImplemented;
2970}
2971
2972static PyObject *
2973datetime_subtract(PyObject *left, PyObject *right)
2974{
2975 PyObject *result = Py_NotImplemented;
2976
2977 if (PyDateTime_Check(left)) {
2978 /* datetime - ??? */
2979 if (PyDateTime_Check(right)) {
2980 /* datetime - datetime */
2981 result = sub_datetime_datetime(
2982 (PyDateTime_DateTime *)left,
2983 (PyDateTime_DateTime *)right);
2984 }
2985 else if (PyDelta_Check(right)) {
2986 /* datetime - delta */
2987 result = sub_datetime_timedelta(
2988 (PyDateTime_DateTime *)left,
2989 (PyDateTime_Delta *)right);
2990 }
2991 }
2992
2993 if (result == Py_NotImplemented)
2994 Py_INCREF(result);
2995 return result;
2996}
2997
2998/* Various ways to turn a datetime into a string. */
2999
3000static PyObject *
3001datetime_repr(PyDateTime_DateTime *self)
3002{
3003 char buffer[1000];
3004 char *typename = self->ob_type->tp_name;
3005
3006 if (DATE_GET_MICROSECOND(self)) {
3007 PyOS_snprintf(buffer, sizeof(buffer),
3008 "%s(%d, %d, %d, %d, %d, %d, %d)",
3009 typename,
3010 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3011 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3012 DATE_GET_SECOND(self),
3013 DATE_GET_MICROSECOND(self));
3014 }
3015 else if (DATE_GET_SECOND(self)) {
3016 PyOS_snprintf(buffer, sizeof(buffer),
3017 "%s(%d, %d, %d, %d, %d, %d)",
3018 typename,
3019 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3020 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3021 DATE_GET_SECOND(self));
3022 }
3023 else {
3024 PyOS_snprintf(buffer, sizeof(buffer),
3025 "%s(%d, %d, %d, %d, %d)",
3026 typename,
3027 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3028 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
3029 }
3030 return PyString_FromString(buffer);
3031}
3032
3033static PyObject *
3034datetime_str(PyDateTime_DateTime *self)
3035{
3036 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
3037}
3038
3039static PyObject *
3040datetime_isoformat(PyDateTime_DateTime *self,
3041 PyObject *args, PyObject *kw)
3042{
3043 char sep = 'T';
3044 static char *keywords[] = {"sep", NULL};
3045 char buffer[100];
3046 char *cp;
3047
3048 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
3049 &sep))
3050 return NULL;
3051 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
3052 assert(cp != NULL);
3053 *cp++ = sep;
3054 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
3055 return PyString_FromString(buffer);
3056}
3057
3058static PyObject *
3059datetime_ctime(PyDateTime_DateTime *self)
3060{
3061 return format_ctime((PyDateTime_Date *)self,
3062 DATE_GET_HOUR(self),
3063 DATE_GET_MINUTE(self),
3064 DATE_GET_SECOND(self));
3065}
3066
3067/* Miscellaneous methods. */
3068
3069/* This is more natural as a tp_compare, but doesn't work then: for whatever
3070 * reason, Python's try_3way_compare ignores tp_compare unless
3071 * PyInstance_Check returns true, but these aren't old-style classes.
3072 * Note that this routine handles all comparisons for datetime and datetimetz.
3073 */
3074static PyObject *
3075datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
3076{
3077 int diff;
3078 naivety n1, n2;
3079 int offset1, offset2;
3080
3081 if (! PyDateTime_Check(other)) {
3082 /* Stop this from falling back to address comparison. */
3083 PyErr_Format(PyExc_TypeError,
3084 "can't compare '%s' to '%s'",
3085 self->ob_type->tp_name,
3086 other->ob_type->tp_name);
3087 return NULL;
3088 }
Tim Peters14b69412002-12-22 18:10:22 +00003089 n1 = classify_utcoffset((PyObject *)self, &offset1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003090 assert(n1 != OFFSET_UNKNOWN);
3091 if (n1 == OFFSET_ERROR)
3092 return NULL;
3093
Tim Peters14b69412002-12-22 18:10:22 +00003094 n2 = classify_utcoffset(other, &offset2);
Tim Peters2a799bf2002-12-16 20:18:38 +00003095 assert(n2 != OFFSET_UNKNOWN);
3096 if (n2 == OFFSET_ERROR)
3097 return NULL;
3098
3099 /* If they're both naive, or both aware and have the same offsets,
3100 * we get off cheap. Note that if they're both naive, offset1 ==
3101 * offset2 == 0 at this point.
3102 */
3103 if (n1 == n2 && offset1 == offset2) {
3104 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
3105 _PyDateTime_DATETIME_DATASIZE);
3106 return diff_to_bool(diff, op);
3107 }
3108
3109 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3110 /* We want the sign of
3111 * (self - offset1 minutes) - (other - offset2 minutes) =
3112 * (self - other) + (offset2 - offset1) minutes.
3113 */
3114 PyDateTime_Delta *delta;
3115 int days, seconds, us;
3116
3117 assert(offset1 != offset2); /* else last "if" handled it */
3118 delta = (PyDateTime_Delta *)sub_datetime_datetime(self,
3119 (PyDateTime_DateTime *)other);
3120 if (delta == NULL)
3121 return NULL;
3122 days = delta->days;
3123 seconds = delta->seconds + (offset2 - offset1) * 60;
3124 us = delta->microseconds;
3125 Py_DECREF(delta);
3126 normalize_d_s_us(&days, &seconds, &us);
3127 diff = days;
3128 if (diff == 0)
3129 diff = seconds | us;
3130 return diff_to_bool(diff, op);
3131 }
3132
3133 assert(n1 != n2);
3134 PyErr_SetString(PyExc_TypeError,
3135 "can't compare offset-naive and "
3136 "offset-aware datetimes");
3137 return NULL;
3138}
3139
3140static PyObject *datetime_getstate(PyDateTime_DateTime *self);
3141
3142static long
3143datetime_hash(PyDateTime_DateTime *self)
3144{
3145 if (self->hashcode == -1) {
3146 naivety n;
3147 int offset;
3148 PyObject *temp;
3149
Tim Peters14b69412002-12-22 18:10:22 +00003150 n = classify_utcoffset((PyObject *)self, &offset);
Tim Peters2a799bf2002-12-16 20:18:38 +00003151 assert(n != OFFSET_UNKNOWN);
3152 if (n == OFFSET_ERROR)
3153 return -1;
3154
3155 /* Reduce this to a hash of another object. */
3156 if (n == OFFSET_NAIVE)
3157 temp = datetime_getstate(self);
3158 else {
3159 int days;
3160 int seconds;
3161
3162 assert(n == OFFSET_AWARE);
3163 assert(PyDateTimeTZ_Check(self));
3164 days = ymd_to_ord(GET_YEAR(self),
3165 GET_MONTH(self),
3166 GET_DAY(self));
3167 seconds = DATE_GET_HOUR(self) * 3600 +
3168 (DATE_GET_MINUTE(self) - offset) * 60 +
3169 DATE_GET_SECOND(self);
3170 temp = new_delta(days,
3171 seconds,
3172 DATE_GET_MICROSECOND(self),
3173 1);
3174 }
3175 if (temp != NULL) {
3176 self->hashcode = PyObject_Hash(temp);
3177 Py_DECREF(temp);
3178 }
3179 }
3180 return self->hashcode;
3181}
3182
3183static PyObject *
3184datetime_timetuple(PyDateTime_DateTime *self)
3185{
3186 return build_struct_time(GET_YEAR(self),
3187 GET_MONTH(self),
3188 GET_DAY(self),
3189 DATE_GET_HOUR(self),
3190 DATE_GET_MINUTE(self),
3191 DATE_GET_SECOND(self),
3192 -1);
3193}
3194
3195static PyObject *
3196datetime_getdate(PyDateTime_DateTime *self)
3197{
3198 return new_date(GET_YEAR(self),
3199 GET_MONTH(self),
3200 GET_DAY(self));
3201}
3202
3203static PyObject *
3204datetime_gettime(PyDateTime_DateTime *self)
3205{
3206 return new_time(DATE_GET_HOUR(self),
3207 DATE_GET_MINUTE(self),
3208 DATE_GET_SECOND(self),
3209 DATE_GET_MICROSECOND(self));
3210}
3211
3212/* Pickle support. Quite a maze! */
3213
3214static PyObject *
3215datetime_getstate(PyDateTime_DateTime *self)
3216{
3217 return PyString_FromStringAndSize(self->data,
3218 _PyDateTime_DATETIME_DATASIZE);
3219}
3220
3221static PyObject *
3222datetime_setstate(PyDateTime_DateTime *self, PyObject *state)
3223{
3224 const int len = PyString_Size(state);
3225 unsigned char *pdata = (unsigned char*)PyString_AsString(state);
3226
3227 if (! PyString_Check(state) ||
3228 len != _PyDateTime_DATETIME_DATASIZE) {
3229 PyErr_SetString(PyExc_TypeError,
3230 "bad argument to datetime.__setstate__");
3231 return NULL;
3232 }
3233 memcpy(self->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3234 self->hashcode = -1;
3235
3236 Py_INCREF(Py_None);
3237 return Py_None;
3238}
3239
3240/* XXX This seems a ridiculously inefficient way to pickle a short string. */
3241static PyObject *
3242datetime_pickler(PyObject *module, PyDateTime_DateTime *datetime)
3243{
3244 PyObject *state;
3245 PyObject *result = NULL;
3246
3247 if (! PyDateTime_CheckExact(datetime)) {
3248 PyErr_Format(PyExc_TypeError,
3249 "bad type passed to datetime pickler: %s",
3250 datetime->ob_type->tp_name);
3251 return NULL;
3252 }
3253 state = datetime_getstate(datetime);
3254 if (state) {
3255 result = Py_BuildValue("O(O)",
3256 datetime_unpickler_object,
3257 state);
3258 Py_DECREF(state);
3259 }
3260 return result;
3261}
3262
3263static PyObject *
3264datetime_unpickler(PyObject *module, PyObject *arg)
3265{
3266 PyDateTime_DateTime *self;
3267
3268 if (! PyString_CheckExact(arg)) {
3269 PyErr_Format(PyExc_TypeError,
3270 "bad type passed to datetime unpickler: %s",
3271 arg->ob_type->tp_name);
3272 return NULL;
3273 }
3274 self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType);
3275 if (self != NULL) {
3276 PyObject *res = datetime_setstate(self, arg);
3277 if (res == NULL) {
3278 Py_DECREF(self);
3279 return NULL;
3280 }
3281 Py_DECREF(res);
3282 }
3283 return (PyObject *)self;
3284}
3285
3286static PyMethodDef datetime_methods[] = {
3287 /* Class methods: */
3288 {"now", (PyCFunction)datetime_now,
3289 METH_NOARGS | METH_CLASS,
3290 PyDoc_STR("Return a new datetime representing local day and time.")},
3291
3292 {"utcnow", (PyCFunction)datetime_utcnow,
3293 METH_NOARGS | METH_CLASS,
3294 PyDoc_STR("Return a new datetime representing UTC day and time.")},
3295
3296 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
3297 METH_VARARGS | METH_CLASS,
3298 PyDoc_STR("timestamp -> local datetime from a POSIX timestamp "
3299 "(like time.time()).")},
3300
3301 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
3302 METH_VARARGS | METH_CLASS,
3303 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
3304 "(like time.time()).")},
3305
3306 {"combine", (PyCFunction)datetime_combine,
3307 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
3308 PyDoc_STR("date, time -> datetime with same date and time fields")},
3309
3310 /* Instance methods: */
3311 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
3312 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
3313
3314 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
3315 PyDoc_STR("Return date object with same year, month and day.")},
3316
3317 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
3318 PyDoc_STR("Return time object with same hour, minute, second and "
3319 "microsecond.")},
3320
3321 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
3322 PyDoc_STR("Return ctime() style string.")},
3323
3324 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
3325 PyDoc_STR("[sep] -> string in ISO 8601 format, "
3326 "YYYY-MM-DDTHH:MM:SS[.mmmmmm].\n\n"
3327 "sep is used to separate the year from the time, and "
3328 "defaults\n"
3329 "to 'T'.")},
3330
3331 {"__setstate__", (PyCFunction)datetime_setstate, METH_O,
3332 PyDoc_STR("__setstate__(state)")},
3333
3334 {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS,
3335 PyDoc_STR("__getstate__() -> state")},
3336 {NULL, NULL}
3337};
3338
3339static char datetime_doc[] =
3340PyDoc_STR("Basic date/time type.");
3341
3342static PyNumberMethods datetime_as_number = {
3343 datetime_add, /* nb_add */
3344 datetime_subtract, /* nb_subtract */
3345 0, /* nb_multiply */
3346 0, /* nb_divide */
3347 0, /* nb_remainder */
3348 0, /* nb_divmod */
3349 0, /* nb_power */
3350 0, /* nb_negative */
3351 0, /* nb_positive */
3352 0, /* nb_absolute */
3353 0, /* nb_nonzero */
3354};
3355
3356statichere PyTypeObject PyDateTime_DateTimeType = {
3357 PyObject_HEAD_INIT(NULL)
3358 0, /* ob_size */
3359 "datetime.datetime", /* tp_name */
3360 sizeof(PyDateTime_DateTime), /* tp_basicsize */
3361 0, /* tp_itemsize */
3362 (destructor)PyObject_Del, /* tp_dealloc */
3363 0, /* tp_print */
3364 0, /* tp_getattr */
3365 0, /* tp_setattr */
3366 0, /* tp_compare */
3367 (reprfunc)datetime_repr, /* tp_repr */
3368 &datetime_as_number, /* tp_as_number */
3369 0, /* tp_as_sequence */
3370 0, /* tp_as_mapping */
3371 (hashfunc)datetime_hash, /* tp_hash */
3372 0, /* tp_call */
3373 (reprfunc)datetime_str, /* tp_str */
3374 PyObject_GenericGetAttr, /* tp_getattro */
3375 0, /* tp_setattro */
3376 0, /* tp_as_buffer */
3377 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3378 Py_TPFLAGS_BASETYPE, /* tp_flags */
3379 datetime_doc, /* tp_doc */
3380 0, /* tp_traverse */
3381 0, /* tp_clear */
3382 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
3383 0, /* tp_weaklistoffset */
3384 0, /* tp_iter */
3385 0, /* tp_iternext */
3386 datetime_methods, /* tp_methods */
3387 0, /* tp_members */
3388 datetime_getset, /* tp_getset */
3389 &PyDateTime_DateType, /* tp_base */
3390 0, /* tp_dict */
3391 0, /* tp_descr_get */
3392 0, /* tp_descr_set */
3393 0, /* tp_dictoffset */
3394 0, /* tp_init */
3395 0, /* tp_alloc */
3396 datetime_new, /* tp_new */
3397 _PyObject_Del, /* tp_free */
3398};
3399
3400/*
3401 * PyDateTime_Time implementation.
3402 */
3403
3404/* Accessor properties. */
3405
3406static PyObject *
3407time_hour(PyDateTime_Time *self, void *unused)
3408{
3409 return PyInt_FromLong(TIME_GET_HOUR(self));
3410}
3411
3412static PyObject *
3413time_minute(PyDateTime_Time *self, void *unused)
3414{
3415 return PyInt_FromLong(TIME_GET_MINUTE(self));
3416}
3417
3418static PyObject *
Jack Jansen51cd8a22002-12-17 20:57:24 +00003419py_time_second(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003420{
3421 return PyInt_FromLong(TIME_GET_SECOND(self));
3422}
3423
3424static PyObject *
3425time_microsecond(PyDateTime_Time *self, void *unused)
3426{
3427 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3428}
3429
3430static PyGetSetDef time_getset[] = {
3431 {"hour", (getter)time_hour},
3432 {"minute", (getter)time_minute},
Jack Jansen51cd8a22002-12-17 20:57:24 +00003433 {"second", (getter)py_time_second},
Tim Peters2a799bf2002-12-16 20:18:38 +00003434 {"microsecond", (getter)time_microsecond},
3435 {NULL}
3436};
3437
3438/* Constructors. */
3439
3440static PyObject *
3441time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3442{
3443 PyObject *self = NULL;
3444 int hour = 0;
3445 int minute = 0;
3446 int second = 0;
3447 int usecond = 0;
3448
3449 static char *keywords[] = {
3450 "hour", "minute", "second", "microsecond", NULL
3451 };
3452
3453 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiii", keywords,
3454 &hour, &minute, &second, &usecond)) {
3455 if (check_time_args(hour, minute, second, usecond) < 0)
3456 return NULL;
3457 self = new_time(hour, minute, second, usecond);
3458 }
3459 return self;
3460}
3461
3462/* Various ways to turn a time into a string. */
3463
3464static PyObject *
3465time_repr(PyDateTime_Time *self)
3466{
3467 char buffer[100];
3468 char *typename = self->ob_type->tp_name;
3469 int h = TIME_GET_HOUR(self);
3470 int m = TIME_GET_MINUTE(self);
3471 int s = TIME_GET_SECOND(self);
3472 int us = TIME_GET_MICROSECOND(self);
3473
3474 if (us)
3475 PyOS_snprintf(buffer, sizeof(buffer),
3476 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3477 else if (s)
3478 PyOS_snprintf(buffer, sizeof(buffer),
3479 "%s(%d, %d, %d)", typename, h, m, s);
3480 else
3481 PyOS_snprintf(buffer, sizeof(buffer),
3482 "%s(%d, %d)", typename, h, m);
3483 return PyString_FromString(buffer);
3484}
3485
3486static PyObject *
3487time_str(PyDateTime_Time *self)
3488{
3489 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3490}
3491
3492static PyObject *
3493time_isoformat(PyDateTime_Time *self)
3494{
3495 char buffer[100];
3496 /* Reuse the time format code from the datetime type. */
3497 PyDateTime_DateTime datetime;
3498 PyDateTime_DateTime *pdatetime = &datetime;
3499
3500 /* Copy over just the time bytes. */
3501 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3502 self->data,
3503 _PyDateTime_TIME_DATASIZE);
3504
3505 isoformat_time(pdatetime, buffer, sizeof(buffer));
3506 return PyString_FromString(buffer);
3507}
3508
3509static PyObject *
3510time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3511{
3512 PyObject *result;
3513 PyObject *format;
3514 PyObject *tuple;
3515 static char *keywords[] = {"format", NULL};
3516
3517 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3518 &PyString_Type, &format))
3519 return NULL;
3520
3521 tuple = Py_BuildValue("iiiiiiiii",
3522 0, 0, 0, /* year, month, day */
3523 TIME_GET_HOUR(self),
3524 TIME_GET_MINUTE(self),
3525 TIME_GET_SECOND(self),
3526 0, 0, -1); /* weekday, daynum, dst */
3527 if (tuple == NULL)
3528 return NULL;
3529 assert(PyTuple_Size(tuple) == 9);
3530 result = wrap_strftime((PyObject *)self, format, tuple);
3531 Py_DECREF(tuple);
3532 return result;
3533}
3534
3535/* Miscellaneous methods. */
3536
3537/* This is more natural as a tp_compare, but doesn't work then: for whatever
3538 * reason, Python's try_3way_compare ignores tp_compare unless
3539 * PyInstance_Check returns true, but these aren't old-style classes.
3540 * Note that this routine handles all comparisons for time and timetz.
3541 */
3542static PyObject *
3543time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3544{
3545 int diff;
3546 naivety n1, n2;
3547 int offset1, offset2;
3548
3549 if (! PyTime_Check(other)) {
3550 /* Stop this from falling back to address comparison. */
3551 PyErr_Format(PyExc_TypeError,
3552 "can't compare '%s' to '%s'",
3553 self->ob_type->tp_name,
3554 other->ob_type->tp_name);
3555 return NULL;
3556 }
Tim Peters14b69412002-12-22 18:10:22 +00003557 n1 = classify_utcoffset((PyObject *)self, &offset1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003558 assert(n1 != OFFSET_UNKNOWN);
3559 if (n1 == OFFSET_ERROR)
3560 return NULL;
3561
Tim Peters14b69412002-12-22 18:10:22 +00003562 n2 = classify_utcoffset(other, &offset2);
Tim Peters2a799bf2002-12-16 20:18:38 +00003563 assert(n2 != OFFSET_UNKNOWN);
3564 if (n2 == OFFSET_ERROR)
3565 return NULL;
3566
3567 /* If they're both naive, or both aware and have the same offsets,
3568 * we get off cheap. Note that if they're both naive, offset1 ==
3569 * offset2 == 0 at this point.
3570 */
3571 if (n1 == n2 && offset1 == offset2) {
3572 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3573 _PyDateTime_TIME_DATASIZE);
3574 return diff_to_bool(diff, op);
3575 }
3576
3577 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3578 assert(offset1 != offset2); /* else last "if" handled it */
3579 /* Convert everything except microseconds to seconds. These
3580 * can't overflow (no more than the # of seconds in 2 days).
3581 */
3582 offset1 = TIME_GET_HOUR(self) * 3600 +
3583 (TIME_GET_MINUTE(self) - offset1) * 60 +
3584 TIME_GET_SECOND(self);
3585 offset2 = TIME_GET_HOUR(other) * 3600 +
3586 (TIME_GET_MINUTE(other) - offset2) * 60 +
3587 TIME_GET_SECOND(other);
3588 diff = offset1 - offset2;
3589 if (diff == 0)
3590 diff = TIME_GET_MICROSECOND(self) -
3591 TIME_GET_MICROSECOND(other);
3592 return diff_to_bool(diff, op);
3593 }
3594
3595 assert(n1 != n2);
3596 PyErr_SetString(PyExc_TypeError,
3597 "can't compare offset-naive and "
3598 "offset-aware times");
3599 return NULL;
3600}
3601
3602static PyObject *time_getstate(PyDateTime_Time *self);
3603
3604static long
3605time_hash(PyDateTime_Time *self)
3606{
3607 if (self->hashcode == -1) {
3608 naivety n;
3609 int offset;
3610 PyObject *temp;
3611
Tim Peters14b69412002-12-22 18:10:22 +00003612 n = classify_utcoffset((PyObject *)self, &offset);
Tim Peters2a799bf2002-12-16 20:18:38 +00003613 assert(n != OFFSET_UNKNOWN);
3614 if (n == OFFSET_ERROR)
3615 return -1;
3616
3617 /* Reduce this to a hash of another object. */
3618 if (offset == 0)
3619 temp = time_getstate(self);
3620 else {
3621 int hour;
3622 int minute;
3623
3624 assert(n == OFFSET_AWARE);
3625 assert(PyTimeTZ_Check(self));
3626 hour = divmod(TIME_GET_HOUR(self) * 60 +
3627 TIME_GET_MINUTE(self) - offset,
3628 60,
3629 &minute);
3630 if (0 <= hour && hour < 24)
3631 temp = new_time(hour, minute,
3632 TIME_GET_SECOND(self),
3633 TIME_GET_MICROSECOND(self));
3634 else
3635 temp = Py_BuildValue("iiii",
3636 hour, minute,
3637 TIME_GET_SECOND(self),
3638 TIME_GET_MICROSECOND(self));
3639 }
3640 if (temp != NULL) {
3641 self->hashcode = PyObject_Hash(temp);
3642 Py_DECREF(temp);
3643 }
3644 }
3645 return self->hashcode;
3646}
3647
3648static int
3649time_nonzero(PyDateTime_Time *self)
3650{
3651 return TIME_GET_HOUR(self) ||
3652 TIME_GET_MINUTE(self) ||
3653 TIME_GET_SECOND(self) ||
3654 TIME_GET_MICROSECOND(self);
3655}
3656
3657/* Pickle support. Quite a maze! */
3658
3659static PyObject *
3660time_getstate(PyDateTime_Time *self)
3661{
3662 return PyString_FromStringAndSize(self->data,
3663 _PyDateTime_TIME_DATASIZE);
3664}
3665
3666static PyObject *
3667time_setstate(PyDateTime_Time *self, PyObject *state)
3668{
3669 const int len = PyString_Size(state);
3670 unsigned char *pdata = (unsigned char*)PyString_AsString(state);
3671
3672 if (! PyString_Check(state) ||
3673 len != _PyDateTime_TIME_DATASIZE) {
3674 PyErr_SetString(PyExc_TypeError,
3675 "bad argument to time.__setstate__");
3676 return NULL;
3677 }
3678 memcpy(self->data, pdata, _PyDateTime_TIME_DATASIZE);
3679 self->hashcode = -1;
3680
3681 Py_INCREF(Py_None);
3682 return Py_None;
3683}
3684
3685/* XXX This seems a ridiculously inefficient way to pickle a short string. */
3686static PyObject *
3687time_pickler(PyObject *module, PyDateTime_Time *time)
3688{
3689 PyObject *state;
3690 PyObject *result = NULL;
3691
3692 if (! PyTime_CheckExact(time)) {
3693 PyErr_Format(PyExc_TypeError,
3694 "bad type passed to time pickler: %s",
3695 time->ob_type->tp_name);
3696 return NULL;
3697 }
3698 state = time_getstate(time);
3699 if (state) {
3700 result = Py_BuildValue("O(O)",
3701 time_unpickler_object,
3702 state);
3703 Py_DECREF(state);
3704 }
3705 return result;
3706}
3707
3708static PyObject *
3709time_unpickler(PyObject *module, PyObject *arg)
3710{
3711 PyDateTime_Time *self;
3712
3713 if (! PyString_CheckExact(arg)) {
3714 PyErr_Format(PyExc_TypeError,
3715 "bad type passed to time unpickler: %s",
3716 arg->ob_type->tp_name);
3717 return NULL;
3718 }
3719 self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType);
3720 if (self != NULL) {
3721 PyObject *res = time_setstate(self, arg);
3722 if (res == NULL) {
3723 Py_DECREF(self);
3724 return NULL;
3725 }
3726 Py_DECREF(res);
3727 }
3728 return (PyObject *)self;
3729}
3730
3731static PyMethodDef time_methods[] = {
3732 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
3733 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm].")},
3734
3735 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3736 PyDoc_STR("format -> strftime() style string.")},
3737
3738 {"__setstate__", (PyCFunction)time_setstate, METH_O,
3739 PyDoc_STR("__setstate__(state)")},
3740
3741 {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS,
3742 PyDoc_STR("__getstate__() -> state")},
3743 {NULL, NULL}
3744};
3745
3746static char time_doc[] =
3747PyDoc_STR("Basic time type.");
3748
3749static PyNumberMethods time_as_number = {
3750 0, /* nb_add */
3751 0, /* nb_subtract */
3752 0, /* nb_multiply */
3753 0, /* nb_divide */
3754 0, /* nb_remainder */
3755 0, /* nb_divmod */
3756 0, /* nb_power */
3757 0, /* nb_negative */
3758 0, /* nb_positive */
3759 0, /* nb_absolute */
3760 (inquiry)time_nonzero, /* nb_nonzero */
3761};
3762
3763statichere PyTypeObject PyDateTime_TimeType = {
3764 PyObject_HEAD_INIT(NULL)
3765 0, /* ob_size */
3766 "datetime.time", /* tp_name */
3767 sizeof(PyDateTime_Time), /* tp_basicsize */
3768 0, /* tp_itemsize */
3769 (destructor)PyObject_Del, /* tp_dealloc */
3770 0, /* tp_print */
3771 0, /* tp_getattr */
3772 0, /* tp_setattr */
3773 0, /* tp_compare */
3774 (reprfunc)time_repr, /* tp_repr */
3775 &time_as_number, /* tp_as_number */
3776 0, /* tp_as_sequence */
3777 0, /* tp_as_mapping */
3778 (hashfunc)time_hash, /* tp_hash */
3779 0, /* tp_call */
3780 (reprfunc)time_str, /* tp_str */
3781 PyObject_GenericGetAttr, /* tp_getattro */
3782 0, /* tp_setattro */
3783 0, /* tp_as_buffer */
3784 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3785 Py_TPFLAGS_BASETYPE, /* tp_flags */
3786 time_doc, /* tp_doc */
3787 0, /* tp_traverse */
3788 0, /* tp_clear */
3789 (richcmpfunc)time_richcompare, /* tp_richcompare */
3790 0, /* tp_weaklistoffset */
3791 0, /* tp_iter */
3792 0, /* tp_iternext */
3793 time_methods, /* tp_methods */
3794 0, /* tp_members */
3795 time_getset, /* tp_getset */
3796 0, /* tp_base */
3797 0, /* tp_dict */
3798 0, /* tp_descr_get */
3799 0, /* tp_descr_set */
3800 0, /* tp_dictoffset */
3801 0, /* tp_init */
3802 0, /* tp_alloc */
3803 time_new, /* tp_new */
3804 _PyObject_Del, /* tp_free */
3805};
3806
3807/*
3808 * PyDateTime_TZInfo implementation.
3809 */
3810
3811/* This is a pure abstract base class, so doesn't do anything beyond
3812 * raising NotImplemented exceptions. Real tzinfo classes need
3813 * to derive from this. This is mostly for clarity, and for efficiency in
3814 * datetimetz and timetz constructors (their tzinfo arguments need to
3815 * be subclasses of this tzinfo class, which is easy and quick to check).
3816 *
3817 * Note: For reasons having to do with pickling of subclasses, we have
3818 * to allow tzinfo objects to be instantiated. This wasn't an issue
3819 * in the Python implementation (__init__() could raise NotImplementedError
3820 * there without ill effect), but doing so in the C implementation hit a
3821 * brick wall.
3822 */
3823
3824static PyObject *
3825tzinfo_nogo(const char* methodname)
3826{
3827 PyErr_Format(PyExc_NotImplementedError,
3828 "a tzinfo subclass must implement %s()",
3829 methodname);
3830 return NULL;
3831}
3832
3833/* Methods. A subclass must implement these. */
3834
3835static PyObject*
3836tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3837{
3838 return tzinfo_nogo("tzname");
3839}
3840
3841static PyObject*
3842tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3843{
3844 return tzinfo_nogo("utcoffset");
3845}
3846
3847static PyObject*
3848tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3849{
3850 return tzinfo_nogo("dst");
3851}
3852
3853/*
3854 * Pickle support. This is solely so that tzinfo subclasses can use
3855 * pickling -- tzinfo itself is supposed to be uninstantiable. The
3856 * pickler and unpickler functions are given module-level private
3857 * names, and registered with copy_reg, by the module init function.
3858 */
3859
3860static PyObject*
3861tzinfo_pickler(PyDateTime_TZInfo *self) {
3862 return Py_BuildValue("O()", tzinfo_unpickler_object);
3863}
3864
3865static PyObject*
3866tzinfo_unpickler(PyObject * unused) {
3867 return PyType_GenericNew(&PyDateTime_TZInfoType, NULL, NULL);
3868}
3869
3870
3871static PyMethodDef tzinfo_methods[] = {
3872 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3873 PyDoc_STR("datetime -> string name of time zone.")},
3874
3875 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
3876 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3877 "west of UTC).")},
3878
3879 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3880 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3881
3882 {NULL, NULL}
3883};
3884
3885static char tzinfo_doc[] =
3886PyDoc_STR("Abstract base class for time zone info objects.");
3887
3888 statichere PyTypeObject PyDateTime_TZInfoType = {
3889 PyObject_HEAD_INIT(NULL)
3890 0, /* ob_size */
3891 "datetime.tzinfo", /* tp_name */
3892 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3893 0, /* tp_itemsize */
3894 0, /* tp_dealloc */
3895 0, /* tp_print */
3896 0, /* tp_getattr */
3897 0, /* tp_setattr */
3898 0, /* tp_compare */
3899 0, /* tp_repr */
3900 0, /* tp_as_number */
3901 0, /* tp_as_sequence */
3902 0, /* tp_as_mapping */
3903 0, /* tp_hash */
3904 0, /* tp_call */
3905 0, /* tp_str */
3906 PyObject_GenericGetAttr, /* tp_getattro */
3907 0, /* tp_setattro */
3908 0, /* tp_as_buffer */
3909 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3910 Py_TPFLAGS_BASETYPE, /* tp_flags */
3911 tzinfo_doc, /* tp_doc */
3912 0, /* tp_traverse */
3913 0, /* tp_clear */
3914 0, /* tp_richcompare */
3915 0, /* tp_weaklistoffset */
3916 0, /* tp_iter */
3917 0, /* tp_iternext */
3918 tzinfo_methods, /* tp_methods */
3919 0, /* tp_members */
3920 0, /* tp_getset */
3921 0, /* tp_base */
3922 0, /* tp_dict */
3923 0, /* tp_descr_get */
3924 0, /* tp_descr_set */
3925 0, /* tp_dictoffset */
3926 0, /* tp_init */
3927 0, /* tp_alloc */
3928 PyType_GenericNew, /* tp_new */
3929 0, /* tp_free */
3930};
3931
3932/*
3933 * PyDateTime_TimeTZ implementation.
3934 */
3935
3936/* Accessor properties. Properties for hour, minute, second and microsecond
3937 * are inherited from time.
3938 */
3939
3940static PyObject *
3941timetz_tzinfo(PyDateTime_TimeTZ *self, void *unused)
3942{
3943 Py_INCREF(self->tzinfo);
3944 return self->tzinfo;
3945}
3946
3947static PyGetSetDef timetz_getset[] = {
3948 {"tzinfo", (getter)timetz_tzinfo},
3949 {NULL}
3950};
3951
3952/*
3953 * Constructors.
3954 */
3955
3956static PyObject *
3957timetz_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3958{
3959 PyObject *self = NULL;
3960 int hour = 0;
3961 int minute = 0;
3962 int second = 0;
3963 int usecond = 0;
3964 PyObject *tzinfo = Py_None;
3965
3966 static char *keywords[] = {
3967 "hour", "minute", "second", "microsecond", "tzinfo", NULL
3968 };
3969
Neal Norwitzc296c632002-12-19 00:42:03 +00003970 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", keywords,
Tim Peters2a799bf2002-12-16 20:18:38 +00003971 &hour, &minute, &second, &usecond,
3972 &tzinfo)) {
3973 if (check_time_args(hour, minute, second, usecond) < 0)
3974 return NULL;
3975 if (check_tzinfo_subclass(tzinfo) < 0)
3976 return NULL;
3977 self = new_timetz(hour, minute, second, usecond, tzinfo);
3978 }
3979 return self;
3980}
3981
3982/*
3983 * Destructor.
3984 */
3985
3986static void
3987timetz_dealloc(PyDateTime_TimeTZ *self)
3988{
3989 Py_XDECREF(self->tzinfo);
3990 self->ob_type->tp_free((PyObject *)self);
3991}
3992
3993/*
Tim Peters855fe882002-12-22 03:43:39 +00003994 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003995 */
3996
Tim Peters2a799bf2002-12-16 20:18:38 +00003997/* These are all METH_NOARGS, so don't need to check the arglist. */
3998static PyObject *
3999timetz_utcoffset(PyDateTime_TimeTZ *self, PyObject *unused) {
Tim Peters855fe882002-12-22 03:43:39 +00004000 return offset_as_timedelta((PyObject *)self, self->tzinfo,
4001 "utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00004002}
4003
4004static PyObject *
4005timetz_dst(PyDateTime_TimeTZ *self, PyObject *unused) {
Tim Peters855fe882002-12-22 03:43:39 +00004006 return offset_as_timedelta((PyObject *)self, self->tzinfo, "dst");
4007}
4008
4009static PyObject *
4010timetz_tzname(PyDateTime_TimeTZ *self, PyObject *unused) {
4011 return call_tzname((PyObject *)self, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004012}
4013
4014/*
4015 * Various ways to turn a timetz into a string.
4016 */
4017
4018static PyObject *
4019timetz_repr(PyDateTime_TimeTZ *self)
4020{
4021 PyObject *baserepr = time_repr((PyDateTime_Time *)self);
4022
4023 if (baserepr == NULL)
4024 return NULL;
4025 return append_keyword_tzinfo(baserepr, self->tzinfo);
4026}
4027
4028/* Note: tp_str is inherited from time. */
4029
4030static PyObject *
4031timetz_isoformat(PyDateTime_TimeTZ *self)
4032{
4033 char buf[100];
4034 PyObject *result = time_isoformat((PyDateTime_Time *)self);
4035
4036 if (result == NULL || self->tzinfo == Py_None)
4037 return result;
4038
4039 /* We need to append the UTC offset. */
4040 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4041 (PyObject *)self) < 0) {
4042 Py_DECREF(result);
4043 return NULL;
4044 }
4045 PyString_ConcatAndDel(&result, PyString_FromString(buf));
4046 return result;
4047}
4048
4049/* Note: strftime() is inherited from time. */
4050
4051/*
4052 * Miscellaneous methods.
4053 */
4054
4055/* Note: tp_richcompare and tp_hash are inherited from time. */
4056
4057static int
4058timetz_nonzero(PyDateTime_TimeTZ *self)
4059{
4060 int offset;
4061 int none;
4062
4063 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
4064 /* Since utcoffset is in whole minutes, nothing can
4065 * alter the conclusion that this is nonzero.
4066 */
4067 return 1;
4068 }
4069 offset = 0;
4070 if (self->tzinfo != Py_None) {
4071 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4072 if (offset == -1 && PyErr_Occurred())
4073 return -1;
4074 }
4075 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
4076}
4077
4078/*
4079 * Pickle support. Quite a maze!
4080 */
4081
4082/* Let basestate be the state string returned by time_getstate.
4083 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4084 * So it's a tuple in any (non-error) case.
4085 */
4086static PyObject *
4087timetz_getstate(PyDateTime_TimeTZ *self)
4088{
4089 PyObject *basestate;
4090 PyObject *result = NULL;
4091
4092 basestate = time_getstate((PyDateTime_Time *)self);
4093 if (basestate != NULL) {
4094 if (self->tzinfo == Py_None)
4095 result = Py_BuildValue("(O)", basestate);
4096 else
4097 result = Py_BuildValue("OO", basestate, self->tzinfo);
4098 Py_DECREF(basestate);
4099 }
4100 return result;
4101}
4102
4103static PyObject *
4104timetz_setstate(PyDateTime_TimeTZ *self, PyObject *state)
4105{
4106 PyObject *temp;
4107 PyObject *basestate;
4108 PyObject *tzinfo = Py_None;
4109
4110 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
4111 &PyString_Type, &basestate,
4112 &tzinfo))
4113 return NULL;
4114 temp = time_setstate((PyDateTime_Time *)self, basestate);
4115 if (temp == NULL)
4116 return NULL;
4117 Py_DECREF(temp);
4118
4119 Py_INCREF(tzinfo);
4120 Py_XDECREF(self->tzinfo);
4121 self->tzinfo = tzinfo;
4122
4123 Py_INCREF(Py_None);
4124 return Py_None;
4125}
4126
4127static PyObject *
4128timetz_pickler(PyObject *module, PyDateTime_TimeTZ *timetz)
4129{
4130 PyObject *state;
4131 PyObject *result = NULL;
4132
4133 if (! PyTimeTZ_CheckExact(timetz)) {
4134 PyErr_Format(PyExc_TypeError,
4135 "bad type passed to timetz pickler: %s",
4136 timetz->ob_type->tp_name);
4137 return NULL;
4138 }
4139 state = timetz_getstate(timetz);
4140 if (state) {
4141 result = Py_BuildValue("O(O)",
4142 timetz_unpickler_object,
4143 state);
4144 Py_DECREF(state);
4145 }
4146 return result;
4147}
4148
4149static PyObject *
4150timetz_unpickler(PyObject *module, PyObject *arg)
4151{
4152 PyDateTime_TimeTZ *self;
4153
4154 self = PyObject_New(PyDateTime_TimeTZ, &PyDateTime_TimeTZType);
4155 if (self != NULL) {
4156 PyObject *res;
4157
4158 self->tzinfo = NULL;
4159 res = timetz_setstate(self, arg);
4160 if (res == NULL) {
4161 Py_DECREF(self);
4162 return NULL;
4163 }
4164 Py_DECREF(res);
4165 }
4166 return (PyObject *)self;
4167}
4168
4169static PyMethodDef timetz_methods[] = {
4170 {"isoformat", (PyCFunction)timetz_isoformat, METH_KEYWORDS,
4171 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
4172 "[+HH:MM].")},
4173
4174 {"utcoffset", (PyCFunction)timetz_utcoffset, METH_NOARGS,
4175 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4176
4177 {"tzname", (PyCFunction)timetz_tzname, METH_NOARGS,
4178 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4179
4180 {"dst", (PyCFunction)timetz_dst, METH_NOARGS,
4181 PyDoc_STR("Return self.tzinfo.dst(self).")},
4182
4183 {"__setstate__", (PyCFunction)timetz_setstate, METH_O,
4184 PyDoc_STR("__setstate__(state)")},
4185
4186 {"__getstate__", (PyCFunction)timetz_getstate, METH_NOARGS,
4187 PyDoc_STR("__getstate__() -> state")},
4188 {NULL, NULL}
4189
4190};
4191
4192static char timetz_doc[] =
4193PyDoc_STR("Time type.");
4194
4195static PyNumberMethods timetz_as_number = {
4196 0, /* nb_add */
4197 0, /* nb_subtract */
4198 0, /* nb_multiply */
4199 0, /* nb_divide */
4200 0, /* nb_remainder */
4201 0, /* nb_divmod */
4202 0, /* nb_power */
4203 0, /* nb_negative */
4204 0, /* nb_positive */
4205 0, /* nb_absolute */
4206 (inquiry)timetz_nonzero, /* nb_nonzero */
4207};
4208
4209statichere PyTypeObject PyDateTime_TimeTZType = {
4210 PyObject_HEAD_INIT(NULL)
4211 0, /* ob_size */
4212 "datetime.timetz", /* tp_name */
4213 sizeof(PyDateTime_TimeTZ), /* tp_basicsize */
4214 0, /* tp_itemsize */
4215 (destructor)timetz_dealloc, /* tp_dealloc */
4216 0, /* tp_print */
4217 0, /* tp_getattr */
4218 0, /* tp_setattr */
4219 0, /* tp_compare */
4220 (reprfunc)timetz_repr, /* tp_repr */
4221 &timetz_as_number, /* tp_as_number */
4222 0, /* tp_as_sequence */
4223 0, /* tp_as_mapping */
4224 0, /* tp_hash */
4225 0, /* tp_call */
4226 0, /* tp_str */
4227 PyObject_GenericGetAttr, /* tp_getattro */
4228 0, /* tp_setattro */
4229 0, /* tp_as_buffer */
4230 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4231 Py_TPFLAGS_BASETYPE, /* tp_flags */
Guido van Rossumbd43e912002-12-16 20:34:55 +00004232 timetz_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004233 0, /* tp_traverse */
4234 0, /* tp_clear */
4235 0, /* tp_richcompare */
4236 0, /* tp_weaklistoffset */
4237 0, /* tp_iter */
4238 0, /* tp_iternext */
4239 timetz_methods, /* tp_methods */
4240 0, /* tp_members */
4241 timetz_getset, /* tp_getset */
4242 &PyDateTime_TimeType, /* tp_base */
4243 0, /* tp_dict */
4244 0, /* tp_descr_get */
4245 0, /* tp_descr_set */
4246 0, /* tp_dictoffset */
4247 0, /* tp_init */
4248 0, /* tp_alloc */
4249 timetz_new, /* tp_new */
4250 _PyObject_Del, /* tp_free */
4251};
4252
4253/*
4254 * PyDateTime_DateTimeTZ implementation.
4255 */
4256
4257/* Accessor properties. Properties for day, month, year, hour, minute,
4258 * second and microsecond are inherited from datetime.
4259 */
4260
4261static PyObject *
4262datetimetz_tzinfo(PyDateTime_DateTimeTZ *self, void *unused)
4263{
4264 Py_INCREF(self->tzinfo);
4265 return self->tzinfo;
4266}
4267
4268static PyGetSetDef datetimetz_getset[] = {
4269 {"tzinfo", (getter)datetimetz_tzinfo},
4270 {NULL}
4271};
4272
4273/*
4274 * Constructors.
4275 * These are like the datetime methods of the same names, but allow an
4276 * optional tzinfo argument.
4277 */
4278
4279/* Internal helper.
4280 * self is a datetimetz. Replace its tzinfo member.
4281 */
4282void
4283replace_tzinfo(PyObject *self, PyObject *newtzinfo)
4284{
4285 assert(self != NULL);
4286 assert(newtzinfo != NULL);
4287 assert(PyDateTimeTZ_Check(self));
4288 Py_INCREF(newtzinfo);
4289 Py_DECREF(((PyDateTime_DateTimeTZ *)self)->tzinfo);
4290 ((PyDateTime_DateTimeTZ *)self)->tzinfo = newtzinfo;
4291}
4292
4293static PyObject *
4294datetimetz_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4295{
4296 PyObject *self = NULL;
4297 int year;
4298 int month;
4299 int day;
4300 int hour = 0;
4301 int minute = 0;
4302 int second = 0;
4303 int usecond = 0;
4304 PyObject *tzinfo = Py_None;
4305
4306 static char *keywords[] = {
4307 "year", "month", "day", "hour", "minute", "second",
4308 "microsecond", "tzinfo", NULL
4309 };
4310
4311 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", keywords,
4312 &year, &month, &day, &hour, &minute,
4313 &second, &usecond, &tzinfo)) {
4314 if (check_date_args(year, month, day) < 0)
4315 return NULL;
4316 if (check_time_args(hour, minute, second, usecond) < 0)
4317 return NULL;
4318 if (check_tzinfo_subclass(tzinfo) < 0)
4319 return NULL;
4320 self = new_datetimetz(year, month, day,
4321 hour, minute, second, usecond,
4322 tzinfo);
4323 }
4324 return self;
4325}
4326
4327/* Return best possible local time -- this isn't constrained by the
4328 * precision of a timestamp.
4329 */
4330static PyObject *
4331datetimetz_now(PyObject *cls, PyObject *args, PyObject *kw)
4332{
4333 PyObject *self = NULL;
4334 PyObject *tzinfo = Py_None;
4335 static char *keywords[] = {"tzinfo", NULL};
4336
4337 if (PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4338 &tzinfo)) {
4339 if (check_tzinfo_subclass(tzinfo) < 0)
4340 return NULL;
4341 self = datetime_best_possible(cls, localtime);
4342 if (self != NULL)
4343 replace_tzinfo(self, tzinfo);
4344 }
4345 return self;
4346}
4347
4348/* Return new local datetime from timestamp (Python timestamp -- a double). */
4349static PyObject *
4350datetimetz_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
4351{
4352 PyObject *self = NULL;
4353 double timestamp;
4354 PyObject *tzinfo = Py_None;
4355 static char *keywords[] = {"timestamp", "tzinfo", NULL};
4356
4357 if (PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4358 keywords, &timestamp, &tzinfo)) {
4359 if (check_tzinfo_subclass(tzinfo) < 0)
4360 return NULL;
4361 self = datetime_from_timestamp(cls, localtime, timestamp);
4362 if (self != NULL)
4363 replace_tzinfo(self, tzinfo);
4364 }
4365 return self;
4366}
4367
4368/* Note: utcnow() is inherited, and doesn't accept tzinfo.
4369 * Ditto utcfromtimestamp(). Ditto combine().
4370 */
4371
4372
4373/*
4374 * Destructor.
4375 */
4376
4377static void
4378datetimetz_dealloc(PyDateTime_DateTimeTZ *self)
4379{
4380 Py_XDECREF(self->tzinfo);
4381 self->ob_type->tp_free((PyObject *)self);
4382}
4383
4384/*
4385 * Indirect access to tzinfo methods.
4386 */
4387
Tim Peters2a799bf2002-12-16 20:18:38 +00004388/* These are all METH_NOARGS, so don't need to check the arglist. */
4389static PyObject *
4390datetimetz_utcoffset(PyDateTime_DateTimeTZ *self, PyObject *unused) {
Tim Peters855fe882002-12-22 03:43:39 +00004391 return offset_as_timedelta((PyObject *)self, self->tzinfo,
4392 "utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00004393}
4394
4395static PyObject *
4396datetimetz_dst(PyDateTime_DateTimeTZ *self, PyObject *unused) {
Tim Peters855fe882002-12-22 03:43:39 +00004397 return offset_as_timedelta((PyObject *)self, self->tzinfo, "dst");
4398}
4399
4400static PyObject *
4401datetimetz_tzname(PyDateTime_DateTimeTZ *self, PyObject *unused) {
4402 return call_tzname((PyObject *)self, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004403}
4404
4405/*
4406 * datetimetz arithmetic.
4407 */
4408
4409/* If base is Py_NotImplemented or NULL, just return it.
4410 * Else base is a datetime, exactly one of {left, right} is a datetimetz,
4411 * and we want to create a datetimetz with the same date and time fields
4412 * as base, and with the tzinfo field from left or right. Do that,
4413 * return it, and decref base. This is used to transform the result of
4414 * a binary datetime operation (base) into a datetimetz result.
4415 */
4416static PyObject *
4417attach_tzinfo(PyObject *base, PyObject *left, PyObject *right)
4418{
4419 PyDateTime_DateTimeTZ *self;
4420 PyDateTime_DateTimeTZ *result;
4421
4422 if (base == NULL || base == Py_NotImplemented)
4423 return base;
4424
4425 assert(PyDateTime_CheckExact(base));
4426
4427 if (PyDateTimeTZ_Check(left)) {
4428 assert(! PyDateTimeTZ_Check(right));
4429 self = (PyDateTime_DateTimeTZ *)left;
4430 }
4431 else {
4432 assert(PyDateTimeTZ_Check(right));
4433 self = (PyDateTime_DateTimeTZ *)right;
4434 }
4435 result = PyObject_New(PyDateTime_DateTimeTZ,
4436 &PyDateTime_DateTimeTZType);
4437 if (result != NULL) {
4438 memcpy(result->data, ((PyDateTime_DateTime *)base)->data,
4439 _PyDateTime_DATETIME_DATASIZE);
4440 Py_INCREF(self->tzinfo);
4441 result->tzinfo = self->tzinfo;
4442 }
4443 Py_DECREF(base);
4444 return (PyObject *)result;
4445}
4446
4447static PyObject *
4448datetimetz_add(PyObject *left, PyObject *right)
4449{
4450 return attach_tzinfo(datetime_add(left, right), left, right);
4451}
4452
4453static PyObject *
4454datetimetz_subtract(PyObject *left, PyObject *right)
4455{
4456 PyObject *result = Py_NotImplemented;
4457
4458 if (PyDateTime_Check(left)) {
4459 /* datetime - ??? */
4460 if (PyDateTime_Check(right)) {
4461 /* datetime - datetime */
4462 naivety n1, n2;
4463 int offset1, offset2;
4464 PyDateTime_Delta *delta;
4465
Tim Peters14b69412002-12-22 18:10:22 +00004466 n1 = classify_utcoffset(left, &offset1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004467 assert(n1 != OFFSET_UNKNOWN);
4468 if (n1 == OFFSET_ERROR)
4469 return NULL;
4470
Tim Peters14b69412002-12-22 18:10:22 +00004471 n2 = classify_utcoffset(right, &offset2);
Tim Peters2a799bf2002-12-16 20:18:38 +00004472 assert(n2 != OFFSET_UNKNOWN);
4473 if (n2 == OFFSET_ERROR)
4474 return NULL;
4475
4476 if (n1 != n2) {
4477 PyErr_SetString(PyExc_TypeError,
4478 "can't subtract offset-naive and "
4479 "offset-aware datetimes");
4480 return NULL;
4481 }
4482 delta = (PyDateTime_Delta *)sub_datetime_datetime(
4483 (PyDateTime_DateTime *)left,
4484 (PyDateTime_DateTime *)right);
4485 if (delta == NULL || offset1 == offset2)
4486 return (PyObject *)delta;
4487 /* (left - offset1) - (right - offset2) =
4488 * (left - right) + (offset2 - offset1)
4489 */
4490 result = new_delta(delta->days,
4491 delta->seconds +
4492 (offset2 - offset1) * 60,
4493 delta->microseconds,
4494 1);
4495 Py_DECREF(delta);
4496 }
4497 else if (PyDelta_Check(right)) {
4498 /* datetimetz - delta */
4499 result = sub_datetime_timedelta(
4500 (PyDateTime_DateTime *)left,
4501 (PyDateTime_Delta *)right);
4502 result = attach_tzinfo(result, left, right);
4503 }
4504 }
4505
4506 if (result == Py_NotImplemented)
4507 Py_INCREF(result);
4508 return result;
4509}
4510
4511/* Various ways to turn a datetime into a string. */
4512
4513static PyObject *
4514datetimetz_repr(PyDateTime_DateTimeTZ *self)
4515{
4516 PyObject *baserepr = datetime_repr((PyDateTime_DateTime *)self);
4517
4518 if (baserepr == NULL)
4519 return NULL;
4520 return append_keyword_tzinfo(baserepr, self->tzinfo);
4521}
4522
4523/* Note: tp_str is inherited from datetime. */
4524
4525static PyObject *
4526datetimetz_isoformat(PyDateTime_DateTimeTZ *self,
4527 PyObject *args, PyObject *kw)
4528{
4529 char buf[100];
4530 PyObject *result = datetime_isoformat((PyDateTime_DateTime *)self,
4531 args, kw);
4532
4533 if (result == NULL || self->tzinfo == Py_None)
4534 return result;
4535
4536 /* We need to append the UTC offset. */
4537 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4538 (PyObject *)self) < 0) {
4539 Py_DECREF(result);
4540 return NULL;
4541 }
4542 PyString_ConcatAndDel(&result, PyString_FromString(buf));
4543 return result;
4544}
4545
4546/* Miscellaneous methods. */
4547
4548/* Note: tp_richcompare and tp_hash are inherited from datetime. */
4549
4550static PyObject *
4551datetimetz_timetuple(PyDateTime_DateTimeTZ *self)
4552{
4553 int dstflag = -1;
4554
4555 if (self->tzinfo != Py_None) {
4556 int none;
4557
4558 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4559 if (dstflag == -1 && PyErr_Occurred())
4560 return NULL;
4561
4562 if (none)
4563 dstflag = -1;
4564 else if (dstflag != 0)
4565 dstflag = 1;
4566
4567 }
4568 return build_struct_time(GET_YEAR(self),
4569 GET_MONTH(self),
4570 GET_DAY(self),
4571 DATE_GET_HOUR(self),
4572 DATE_GET_MINUTE(self),
4573 DATE_GET_SECOND(self),
4574 dstflag);
4575}
4576
4577static PyObject *
4578datetimetz_utctimetuple(PyDateTime_DateTimeTZ *self)
4579{
4580 int y = GET_YEAR(self);
4581 int m = GET_MONTH(self);
4582 int d = GET_DAY(self);
4583 int hh = DATE_GET_HOUR(self);
4584 int mm = DATE_GET_MINUTE(self);
4585 int ss = DATE_GET_SECOND(self);
4586 int us = 0; /* microseconds are ignored in a timetuple */
4587 int offset = 0;
4588
4589 if (self->tzinfo != Py_None) {
4590 int none;
4591
4592 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4593 if (offset == -1 && PyErr_Occurred())
4594 return NULL;
4595 }
4596 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4597 * 0 in a UTC timetuple regardless of what dst() says.
4598 */
4599 if (offset) {
4600 /* Subtract offset minutes & normalize. */
4601 int stat;
4602
4603 mm -= offset;
4604 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4605 if (stat < 0) {
4606 /* At the edges, it's possible we overflowed
4607 * beyond MINYEAR or MAXYEAR.
4608 */
4609 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4610 PyErr_Clear();
4611 else
4612 return NULL;
4613 }
4614 }
4615 return build_struct_time(y, m, d, hh, mm, ss, 0);
4616}
4617
4618static PyObject *
4619datetimetz_gettimetz(PyDateTime_DateTimeTZ *self)
4620{
4621 return new_timetz(DATE_GET_HOUR(self),
4622 DATE_GET_MINUTE(self),
4623 DATE_GET_SECOND(self),
4624 DATE_GET_MICROSECOND(self),
4625 self->tzinfo);
4626}
4627
4628/*
4629 * Pickle support. Quite a maze!
4630 */
4631
4632/* Let basestate be the state string returned by datetime_getstate.
4633 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4634 * So it's a tuple in any (non-error) case.
4635 */
4636static PyObject *
4637datetimetz_getstate(PyDateTime_DateTimeTZ *self)
4638{
4639 PyObject *basestate;
4640 PyObject *result = NULL;
4641
4642 basestate = datetime_getstate((PyDateTime_DateTime *)self);
4643 if (basestate != NULL) {
4644 if (self->tzinfo == Py_None)
4645 result = Py_BuildValue("(O)", basestate);
4646 else
4647 result = Py_BuildValue("OO", basestate, self->tzinfo);
4648 Py_DECREF(basestate);
4649 }
4650 return result;
4651}
4652
4653static PyObject *
4654datetimetz_setstate(PyDateTime_DateTimeTZ *self, PyObject *state)
4655{
4656 PyObject *temp;
4657 PyObject *basestate;
4658 PyObject *tzinfo = Py_None;
4659
4660 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
4661 &PyString_Type, &basestate,
4662 &tzinfo))
4663 return NULL;
4664 temp = datetime_setstate((PyDateTime_DateTime *)self, basestate);
4665 if (temp == NULL)
4666 return NULL;
4667 Py_DECREF(temp);
4668
4669 Py_INCREF(tzinfo);
4670 Py_XDECREF(self->tzinfo);
4671 self->tzinfo = tzinfo;
4672
4673 Py_INCREF(Py_None);
4674 return Py_None;
4675}
4676
4677static PyObject *
4678datetimetz_pickler(PyObject *module, PyDateTime_DateTimeTZ *datetimetz)
4679{
4680 PyObject *state;
4681 PyObject *result = NULL;
4682
4683 if (! PyDateTimeTZ_CheckExact(datetimetz)) {
4684 PyErr_Format(PyExc_TypeError,
4685 "bad type passed to datetimetz pickler: %s",
4686 datetimetz->ob_type->tp_name);
4687 return NULL;
4688 }
4689 state = datetimetz_getstate(datetimetz);
4690 if (state) {
4691 result = Py_BuildValue("O(O)",
4692 datetimetz_unpickler_object,
4693 state);
4694 Py_DECREF(state);
4695 }
4696 return result;
4697}
4698
4699static PyObject *
4700datetimetz_unpickler(PyObject *module, PyObject *arg)
4701{
4702 PyDateTime_DateTimeTZ *self;
4703
4704 self = PyObject_New(PyDateTime_DateTimeTZ, &PyDateTime_DateTimeTZType);
4705 if (self != NULL) {
4706 PyObject *res;
4707
4708 self->tzinfo = NULL;
4709 res = datetimetz_setstate(self, arg);
4710 if (res == NULL) {
4711 Py_DECREF(self);
4712 return NULL;
4713 }
4714 Py_DECREF(res);
4715 }
4716 return (PyObject *)self;
4717}
4718
4719
4720static PyMethodDef datetimetz_methods[] = {
4721 /* Class methods: */
4722 /* Inherited: combine(), utcnow(), utcfromtimestamp() */
4723
4724 {"now", (PyCFunction)datetimetz_now,
4725 METH_KEYWORDS | METH_CLASS,
4726 PyDoc_STR("[tzinfo] -> new datetimetz with local day and time.")},
4727
4728 {"fromtimestamp", (PyCFunction)datetimetz_fromtimestamp,
4729 METH_KEYWORDS | METH_CLASS,
4730 PyDoc_STR("timestamp[, tzinfo] -> local time from POSIX timestamp.")},
4731
4732 /* Instance methods: */
4733 /* Inherited: date(), time(), ctime(). */
4734 {"timetuple", (PyCFunction)datetimetz_timetuple, METH_NOARGS,
4735 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4736
4737 {"utctimetuple", (PyCFunction)datetimetz_utctimetuple, METH_NOARGS,
4738 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4739
4740 {"timetz", (PyCFunction)datetimetz_gettimetz, METH_NOARGS,
4741 PyDoc_STR("Return timetz object with same hour, minute, second, "
4742 "microsecond, and tzinfo.")},
4743
4744 {"isoformat", (PyCFunction)datetimetz_isoformat, METH_KEYWORDS,
4745 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4746 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4747 "sep is used to separate the year from the time, and "
4748 "defaults to 'T'.")},
4749
4750 {"utcoffset", (PyCFunction)datetimetz_utcoffset, METH_NOARGS,
4751 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4752
4753 {"tzname", (PyCFunction)datetimetz_tzname, METH_NOARGS,
4754 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4755
4756 {"dst", (PyCFunction)datetimetz_dst, METH_NOARGS,
4757 PyDoc_STR("Return self.tzinfo.dst(self).")},
4758
4759 {"__setstate__", (PyCFunction)datetimetz_setstate, METH_O,
4760 PyDoc_STR("__setstate__(state)")},
4761
4762 {"__getstate__", (PyCFunction)datetimetz_getstate, METH_NOARGS,
4763 PyDoc_STR("__getstate__() -> state")},
4764 {NULL, NULL}
4765};
4766
4767static char datetimetz_doc[] =
4768PyDoc_STR("date/time type.");
4769
4770static PyNumberMethods datetimetz_as_number = {
4771 datetimetz_add, /* nb_add */
4772 datetimetz_subtract, /* nb_subtract */
4773 0, /* nb_multiply */
4774 0, /* nb_divide */
4775 0, /* nb_remainder */
4776 0, /* nb_divmod */
4777 0, /* nb_power */
4778 0, /* nb_negative */
4779 0, /* nb_positive */
4780 0, /* nb_absolute */
4781 0, /* nb_nonzero */
4782};
4783
4784statichere PyTypeObject PyDateTime_DateTimeTZType = {
4785 PyObject_HEAD_INIT(NULL)
4786 0, /* ob_size */
4787 "datetime.datetimetz", /* tp_name */
4788 sizeof(PyDateTime_DateTimeTZ), /* tp_basicsize */
4789 0, /* tp_itemsize */
4790 (destructor)datetimetz_dealloc, /* tp_dealloc */
4791 0, /* tp_print */
4792 0, /* tp_getattr */
4793 0, /* tp_setattr */
4794 0, /* tp_compare */
4795 (reprfunc)datetimetz_repr, /* tp_repr */
4796 &datetimetz_as_number, /* tp_as_number */
4797 0, /* tp_as_sequence */
4798 0, /* tp_as_mapping */
4799 0, /* tp_hash */
4800 0, /* tp_call */
4801 0, /* tp_str */
4802 PyObject_GenericGetAttr, /* tp_getattro */
4803 0, /* tp_setattro */
4804 0, /* tp_as_buffer */
4805 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4806 Py_TPFLAGS_BASETYPE, /* tp_flags */
4807 datetimetz_doc, /* tp_doc */
4808 0, /* tp_traverse */
4809 0, /* tp_clear */
4810 0, /* tp_richcompare */
4811 0, /* tp_weaklistoffset */
4812 0, /* tp_iter */
4813 0, /* tp_iternext */
4814 datetimetz_methods, /* tp_methods */
4815 0, /* tp_members */
4816 datetimetz_getset, /* tp_getset */
4817 &PyDateTime_DateTimeType, /* tp_base */
4818 0, /* tp_dict */
4819 0, /* tp_descr_get */
4820 0, /* tp_descr_set */
4821 0, /* tp_dictoffset */
4822 0, /* tp_init */
4823 0, /* tp_alloc */
4824 datetimetz_new, /* tp_new */
4825 _PyObject_Del, /* tp_free */
4826};
4827
4828/* ---------------------------------------------------------------------------
4829 * Module methods and initialization.
4830 */
4831
4832static PyMethodDef module_methods[] = {
4833 /* Private functions for pickling support, registered with the
4834 * copy_reg module by the module init function.
4835 */
4836 {"_date_pickler", (PyCFunction)date_pickler, METH_O, NULL},
4837 {"_date_unpickler", (PyCFunction)date_unpickler, METH_O, NULL},
4838 {"_datetime_pickler", (PyCFunction)datetime_pickler, METH_O, NULL},
4839 {"_datetime_unpickler", (PyCFunction)datetime_unpickler,METH_O, NULL},
4840 {"_datetimetz_pickler", (PyCFunction)datetimetz_pickler,METH_O, NULL},
4841 {"_datetimetz_unpickler",(PyCFunction)datetimetz_unpickler,METH_O, NULL},
4842 {"_time_pickler", (PyCFunction)time_pickler, METH_O, NULL},
4843 {"_time_unpickler", (PyCFunction)time_unpickler, METH_O, NULL},
4844 {"_timetz_pickler", (PyCFunction)timetz_pickler, METH_O, NULL},
4845 {"_timetz_unpickler", (PyCFunction)timetz_unpickler, METH_O, NULL},
4846 {"_tzinfo_pickler", (PyCFunction)tzinfo_pickler, METH_O, NULL},
4847 {"_tzinfo_unpickler", (PyCFunction)tzinfo_unpickler, METH_NOARGS,
4848 NULL},
4849 {NULL, NULL}
4850};
4851
4852PyMODINIT_FUNC
4853initdatetime(void)
4854{
4855 PyObject *m; /* a module object */
4856 PyObject *d; /* its dict */
4857 PyObject *x;
4858
4859 /* Types that use __reduce__ for pickling need to set the following
4860 * magical attr in the type dict, with a true value.
4861 */
4862 PyObject *safepickle = PyString_FromString("__safe_for_unpickling__");
4863 if (safepickle == NULL)
4864 return;
4865
4866 m = Py_InitModule3("datetime", module_methods,
4867 "Fast implementation of the datetime type.");
4868
4869 if (PyType_Ready(&PyDateTime_DateType) < 0)
4870 return;
4871 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4872 return;
4873 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4874 return;
4875 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4876 return;
4877 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4878 return;
4879 if (PyType_Ready(&PyDateTime_TimeTZType) < 0)
4880 return;
4881 if (PyType_Ready(&PyDateTime_DateTimeTZType) < 0)
4882 return;
4883
4884 /* Pickling support, via registering functions with copy_reg. */
4885 {
4886 PyObject *pickler;
4887 PyObject *copyreg = PyImport_ImportModule("copy_reg");
4888
4889 if (copyreg == NULL) return;
4890
4891 pickler = PyObject_GetAttrString(m, "_date_pickler");
4892 if (pickler == NULL) return;
4893 date_unpickler_object = PyObject_GetAttrString(m,
4894 "_date_unpickler");
4895 if (date_unpickler_object == NULL) return;
4896 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4897 &PyDateTime_DateType,
4898 pickler,
4899 date_unpickler_object);
4900 if (x == NULL) return;
4901 Py_DECREF(x);
4902 Py_DECREF(pickler);
4903
4904 pickler = PyObject_GetAttrString(m, "_datetime_pickler");
4905 if (pickler == NULL) return;
4906 datetime_unpickler_object = PyObject_GetAttrString(m,
4907 "_datetime_unpickler");
4908 if (datetime_unpickler_object == NULL) return;
4909 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4910 &PyDateTime_DateTimeType,
4911 pickler,
4912 datetime_unpickler_object);
4913 if (x == NULL) return;
4914 Py_DECREF(x);
4915 Py_DECREF(pickler);
4916
4917 pickler = PyObject_GetAttrString(m, "_time_pickler");
4918 if (pickler == NULL) return;
4919 time_unpickler_object = PyObject_GetAttrString(m,
4920 "_time_unpickler");
4921 if (time_unpickler_object == NULL) return;
4922 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4923 &PyDateTime_TimeType,
4924 pickler,
4925 time_unpickler_object);
4926 if (x == NULL) return;
4927 Py_DECREF(x);
4928 Py_DECREF(pickler);
4929
4930 pickler = PyObject_GetAttrString(m, "_timetz_pickler");
4931 if (pickler == NULL) return;
4932 timetz_unpickler_object = PyObject_GetAttrString(m,
4933 "_timetz_unpickler");
4934 if (timetz_unpickler_object == NULL) return;
4935 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4936 &PyDateTime_TimeTZType,
4937 pickler,
4938 timetz_unpickler_object);
4939 if (x == NULL) return;
4940 Py_DECREF(x);
4941 Py_DECREF(pickler);
4942
4943 pickler = PyObject_GetAttrString(m, "_tzinfo_pickler");
4944 if (pickler == NULL) return;
4945 tzinfo_unpickler_object = PyObject_GetAttrString(m,
4946 "_tzinfo_unpickler");
4947 if (tzinfo_unpickler_object == NULL) return;
4948 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4949 &PyDateTime_TZInfoType,
4950 pickler,
4951 tzinfo_unpickler_object);
4952 if (x== NULL) return;
4953 Py_DECREF(x);
4954 Py_DECREF(pickler);
4955
4956 pickler = PyObject_GetAttrString(m, "_datetimetz_pickler");
4957 if (pickler == NULL) return;
4958 datetimetz_unpickler_object = PyObject_GetAttrString(m,
4959 "_datetimetz_unpickler");
4960 if (datetimetz_unpickler_object == NULL) return;
4961 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4962 &PyDateTime_DateTimeTZType,
4963 pickler,
4964 datetimetz_unpickler_object);
4965 if (x== NULL) return;
4966 Py_DECREF(x);
4967 Py_DECREF(pickler);
4968
4969 Py_DECREF(copyreg);
4970 }
4971
4972 /* timedelta values */
4973 d = PyDateTime_DeltaType.tp_dict;
4974
4975 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
4976 return;
4977
4978 x = new_delta(0, 0, 1, 0);
4979 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4980 return;
4981 Py_DECREF(x);
4982
4983 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4984 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4985 return;
4986 Py_DECREF(x);
4987
4988 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4989 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4990 return;
4991 Py_DECREF(x);
4992
4993 /* date values */
4994 d = PyDateTime_DateType.tp_dict;
4995
4996 x = new_date(1, 1, 1);
4997 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4998 return;
4999 Py_DECREF(x);
5000
5001 x = new_date(MAXYEAR, 12, 31);
5002 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5003 return;
5004 Py_DECREF(x);
5005
5006 x = new_delta(1, 0, 0, 0);
5007 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5008 return;
5009 Py_DECREF(x);
5010
5011 /* datetime values */
5012 d = PyDateTime_DateTimeType.tp_dict;
5013
5014 x = new_datetime(1, 1, 1, 0, 0, 0, 0);
5015 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5016 return;
5017 Py_DECREF(x);
5018
5019 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999);
5020 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5021 return;
5022 Py_DECREF(x);
5023
5024 x = new_delta(0, 0, 1, 0);
5025 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5026 return;
5027 Py_DECREF(x);
5028
5029 /* time values */
5030 d = PyDateTime_TimeType.tp_dict;
5031
5032 x = new_time(0, 0, 0, 0);
5033 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5034 return;
5035 Py_DECREF(x);
5036
5037 x = new_time(23, 59, 59, 999999);
5038 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5039 return;
5040 Py_DECREF(x);
5041
5042 x = new_delta(0, 0, 1, 0);
5043 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5044 return;
5045 Py_DECREF(x);
5046
5047 /* timetz values */
5048 d = PyDateTime_TimeTZType.tp_dict;
5049
5050 x = new_timetz(0, 0, 0, 0, Py_None);
5051 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5052 return;
5053 Py_DECREF(x);
5054
5055 x = new_timetz(23, 59, 59, 999999, Py_None);
5056 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5057 return;
5058 Py_DECREF(x);
5059
5060 x = new_delta(0, 0, 1, 0);
5061 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5062 return;
5063 Py_DECREF(x);
5064
5065 /* datetimetz values */
5066 d = PyDateTime_DateTimeTZType.tp_dict;
5067
5068 x = new_datetimetz(1, 1, 1, 0, 0, 0, 0, Py_None);
5069 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5070 return;
5071 Py_DECREF(x);
5072
5073 x = new_datetimetz(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5074 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5075 return;
5076 Py_DECREF(x);
5077
5078 x = new_delta(0, 0, 1, 0);
5079 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5080 return;
5081 Py_DECREF(x);
5082
5083 Py_DECREF(safepickle);
5084
5085 /* module initialization */
5086 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5087 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
5088
5089 Py_INCREF(&PyDateTime_DateType);
5090 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
5091
5092 Py_INCREF(&PyDateTime_DateTimeType);
5093 PyModule_AddObject(m, "datetime",
5094 (PyObject *) &PyDateTime_DateTimeType);
5095
5096 Py_INCREF(&PyDateTime_DeltaType);
5097 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
5098
5099 Py_INCREF(&PyDateTime_TimeType);
5100 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
5101
5102 Py_INCREF(&PyDateTime_TZInfoType);
5103 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
5104
5105 Py_INCREF(&PyDateTime_TimeTZType);
5106 PyModule_AddObject(m, "timetz", (PyObject *) &PyDateTime_TimeTZType);
5107
5108 Py_INCREF(&PyDateTime_DateTimeTZType);
5109 PyModule_AddObject(m, "datetimetz",
5110 (PyObject *)&PyDateTime_DateTimeTZType);
5111
5112 /* A 4-year cycle has an extra leap day over what we'd get from
5113 * pasting together 4 single years.
5114 */
5115 assert(DI4Y == 4 * 365 + 1);
5116 assert(DI4Y == days_before_year(4+1));
5117
5118 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5119 * get from pasting together 4 100-year cycles.
5120 */
5121 assert(DI400Y == 4 * DI100Y + 1);
5122 assert(DI400Y == days_before_year(400+1));
5123
5124 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5125 * pasting together 25 4-year cycles.
5126 */
5127 assert(DI100Y == 25 * DI4Y - 1);
5128 assert(DI100Y == days_before_year(100+1));
5129
5130 us_per_us = PyInt_FromLong(1);
5131 us_per_ms = PyInt_FromLong(1000);
5132 us_per_second = PyInt_FromLong(1000000);
5133 us_per_minute = PyInt_FromLong(60000000);
5134 seconds_per_day = PyInt_FromLong(24 * 3600);
5135 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5136 us_per_minute == NULL || seconds_per_day == NULL)
5137 return;
5138
5139 /* The rest are too big for 32-bit ints, but even
5140 * us_per_week fits in 40 bits, so doubles should be exact.
5141 */
5142 us_per_hour = PyLong_FromDouble(3600000000.0);
5143 us_per_day = PyLong_FromDouble(86400000000.0);
5144 us_per_week = PyLong_FromDouble(604800000000.0);
5145 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5146 return;
5147}