blob: a9675d60515f26d1d6487bd2c1fe39aa1248234f [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
Tim Petersd6844152002-12-22 20:58:42 +0000943 /* Give up if the year is before 1900.
944 * Python strftime() plays games with the year, and different
945 * games depending on whether envar PYTHON2K is set. This makes
946 * years before 1900 a nightmare, even if the platform strftime
947 * supports them (and not all do).
948 * We could get a lot farther here by avoiding Python's strftime
949 * wrapper and calling the C strftime() directly, but that isn't
950 * an option in the Python implementation of this module.
951 */
952 {
953 long year;
954 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
955 if (pyyear == NULL) return NULL;
956 assert(PyInt_Check(pyyear));
957 year = PyInt_AsLong(pyyear);
958 Py_DECREF(pyyear);
959 if (year < 1900) {
960 PyErr_Format(PyExc_ValueError, "year=%ld is before "
961 "1900; the datetime strftime() "
962 "methods require year >= 1900",
963 year);
964 return NULL;
965 }
966 }
967
Tim Peters2a799bf2002-12-16 20:18:38 +0000968 /* Scan the input format, looking for %z and %Z escapes, building
Tim Peters328fff72002-12-20 01:31:27 +0000969 * a new format. Since computing the replacements for those codes
970 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +0000971 */
972 totalnew = PyString_Size(format); /* realistic if no %z/%Z */
973 newfmt = PyString_FromStringAndSize(NULL, totalnew);
974 if (newfmt == NULL) goto Done;
975 pnew = PyString_AsString(newfmt);
976 usednew = 0;
977
978 pin = PyString_AsString(format);
979 while ((ch = *pin++) != '\0') {
980 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +0000981 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000982 ntoappend = 1;
983 }
984 else if ((ch = *pin++) == '\0') {
985 /* There's a lone trailing %; doesn't make sense. */
986 PyErr_SetString(PyExc_ValueError, "strftime format "
987 "ends with raw %");
988 goto Done;
989 }
990 /* A % has been seen and ch is the character after it. */
991 else if (ch == 'z') {
992 if (zreplacement == NULL) {
993 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +0000994 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +0000995 PyObject *tzinfo = get_tzinfo_member(object);
996 zreplacement = PyString_FromString("");
997 if (zreplacement == NULL) goto Done;
998 if (tzinfo != Py_None && tzinfo != NULL) {
999 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001000 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001001 "",
1002 tzinfo,
1003 object) < 0)
1004 goto Done;
1005 Py_DECREF(zreplacement);
1006 zreplacement = PyString_FromString(buf);
1007 if (zreplacement == NULL) goto Done;
1008 }
1009 }
1010 assert(zreplacement != NULL);
1011 ptoappend = PyString_AsString(zreplacement);
1012 ntoappend = PyString_Size(zreplacement);
1013 }
1014 else if (ch == 'Z') {
1015 /* format tzname */
1016 if (Zreplacement == NULL) {
1017 PyObject *tzinfo = get_tzinfo_member(object);
1018 Zreplacement = PyString_FromString("");
1019 if (Zreplacement == NULL) goto Done;
1020 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Peters855fe882002-12-22 03:43:39 +00001021 PyObject *temp = call_tzname(object,
1022 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00001023 if (temp == NULL) goto Done;
1024 if (temp != Py_None) {
1025 assert(PyString_Check(temp));
1026 /* Since the tzname is getting
1027 * stuffed into the format, we
1028 * have to double any % signs
1029 * so that strftime doesn't
1030 * treat them as format codes.
1031 */
1032 Py_DECREF(Zreplacement);
1033 Zreplacement = PyObject_CallMethod(
1034 temp, "replace",
1035 "ss", "%", "%%");
1036 Py_DECREF(temp);
1037 if (Zreplacement == NULL)
1038 goto Done;
1039 }
1040 else
1041 Py_DECREF(temp);
1042 }
1043 }
1044 assert(Zreplacement != NULL);
1045 ptoappend = PyString_AsString(Zreplacement);
1046 ntoappend = PyString_Size(Zreplacement);
1047 }
1048 else {
Tim Peters328fff72002-12-20 01:31:27 +00001049 /* percent followed by neither z nor Z */
1050 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001051 ntoappend = 2;
1052 }
1053
1054 /* Append the ntoappend chars starting at ptoappend to
1055 * the new format.
1056 */
1057 assert(ntoappend >= 0);
1058 if (ntoappend == 0)
1059 continue;
1060 while (usednew + ntoappend > totalnew) {
1061 int bigger = totalnew << 1;
1062 if ((bigger >> 1) != totalnew) { /* overflow */
1063 PyErr_NoMemory();
1064 goto Done;
1065 }
1066 if (_PyString_Resize(&newfmt, bigger) < 0)
1067 goto Done;
1068 totalnew = bigger;
1069 pnew = PyString_AsString(newfmt) + usednew;
1070 }
1071 memcpy(pnew, ptoappend, ntoappend);
1072 pnew += ntoappend;
1073 usednew += ntoappend;
1074 assert(usednew <= totalnew);
1075 } /* end while() */
1076
1077 if (_PyString_Resize(&newfmt, usednew) < 0)
1078 goto Done;
1079 {
1080 PyObject *time = PyImport_ImportModule("time");
1081 if (time == NULL)
1082 goto Done;
1083 result = PyObject_CallMethod(time, "strftime", "OO",
1084 newfmt, timetuple);
1085 Py_DECREF(time);
1086 }
1087 Done:
1088 Py_XDECREF(zreplacement);
1089 Py_XDECREF(Zreplacement);
1090 Py_XDECREF(newfmt);
1091 return result;
1092}
1093
1094static char *
1095isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1096{
1097 int x;
1098 x = PyOS_snprintf(buffer, bufflen,
1099 "%04d-%02d-%02d",
1100 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1101 return buffer + x;
1102}
1103
1104static void
1105isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1106{
1107 int us = DATE_GET_MICROSECOND(dt);
1108
1109 PyOS_snprintf(buffer, bufflen,
1110 "%02d:%02d:%02d", /* 8 characters */
1111 DATE_GET_HOUR(dt),
1112 DATE_GET_MINUTE(dt),
1113 DATE_GET_SECOND(dt));
1114 if (us)
1115 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1116}
1117
1118/* ---------------------------------------------------------------------------
1119 * Wrap functions from the time module. These aren't directly available
1120 * from C. Perhaps they should be.
1121 */
1122
1123/* Call time.time() and return its result (a Python float). */
1124static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001125time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001126{
1127 PyObject *result = NULL;
1128 PyObject *time = PyImport_ImportModule("time");
1129
1130 if (time != NULL) {
1131 result = PyObject_CallMethod(time, "time", "()");
1132 Py_DECREF(time);
1133 }
1134 return result;
1135}
1136
1137/* Build a time.struct_time. The weekday and day number are automatically
1138 * computed from the y,m,d args.
1139 */
1140static PyObject *
1141build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1142{
1143 PyObject *time;
1144 PyObject *result = NULL;
1145
1146 time = PyImport_ImportModule("time");
1147 if (time != NULL) {
1148 result = PyObject_CallMethod(time, "struct_time",
1149 "((iiiiiiiii))",
1150 y, m, d,
1151 hh, mm, ss,
1152 weekday(y, m, d),
1153 days_before_month(y, m) + d,
1154 dstflag);
1155 Py_DECREF(time);
1156 }
1157 return result;
1158}
1159
1160/* ---------------------------------------------------------------------------
1161 * Miscellaneous helpers.
1162 */
1163
1164/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1165 * The comparisons here all most naturally compute a cmp()-like result.
1166 * This little helper turns that into a bool result for rich comparisons.
1167 */
1168static PyObject *
1169diff_to_bool(int diff, int op)
1170{
1171 PyObject *result;
1172 int istrue;
1173
1174 switch (op) {
1175 case Py_EQ: istrue = diff == 0; break;
1176 case Py_NE: istrue = diff != 0; break;
1177 case Py_LE: istrue = diff <= 0; break;
1178 case Py_GE: istrue = diff >= 0; break;
1179 case Py_LT: istrue = diff < 0; break;
1180 case Py_GT: istrue = diff > 0; break;
1181 default:
1182 assert(! "op unknown");
1183 istrue = 0; /* To shut up compiler */
1184 }
1185 result = istrue ? Py_True : Py_False;
1186 Py_INCREF(result);
1187 return result;
1188}
1189
1190/* ---------------------------------------------------------------------------
1191 * Helpers for setting object fields. These work on pointers to the
1192 * appropriate base class.
1193 */
1194
1195/* For date, datetime and datetimetz. */
1196static void
1197set_date_fields(PyDateTime_Date *self, int y, int m, int d)
1198{
1199 self->hashcode = -1;
1200 SET_YEAR(self, y);
1201 SET_MONTH(self, m);
1202 SET_DAY(self, d);
1203}
1204
1205/* For datetime and datetimetz. */
1206static void
1207set_datetime_time_fields(PyDateTime_Date *self, int h, int m, int s, int us)
1208{
1209 DATE_SET_HOUR(self, h);
1210 DATE_SET_MINUTE(self, m);
1211 DATE_SET_SECOND(self, s);
1212 DATE_SET_MICROSECOND(self, us);
1213}
1214
1215/* For time and timetz. */
1216static void
1217set_time_fields(PyDateTime_Time *self, int h, int m, int s, int us)
1218{
1219 self->hashcode = -1;
1220 TIME_SET_HOUR(self, h);
1221 TIME_SET_MINUTE(self, m);
1222 TIME_SET_SECOND(self, s);
1223 TIME_SET_MICROSECOND(self, us);
1224}
1225
1226/* ---------------------------------------------------------------------------
1227 * Create various objects, mostly without range checking.
1228 */
1229
1230/* Create a date instance with no range checking. */
1231static PyObject *
1232new_date(int year, int month, int day)
1233{
1234 PyDateTime_Date *self;
1235
1236 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
1237 if (self != NULL)
1238 set_date_fields(self, year, month, day);
1239 return (PyObject *) self;
1240}
1241
1242/* Create a datetime instance with no range checking. */
1243static PyObject *
1244new_datetime(int year, int month, int day, int hour, int minute,
1245 int second, int usecond)
1246{
1247 PyDateTime_DateTime *self;
1248
1249 self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType);
1250 if (self != NULL) {
1251 set_date_fields((PyDateTime_Date *)self, year, month, day);
1252 set_datetime_time_fields((PyDateTime_Date *)self,
1253 hour, minute, second, usecond);
1254 }
1255 return (PyObject *) self;
1256}
1257
1258/* Create a datetimetz instance with no range checking. */
1259static PyObject *
1260new_datetimetz(int year, int month, int day, int hour, int minute,
1261 int second, int usecond, PyObject *tzinfo)
1262{
1263 PyDateTime_DateTimeTZ *self;
1264
1265 self = PyObject_New(PyDateTime_DateTimeTZ, &PyDateTime_DateTimeTZType);
1266 if (self != NULL) {
1267 set_date_fields((PyDateTime_Date *)self, year, month, day);
1268 set_datetime_time_fields((PyDateTime_Date *)self,
1269 hour, minute, second, usecond);
1270 Py_INCREF(tzinfo);
1271 self->tzinfo = tzinfo;
1272 }
1273 return (PyObject *) self;
1274}
1275
1276/* Create a time instance with no range checking. */
1277static PyObject *
1278new_time(int hour, int minute, int second, int usecond)
1279{
1280 PyDateTime_Time *self;
1281
1282 self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType);
1283 if (self != NULL)
1284 set_time_fields(self, hour, minute, second, usecond);
1285 return (PyObject *) self;
1286}
1287
1288/* Create a timetz instance with no range checking. */
1289static PyObject *
1290new_timetz(int hour, int minute, int second, int usecond, PyObject *tzinfo)
1291{
1292 PyDateTime_TimeTZ *self;
1293
1294 self = PyObject_New(PyDateTime_TimeTZ, &PyDateTime_TimeTZType);
1295 if (self != NULL) {
1296 set_time_fields((PyDateTime_Time *)self,
1297 hour, minute, second, usecond);
1298 Py_INCREF(tzinfo);
1299 self->tzinfo = tzinfo;
1300 }
1301 return (PyObject *) self;
1302}
1303
1304/* Create a timedelta instance. Normalize the members iff normalize is
1305 * true. Passing false is a speed optimization, if you know for sure
1306 * that seconds and microseconds are already in their proper ranges. In any
1307 * case, raises OverflowError and returns NULL if the normalized days is out
1308 * of range).
1309 */
1310static PyObject *
1311new_delta(int days, int seconds, int microseconds, int normalize)
1312{
1313 PyDateTime_Delta *self;
1314
1315 if (normalize)
1316 normalize_d_s_us(&days, &seconds, &microseconds);
1317 assert(0 <= seconds && seconds < 24*3600);
1318 assert(0 <= microseconds && microseconds < 1000000);
1319
1320 if (check_delta_day_range(days) < 0)
1321 return NULL;
1322
1323 self = PyObject_New(PyDateTime_Delta, &PyDateTime_DeltaType);
1324 if (self != NULL) {
1325 self->hashcode = -1;
1326 SET_TD_DAYS(self, days);
1327 SET_TD_SECONDS(self, seconds);
1328 SET_TD_MICROSECONDS(self, microseconds);
1329 }
1330 return (PyObject *) self;
1331}
1332
1333
1334/* ---------------------------------------------------------------------------
1335 * Cached Python objects; these are set by the module init function.
1336 */
1337
1338/* Conversion factors. */
1339static PyObject *us_per_us = NULL; /* 1 */
1340static PyObject *us_per_ms = NULL; /* 1000 */
1341static PyObject *us_per_second = NULL; /* 1000000 */
1342static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1343static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1344static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1345static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1346static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1347
1348/* Callables to support unpickling. */
1349static PyObject *date_unpickler_object = NULL;
1350static PyObject *datetime_unpickler_object = NULL;
1351static PyObject *datetimetz_unpickler_object = NULL;
1352static PyObject *tzinfo_unpickler_object = NULL;
1353static PyObject *time_unpickler_object = NULL;
1354static PyObject *timetz_unpickler_object = NULL;
1355
1356/* ---------------------------------------------------------------------------
1357 * Class implementations.
1358 */
1359
1360/*
1361 * PyDateTime_Delta implementation.
1362 */
1363
1364/* Convert a timedelta to a number of us,
1365 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1366 * as a Python int or long.
1367 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1368 * due to ubiquitous overflow possibilities.
1369 */
1370static PyObject *
1371delta_to_microseconds(PyDateTime_Delta *self)
1372{
1373 PyObject *x1 = NULL;
1374 PyObject *x2 = NULL;
1375 PyObject *x3 = NULL;
1376 PyObject *result = NULL;
1377
1378 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1379 if (x1 == NULL)
1380 goto Done;
1381 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1382 if (x2 == NULL)
1383 goto Done;
1384 Py_DECREF(x1);
1385 x1 = NULL;
1386
1387 /* x2 has days in seconds */
1388 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1389 if (x1 == NULL)
1390 goto Done;
1391 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1392 if (x3 == NULL)
1393 goto Done;
1394 Py_DECREF(x1);
1395 Py_DECREF(x2);
1396 x1 = x2 = NULL;
1397
1398 /* x3 has days+seconds in seconds */
1399 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1400 if (x1 == NULL)
1401 goto Done;
1402 Py_DECREF(x3);
1403 x3 = NULL;
1404
1405 /* x1 has days+seconds in us */
1406 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1407 if (x2 == NULL)
1408 goto Done;
1409 result = PyNumber_Add(x1, x2);
1410
1411Done:
1412 Py_XDECREF(x1);
1413 Py_XDECREF(x2);
1414 Py_XDECREF(x3);
1415 return result;
1416}
1417
1418/* Convert a number of us (as a Python int or long) to a timedelta.
1419 */
1420static PyObject *
1421microseconds_to_delta(PyObject *pyus)
1422{
1423 int us;
1424 int s;
1425 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001426 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001427
1428 PyObject *tuple = NULL;
1429 PyObject *num = NULL;
1430 PyObject *result = NULL;
1431
1432 tuple = PyNumber_Divmod(pyus, us_per_second);
1433 if (tuple == NULL)
1434 goto Done;
1435
1436 num = PyTuple_GetItem(tuple, 1); /* us */
1437 if (num == NULL)
1438 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001439 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001440 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001441 if (temp == -1 && PyErr_Occurred())
1442 goto Done;
1443 assert(0 <= temp && temp < 1000000);
1444 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001445 if (us < 0) {
1446 /* The divisor was positive, so this must be an error. */
1447 assert(PyErr_Occurred());
1448 goto Done;
1449 }
1450
1451 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1452 if (num == NULL)
1453 goto Done;
1454 Py_INCREF(num);
1455 Py_DECREF(tuple);
1456
1457 tuple = PyNumber_Divmod(num, seconds_per_day);
1458 if (tuple == NULL)
1459 goto Done;
1460 Py_DECREF(num);
1461
1462 num = PyTuple_GetItem(tuple, 1); /* seconds */
1463 if (num == NULL)
1464 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001465 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001466 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001467 if (temp == -1 && PyErr_Occurred())
1468 goto Done;
1469 assert(0 <= temp && temp < 24*3600);
1470 s = (int)temp;
1471
Tim Peters2a799bf2002-12-16 20:18:38 +00001472 if (s < 0) {
1473 /* The divisor was positive, so this must be an error. */
1474 assert(PyErr_Occurred());
1475 goto Done;
1476 }
1477
1478 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1479 if (num == NULL)
1480 goto Done;
1481 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001482 temp = PyLong_AsLong(num);
1483 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001484 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001485 d = (int)temp;
1486 if ((long)d != temp) {
1487 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1488 "large to fit in a C int");
1489 goto Done;
1490 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001491 result = new_delta(d, s, us, 0);
1492
1493Done:
1494 Py_XDECREF(tuple);
1495 Py_XDECREF(num);
1496 return result;
1497}
1498
1499static PyObject *
1500multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1501{
1502 PyObject *pyus_in;
1503 PyObject *pyus_out;
1504 PyObject *result;
1505
1506 pyus_in = delta_to_microseconds(delta);
1507 if (pyus_in == NULL)
1508 return NULL;
1509
1510 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1511 Py_DECREF(pyus_in);
1512 if (pyus_out == NULL)
1513 return NULL;
1514
1515 result = microseconds_to_delta(pyus_out);
1516 Py_DECREF(pyus_out);
1517 return result;
1518}
1519
1520static PyObject *
1521divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1522{
1523 PyObject *pyus_in;
1524 PyObject *pyus_out;
1525 PyObject *result;
1526
1527 pyus_in = delta_to_microseconds(delta);
1528 if (pyus_in == NULL)
1529 return NULL;
1530
1531 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1532 Py_DECREF(pyus_in);
1533 if (pyus_out == NULL)
1534 return NULL;
1535
1536 result = microseconds_to_delta(pyus_out);
1537 Py_DECREF(pyus_out);
1538 return result;
1539}
1540
1541static PyObject *
1542delta_add(PyObject *left, PyObject *right)
1543{
1544 PyObject *result = Py_NotImplemented;
1545
1546 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1547 /* delta + delta */
1548 /* The C-level additions can't overflow because of the
1549 * invariant bounds.
1550 */
1551 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1552 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1553 int microseconds = GET_TD_MICROSECONDS(left) +
1554 GET_TD_MICROSECONDS(right);
1555 result = new_delta(days, seconds, microseconds, 1);
1556 }
1557
1558 if (result == Py_NotImplemented)
1559 Py_INCREF(result);
1560 return result;
1561}
1562
1563static PyObject *
1564delta_negative(PyDateTime_Delta *self)
1565{
1566 return new_delta(-GET_TD_DAYS(self),
1567 -GET_TD_SECONDS(self),
1568 -GET_TD_MICROSECONDS(self),
1569 1);
1570}
1571
1572static PyObject *
1573delta_positive(PyDateTime_Delta *self)
1574{
1575 /* Could optimize this (by returning self) if this isn't a
1576 * subclass -- but who uses unary + ? Approximately nobody.
1577 */
1578 return new_delta(GET_TD_DAYS(self),
1579 GET_TD_SECONDS(self),
1580 GET_TD_MICROSECONDS(self),
1581 0);
1582}
1583
1584static PyObject *
1585delta_abs(PyDateTime_Delta *self)
1586{
1587 PyObject *result;
1588
1589 assert(GET_TD_MICROSECONDS(self) >= 0);
1590 assert(GET_TD_SECONDS(self) >= 0);
1591
1592 if (GET_TD_DAYS(self) < 0)
1593 result = delta_negative(self);
1594 else
1595 result = delta_positive(self);
1596
1597 return result;
1598}
1599
1600static PyObject *
1601delta_subtract(PyObject *left, PyObject *right)
1602{
1603 PyObject *result = Py_NotImplemented;
1604
1605 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1606 /* delta - delta */
1607 PyObject *minus_right = PyNumber_Negative(right);
1608 if (minus_right) {
1609 result = delta_add(left, minus_right);
1610 Py_DECREF(minus_right);
1611 }
1612 else
1613 result = NULL;
1614 }
1615
1616 if (result == Py_NotImplemented)
1617 Py_INCREF(result);
1618 return result;
1619}
1620
1621/* This is more natural as a tp_compare, but doesn't work then: for whatever
1622 * reason, Python's try_3way_compare ignores tp_compare unless
1623 * PyInstance_Check returns true, but these aren't old-style classes.
1624 */
1625static PyObject *
1626delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1627{
1628 int diff;
1629
1630 if (! PyDelta_CheckExact(other)) {
1631 PyErr_Format(PyExc_TypeError,
1632 "can't compare %s to %s instance",
1633 self->ob_type->tp_name, other->ob_type->tp_name);
1634 return NULL;
1635 }
1636 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1637 if (diff == 0) {
1638 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1639 if (diff == 0)
1640 diff = GET_TD_MICROSECONDS(self) -
1641 GET_TD_MICROSECONDS(other);
1642 }
1643 return diff_to_bool(diff, op);
1644}
1645
1646static PyObject *delta_getstate(PyDateTime_Delta *self);
1647
1648static long
1649delta_hash(PyDateTime_Delta *self)
1650{
1651 if (self->hashcode == -1) {
1652 PyObject *temp = delta_getstate(self);
1653 if (temp != NULL) {
1654 self->hashcode = PyObject_Hash(temp);
1655 Py_DECREF(temp);
1656 }
1657 }
1658 return self->hashcode;
1659}
1660
1661static PyObject *
1662delta_multiply(PyObject *left, PyObject *right)
1663{
1664 PyObject *result = Py_NotImplemented;
1665
1666 if (PyDelta_Check(left)) {
1667 /* delta * ??? */
1668 if (PyInt_Check(right) || PyLong_Check(right))
1669 result = multiply_int_timedelta(right,
1670 (PyDateTime_Delta *) left);
1671 }
1672 else if (PyInt_Check(left) || PyLong_Check(left))
1673 result = multiply_int_timedelta(left,
1674 (PyDateTime_Delta *) right);
1675
1676 if (result == Py_NotImplemented)
1677 Py_INCREF(result);
1678 return result;
1679}
1680
1681static PyObject *
1682delta_divide(PyObject *left, PyObject *right)
1683{
1684 PyObject *result = Py_NotImplemented;
1685
1686 if (PyDelta_Check(left)) {
1687 /* delta * ??? */
1688 if (PyInt_Check(right) || PyLong_Check(right))
1689 result = divide_timedelta_int(
1690 (PyDateTime_Delta *)left,
1691 right);
1692 }
1693
1694 if (result == Py_NotImplemented)
1695 Py_INCREF(result);
1696 return result;
1697}
1698
1699/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1700 * timedelta constructor. sofar is the # of microseconds accounted for
1701 * so far, and there are factor microseconds per current unit, the number
1702 * of which is given by num. num * factor is added to sofar in a
1703 * numerically careful way, and that's the result. Any fractional
1704 * microseconds left over (this can happen if num is a float type) are
1705 * added into *leftover.
1706 * Note that there are many ways this can give an error (NULL) return.
1707 */
1708static PyObject *
1709accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1710 double *leftover)
1711{
1712 PyObject *prod;
1713 PyObject *sum;
1714
1715 assert(num != NULL);
1716
1717 if (PyInt_Check(num) || PyLong_Check(num)) {
1718 prod = PyNumber_Multiply(num, factor);
1719 if (prod == NULL)
1720 return NULL;
1721 sum = PyNumber_Add(sofar, prod);
1722 Py_DECREF(prod);
1723 return sum;
1724 }
1725
1726 if (PyFloat_Check(num)) {
1727 double dnum;
1728 double fracpart;
1729 double intpart;
1730 PyObject *x;
1731 PyObject *y;
1732
1733 /* The Plan: decompose num into an integer part and a
1734 * fractional part, num = intpart + fracpart.
1735 * Then num * factor ==
1736 * intpart * factor + fracpart * factor
1737 * and the LHS can be computed exactly in long arithmetic.
1738 * The RHS is again broken into an int part and frac part.
1739 * and the frac part is added into *leftover.
1740 */
1741 dnum = PyFloat_AsDouble(num);
1742 if (dnum == -1.0 && PyErr_Occurred())
1743 return NULL;
1744 fracpart = modf(dnum, &intpart);
1745 x = PyLong_FromDouble(intpart);
1746 if (x == NULL)
1747 return NULL;
1748
1749 prod = PyNumber_Multiply(x, factor);
1750 Py_DECREF(x);
1751 if (prod == NULL)
1752 return NULL;
1753
1754 sum = PyNumber_Add(sofar, prod);
1755 Py_DECREF(prod);
1756 if (sum == NULL)
1757 return NULL;
1758
1759 if (fracpart == 0.0)
1760 return sum;
1761 /* So far we've lost no information. Dealing with the
1762 * fractional part requires float arithmetic, and may
1763 * lose a little info.
1764 */
1765 assert(PyInt_Check(factor) || PyLong_Check(factor));
1766 if (PyInt_Check(factor))
1767 dnum = (double)PyInt_AsLong(factor);
1768 else
1769 dnum = PyLong_AsDouble(factor);
1770
1771 dnum *= fracpart;
1772 fracpart = modf(dnum, &intpart);
1773 x = PyLong_FromDouble(intpart);
1774 if (x == NULL) {
1775 Py_DECREF(sum);
1776 return NULL;
1777 }
1778
1779 y = PyNumber_Add(sum, x);
1780 Py_DECREF(sum);
1781 Py_DECREF(x);
1782 *leftover += fracpart;
1783 return y;
1784 }
1785
1786 PyErr_Format(PyExc_TypeError,
1787 "unsupported type for timedelta %s component: %s",
1788 tag, num->ob_type->tp_name);
1789 return NULL;
1790}
1791
1792static PyObject *
1793delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1794{
1795 PyObject *self = NULL;
1796
1797 /* Argument objects. */
1798 PyObject *day = NULL;
1799 PyObject *second = NULL;
1800 PyObject *us = NULL;
1801 PyObject *ms = NULL;
1802 PyObject *minute = NULL;
1803 PyObject *hour = NULL;
1804 PyObject *week = NULL;
1805
1806 PyObject *x = NULL; /* running sum of microseconds */
1807 PyObject *y = NULL; /* temp sum of microseconds */
1808 double leftover_us = 0.0;
1809
1810 static char *keywords[] = {
1811 "days", "seconds", "microseconds", "milliseconds",
1812 "minutes", "hours", "weeks", NULL
1813 };
1814
1815 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1816 keywords,
1817 &day, &second, &us,
1818 &ms, &minute, &hour, &week) == 0)
1819 goto Done;
1820
1821 x = PyInt_FromLong(0);
1822 if (x == NULL)
1823 goto Done;
1824
1825#define CLEANUP \
1826 Py_DECREF(x); \
1827 x = y; \
1828 if (x == NULL) \
1829 goto Done
1830
1831 if (us) {
1832 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1833 CLEANUP;
1834 }
1835 if (ms) {
1836 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1837 CLEANUP;
1838 }
1839 if (second) {
1840 y = accum("seconds", x, second, us_per_second, &leftover_us);
1841 CLEANUP;
1842 }
1843 if (minute) {
1844 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1845 CLEANUP;
1846 }
1847 if (hour) {
1848 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1849 CLEANUP;
1850 }
1851 if (day) {
1852 y = accum("days", x, day, us_per_day, &leftover_us);
1853 CLEANUP;
1854 }
1855 if (week) {
1856 y = accum("weeks", x, week, us_per_week, &leftover_us);
1857 CLEANUP;
1858 }
1859 if (leftover_us) {
1860 /* Round to nearest whole # of us, and add into x. */
1861 PyObject *temp;
1862 if (leftover_us >= 0.0)
1863 leftover_us = floor(leftover_us + 0.5);
1864 else
1865 leftover_us = ceil(leftover_us - 0.5);
1866 temp = PyLong_FromDouble(leftover_us);
1867 if (temp == NULL) {
1868 Py_DECREF(x);
1869 goto Done;
1870 }
1871 y = PyNumber_Add(x, temp);
1872 Py_DECREF(temp);
1873 CLEANUP;
1874 }
1875
1876 self = microseconds_to_delta(x);
1877 Py_DECREF(x);
1878Done:
1879 return self;
1880
1881#undef CLEANUP
1882}
1883
1884static int
1885delta_nonzero(PyDateTime_Delta *self)
1886{
1887 return (GET_TD_DAYS(self) != 0
1888 || GET_TD_SECONDS(self) != 0
1889 || GET_TD_MICROSECONDS(self) != 0);
1890}
1891
1892static PyObject *
1893delta_repr(PyDateTime_Delta *self)
1894{
1895 if (GET_TD_MICROSECONDS(self) != 0)
1896 return PyString_FromFormat("%s(%d, %d, %d)",
1897 self->ob_type->tp_name,
1898 GET_TD_DAYS(self),
1899 GET_TD_SECONDS(self),
1900 GET_TD_MICROSECONDS(self));
1901 if (GET_TD_SECONDS(self) != 0)
1902 return PyString_FromFormat("%s(%d, %d)",
1903 self->ob_type->tp_name,
1904 GET_TD_DAYS(self),
1905 GET_TD_SECONDS(self));
1906
1907 return PyString_FromFormat("%s(%d)",
1908 self->ob_type->tp_name,
1909 GET_TD_DAYS(self));
1910}
1911
1912static PyObject *
1913delta_str(PyDateTime_Delta *self)
1914{
1915 int days = GET_TD_DAYS(self);
1916 int seconds = GET_TD_SECONDS(self);
1917 int us = GET_TD_MICROSECONDS(self);
1918 int hours;
1919 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001920 char buf[100];
1921 char *pbuf = buf;
1922 size_t buflen = sizeof(buf);
1923 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001924
1925 minutes = divmod(seconds, 60, &seconds);
1926 hours = divmod(minutes, 60, &minutes);
1927
1928 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00001929 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
1930 (days == 1 || days == -1) ? "" : "s");
1931 if (n < 0 || (size_t)n >= buflen)
1932 goto Fail;
1933 pbuf += n;
1934 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001935 }
1936
Tim Petersba873472002-12-18 20:19:21 +00001937 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
1938 hours, minutes, seconds);
1939 if (n < 0 || (size_t)n >= buflen)
1940 goto Fail;
1941 pbuf += n;
1942 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001943
1944 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00001945 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
1946 if (n < 0 || (size_t)n >= buflen)
1947 goto Fail;
1948 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001949 }
1950
Tim Petersba873472002-12-18 20:19:21 +00001951 return PyString_FromStringAndSize(buf, pbuf - buf);
1952
1953 Fail:
1954 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
1955 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001956}
1957
1958/* Pickle support. Quite a maze! While __getstate__/__setstate__ sufficed
1959 * in the Python implementation, the C implementation also requires
1960 * __reduce__, and a __safe_for_unpickling__ attr in the type object.
1961 */
1962static PyObject *
1963delta_getstate(PyDateTime_Delta *self)
1964{
1965 return Py_BuildValue("iii", GET_TD_DAYS(self),
1966 GET_TD_SECONDS(self),
1967 GET_TD_MICROSECONDS(self));
1968}
1969
1970static PyObject *
1971delta_setstate(PyDateTime_Delta *self, PyObject *state)
1972{
1973 int day;
1974 int second;
1975 int us;
1976
1977 if (!PyArg_ParseTuple(state, "iii:__setstate__", &day, &second, &us))
1978 return NULL;
1979
1980 self->hashcode = -1;
1981 SET_TD_DAYS(self, day);
1982 SET_TD_SECONDS(self, second);
1983 SET_TD_MICROSECONDS(self, us);
1984
1985 Py_INCREF(Py_None);
1986 return Py_None;
1987}
1988
1989static PyObject *
1990delta_reduce(PyDateTime_Delta* self)
1991{
1992 PyObject* result = NULL;
1993 PyObject* state = delta_getstate(self);
1994
1995 if (state != NULL) {
1996 /* The funky "()" in the format string creates an empty
1997 * tuple as the 2nd component of the result 3-tuple.
1998 */
1999 result = Py_BuildValue("O()O", self->ob_type, state);
2000 Py_DECREF(state);
2001 }
2002 return result;
2003}
2004
2005#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2006
2007static PyMemberDef delta_members[] = {
Neal Norwitzdfb80862002-12-19 02:30:56 +00002008 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002009 PyDoc_STR("Number of days.")},
2010
Neal Norwitzdfb80862002-12-19 02:30:56 +00002011 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002012 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2013
Neal Norwitzdfb80862002-12-19 02:30:56 +00002014 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002015 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2016 {NULL}
2017};
2018
2019static PyMethodDef delta_methods[] = {
2020 {"__setstate__", (PyCFunction)delta_setstate, METH_O,
2021 PyDoc_STR("__setstate__(state)")},
2022
2023 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2024 PyDoc_STR("__setstate__(state)")},
2025
2026 {"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS,
2027 PyDoc_STR("__getstate__() -> state")},
2028 {NULL, NULL},
2029};
2030
2031static char delta_doc[] =
2032PyDoc_STR("Difference between two datetime values.");
2033
2034static PyNumberMethods delta_as_number = {
2035 delta_add, /* nb_add */
2036 delta_subtract, /* nb_subtract */
2037 delta_multiply, /* nb_multiply */
2038 delta_divide, /* nb_divide */
2039 0, /* nb_remainder */
2040 0, /* nb_divmod */
2041 0, /* nb_power */
2042 (unaryfunc)delta_negative, /* nb_negative */
2043 (unaryfunc)delta_positive, /* nb_positive */
2044 (unaryfunc)delta_abs, /* nb_absolute */
2045 (inquiry)delta_nonzero, /* nb_nonzero */
2046 0, /*nb_invert*/
2047 0, /*nb_lshift*/
2048 0, /*nb_rshift*/
2049 0, /*nb_and*/
2050 0, /*nb_xor*/
2051 0, /*nb_or*/
2052 0, /*nb_coerce*/
2053 0, /*nb_int*/
2054 0, /*nb_long*/
2055 0, /*nb_float*/
2056 0, /*nb_oct*/
2057 0, /*nb_hex*/
2058 0, /*nb_inplace_add*/
2059 0, /*nb_inplace_subtract*/
2060 0, /*nb_inplace_multiply*/
2061 0, /*nb_inplace_divide*/
2062 0, /*nb_inplace_remainder*/
2063 0, /*nb_inplace_power*/
2064 0, /*nb_inplace_lshift*/
2065 0, /*nb_inplace_rshift*/
2066 0, /*nb_inplace_and*/
2067 0, /*nb_inplace_xor*/
2068 0, /*nb_inplace_or*/
2069 delta_divide, /* nb_floor_divide */
2070 0, /* nb_true_divide */
2071 0, /* nb_inplace_floor_divide */
2072 0, /* nb_inplace_true_divide */
2073};
2074
2075static PyTypeObject PyDateTime_DeltaType = {
2076 PyObject_HEAD_INIT(NULL)
2077 0, /* ob_size */
2078 "datetime.timedelta", /* tp_name */
2079 sizeof(PyDateTime_Delta), /* tp_basicsize */
2080 0, /* tp_itemsize */
2081 0, /* tp_dealloc */
2082 0, /* tp_print */
2083 0, /* tp_getattr */
2084 0, /* tp_setattr */
2085 0, /* tp_compare */
2086 (reprfunc)delta_repr, /* tp_repr */
2087 &delta_as_number, /* tp_as_number */
2088 0, /* tp_as_sequence */
2089 0, /* tp_as_mapping */
2090 (hashfunc)delta_hash, /* tp_hash */
2091 0, /* tp_call */
2092 (reprfunc)delta_str, /* tp_str */
2093 PyObject_GenericGetAttr, /* tp_getattro */
2094 0, /* tp_setattro */
2095 0, /* tp_as_buffer */
2096 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
2097 delta_doc, /* tp_doc */
2098 0, /* tp_traverse */
2099 0, /* tp_clear */
2100 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2101 0, /* tp_weaklistoffset */
2102 0, /* tp_iter */
2103 0, /* tp_iternext */
2104 delta_methods, /* tp_methods */
2105 delta_members, /* tp_members */
2106 0, /* tp_getset */
2107 0, /* tp_base */
2108 0, /* tp_dict */
2109 0, /* tp_descr_get */
2110 0, /* tp_descr_set */
2111 0, /* tp_dictoffset */
2112 0, /* tp_init */
2113 0, /* tp_alloc */
2114 delta_new, /* tp_new */
2115 _PyObject_Del, /* tp_free */
2116};
2117
2118/*
2119 * PyDateTime_Date implementation.
2120 */
2121
2122/* Accessor properties. */
2123
2124static PyObject *
2125date_year(PyDateTime_Date *self, void *unused)
2126{
2127 return PyInt_FromLong(GET_YEAR(self));
2128}
2129
2130static PyObject *
2131date_month(PyDateTime_Date *self, void *unused)
2132{
2133 return PyInt_FromLong(GET_MONTH(self));
2134}
2135
2136static PyObject *
2137date_day(PyDateTime_Date *self, void *unused)
2138{
2139 return PyInt_FromLong(GET_DAY(self));
2140}
2141
2142static PyGetSetDef date_getset[] = {
2143 {"year", (getter)date_year},
2144 {"month", (getter)date_month},
2145 {"day", (getter)date_day},
2146 {NULL}
2147};
2148
2149/* Constructors. */
2150
2151static PyObject *
2152date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2153{
2154 PyObject *self = NULL;
2155 int year;
2156 int month;
2157 int day;
2158
2159 static char *keywords[] = {
2160 "year", "month", "day", NULL
2161 };
2162
2163 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", keywords,
2164 &year, &month, &day)) {
2165 if (check_date_args(year, month, day) < 0)
2166 return NULL;
2167 self = new_date(year, month, day);
2168 }
2169 return self;
2170}
2171
2172/* Return new date from localtime(t). */
2173static PyObject *
2174date_local_from_time_t(PyObject *cls, time_t t)
2175{
2176 struct tm *tm;
2177 PyObject *result = NULL;
2178
2179 tm = localtime(&t);
2180 if (tm)
2181 result = PyObject_CallFunction(cls, "iii",
2182 tm->tm_year + 1900,
2183 tm->tm_mon + 1,
2184 tm->tm_mday);
2185 else
2186 PyErr_SetString(PyExc_ValueError,
2187 "timestamp out of range for "
2188 "platform localtime() function");
2189 return result;
2190}
2191
2192/* Return new date from current time.
2193 * We say this is equivalent to fromtimestamp(time.time()), and the
2194 * only way to be sure of that is to *call* time.time(). That's not
2195 * generally the same as calling C's time.
2196 */
2197static PyObject *
2198date_today(PyObject *cls, PyObject *dummy)
2199{
2200 PyObject *time;
2201 PyObject *result;
2202
2203 time = time_time();
2204 if (time == NULL)
2205 return NULL;
2206
2207 /* Note well: today() is a class method, so this may not call
2208 * date.fromtimestamp. For example, it may call
2209 * datetime.fromtimestamp. That's why we need all the accuracy
2210 * time.time() delivers; if someone were gonzo about optimization,
2211 * date.today() could get away with plain C time().
2212 */
2213 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2214 Py_DECREF(time);
2215 return result;
2216}
2217
2218/* Return new date from given timestamp (Python timestamp -- a double). */
2219static PyObject *
2220date_fromtimestamp(PyObject *cls, PyObject *args)
2221{
2222 double timestamp;
2223 PyObject *result = NULL;
2224
2225 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2226 result = date_local_from_time_t(cls, (time_t)timestamp);
2227 return result;
2228}
2229
2230/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2231 * the ordinal is out of range.
2232 */
2233static PyObject *
2234date_fromordinal(PyObject *cls, PyObject *args)
2235{
2236 PyObject *result = NULL;
2237 int ordinal;
2238
2239 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2240 int year;
2241 int month;
2242 int day;
2243
2244 if (ordinal < 1)
2245 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2246 ">= 1");
2247 else {
2248 ord_to_ymd(ordinal, &year, &month, &day);
2249 result = PyObject_CallFunction(cls, "iii",
2250 year, month, day);
2251 }
2252 }
2253 return result;
2254}
2255
2256/*
2257 * Date arithmetic.
2258 */
2259
2260/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2261 * instead.
2262 */
2263static PyObject *
2264add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2265{
2266 PyObject *result = NULL;
2267 int year = GET_YEAR(date);
2268 int month = GET_MONTH(date);
2269 int deltadays = GET_TD_DAYS(delta);
2270 /* C-level overflow is impossible because |deltadays| < 1e9. */
2271 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2272
2273 if (normalize_date(&year, &month, &day) >= 0)
2274 result = new_date(year, month, day);
2275 return result;
2276}
2277
2278static PyObject *
2279date_add(PyObject *left, PyObject *right)
2280{
2281 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2282 Py_INCREF(Py_NotImplemented);
2283 return Py_NotImplemented;
2284 }
2285 if (PyDate_CheckExact(left)) {
2286 /* date + ??? */
2287 if (PyDelta_Check(right))
2288 /* date + delta */
2289 return add_date_timedelta((PyDateTime_Date *) left,
2290 (PyDateTime_Delta *) right,
2291 0);
2292 }
2293 else {
2294 /* ??? + date
2295 * 'right' must be one of us, or we wouldn't have been called
2296 */
2297 if (PyDelta_Check(left))
2298 /* delta + date */
2299 return add_date_timedelta((PyDateTime_Date *) right,
2300 (PyDateTime_Delta *) left,
2301 0);
2302 }
2303 Py_INCREF(Py_NotImplemented);
2304 return Py_NotImplemented;
2305}
2306
2307static PyObject *
2308date_subtract(PyObject *left, PyObject *right)
2309{
2310 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2311 Py_INCREF(Py_NotImplemented);
2312 return Py_NotImplemented;
2313 }
2314 if (PyDate_CheckExact(left)) {
2315 if (PyDate_CheckExact(right)) {
2316 /* date - date */
2317 int left_ord = ymd_to_ord(GET_YEAR(left),
2318 GET_MONTH(left),
2319 GET_DAY(left));
2320 int right_ord = ymd_to_ord(GET_YEAR(right),
2321 GET_MONTH(right),
2322 GET_DAY(right));
2323 return new_delta(left_ord - right_ord, 0, 0, 0);
2324 }
2325 if (PyDelta_Check(right)) {
2326 /* date - delta */
2327 return add_date_timedelta((PyDateTime_Date *) left,
2328 (PyDateTime_Delta *) right,
2329 1);
2330 }
2331 }
2332 Py_INCREF(Py_NotImplemented);
2333 return Py_NotImplemented;
2334}
2335
2336
2337/* Various ways to turn a date into a string. */
2338
2339static PyObject *
2340date_repr(PyDateTime_Date *self)
2341{
2342 char buffer[1028];
2343 char *typename;
2344
2345 typename = self->ob_type->tp_name;
2346 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2347 typename,
2348 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2349
2350 return PyString_FromString(buffer);
2351}
2352
2353static PyObject *
2354date_isoformat(PyDateTime_Date *self)
2355{
2356 char buffer[128];
2357
2358 isoformat_date(self, buffer, sizeof(buffer));
2359 return PyString_FromString(buffer);
2360}
2361
2362/* str() calls the appropriate isofomat() method. */
2363static PyObject *
2364date_str(PyDateTime_Date *self)
2365{
2366 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2367}
2368
2369
2370static PyObject *
2371date_ctime(PyDateTime_Date *self)
2372{
2373 return format_ctime(self, 0, 0, 0);
2374}
2375
2376static PyObject *
2377date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2378{
2379 /* This method can be inherited, and needs to call the
2380 * timetuple() method appropriate to self's class.
2381 */
2382 PyObject *result;
2383 PyObject *format;
2384 PyObject *tuple;
2385 static char *keywords[] = {"format", NULL};
2386
2387 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2388 &PyString_Type, &format))
2389 return NULL;
2390
2391 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2392 if (tuple == NULL)
2393 return NULL;
2394 result = wrap_strftime((PyObject *)self, format, tuple);
2395 Py_DECREF(tuple);
2396 return result;
2397}
2398
2399/* ISO methods. */
2400
2401static PyObject *
2402date_isoweekday(PyDateTime_Date *self)
2403{
2404 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2405
2406 return PyInt_FromLong(dow + 1);
2407}
2408
2409static PyObject *
2410date_isocalendar(PyDateTime_Date *self)
2411{
2412 int year = GET_YEAR(self);
2413 int week1_monday = iso_week1_monday(year);
2414 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2415 int week;
2416 int day;
2417
2418 week = divmod(today - week1_monday, 7, &day);
2419 if (week < 0) {
2420 --year;
2421 week1_monday = iso_week1_monday(year);
2422 week = divmod(today - week1_monday, 7, &day);
2423 }
2424 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2425 ++year;
2426 week = 0;
2427 }
2428 return Py_BuildValue("iii", year, week + 1, day + 1);
2429}
2430
2431/* Miscellaneous methods. */
2432
2433/* This is more natural as a tp_compare, but doesn't work then: for whatever
2434 * reason, Python's try_3way_compare ignores tp_compare unless
2435 * PyInstance_Check returns true, but these aren't old-style classes.
2436 */
2437static PyObject *
2438date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2439{
2440 int diff;
2441
2442 if (! PyDate_Check(other)) {
2443 PyErr_Format(PyExc_TypeError,
2444 "can't compare date to %s instance",
2445 other->ob_type->tp_name);
2446 return NULL;
2447 }
2448 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2449 _PyDateTime_DATE_DATASIZE);
2450 return diff_to_bool(diff, op);
2451}
2452
2453static PyObject *
2454date_timetuple(PyDateTime_Date *self)
2455{
2456 return build_struct_time(GET_YEAR(self),
2457 GET_MONTH(self),
2458 GET_DAY(self),
2459 0, 0, 0, -1);
2460}
2461
2462static PyObject *date_getstate(PyDateTime_Date *self);
2463
2464static long
2465date_hash(PyDateTime_Date *self)
2466{
2467 if (self->hashcode == -1) {
2468 PyObject *temp = date_getstate(self);
2469 if (temp != NULL) {
2470 self->hashcode = PyObject_Hash(temp);
2471 Py_DECREF(temp);
2472 }
2473 }
2474 return self->hashcode;
2475}
2476
2477static PyObject *
2478date_toordinal(PyDateTime_Date *self)
2479{
2480 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2481 GET_DAY(self)));
2482}
2483
2484static PyObject *
2485date_weekday(PyDateTime_Date *self)
2486{
2487 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2488
2489 return PyInt_FromLong(dow);
2490}
2491
2492/* Pickle support. Quite a maze! */
2493
2494static PyObject *
2495date_getstate(PyDateTime_Date *self)
2496{
2497 return PyString_FromStringAndSize(self->data,
2498 _PyDateTime_DATE_DATASIZE);
2499}
2500
2501static PyObject *
2502date_setstate(PyDateTime_Date *self, PyObject *state)
2503{
2504 const int len = PyString_Size(state);
2505 unsigned char *pdata = (unsigned char*)PyString_AsString(state);
2506
2507 if (! PyString_Check(state) ||
2508 len != _PyDateTime_DATE_DATASIZE) {
2509 PyErr_SetString(PyExc_TypeError,
2510 "bad argument to date.__setstate__");
2511 return NULL;
2512 }
2513 memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE);
2514 self->hashcode = -1;
2515
2516 Py_INCREF(Py_None);
2517 return Py_None;
2518}
2519
2520/* XXX This seems a ridiculously inefficient way to pickle a short string. */
2521static PyObject *
2522date_pickler(PyObject *module, PyDateTime_Date *date)
2523{
2524 PyObject *state;
2525 PyObject *result = NULL;
2526
2527 if (! PyDate_CheckExact(date)) {
2528 PyErr_Format(PyExc_TypeError,
2529 "bad type passed to date pickler: %s",
2530 date->ob_type->tp_name);
2531 return NULL;
2532 }
2533 state = date_getstate(date);
2534 if (state) {
2535 result = Py_BuildValue("O(O)", date_unpickler_object, state);
2536 Py_DECREF(state);
2537 }
2538 return result;
2539}
2540
2541static PyObject *
2542date_unpickler(PyObject *module, PyObject *arg)
2543{
2544 PyDateTime_Date *self;
2545
2546 if (! PyString_CheckExact(arg)) {
2547 PyErr_Format(PyExc_TypeError,
2548 "bad type passed to date unpickler: %s",
2549 arg->ob_type->tp_name);
2550 return NULL;
2551 }
2552 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
2553 if (self != NULL) {
2554 PyObject *res = date_setstate(self, arg);
2555 if (res == NULL) {
2556 Py_DECREF(self);
2557 return NULL;
2558 }
2559 Py_DECREF(res);
2560 }
2561 return (PyObject *)self;
2562}
2563
2564static PyMethodDef date_methods[] = {
2565 /* Class methods: */
2566 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2567 METH_CLASS,
2568 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2569 "time.time()).")},
2570
2571 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2572 METH_CLASS,
2573 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2574 "ordinal.")},
2575
2576 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2577 PyDoc_STR("Current date or datetime: same as "
2578 "self.__class__.fromtimestamp(time.time()).")},
2579
2580 /* Instance methods: */
2581
2582 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2583 PyDoc_STR("Return ctime() style string.")},
2584
2585 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2586 PyDoc_STR("format -> strftime() style string.")},
2587
2588 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2589 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2590
2591 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2592 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2593 "weekday.")},
2594
2595 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2596 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2597
2598 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2599 PyDoc_STR("Return the day of the week represented by the date.\n"
2600 "Monday == 1 ... Sunday == 7")},
2601
2602 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2603 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2604 "1 is day 1.")},
2605
2606 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2607 PyDoc_STR("Return the day of the week represented by the date.\n"
2608 "Monday == 0 ... Sunday == 6")},
2609
2610 {"__setstate__", (PyCFunction)date_setstate, METH_O,
2611 PyDoc_STR("__setstate__(state)")},
2612
2613 {"__getstate__", (PyCFunction)date_getstate, METH_NOARGS,
2614 PyDoc_STR("__getstate__() -> state")},
2615
2616 {NULL, NULL}
2617};
2618
2619static char date_doc[] =
2620PyDoc_STR("Basic date type.");
2621
2622static PyNumberMethods date_as_number = {
2623 date_add, /* nb_add */
2624 date_subtract, /* nb_subtract */
2625 0, /* nb_multiply */
2626 0, /* nb_divide */
2627 0, /* nb_remainder */
2628 0, /* nb_divmod */
2629 0, /* nb_power */
2630 0, /* nb_negative */
2631 0, /* nb_positive */
2632 0, /* nb_absolute */
2633 0, /* nb_nonzero */
2634};
2635
2636static PyTypeObject PyDateTime_DateType = {
2637 PyObject_HEAD_INIT(NULL)
2638 0, /* ob_size */
2639 "datetime.date", /* tp_name */
2640 sizeof(PyDateTime_Date), /* tp_basicsize */
2641 0, /* tp_itemsize */
2642 (destructor)PyObject_Del, /* tp_dealloc */
2643 0, /* tp_print */
2644 0, /* tp_getattr */
2645 0, /* tp_setattr */
2646 0, /* tp_compare */
2647 (reprfunc)date_repr, /* tp_repr */
2648 &date_as_number, /* tp_as_number */
2649 0, /* tp_as_sequence */
2650 0, /* tp_as_mapping */
2651 (hashfunc)date_hash, /* tp_hash */
2652 0, /* tp_call */
2653 (reprfunc)date_str, /* tp_str */
2654 PyObject_GenericGetAttr, /* tp_getattro */
2655 0, /* tp_setattro */
2656 0, /* tp_as_buffer */
2657 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2658 Py_TPFLAGS_BASETYPE, /* tp_flags */
2659 date_doc, /* tp_doc */
2660 0, /* tp_traverse */
2661 0, /* tp_clear */
2662 (richcmpfunc)date_richcompare, /* tp_richcompare */
2663 0, /* tp_weaklistoffset */
2664 0, /* tp_iter */
2665 0, /* tp_iternext */
2666 date_methods, /* tp_methods */
2667 0, /* tp_members */
2668 date_getset, /* tp_getset */
2669 0, /* tp_base */
2670 0, /* tp_dict */
2671 0, /* tp_descr_get */
2672 0, /* tp_descr_set */
2673 0, /* tp_dictoffset */
2674 0, /* tp_init */
2675 0, /* tp_alloc */
2676 date_new, /* tp_new */
2677 _PyObject_Del, /* tp_free */
2678};
2679
2680/*
2681 * PyDateTime_DateTime implementation.
2682 */
2683
2684/* Accessor properties. */
2685
2686static PyObject *
2687datetime_hour(PyDateTime_DateTime *self, void *unused)
2688{
2689 return PyInt_FromLong(DATE_GET_HOUR(self));
2690}
2691
2692static PyObject *
2693datetime_minute(PyDateTime_DateTime *self, void *unused)
2694{
2695 return PyInt_FromLong(DATE_GET_MINUTE(self));
2696}
2697
2698static PyObject *
2699datetime_second(PyDateTime_DateTime *self, void *unused)
2700{
2701 return PyInt_FromLong(DATE_GET_SECOND(self));
2702}
2703
2704static PyObject *
2705datetime_microsecond(PyDateTime_DateTime *self, void *unused)
2706{
2707 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
2708}
2709
2710static PyGetSetDef datetime_getset[] = {
2711 {"hour", (getter)datetime_hour},
2712 {"minute", (getter)datetime_minute},
2713 {"second", (getter)datetime_second},
2714 {"microsecond", (getter)datetime_microsecond},
2715 {NULL}
2716};
2717
2718/* Constructors. */
2719
2720static PyObject *
2721datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2722{
2723 PyObject *self = NULL;
2724 int year;
2725 int month;
2726 int day;
2727 int hour = 0;
2728 int minute = 0;
2729 int second = 0;
2730 int usecond = 0;
2731
2732 static char *keywords[] = {
2733 "year", "month", "day", "hour", "minute", "second",
2734 "microsecond", NULL
2735 };
2736
2737 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiii", keywords,
2738 &year, &month, &day, &hour, &minute,
2739 &second, &usecond)) {
2740 if (check_date_args(year, month, day) < 0)
2741 return NULL;
2742 if (check_time_args(hour, minute, second, usecond) < 0)
2743 return NULL;
2744 self = new_datetime(year, month, day,
2745 hour, minute, second, usecond);
2746 }
2747 return self;
2748}
2749
2750
2751/* TM_FUNC is the shared type of localtime() and gmtime(). */
2752typedef struct tm *(*TM_FUNC)(const time_t *timer);
2753
2754/* Internal helper.
2755 * Build datetime from a time_t and a distinct count of microseconds.
2756 * Pass localtime or gmtime for f, to control the interpretation of timet.
2757 */
2758static PyObject *
2759datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us)
2760{
2761 struct tm *tm;
2762 PyObject *result = NULL;
2763
2764 tm = f(&timet);
2765 if (tm)
2766 result = PyObject_CallFunction(cls, "iiiiiii",
2767 tm->tm_year + 1900,
2768 tm->tm_mon + 1,
2769 tm->tm_mday,
2770 tm->tm_hour,
2771 tm->tm_min,
2772 tm->tm_sec,
2773 us);
2774 else
2775 PyErr_SetString(PyExc_ValueError,
2776 "timestamp out of range for "
2777 "platform localtime()/gmtime() function");
2778 return result;
2779}
2780
2781/* Internal helper.
2782 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
2783 * to control the interpretation of the timestamp. Since a double doesn't
2784 * have enough bits to cover a datetime's full range of precision, it's
2785 * better to call datetime_from_timet_and_us provided you have a way
2786 * to get that much precision (e.g., C time() isn't good enough).
2787 */
2788static PyObject *
2789datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp)
2790{
2791 time_t timet = (time_t)timestamp;
2792 int us = (int)((timestamp - (double)timet) * 1e6);
2793
2794 return datetime_from_timet_and_us(cls, f, timet, us);
2795}
2796
2797/* Internal helper.
2798 * Build most accurate possible datetime for current time. Pass localtime or
2799 * gmtime for f as appropriate.
2800 */
2801static PyObject *
2802datetime_best_possible(PyObject *cls, TM_FUNC f)
2803{
2804#ifdef HAVE_GETTIMEOFDAY
2805 struct timeval t;
2806
2807#ifdef GETTIMEOFDAY_NO_TZ
2808 gettimeofday(&t);
2809#else
2810 gettimeofday(&t, (struct timezone *)NULL);
2811#endif
2812 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec);
2813
2814#else /* ! HAVE_GETTIMEOFDAY */
2815 /* No flavor of gettimeofday exists on this platform. Python's
2816 * time.time() does a lot of other platform tricks to get the
2817 * best time it can on the platform, and we're not going to do
2818 * better than that (if we could, the better code would belong
2819 * in time.time()!) We're limited by the precision of a double,
2820 * though.
2821 */
2822 PyObject *time;
2823 double dtime;
2824
2825 time = time_time();
2826 if (time == NULL)
2827 return NULL;
2828 dtime = PyFloat_AsDouble(time);
2829 Py_DECREF(time);
2830 if (dtime == -1.0 && PyErr_Occurred())
2831 return NULL;
2832 return datetime_from_timestamp(cls, f, dtime);
2833#endif /* ! HAVE_GETTIMEOFDAY */
2834}
2835
2836/* Return new local datetime from timestamp (Python timestamp -- a double). */
2837static PyObject *
2838datetime_fromtimestamp(PyObject *cls, PyObject *args)
2839{
2840 double timestamp;
2841 PyObject *result = NULL;
2842
2843 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2844 result = datetime_from_timestamp(cls, localtime, timestamp);
2845 return result;
2846}
2847
2848/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
2849static PyObject *
2850datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
2851{
2852 double timestamp;
2853 PyObject *result = NULL;
2854
2855 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
2856 result = datetime_from_timestamp(cls, gmtime, timestamp);
2857 return result;
2858}
2859
2860/* Return best possible local time -- this isn't constrained by the
2861 * precision of a timestamp.
2862 */
2863static PyObject *
2864datetime_now(PyObject *cls, PyObject *dummy)
2865{
2866 return datetime_best_possible(cls, localtime);
2867}
2868
2869/* Return best possible UTC time -- this isn't constrained by the
2870 * precision of a timestamp.
2871 */
2872static PyObject *
2873datetime_utcnow(PyObject *cls, PyObject *dummy)
2874{
2875 return datetime_best_possible(cls, gmtime);
2876}
2877
2878/* Return new datetime or datetimetz from date/datetime/datetimetz and
2879 * time/timetz arguments.
2880 */
2881static PyObject *
2882datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
2883{
2884 static char *keywords[] = {"date", "time", NULL};
2885 PyObject *date;
2886 PyObject *time;
2887 PyObject *result = NULL;
2888
2889 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
2890 &PyDateTime_DateType, &date,
2891 &PyDateTime_TimeType, &time))
2892 result = PyObject_CallFunction(cls, "iiiiiii",
2893 GET_YEAR(date),
2894 GET_MONTH(date),
2895 GET_DAY(date),
2896 TIME_GET_HOUR(time),
2897 TIME_GET_MINUTE(time),
2898 TIME_GET_SECOND(time),
2899 TIME_GET_MICROSECOND(time));
2900 if (result && PyTimeTZ_Check(time) && PyDateTimeTZ_Check(result)) {
2901 /* Copy the tzinfo field. */
2902 PyObject *tzinfo = ((PyDateTime_TimeTZ *)time)->tzinfo;
2903 Py_INCREF(tzinfo);
2904 Py_DECREF(((PyDateTime_DateTimeTZ *)result)->tzinfo);
2905 ((PyDateTime_DateTimeTZ *)result)->tzinfo = tzinfo;
2906 }
2907 return result;
2908}
2909
2910/* datetime arithmetic. */
2911
2912static PyObject *
2913add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta)
2914{
2915 /* Note that the C-level additions can't overflow, because of
2916 * invariant bounds on the member values.
2917 */
2918 int year = GET_YEAR(date);
2919 int month = GET_MONTH(date);
2920 int day = GET_DAY(date) + GET_TD_DAYS(delta);
2921 int hour = DATE_GET_HOUR(date);
2922 int minute = DATE_GET_MINUTE(date);
2923 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta);
2924 int microsecond = DATE_GET_MICROSECOND(date) +
2925 GET_TD_MICROSECONDS(delta);
2926
2927 if (normalize_datetime(&year, &month, &day,
2928 &hour, &minute, &second, &microsecond) < 0)
2929 return NULL;
2930 else
2931 return new_datetime(year, month, day,
2932 hour, minute, second, microsecond);
2933}
2934
2935static PyObject *
2936sub_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta)
2937{
2938 /* Note that the C-level subtractions can't overflow, because of
2939 * invariant bounds on the member values.
2940 */
2941 int year = GET_YEAR(date);
2942 int month = GET_MONTH(date);
2943 int day = GET_DAY(date) - GET_TD_DAYS(delta);
2944 int hour = DATE_GET_HOUR(date);
2945 int minute = DATE_GET_MINUTE(date);
2946 int second = DATE_GET_SECOND(date) - GET_TD_SECONDS(delta);
2947 int microsecond = DATE_GET_MICROSECOND(date) -
2948 GET_TD_MICROSECONDS(delta);
2949
2950 if (normalize_datetime(&year, &month, &day,
2951 &hour, &minute, &second, &microsecond) < 0)
2952 return NULL;
2953 else
2954 return new_datetime(year, month, day,
2955 hour, minute, second, microsecond);
2956}
2957
2958static PyObject *
2959sub_datetime_datetime(PyDateTime_DateTime *left, PyDateTime_DateTime *right)
2960{
2961 int days1 = ymd_to_ord(GET_YEAR(left), GET_MONTH(left), GET_DAY(left));
2962 int days2 = ymd_to_ord(GET_YEAR(right),
2963 GET_MONTH(right),
2964 GET_DAY(right));
2965 /* These can't overflow, since the values are normalized. At most
2966 * this gives the number of seconds in one day.
2967 */
2968 int delta_s = (DATE_GET_HOUR(left) - DATE_GET_HOUR(right)) * 3600 +
2969 (DATE_GET_MINUTE(left) - DATE_GET_MINUTE(right)) * 60 +
2970 DATE_GET_SECOND(left) - DATE_GET_SECOND(right);
2971 int delta_us = DATE_GET_MICROSECOND(left) -
2972 DATE_GET_MICROSECOND(right);
2973
2974 return new_delta(days1 - days2, delta_s, delta_us, 1);
2975}
2976
2977static PyObject *
2978datetime_add(PyObject *left, PyObject *right)
2979{
2980 if (PyDateTime_Check(left)) {
2981 /* datetime + ??? */
2982 if (PyDelta_Check(right))
2983 /* datetime + delta */
2984 return add_datetime_timedelta(
2985 (PyDateTime_DateTime *)left,
2986 (PyDateTime_Delta *)right);
2987 }
2988 else if (PyDelta_Check(left)) {
2989 /* delta + datetime */
2990 return add_datetime_timedelta((PyDateTime_DateTime *) right,
2991 (PyDateTime_Delta *) left);
2992 }
2993 Py_INCREF(Py_NotImplemented);
2994 return Py_NotImplemented;
2995}
2996
2997static PyObject *
2998datetime_subtract(PyObject *left, PyObject *right)
2999{
3000 PyObject *result = Py_NotImplemented;
3001
3002 if (PyDateTime_Check(left)) {
3003 /* datetime - ??? */
3004 if (PyDateTime_Check(right)) {
3005 /* datetime - datetime */
3006 result = sub_datetime_datetime(
3007 (PyDateTime_DateTime *)left,
3008 (PyDateTime_DateTime *)right);
3009 }
3010 else if (PyDelta_Check(right)) {
3011 /* datetime - delta */
3012 result = sub_datetime_timedelta(
3013 (PyDateTime_DateTime *)left,
3014 (PyDateTime_Delta *)right);
3015 }
3016 }
3017
3018 if (result == Py_NotImplemented)
3019 Py_INCREF(result);
3020 return result;
3021}
3022
3023/* Various ways to turn a datetime into a string. */
3024
3025static PyObject *
3026datetime_repr(PyDateTime_DateTime *self)
3027{
3028 char buffer[1000];
3029 char *typename = self->ob_type->tp_name;
3030
3031 if (DATE_GET_MICROSECOND(self)) {
3032 PyOS_snprintf(buffer, sizeof(buffer),
3033 "%s(%d, %d, %d, %d, %d, %d, %d)",
3034 typename,
3035 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3036 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3037 DATE_GET_SECOND(self),
3038 DATE_GET_MICROSECOND(self));
3039 }
3040 else if (DATE_GET_SECOND(self)) {
3041 PyOS_snprintf(buffer, sizeof(buffer),
3042 "%s(%d, %d, %d, %d, %d, %d)",
3043 typename,
3044 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3045 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3046 DATE_GET_SECOND(self));
3047 }
3048 else {
3049 PyOS_snprintf(buffer, sizeof(buffer),
3050 "%s(%d, %d, %d, %d, %d)",
3051 typename,
3052 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3053 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
3054 }
3055 return PyString_FromString(buffer);
3056}
3057
3058static PyObject *
3059datetime_str(PyDateTime_DateTime *self)
3060{
3061 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
3062}
3063
3064static PyObject *
3065datetime_isoformat(PyDateTime_DateTime *self,
3066 PyObject *args, PyObject *kw)
3067{
3068 char sep = 'T';
3069 static char *keywords[] = {"sep", NULL};
3070 char buffer[100];
3071 char *cp;
3072
3073 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
3074 &sep))
3075 return NULL;
3076 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
3077 assert(cp != NULL);
3078 *cp++ = sep;
3079 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
3080 return PyString_FromString(buffer);
3081}
3082
3083static PyObject *
3084datetime_ctime(PyDateTime_DateTime *self)
3085{
3086 return format_ctime((PyDateTime_Date *)self,
3087 DATE_GET_HOUR(self),
3088 DATE_GET_MINUTE(self),
3089 DATE_GET_SECOND(self));
3090}
3091
3092/* Miscellaneous methods. */
3093
3094/* This is more natural as a tp_compare, but doesn't work then: for whatever
3095 * reason, Python's try_3way_compare ignores tp_compare unless
3096 * PyInstance_Check returns true, but these aren't old-style classes.
3097 * Note that this routine handles all comparisons for datetime and datetimetz.
3098 */
3099static PyObject *
3100datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
3101{
3102 int diff;
3103 naivety n1, n2;
3104 int offset1, offset2;
3105
3106 if (! PyDateTime_Check(other)) {
3107 /* Stop this from falling back to address comparison. */
3108 PyErr_Format(PyExc_TypeError,
3109 "can't compare '%s' to '%s'",
3110 self->ob_type->tp_name,
3111 other->ob_type->tp_name);
3112 return NULL;
3113 }
Tim Peters14b69412002-12-22 18:10:22 +00003114 n1 = classify_utcoffset((PyObject *)self, &offset1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003115 assert(n1 != OFFSET_UNKNOWN);
3116 if (n1 == OFFSET_ERROR)
3117 return NULL;
3118
Tim Peters14b69412002-12-22 18:10:22 +00003119 n2 = classify_utcoffset(other, &offset2);
Tim Peters2a799bf2002-12-16 20:18:38 +00003120 assert(n2 != OFFSET_UNKNOWN);
3121 if (n2 == OFFSET_ERROR)
3122 return NULL;
3123
3124 /* If they're both naive, or both aware and have the same offsets,
3125 * we get off cheap. Note that if they're both naive, offset1 ==
3126 * offset2 == 0 at this point.
3127 */
3128 if (n1 == n2 && offset1 == offset2) {
3129 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
3130 _PyDateTime_DATETIME_DATASIZE);
3131 return diff_to_bool(diff, op);
3132 }
3133
3134 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3135 /* We want the sign of
3136 * (self - offset1 minutes) - (other - offset2 minutes) =
3137 * (self - other) + (offset2 - offset1) minutes.
3138 */
3139 PyDateTime_Delta *delta;
3140 int days, seconds, us;
3141
3142 assert(offset1 != offset2); /* else last "if" handled it */
3143 delta = (PyDateTime_Delta *)sub_datetime_datetime(self,
3144 (PyDateTime_DateTime *)other);
3145 if (delta == NULL)
3146 return NULL;
3147 days = delta->days;
3148 seconds = delta->seconds + (offset2 - offset1) * 60;
3149 us = delta->microseconds;
3150 Py_DECREF(delta);
3151 normalize_d_s_us(&days, &seconds, &us);
3152 diff = days;
3153 if (diff == 0)
3154 diff = seconds | us;
3155 return diff_to_bool(diff, op);
3156 }
3157
3158 assert(n1 != n2);
3159 PyErr_SetString(PyExc_TypeError,
3160 "can't compare offset-naive and "
3161 "offset-aware datetimes");
3162 return NULL;
3163}
3164
3165static PyObject *datetime_getstate(PyDateTime_DateTime *self);
3166
3167static long
3168datetime_hash(PyDateTime_DateTime *self)
3169{
3170 if (self->hashcode == -1) {
3171 naivety n;
3172 int offset;
3173 PyObject *temp;
3174
Tim Peters14b69412002-12-22 18:10:22 +00003175 n = classify_utcoffset((PyObject *)self, &offset);
Tim Peters2a799bf2002-12-16 20:18:38 +00003176 assert(n != OFFSET_UNKNOWN);
3177 if (n == OFFSET_ERROR)
3178 return -1;
3179
3180 /* Reduce this to a hash of another object. */
3181 if (n == OFFSET_NAIVE)
3182 temp = datetime_getstate(self);
3183 else {
3184 int days;
3185 int seconds;
3186
3187 assert(n == OFFSET_AWARE);
3188 assert(PyDateTimeTZ_Check(self));
3189 days = ymd_to_ord(GET_YEAR(self),
3190 GET_MONTH(self),
3191 GET_DAY(self));
3192 seconds = DATE_GET_HOUR(self) * 3600 +
3193 (DATE_GET_MINUTE(self) - offset) * 60 +
3194 DATE_GET_SECOND(self);
3195 temp = new_delta(days,
3196 seconds,
3197 DATE_GET_MICROSECOND(self),
3198 1);
3199 }
3200 if (temp != NULL) {
3201 self->hashcode = PyObject_Hash(temp);
3202 Py_DECREF(temp);
3203 }
3204 }
3205 return self->hashcode;
3206}
3207
3208static PyObject *
3209datetime_timetuple(PyDateTime_DateTime *self)
3210{
3211 return build_struct_time(GET_YEAR(self),
3212 GET_MONTH(self),
3213 GET_DAY(self),
3214 DATE_GET_HOUR(self),
3215 DATE_GET_MINUTE(self),
3216 DATE_GET_SECOND(self),
3217 -1);
3218}
3219
3220static PyObject *
3221datetime_getdate(PyDateTime_DateTime *self)
3222{
3223 return new_date(GET_YEAR(self),
3224 GET_MONTH(self),
3225 GET_DAY(self));
3226}
3227
3228static PyObject *
3229datetime_gettime(PyDateTime_DateTime *self)
3230{
3231 return new_time(DATE_GET_HOUR(self),
3232 DATE_GET_MINUTE(self),
3233 DATE_GET_SECOND(self),
3234 DATE_GET_MICROSECOND(self));
3235}
3236
3237/* Pickle support. Quite a maze! */
3238
3239static PyObject *
3240datetime_getstate(PyDateTime_DateTime *self)
3241{
3242 return PyString_FromStringAndSize(self->data,
3243 _PyDateTime_DATETIME_DATASIZE);
3244}
3245
3246static PyObject *
3247datetime_setstate(PyDateTime_DateTime *self, PyObject *state)
3248{
3249 const int len = PyString_Size(state);
3250 unsigned char *pdata = (unsigned char*)PyString_AsString(state);
3251
3252 if (! PyString_Check(state) ||
3253 len != _PyDateTime_DATETIME_DATASIZE) {
3254 PyErr_SetString(PyExc_TypeError,
3255 "bad argument to datetime.__setstate__");
3256 return NULL;
3257 }
3258 memcpy(self->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3259 self->hashcode = -1;
3260
3261 Py_INCREF(Py_None);
3262 return Py_None;
3263}
3264
3265/* XXX This seems a ridiculously inefficient way to pickle a short string. */
3266static PyObject *
3267datetime_pickler(PyObject *module, PyDateTime_DateTime *datetime)
3268{
3269 PyObject *state;
3270 PyObject *result = NULL;
3271
3272 if (! PyDateTime_CheckExact(datetime)) {
3273 PyErr_Format(PyExc_TypeError,
3274 "bad type passed to datetime pickler: %s",
3275 datetime->ob_type->tp_name);
3276 return NULL;
3277 }
3278 state = datetime_getstate(datetime);
3279 if (state) {
3280 result = Py_BuildValue("O(O)",
3281 datetime_unpickler_object,
3282 state);
3283 Py_DECREF(state);
3284 }
3285 return result;
3286}
3287
3288static PyObject *
3289datetime_unpickler(PyObject *module, PyObject *arg)
3290{
3291 PyDateTime_DateTime *self;
3292
3293 if (! PyString_CheckExact(arg)) {
3294 PyErr_Format(PyExc_TypeError,
3295 "bad type passed to datetime unpickler: %s",
3296 arg->ob_type->tp_name);
3297 return NULL;
3298 }
3299 self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType);
3300 if (self != NULL) {
3301 PyObject *res = datetime_setstate(self, arg);
3302 if (res == NULL) {
3303 Py_DECREF(self);
3304 return NULL;
3305 }
3306 Py_DECREF(res);
3307 }
3308 return (PyObject *)self;
3309}
3310
3311static PyMethodDef datetime_methods[] = {
3312 /* Class methods: */
3313 {"now", (PyCFunction)datetime_now,
3314 METH_NOARGS | METH_CLASS,
3315 PyDoc_STR("Return a new datetime representing local day and time.")},
3316
3317 {"utcnow", (PyCFunction)datetime_utcnow,
3318 METH_NOARGS | METH_CLASS,
3319 PyDoc_STR("Return a new datetime representing UTC day and time.")},
3320
3321 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
3322 METH_VARARGS | METH_CLASS,
3323 PyDoc_STR("timestamp -> local datetime from a POSIX timestamp "
3324 "(like time.time()).")},
3325
3326 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
3327 METH_VARARGS | METH_CLASS,
3328 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
3329 "(like time.time()).")},
3330
3331 {"combine", (PyCFunction)datetime_combine,
3332 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
3333 PyDoc_STR("date, time -> datetime with same date and time fields")},
3334
3335 /* Instance methods: */
3336 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
3337 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
3338
3339 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
3340 PyDoc_STR("Return date object with same year, month and day.")},
3341
3342 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
3343 PyDoc_STR("Return time object with same hour, minute, second and "
3344 "microsecond.")},
3345
3346 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
3347 PyDoc_STR("Return ctime() style string.")},
3348
3349 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
3350 PyDoc_STR("[sep] -> string in ISO 8601 format, "
3351 "YYYY-MM-DDTHH:MM:SS[.mmmmmm].\n\n"
3352 "sep is used to separate the year from the time, and "
3353 "defaults\n"
3354 "to 'T'.")},
3355
3356 {"__setstate__", (PyCFunction)datetime_setstate, METH_O,
3357 PyDoc_STR("__setstate__(state)")},
3358
3359 {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS,
3360 PyDoc_STR("__getstate__() -> state")},
3361 {NULL, NULL}
3362};
3363
3364static char datetime_doc[] =
3365PyDoc_STR("Basic date/time type.");
3366
3367static PyNumberMethods datetime_as_number = {
3368 datetime_add, /* nb_add */
3369 datetime_subtract, /* nb_subtract */
3370 0, /* nb_multiply */
3371 0, /* nb_divide */
3372 0, /* nb_remainder */
3373 0, /* nb_divmod */
3374 0, /* nb_power */
3375 0, /* nb_negative */
3376 0, /* nb_positive */
3377 0, /* nb_absolute */
3378 0, /* nb_nonzero */
3379};
3380
3381statichere PyTypeObject PyDateTime_DateTimeType = {
3382 PyObject_HEAD_INIT(NULL)
3383 0, /* ob_size */
3384 "datetime.datetime", /* tp_name */
3385 sizeof(PyDateTime_DateTime), /* tp_basicsize */
3386 0, /* tp_itemsize */
3387 (destructor)PyObject_Del, /* tp_dealloc */
3388 0, /* tp_print */
3389 0, /* tp_getattr */
3390 0, /* tp_setattr */
3391 0, /* tp_compare */
3392 (reprfunc)datetime_repr, /* tp_repr */
3393 &datetime_as_number, /* tp_as_number */
3394 0, /* tp_as_sequence */
3395 0, /* tp_as_mapping */
3396 (hashfunc)datetime_hash, /* tp_hash */
3397 0, /* tp_call */
3398 (reprfunc)datetime_str, /* tp_str */
3399 PyObject_GenericGetAttr, /* tp_getattro */
3400 0, /* tp_setattro */
3401 0, /* tp_as_buffer */
3402 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3403 Py_TPFLAGS_BASETYPE, /* tp_flags */
3404 datetime_doc, /* tp_doc */
3405 0, /* tp_traverse */
3406 0, /* tp_clear */
3407 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
3408 0, /* tp_weaklistoffset */
3409 0, /* tp_iter */
3410 0, /* tp_iternext */
3411 datetime_methods, /* tp_methods */
3412 0, /* tp_members */
3413 datetime_getset, /* tp_getset */
3414 &PyDateTime_DateType, /* tp_base */
3415 0, /* tp_dict */
3416 0, /* tp_descr_get */
3417 0, /* tp_descr_set */
3418 0, /* tp_dictoffset */
3419 0, /* tp_init */
3420 0, /* tp_alloc */
3421 datetime_new, /* tp_new */
3422 _PyObject_Del, /* tp_free */
3423};
3424
3425/*
3426 * PyDateTime_Time implementation.
3427 */
3428
3429/* Accessor properties. */
3430
3431static PyObject *
3432time_hour(PyDateTime_Time *self, void *unused)
3433{
3434 return PyInt_FromLong(TIME_GET_HOUR(self));
3435}
3436
3437static PyObject *
3438time_minute(PyDateTime_Time *self, void *unused)
3439{
3440 return PyInt_FromLong(TIME_GET_MINUTE(self));
3441}
3442
3443static PyObject *
Jack Jansen51cd8a22002-12-17 20:57:24 +00003444py_time_second(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003445{
3446 return PyInt_FromLong(TIME_GET_SECOND(self));
3447}
3448
3449static PyObject *
3450time_microsecond(PyDateTime_Time *self, void *unused)
3451{
3452 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3453}
3454
3455static PyGetSetDef time_getset[] = {
3456 {"hour", (getter)time_hour},
3457 {"minute", (getter)time_minute},
Jack Jansen51cd8a22002-12-17 20:57:24 +00003458 {"second", (getter)py_time_second},
Tim Peters2a799bf2002-12-16 20:18:38 +00003459 {"microsecond", (getter)time_microsecond},
3460 {NULL}
3461};
3462
3463/* Constructors. */
3464
3465static PyObject *
3466time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3467{
3468 PyObject *self = NULL;
3469 int hour = 0;
3470 int minute = 0;
3471 int second = 0;
3472 int usecond = 0;
3473
3474 static char *keywords[] = {
3475 "hour", "minute", "second", "microsecond", NULL
3476 };
3477
3478 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiii", keywords,
3479 &hour, &minute, &second, &usecond)) {
3480 if (check_time_args(hour, minute, second, usecond) < 0)
3481 return NULL;
3482 self = new_time(hour, minute, second, usecond);
3483 }
3484 return self;
3485}
3486
3487/* Various ways to turn a time into a string. */
3488
3489static PyObject *
3490time_repr(PyDateTime_Time *self)
3491{
3492 char buffer[100];
3493 char *typename = self->ob_type->tp_name;
3494 int h = TIME_GET_HOUR(self);
3495 int m = TIME_GET_MINUTE(self);
3496 int s = TIME_GET_SECOND(self);
3497 int us = TIME_GET_MICROSECOND(self);
3498
3499 if (us)
3500 PyOS_snprintf(buffer, sizeof(buffer),
3501 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3502 else if (s)
3503 PyOS_snprintf(buffer, sizeof(buffer),
3504 "%s(%d, %d, %d)", typename, h, m, s);
3505 else
3506 PyOS_snprintf(buffer, sizeof(buffer),
3507 "%s(%d, %d)", typename, h, m);
3508 return PyString_FromString(buffer);
3509}
3510
3511static PyObject *
3512time_str(PyDateTime_Time *self)
3513{
3514 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3515}
3516
3517static PyObject *
3518time_isoformat(PyDateTime_Time *self)
3519{
3520 char buffer[100];
3521 /* Reuse the time format code from the datetime type. */
3522 PyDateTime_DateTime datetime;
3523 PyDateTime_DateTime *pdatetime = &datetime;
3524
3525 /* Copy over just the time bytes. */
3526 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3527 self->data,
3528 _PyDateTime_TIME_DATASIZE);
3529
3530 isoformat_time(pdatetime, buffer, sizeof(buffer));
3531 return PyString_FromString(buffer);
3532}
3533
3534static PyObject *
3535time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3536{
3537 PyObject *result;
3538 PyObject *format;
3539 PyObject *tuple;
3540 static char *keywords[] = {"format", NULL};
3541
3542 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3543 &PyString_Type, &format))
3544 return NULL;
3545
Tim Peters83b85f12002-12-22 20:34:46 +00003546 /* Python's strftime does insane things with the year part of the
3547 * timetuple. The year is forced to (the otherwise nonsensical)
3548 * 1900 to worm around that.
3549 */
Tim Peters2a799bf2002-12-16 20:18:38 +00003550 tuple = Py_BuildValue("iiiiiiiii",
Tim Peters83b85f12002-12-22 20:34:46 +00003551 1900, 0, 0, /* year, month, day */
Tim Peters2a799bf2002-12-16 20:18:38 +00003552 TIME_GET_HOUR(self),
3553 TIME_GET_MINUTE(self),
3554 TIME_GET_SECOND(self),
3555 0, 0, -1); /* weekday, daynum, dst */
3556 if (tuple == NULL)
3557 return NULL;
3558 assert(PyTuple_Size(tuple) == 9);
3559 result = wrap_strftime((PyObject *)self, format, tuple);
3560 Py_DECREF(tuple);
3561 return result;
3562}
3563
3564/* Miscellaneous methods. */
3565
3566/* This is more natural as a tp_compare, but doesn't work then: for whatever
3567 * reason, Python's try_3way_compare ignores tp_compare unless
3568 * PyInstance_Check returns true, but these aren't old-style classes.
3569 * Note that this routine handles all comparisons for time and timetz.
3570 */
3571static PyObject *
3572time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3573{
3574 int diff;
3575 naivety n1, n2;
3576 int offset1, offset2;
3577
3578 if (! PyTime_Check(other)) {
3579 /* Stop this from falling back to address comparison. */
3580 PyErr_Format(PyExc_TypeError,
3581 "can't compare '%s' to '%s'",
3582 self->ob_type->tp_name,
3583 other->ob_type->tp_name);
3584 return NULL;
3585 }
Tim Peters14b69412002-12-22 18:10:22 +00003586 n1 = classify_utcoffset((PyObject *)self, &offset1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003587 assert(n1 != OFFSET_UNKNOWN);
3588 if (n1 == OFFSET_ERROR)
3589 return NULL;
3590
Tim Peters14b69412002-12-22 18:10:22 +00003591 n2 = classify_utcoffset(other, &offset2);
Tim Peters2a799bf2002-12-16 20:18:38 +00003592 assert(n2 != OFFSET_UNKNOWN);
3593 if (n2 == OFFSET_ERROR)
3594 return NULL;
3595
3596 /* If they're both naive, or both aware and have the same offsets,
3597 * we get off cheap. Note that if they're both naive, offset1 ==
3598 * offset2 == 0 at this point.
3599 */
3600 if (n1 == n2 && offset1 == offset2) {
3601 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3602 _PyDateTime_TIME_DATASIZE);
3603 return diff_to_bool(diff, op);
3604 }
3605
3606 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3607 assert(offset1 != offset2); /* else last "if" handled it */
3608 /* Convert everything except microseconds to seconds. These
3609 * can't overflow (no more than the # of seconds in 2 days).
3610 */
3611 offset1 = TIME_GET_HOUR(self) * 3600 +
3612 (TIME_GET_MINUTE(self) - offset1) * 60 +
3613 TIME_GET_SECOND(self);
3614 offset2 = TIME_GET_HOUR(other) * 3600 +
3615 (TIME_GET_MINUTE(other) - offset2) * 60 +
3616 TIME_GET_SECOND(other);
3617 diff = offset1 - offset2;
3618 if (diff == 0)
3619 diff = TIME_GET_MICROSECOND(self) -
3620 TIME_GET_MICROSECOND(other);
3621 return diff_to_bool(diff, op);
3622 }
3623
3624 assert(n1 != n2);
3625 PyErr_SetString(PyExc_TypeError,
3626 "can't compare offset-naive and "
3627 "offset-aware times");
3628 return NULL;
3629}
3630
3631static PyObject *time_getstate(PyDateTime_Time *self);
3632
3633static long
3634time_hash(PyDateTime_Time *self)
3635{
3636 if (self->hashcode == -1) {
3637 naivety n;
3638 int offset;
3639 PyObject *temp;
3640
Tim Peters14b69412002-12-22 18:10:22 +00003641 n = classify_utcoffset((PyObject *)self, &offset);
Tim Peters2a799bf2002-12-16 20:18:38 +00003642 assert(n != OFFSET_UNKNOWN);
3643 if (n == OFFSET_ERROR)
3644 return -1;
3645
3646 /* Reduce this to a hash of another object. */
3647 if (offset == 0)
3648 temp = time_getstate(self);
3649 else {
3650 int hour;
3651 int minute;
3652
3653 assert(n == OFFSET_AWARE);
3654 assert(PyTimeTZ_Check(self));
3655 hour = divmod(TIME_GET_HOUR(self) * 60 +
3656 TIME_GET_MINUTE(self) - offset,
3657 60,
3658 &minute);
3659 if (0 <= hour && hour < 24)
3660 temp = new_time(hour, minute,
3661 TIME_GET_SECOND(self),
3662 TIME_GET_MICROSECOND(self));
3663 else
3664 temp = Py_BuildValue("iiii",
3665 hour, minute,
3666 TIME_GET_SECOND(self),
3667 TIME_GET_MICROSECOND(self));
3668 }
3669 if (temp != NULL) {
3670 self->hashcode = PyObject_Hash(temp);
3671 Py_DECREF(temp);
3672 }
3673 }
3674 return self->hashcode;
3675}
3676
3677static int
3678time_nonzero(PyDateTime_Time *self)
3679{
3680 return TIME_GET_HOUR(self) ||
3681 TIME_GET_MINUTE(self) ||
3682 TIME_GET_SECOND(self) ||
3683 TIME_GET_MICROSECOND(self);
3684}
3685
3686/* Pickle support. Quite a maze! */
3687
3688static PyObject *
3689time_getstate(PyDateTime_Time *self)
3690{
3691 return PyString_FromStringAndSize(self->data,
3692 _PyDateTime_TIME_DATASIZE);
3693}
3694
3695static PyObject *
3696time_setstate(PyDateTime_Time *self, PyObject *state)
3697{
3698 const int len = PyString_Size(state);
3699 unsigned char *pdata = (unsigned char*)PyString_AsString(state);
3700
3701 if (! PyString_Check(state) ||
3702 len != _PyDateTime_TIME_DATASIZE) {
3703 PyErr_SetString(PyExc_TypeError,
3704 "bad argument to time.__setstate__");
3705 return NULL;
3706 }
3707 memcpy(self->data, pdata, _PyDateTime_TIME_DATASIZE);
3708 self->hashcode = -1;
3709
3710 Py_INCREF(Py_None);
3711 return Py_None;
3712}
3713
3714/* XXX This seems a ridiculously inefficient way to pickle a short string. */
3715static PyObject *
3716time_pickler(PyObject *module, PyDateTime_Time *time)
3717{
3718 PyObject *state;
3719 PyObject *result = NULL;
3720
3721 if (! PyTime_CheckExact(time)) {
3722 PyErr_Format(PyExc_TypeError,
3723 "bad type passed to time pickler: %s",
3724 time->ob_type->tp_name);
3725 return NULL;
3726 }
3727 state = time_getstate(time);
3728 if (state) {
3729 result = Py_BuildValue("O(O)",
3730 time_unpickler_object,
3731 state);
3732 Py_DECREF(state);
3733 }
3734 return result;
3735}
3736
3737static PyObject *
3738time_unpickler(PyObject *module, PyObject *arg)
3739{
3740 PyDateTime_Time *self;
3741
3742 if (! PyString_CheckExact(arg)) {
3743 PyErr_Format(PyExc_TypeError,
3744 "bad type passed to time unpickler: %s",
3745 arg->ob_type->tp_name);
3746 return NULL;
3747 }
3748 self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType);
3749 if (self != NULL) {
3750 PyObject *res = time_setstate(self, arg);
3751 if (res == NULL) {
3752 Py_DECREF(self);
3753 return NULL;
3754 }
3755 Py_DECREF(res);
3756 }
3757 return (PyObject *)self;
3758}
3759
3760static PyMethodDef time_methods[] = {
3761 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
3762 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm].")},
3763
3764 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3765 PyDoc_STR("format -> strftime() style string.")},
3766
3767 {"__setstate__", (PyCFunction)time_setstate, METH_O,
3768 PyDoc_STR("__setstate__(state)")},
3769
3770 {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS,
3771 PyDoc_STR("__getstate__() -> state")},
3772 {NULL, NULL}
3773};
3774
3775static char time_doc[] =
3776PyDoc_STR("Basic time type.");
3777
3778static PyNumberMethods time_as_number = {
3779 0, /* nb_add */
3780 0, /* nb_subtract */
3781 0, /* nb_multiply */
3782 0, /* nb_divide */
3783 0, /* nb_remainder */
3784 0, /* nb_divmod */
3785 0, /* nb_power */
3786 0, /* nb_negative */
3787 0, /* nb_positive */
3788 0, /* nb_absolute */
3789 (inquiry)time_nonzero, /* nb_nonzero */
3790};
3791
3792statichere PyTypeObject PyDateTime_TimeType = {
3793 PyObject_HEAD_INIT(NULL)
3794 0, /* ob_size */
3795 "datetime.time", /* tp_name */
3796 sizeof(PyDateTime_Time), /* tp_basicsize */
3797 0, /* tp_itemsize */
3798 (destructor)PyObject_Del, /* tp_dealloc */
3799 0, /* tp_print */
3800 0, /* tp_getattr */
3801 0, /* tp_setattr */
3802 0, /* tp_compare */
3803 (reprfunc)time_repr, /* tp_repr */
3804 &time_as_number, /* tp_as_number */
3805 0, /* tp_as_sequence */
3806 0, /* tp_as_mapping */
3807 (hashfunc)time_hash, /* tp_hash */
3808 0, /* tp_call */
3809 (reprfunc)time_str, /* tp_str */
3810 PyObject_GenericGetAttr, /* tp_getattro */
3811 0, /* tp_setattro */
3812 0, /* tp_as_buffer */
3813 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3814 Py_TPFLAGS_BASETYPE, /* tp_flags */
3815 time_doc, /* tp_doc */
3816 0, /* tp_traverse */
3817 0, /* tp_clear */
3818 (richcmpfunc)time_richcompare, /* tp_richcompare */
3819 0, /* tp_weaklistoffset */
3820 0, /* tp_iter */
3821 0, /* tp_iternext */
3822 time_methods, /* tp_methods */
3823 0, /* tp_members */
3824 time_getset, /* tp_getset */
3825 0, /* tp_base */
3826 0, /* tp_dict */
3827 0, /* tp_descr_get */
3828 0, /* tp_descr_set */
3829 0, /* tp_dictoffset */
3830 0, /* tp_init */
3831 0, /* tp_alloc */
3832 time_new, /* tp_new */
3833 _PyObject_Del, /* tp_free */
3834};
3835
3836/*
3837 * PyDateTime_TZInfo implementation.
3838 */
3839
3840/* This is a pure abstract base class, so doesn't do anything beyond
3841 * raising NotImplemented exceptions. Real tzinfo classes need
3842 * to derive from this. This is mostly for clarity, and for efficiency in
3843 * datetimetz and timetz constructors (their tzinfo arguments need to
3844 * be subclasses of this tzinfo class, which is easy and quick to check).
3845 *
3846 * Note: For reasons having to do with pickling of subclasses, we have
3847 * to allow tzinfo objects to be instantiated. This wasn't an issue
3848 * in the Python implementation (__init__() could raise NotImplementedError
3849 * there without ill effect), but doing so in the C implementation hit a
3850 * brick wall.
3851 */
3852
3853static PyObject *
3854tzinfo_nogo(const char* methodname)
3855{
3856 PyErr_Format(PyExc_NotImplementedError,
3857 "a tzinfo subclass must implement %s()",
3858 methodname);
3859 return NULL;
3860}
3861
3862/* Methods. A subclass must implement these. */
3863
3864static PyObject*
3865tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3866{
3867 return tzinfo_nogo("tzname");
3868}
3869
3870static PyObject*
3871tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3872{
3873 return tzinfo_nogo("utcoffset");
3874}
3875
3876static PyObject*
3877tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3878{
3879 return tzinfo_nogo("dst");
3880}
3881
3882/*
3883 * Pickle support. This is solely so that tzinfo subclasses can use
3884 * pickling -- tzinfo itself is supposed to be uninstantiable. The
3885 * pickler and unpickler functions are given module-level private
3886 * names, and registered with copy_reg, by the module init function.
3887 */
3888
3889static PyObject*
3890tzinfo_pickler(PyDateTime_TZInfo *self) {
3891 return Py_BuildValue("O()", tzinfo_unpickler_object);
3892}
3893
3894static PyObject*
3895tzinfo_unpickler(PyObject * unused) {
3896 return PyType_GenericNew(&PyDateTime_TZInfoType, NULL, NULL);
3897}
3898
3899
3900static PyMethodDef tzinfo_methods[] = {
3901 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3902 PyDoc_STR("datetime -> string name of time zone.")},
3903
3904 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
3905 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3906 "west of UTC).")},
3907
3908 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3909 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3910
3911 {NULL, NULL}
3912};
3913
3914static char tzinfo_doc[] =
3915PyDoc_STR("Abstract base class for time zone info objects.");
3916
3917 statichere PyTypeObject PyDateTime_TZInfoType = {
3918 PyObject_HEAD_INIT(NULL)
3919 0, /* ob_size */
3920 "datetime.tzinfo", /* tp_name */
3921 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3922 0, /* tp_itemsize */
3923 0, /* tp_dealloc */
3924 0, /* tp_print */
3925 0, /* tp_getattr */
3926 0, /* tp_setattr */
3927 0, /* tp_compare */
3928 0, /* tp_repr */
3929 0, /* tp_as_number */
3930 0, /* tp_as_sequence */
3931 0, /* tp_as_mapping */
3932 0, /* tp_hash */
3933 0, /* tp_call */
3934 0, /* tp_str */
3935 PyObject_GenericGetAttr, /* tp_getattro */
3936 0, /* tp_setattro */
3937 0, /* tp_as_buffer */
3938 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3939 Py_TPFLAGS_BASETYPE, /* tp_flags */
3940 tzinfo_doc, /* tp_doc */
3941 0, /* tp_traverse */
3942 0, /* tp_clear */
3943 0, /* tp_richcompare */
3944 0, /* tp_weaklistoffset */
3945 0, /* tp_iter */
3946 0, /* tp_iternext */
3947 tzinfo_methods, /* tp_methods */
3948 0, /* tp_members */
3949 0, /* tp_getset */
3950 0, /* tp_base */
3951 0, /* tp_dict */
3952 0, /* tp_descr_get */
3953 0, /* tp_descr_set */
3954 0, /* tp_dictoffset */
3955 0, /* tp_init */
3956 0, /* tp_alloc */
3957 PyType_GenericNew, /* tp_new */
3958 0, /* tp_free */
3959};
3960
3961/*
3962 * PyDateTime_TimeTZ implementation.
3963 */
3964
3965/* Accessor properties. Properties for hour, minute, second and microsecond
3966 * are inherited from time.
3967 */
3968
3969static PyObject *
3970timetz_tzinfo(PyDateTime_TimeTZ *self, void *unused)
3971{
3972 Py_INCREF(self->tzinfo);
3973 return self->tzinfo;
3974}
3975
3976static PyGetSetDef timetz_getset[] = {
3977 {"tzinfo", (getter)timetz_tzinfo},
3978 {NULL}
3979};
3980
3981/*
3982 * Constructors.
3983 */
3984
3985static PyObject *
3986timetz_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3987{
3988 PyObject *self = NULL;
3989 int hour = 0;
3990 int minute = 0;
3991 int second = 0;
3992 int usecond = 0;
3993 PyObject *tzinfo = Py_None;
3994
3995 static char *keywords[] = {
3996 "hour", "minute", "second", "microsecond", "tzinfo", NULL
3997 };
3998
Neal Norwitzc296c632002-12-19 00:42:03 +00003999 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", keywords,
Tim Peters2a799bf2002-12-16 20:18:38 +00004000 &hour, &minute, &second, &usecond,
4001 &tzinfo)) {
4002 if (check_time_args(hour, minute, second, usecond) < 0)
4003 return NULL;
4004 if (check_tzinfo_subclass(tzinfo) < 0)
4005 return NULL;
4006 self = new_timetz(hour, minute, second, usecond, tzinfo);
4007 }
4008 return self;
4009}
4010
4011/*
4012 * Destructor.
4013 */
4014
4015static void
4016timetz_dealloc(PyDateTime_TimeTZ *self)
4017{
4018 Py_XDECREF(self->tzinfo);
4019 self->ob_type->tp_free((PyObject *)self);
4020}
4021
4022/*
Tim Peters855fe882002-12-22 03:43:39 +00004023 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00004024 */
4025
Tim Peters2a799bf2002-12-16 20:18:38 +00004026/* These are all METH_NOARGS, so don't need to check the arglist. */
4027static PyObject *
4028timetz_utcoffset(PyDateTime_TimeTZ *self, PyObject *unused) {
Tim Peters855fe882002-12-22 03:43:39 +00004029 return offset_as_timedelta((PyObject *)self, self->tzinfo,
4030 "utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00004031}
4032
4033static PyObject *
4034timetz_dst(PyDateTime_TimeTZ *self, PyObject *unused) {
Tim Peters855fe882002-12-22 03:43:39 +00004035 return offset_as_timedelta((PyObject *)self, self->tzinfo, "dst");
4036}
4037
4038static PyObject *
4039timetz_tzname(PyDateTime_TimeTZ *self, PyObject *unused) {
4040 return call_tzname((PyObject *)self, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004041}
4042
4043/*
4044 * Various ways to turn a timetz into a string.
4045 */
4046
4047static PyObject *
4048timetz_repr(PyDateTime_TimeTZ *self)
4049{
4050 PyObject *baserepr = time_repr((PyDateTime_Time *)self);
4051
4052 if (baserepr == NULL)
4053 return NULL;
4054 return append_keyword_tzinfo(baserepr, self->tzinfo);
4055}
4056
4057/* Note: tp_str is inherited from time. */
4058
4059static PyObject *
4060timetz_isoformat(PyDateTime_TimeTZ *self)
4061{
4062 char buf[100];
4063 PyObject *result = time_isoformat((PyDateTime_Time *)self);
4064
4065 if (result == NULL || self->tzinfo == Py_None)
4066 return result;
4067
4068 /* We need to append the UTC offset. */
4069 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4070 (PyObject *)self) < 0) {
4071 Py_DECREF(result);
4072 return NULL;
4073 }
4074 PyString_ConcatAndDel(&result, PyString_FromString(buf));
4075 return result;
4076}
4077
4078/* Note: strftime() is inherited from time. */
4079
4080/*
4081 * Miscellaneous methods.
4082 */
4083
4084/* Note: tp_richcompare and tp_hash are inherited from time. */
4085
4086static int
4087timetz_nonzero(PyDateTime_TimeTZ *self)
4088{
4089 int offset;
4090 int none;
4091
4092 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
4093 /* Since utcoffset is in whole minutes, nothing can
4094 * alter the conclusion that this is nonzero.
4095 */
4096 return 1;
4097 }
4098 offset = 0;
4099 if (self->tzinfo != Py_None) {
4100 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4101 if (offset == -1 && PyErr_Occurred())
4102 return -1;
4103 }
4104 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
4105}
4106
4107/*
4108 * Pickle support. Quite a maze!
4109 */
4110
4111/* Let basestate be the state string returned by time_getstate.
4112 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4113 * So it's a tuple in any (non-error) case.
4114 */
4115static PyObject *
4116timetz_getstate(PyDateTime_TimeTZ *self)
4117{
4118 PyObject *basestate;
4119 PyObject *result = NULL;
4120
4121 basestate = time_getstate((PyDateTime_Time *)self);
4122 if (basestate != NULL) {
4123 if (self->tzinfo == Py_None)
4124 result = Py_BuildValue("(O)", basestate);
4125 else
4126 result = Py_BuildValue("OO", basestate, self->tzinfo);
4127 Py_DECREF(basestate);
4128 }
4129 return result;
4130}
4131
4132static PyObject *
4133timetz_setstate(PyDateTime_TimeTZ *self, PyObject *state)
4134{
4135 PyObject *temp;
4136 PyObject *basestate;
4137 PyObject *tzinfo = Py_None;
4138
4139 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
4140 &PyString_Type, &basestate,
4141 &tzinfo))
4142 return NULL;
4143 temp = time_setstate((PyDateTime_Time *)self, basestate);
4144 if (temp == NULL)
4145 return NULL;
4146 Py_DECREF(temp);
4147
4148 Py_INCREF(tzinfo);
4149 Py_XDECREF(self->tzinfo);
4150 self->tzinfo = tzinfo;
4151
4152 Py_INCREF(Py_None);
4153 return Py_None;
4154}
4155
4156static PyObject *
4157timetz_pickler(PyObject *module, PyDateTime_TimeTZ *timetz)
4158{
4159 PyObject *state;
4160 PyObject *result = NULL;
4161
4162 if (! PyTimeTZ_CheckExact(timetz)) {
4163 PyErr_Format(PyExc_TypeError,
4164 "bad type passed to timetz pickler: %s",
4165 timetz->ob_type->tp_name);
4166 return NULL;
4167 }
4168 state = timetz_getstate(timetz);
4169 if (state) {
4170 result = Py_BuildValue("O(O)",
4171 timetz_unpickler_object,
4172 state);
4173 Py_DECREF(state);
4174 }
4175 return result;
4176}
4177
4178static PyObject *
4179timetz_unpickler(PyObject *module, PyObject *arg)
4180{
4181 PyDateTime_TimeTZ *self;
4182
4183 self = PyObject_New(PyDateTime_TimeTZ, &PyDateTime_TimeTZType);
4184 if (self != NULL) {
4185 PyObject *res;
4186
4187 self->tzinfo = NULL;
4188 res = timetz_setstate(self, arg);
4189 if (res == NULL) {
4190 Py_DECREF(self);
4191 return NULL;
4192 }
4193 Py_DECREF(res);
4194 }
4195 return (PyObject *)self;
4196}
4197
4198static PyMethodDef timetz_methods[] = {
4199 {"isoformat", (PyCFunction)timetz_isoformat, METH_KEYWORDS,
4200 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
4201 "[+HH:MM].")},
4202
4203 {"utcoffset", (PyCFunction)timetz_utcoffset, METH_NOARGS,
4204 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4205
4206 {"tzname", (PyCFunction)timetz_tzname, METH_NOARGS,
4207 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4208
4209 {"dst", (PyCFunction)timetz_dst, METH_NOARGS,
4210 PyDoc_STR("Return self.tzinfo.dst(self).")},
4211
4212 {"__setstate__", (PyCFunction)timetz_setstate, METH_O,
4213 PyDoc_STR("__setstate__(state)")},
4214
4215 {"__getstate__", (PyCFunction)timetz_getstate, METH_NOARGS,
4216 PyDoc_STR("__getstate__() -> state")},
4217 {NULL, NULL}
4218
4219};
4220
4221static char timetz_doc[] =
4222PyDoc_STR("Time type.");
4223
4224static PyNumberMethods timetz_as_number = {
4225 0, /* nb_add */
4226 0, /* nb_subtract */
4227 0, /* nb_multiply */
4228 0, /* nb_divide */
4229 0, /* nb_remainder */
4230 0, /* nb_divmod */
4231 0, /* nb_power */
4232 0, /* nb_negative */
4233 0, /* nb_positive */
4234 0, /* nb_absolute */
4235 (inquiry)timetz_nonzero, /* nb_nonzero */
4236};
4237
4238statichere PyTypeObject PyDateTime_TimeTZType = {
4239 PyObject_HEAD_INIT(NULL)
4240 0, /* ob_size */
4241 "datetime.timetz", /* tp_name */
4242 sizeof(PyDateTime_TimeTZ), /* tp_basicsize */
4243 0, /* tp_itemsize */
4244 (destructor)timetz_dealloc, /* tp_dealloc */
4245 0, /* tp_print */
4246 0, /* tp_getattr */
4247 0, /* tp_setattr */
4248 0, /* tp_compare */
4249 (reprfunc)timetz_repr, /* tp_repr */
4250 &timetz_as_number, /* tp_as_number */
4251 0, /* tp_as_sequence */
4252 0, /* tp_as_mapping */
4253 0, /* tp_hash */
4254 0, /* tp_call */
4255 0, /* tp_str */
4256 PyObject_GenericGetAttr, /* tp_getattro */
4257 0, /* tp_setattro */
4258 0, /* tp_as_buffer */
4259 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4260 Py_TPFLAGS_BASETYPE, /* tp_flags */
Guido van Rossumbd43e912002-12-16 20:34:55 +00004261 timetz_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004262 0, /* tp_traverse */
4263 0, /* tp_clear */
4264 0, /* tp_richcompare */
4265 0, /* tp_weaklistoffset */
4266 0, /* tp_iter */
4267 0, /* tp_iternext */
4268 timetz_methods, /* tp_methods */
4269 0, /* tp_members */
4270 timetz_getset, /* tp_getset */
4271 &PyDateTime_TimeType, /* tp_base */
4272 0, /* tp_dict */
4273 0, /* tp_descr_get */
4274 0, /* tp_descr_set */
4275 0, /* tp_dictoffset */
4276 0, /* tp_init */
4277 0, /* tp_alloc */
4278 timetz_new, /* tp_new */
4279 _PyObject_Del, /* tp_free */
4280};
4281
4282/*
4283 * PyDateTime_DateTimeTZ implementation.
4284 */
4285
4286/* Accessor properties. Properties for day, month, year, hour, minute,
4287 * second and microsecond are inherited from datetime.
4288 */
4289
4290static PyObject *
4291datetimetz_tzinfo(PyDateTime_DateTimeTZ *self, void *unused)
4292{
4293 Py_INCREF(self->tzinfo);
4294 return self->tzinfo;
4295}
4296
4297static PyGetSetDef datetimetz_getset[] = {
4298 {"tzinfo", (getter)datetimetz_tzinfo},
4299 {NULL}
4300};
4301
4302/*
4303 * Constructors.
4304 * These are like the datetime methods of the same names, but allow an
4305 * optional tzinfo argument.
4306 */
4307
4308/* Internal helper.
4309 * self is a datetimetz. Replace its tzinfo member.
4310 */
4311void
4312replace_tzinfo(PyObject *self, PyObject *newtzinfo)
4313{
4314 assert(self != NULL);
4315 assert(newtzinfo != NULL);
4316 assert(PyDateTimeTZ_Check(self));
4317 Py_INCREF(newtzinfo);
4318 Py_DECREF(((PyDateTime_DateTimeTZ *)self)->tzinfo);
4319 ((PyDateTime_DateTimeTZ *)self)->tzinfo = newtzinfo;
4320}
4321
4322static PyObject *
4323datetimetz_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4324{
4325 PyObject *self = NULL;
4326 int year;
4327 int month;
4328 int day;
4329 int hour = 0;
4330 int minute = 0;
4331 int second = 0;
4332 int usecond = 0;
4333 PyObject *tzinfo = Py_None;
4334
4335 static char *keywords[] = {
4336 "year", "month", "day", "hour", "minute", "second",
4337 "microsecond", "tzinfo", NULL
4338 };
4339
4340 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", keywords,
4341 &year, &month, &day, &hour, &minute,
4342 &second, &usecond, &tzinfo)) {
4343 if (check_date_args(year, month, day) < 0)
4344 return NULL;
4345 if (check_time_args(hour, minute, second, usecond) < 0)
4346 return NULL;
4347 if (check_tzinfo_subclass(tzinfo) < 0)
4348 return NULL;
4349 self = new_datetimetz(year, month, day,
4350 hour, minute, second, usecond,
4351 tzinfo);
4352 }
4353 return self;
4354}
4355
4356/* Return best possible local time -- this isn't constrained by the
4357 * precision of a timestamp.
4358 */
4359static PyObject *
4360datetimetz_now(PyObject *cls, PyObject *args, PyObject *kw)
4361{
4362 PyObject *self = NULL;
4363 PyObject *tzinfo = Py_None;
4364 static char *keywords[] = {"tzinfo", NULL};
4365
4366 if (PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
4367 &tzinfo)) {
4368 if (check_tzinfo_subclass(tzinfo) < 0)
4369 return NULL;
4370 self = datetime_best_possible(cls, localtime);
4371 if (self != NULL)
4372 replace_tzinfo(self, tzinfo);
4373 }
4374 return self;
4375}
4376
4377/* Return new local datetime from timestamp (Python timestamp -- a double). */
4378static PyObject *
4379datetimetz_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
4380{
4381 PyObject *self = NULL;
4382 double timestamp;
4383 PyObject *tzinfo = Py_None;
4384 static char *keywords[] = {"timestamp", "tzinfo", NULL};
4385
4386 if (PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
4387 keywords, &timestamp, &tzinfo)) {
4388 if (check_tzinfo_subclass(tzinfo) < 0)
4389 return NULL;
4390 self = datetime_from_timestamp(cls, localtime, timestamp);
4391 if (self != NULL)
4392 replace_tzinfo(self, tzinfo);
4393 }
4394 return self;
4395}
4396
4397/* Note: utcnow() is inherited, and doesn't accept tzinfo.
4398 * Ditto utcfromtimestamp(). Ditto combine().
4399 */
4400
4401
4402/*
4403 * Destructor.
4404 */
4405
4406static void
4407datetimetz_dealloc(PyDateTime_DateTimeTZ *self)
4408{
4409 Py_XDECREF(self->tzinfo);
4410 self->ob_type->tp_free((PyObject *)self);
4411}
4412
4413/*
4414 * Indirect access to tzinfo methods.
4415 */
4416
Tim Peters2a799bf2002-12-16 20:18:38 +00004417/* These are all METH_NOARGS, so don't need to check the arglist. */
4418static PyObject *
4419datetimetz_utcoffset(PyDateTime_DateTimeTZ *self, PyObject *unused) {
Tim Peters855fe882002-12-22 03:43:39 +00004420 return offset_as_timedelta((PyObject *)self, self->tzinfo,
4421 "utcoffset");
Tim Peters2a799bf2002-12-16 20:18:38 +00004422}
4423
4424static PyObject *
4425datetimetz_dst(PyDateTime_DateTimeTZ *self, PyObject *unused) {
Tim Peters855fe882002-12-22 03:43:39 +00004426 return offset_as_timedelta((PyObject *)self, self->tzinfo, "dst");
4427}
4428
4429static PyObject *
4430datetimetz_tzname(PyDateTime_DateTimeTZ *self, PyObject *unused) {
4431 return call_tzname((PyObject *)self, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004432}
4433
4434/*
4435 * datetimetz arithmetic.
4436 */
4437
4438/* If base is Py_NotImplemented or NULL, just return it.
4439 * Else base is a datetime, exactly one of {left, right} is a datetimetz,
4440 * and we want to create a datetimetz with the same date and time fields
4441 * as base, and with the tzinfo field from left or right. Do that,
4442 * return it, and decref base. This is used to transform the result of
4443 * a binary datetime operation (base) into a datetimetz result.
4444 */
4445static PyObject *
4446attach_tzinfo(PyObject *base, PyObject *left, PyObject *right)
4447{
4448 PyDateTime_DateTimeTZ *self;
4449 PyDateTime_DateTimeTZ *result;
4450
4451 if (base == NULL || base == Py_NotImplemented)
4452 return base;
4453
4454 assert(PyDateTime_CheckExact(base));
4455
4456 if (PyDateTimeTZ_Check(left)) {
4457 assert(! PyDateTimeTZ_Check(right));
4458 self = (PyDateTime_DateTimeTZ *)left;
4459 }
4460 else {
4461 assert(PyDateTimeTZ_Check(right));
4462 self = (PyDateTime_DateTimeTZ *)right;
4463 }
4464 result = PyObject_New(PyDateTime_DateTimeTZ,
4465 &PyDateTime_DateTimeTZType);
4466 if (result != NULL) {
4467 memcpy(result->data, ((PyDateTime_DateTime *)base)->data,
4468 _PyDateTime_DATETIME_DATASIZE);
4469 Py_INCREF(self->tzinfo);
4470 result->tzinfo = self->tzinfo;
4471 }
4472 Py_DECREF(base);
4473 return (PyObject *)result;
4474}
4475
4476static PyObject *
4477datetimetz_add(PyObject *left, PyObject *right)
4478{
4479 return attach_tzinfo(datetime_add(left, right), left, right);
4480}
4481
4482static PyObject *
4483datetimetz_subtract(PyObject *left, PyObject *right)
4484{
4485 PyObject *result = Py_NotImplemented;
4486
4487 if (PyDateTime_Check(left)) {
4488 /* datetime - ??? */
4489 if (PyDateTime_Check(right)) {
4490 /* datetime - datetime */
4491 naivety n1, n2;
4492 int offset1, offset2;
4493 PyDateTime_Delta *delta;
4494
Tim Peters14b69412002-12-22 18:10:22 +00004495 n1 = classify_utcoffset(left, &offset1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004496 assert(n1 != OFFSET_UNKNOWN);
4497 if (n1 == OFFSET_ERROR)
4498 return NULL;
4499
Tim Peters14b69412002-12-22 18:10:22 +00004500 n2 = classify_utcoffset(right, &offset2);
Tim Peters2a799bf2002-12-16 20:18:38 +00004501 assert(n2 != OFFSET_UNKNOWN);
4502 if (n2 == OFFSET_ERROR)
4503 return NULL;
4504
4505 if (n1 != n2) {
4506 PyErr_SetString(PyExc_TypeError,
4507 "can't subtract offset-naive and "
4508 "offset-aware datetimes");
4509 return NULL;
4510 }
4511 delta = (PyDateTime_Delta *)sub_datetime_datetime(
4512 (PyDateTime_DateTime *)left,
4513 (PyDateTime_DateTime *)right);
4514 if (delta == NULL || offset1 == offset2)
4515 return (PyObject *)delta;
4516 /* (left - offset1) - (right - offset2) =
4517 * (left - right) + (offset2 - offset1)
4518 */
4519 result = new_delta(delta->days,
4520 delta->seconds +
4521 (offset2 - offset1) * 60,
4522 delta->microseconds,
4523 1);
4524 Py_DECREF(delta);
4525 }
4526 else if (PyDelta_Check(right)) {
4527 /* datetimetz - delta */
4528 result = sub_datetime_timedelta(
4529 (PyDateTime_DateTime *)left,
4530 (PyDateTime_Delta *)right);
4531 result = attach_tzinfo(result, left, right);
4532 }
4533 }
4534
4535 if (result == Py_NotImplemented)
4536 Py_INCREF(result);
4537 return result;
4538}
4539
4540/* Various ways to turn a datetime into a string. */
4541
4542static PyObject *
4543datetimetz_repr(PyDateTime_DateTimeTZ *self)
4544{
4545 PyObject *baserepr = datetime_repr((PyDateTime_DateTime *)self);
4546
4547 if (baserepr == NULL)
4548 return NULL;
4549 return append_keyword_tzinfo(baserepr, self->tzinfo);
4550}
4551
4552/* Note: tp_str is inherited from datetime. */
4553
4554static PyObject *
4555datetimetz_isoformat(PyDateTime_DateTimeTZ *self,
4556 PyObject *args, PyObject *kw)
4557{
4558 char buf[100];
4559 PyObject *result = datetime_isoformat((PyDateTime_DateTime *)self,
4560 args, kw);
4561
4562 if (result == NULL || self->tzinfo == Py_None)
4563 return result;
4564
4565 /* We need to append the UTC offset. */
4566 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
4567 (PyObject *)self) < 0) {
4568 Py_DECREF(result);
4569 return NULL;
4570 }
4571 PyString_ConcatAndDel(&result, PyString_FromString(buf));
4572 return result;
4573}
4574
4575/* Miscellaneous methods. */
4576
4577/* Note: tp_richcompare and tp_hash are inherited from datetime. */
4578
4579static PyObject *
4580datetimetz_timetuple(PyDateTime_DateTimeTZ *self)
4581{
4582 int dstflag = -1;
4583
4584 if (self->tzinfo != Py_None) {
4585 int none;
4586
4587 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4588 if (dstflag == -1 && PyErr_Occurred())
4589 return NULL;
4590
4591 if (none)
4592 dstflag = -1;
4593 else if (dstflag != 0)
4594 dstflag = 1;
4595
4596 }
4597 return build_struct_time(GET_YEAR(self),
4598 GET_MONTH(self),
4599 GET_DAY(self),
4600 DATE_GET_HOUR(self),
4601 DATE_GET_MINUTE(self),
4602 DATE_GET_SECOND(self),
4603 dstflag);
4604}
4605
4606static PyObject *
4607datetimetz_utctimetuple(PyDateTime_DateTimeTZ *self)
4608{
4609 int y = GET_YEAR(self);
4610 int m = GET_MONTH(self);
4611 int d = GET_DAY(self);
4612 int hh = DATE_GET_HOUR(self);
4613 int mm = DATE_GET_MINUTE(self);
4614 int ss = DATE_GET_SECOND(self);
4615 int us = 0; /* microseconds are ignored in a timetuple */
4616 int offset = 0;
4617
4618 if (self->tzinfo != Py_None) {
4619 int none;
4620
4621 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4622 if (offset == -1 && PyErr_Occurred())
4623 return NULL;
4624 }
4625 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4626 * 0 in a UTC timetuple regardless of what dst() says.
4627 */
4628 if (offset) {
4629 /* Subtract offset minutes & normalize. */
4630 int stat;
4631
4632 mm -= offset;
4633 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4634 if (stat < 0) {
4635 /* At the edges, it's possible we overflowed
4636 * beyond MINYEAR or MAXYEAR.
4637 */
4638 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4639 PyErr_Clear();
4640 else
4641 return NULL;
4642 }
4643 }
4644 return build_struct_time(y, m, d, hh, mm, ss, 0);
4645}
4646
4647static PyObject *
4648datetimetz_gettimetz(PyDateTime_DateTimeTZ *self)
4649{
4650 return new_timetz(DATE_GET_HOUR(self),
4651 DATE_GET_MINUTE(self),
4652 DATE_GET_SECOND(self),
4653 DATE_GET_MICROSECOND(self),
4654 self->tzinfo);
4655}
4656
4657/*
4658 * Pickle support. Quite a maze!
4659 */
4660
4661/* Let basestate be the state string returned by datetime_getstate.
4662 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4663 * So it's a tuple in any (non-error) case.
4664 */
4665static PyObject *
4666datetimetz_getstate(PyDateTime_DateTimeTZ *self)
4667{
4668 PyObject *basestate;
4669 PyObject *result = NULL;
4670
4671 basestate = datetime_getstate((PyDateTime_DateTime *)self);
4672 if (basestate != NULL) {
4673 if (self->tzinfo == Py_None)
4674 result = Py_BuildValue("(O)", basestate);
4675 else
4676 result = Py_BuildValue("OO", basestate, self->tzinfo);
4677 Py_DECREF(basestate);
4678 }
4679 return result;
4680}
4681
4682static PyObject *
4683datetimetz_setstate(PyDateTime_DateTimeTZ *self, PyObject *state)
4684{
4685 PyObject *temp;
4686 PyObject *basestate;
4687 PyObject *tzinfo = Py_None;
4688
4689 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
4690 &PyString_Type, &basestate,
4691 &tzinfo))
4692 return NULL;
4693 temp = datetime_setstate((PyDateTime_DateTime *)self, basestate);
4694 if (temp == NULL)
4695 return NULL;
4696 Py_DECREF(temp);
4697
4698 Py_INCREF(tzinfo);
4699 Py_XDECREF(self->tzinfo);
4700 self->tzinfo = tzinfo;
4701
4702 Py_INCREF(Py_None);
4703 return Py_None;
4704}
4705
4706static PyObject *
4707datetimetz_pickler(PyObject *module, PyDateTime_DateTimeTZ *datetimetz)
4708{
4709 PyObject *state;
4710 PyObject *result = NULL;
4711
4712 if (! PyDateTimeTZ_CheckExact(datetimetz)) {
4713 PyErr_Format(PyExc_TypeError,
4714 "bad type passed to datetimetz pickler: %s",
4715 datetimetz->ob_type->tp_name);
4716 return NULL;
4717 }
4718 state = datetimetz_getstate(datetimetz);
4719 if (state) {
4720 result = Py_BuildValue("O(O)",
4721 datetimetz_unpickler_object,
4722 state);
4723 Py_DECREF(state);
4724 }
4725 return result;
4726}
4727
4728static PyObject *
4729datetimetz_unpickler(PyObject *module, PyObject *arg)
4730{
4731 PyDateTime_DateTimeTZ *self;
4732
4733 self = PyObject_New(PyDateTime_DateTimeTZ, &PyDateTime_DateTimeTZType);
4734 if (self != NULL) {
4735 PyObject *res;
4736
4737 self->tzinfo = NULL;
4738 res = datetimetz_setstate(self, arg);
4739 if (res == NULL) {
4740 Py_DECREF(self);
4741 return NULL;
4742 }
4743 Py_DECREF(res);
4744 }
4745 return (PyObject *)self;
4746}
4747
4748
4749static PyMethodDef datetimetz_methods[] = {
4750 /* Class methods: */
4751 /* Inherited: combine(), utcnow(), utcfromtimestamp() */
4752
4753 {"now", (PyCFunction)datetimetz_now,
4754 METH_KEYWORDS | METH_CLASS,
4755 PyDoc_STR("[tzinfo] -> new datetimetz with local day and time.")},
4756
4757 {"fromtimestamp", (PyCFunction)datetimetz_fromtimestamp,
4758 METH_KEYWORDS | METH_CLASS,
4759 PyDoc_STR("timestamp[, tzinfo] -> local time from POSIX timestamp.")},
4760
4761 /* Instance methods: */
4762 /* Inherited: date(), time(), ctime(). */
4763 {"timetuple", (PyCFunction)datetimetz_timetuple, METH_NOARGS,
4764 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4765
4766 {"utctimetuple", (PyCFunction)datetimetz_utctimetuple, METH_NOARGS,
4767 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4768
4769 {"timetz", (PyCFunction)datetimetz_gettimetz, METH_NOARGS,
4770 PyDoc_STR("Return timetz object with same hour, minute, second, "
4771 "microsecond, and tzinfo.")},
4772
4773 {"isoformat", (PyCFunction)datetimetz_isoformat, METH_KEYWORDS,
4774 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4775 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4776 "sep is used to separate the year from the time, and "
4777 "defaults to 'T'.")},
4778
4779 {"utcoffset", (PyCFunction)datetimetz_utcoffset, METH_NOARGS,
4780 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4781
4782 {"tzname", (PyCFunction)datetimetz_tzname, METH_NOARGS,
4783 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4784
4785 {"dst", (PyCFunction)datetimetz_dst, METH_NOARGS,
4786 PyDoc_STR("Return self.tzinfo.dst(self).")},
4787
4788 {"__setstate__", (PyCFunction)datetimetz_setstate, METH_O,
4789 PyDoc_STR("__setstate__(state)")},
4790
4791 {"__getstate__", (PyCFunction)datetimetz_getstate, METH_NOARGS,
4792 PyDoc_STR("__getstate__() -> state")},
4793 {NULL, NULL}
4794};
4795
4796static char datetimetz_doc[] =
4797PyDoc_STR("date/time type.");
4798
4799static PyNumberMethods datetimetz_as_number = {
4800 datetimetz_add, /* nb_add */
4801 datetimetz_subtract, /* nb_subtract */
4802 0, /* nb_multiply */
4803 0, /* nb_divide */
4804 0, /* nb_remainder */
4805 0, /* nb_divmod */
4806 0, /* nb_power */
4807 0, /* nb_negative */
4808 0, /* nb_positive */
4809 0, /* nb_absolute */
4810 0, /* nb_nonzero */
4811};
4812
4813statichere PyTypeObject PyDateTime_DateTimeTZType = {
4814 PyObject_HEAD_INIT(NULL)
4815 0, /* ob_size */
4816 "datetime.datetimetz", /* tp_name */
4817 sizeof(PyDateTime_DateTimeTZ), /* tp_basicsize */
4818 0, /* tp_itemsize */
4819 (destructor)datetimetz_dealloc, /* tp_dealloc */
4820 0, /* tp_print */
4821 0, /* tp_getattr */
4822 0, /* tp_setattr */
4823 0, /* tp_compare */
4824 (reprfunc)datetimetz_repr, /* tp_repr */
4825 &datetimetz_as_number, /* tp_as_number */
4826 0, /* tp_as_sequence */
4827 0, /* tp_as_mapping */
4828 0, /* tp_hash */
4829 0, /* tp_call */
4830 0, /* tp_str */
4831 PyObject_GenericGetAttr, /* tp_getattro */
4832 0, /* tp_setattro */
4833 0, /* tp_as_buffer */
4834 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4835 Py_TPFLAGS_BASETYPE, /* tp_flags */
4836 datetimetz_doc, /* tp_doc */
4837 0, /* tp_traverse */
4838 0, /* tp_clear */
4839 0, /* tp_richcompare */
4840 0, /* tp_weaklistoffset */
4841 0, /* tp_iter */
4842 0, /* tp_iternext */
4843 datetimetz_methods, /* tp_methods */
4844 0, /* tp_members */
4845 datetimetz_getset, /* tp_getset */
4846 &PyDateTime_DateTimeType, /* tp_base */
4847 0, /* tp_dict */
4848 0, /* tp_descr_get */
4849 0, /* tp_descr_set */
4850 0, /* tp_dictoffset */
4851 0, /* tp_init */
4852 0, /* tp_alloc */
4853 datetimetz_new, /* tp_new */
4854 _PyObject_Del, /* tp_free */
4855};
4856
4857/* ---------------------------------------------------------------------------
4858 * Module methods and initialization.
4859 */
4860
4861static PyMethodDef module_methods[] = {
4862 /* Private functions for pickling support, registered with the
4863 * copy_reg module by the module init function.
4864 */
4865 {"_date_pickler", (PyCFunction)date_pickler, METH_O, NULL},
4866 {"_date_unpickler", (PyCFunction)date_unpickler, METH_O, NULL},
4867 {"_datetime_pickler", (PyCFunction)datetime_pickler, METH_O, NULL},
4868 {"_datetime_unpickler", (PyCFunction)datetime_unpickler,METH_O, NULL},
4869 {"_datetimetz_pickler", (PyCFunction)datetimetz_pickler,METH_O, NULL},
4870 {"_datetimetz_unpickler",(PyCFunction)datetimetz_unpickler,METH_O, NULL},
4871 {"_time_pickler", (PyCFunction)time_pickler, METH_O, NULL},
4872 {"_time_unpickler", (PyCFunction)time_unpickler, METH_O, NULL},
4873 {"_timetz_pickler", (PyCFunction)timetz_pickler, METH_O, NULL},
4874 {"_timetz_unpickler", (PyCFunction)timetz_unpickler, METH_O, NULL},
4875 {"_tzinfo_pickler", (PyCFunction)tzinfo_pickler, METH_O, NULL},
4876 {"_tzinfo_unpickler", (PyCFunction)tzinfo_unpickler, METH_NOARGS,
4877 NULL},
4878 {NULL, NULL}
4879};
4880
4881PyMODINIT_FUNC
4882initdatetime(void)
4883{
4884 PyObject *m; /* a module object */
4885 PyObject *d; /* its dict */
4886 PyObject *x;
4887
4888 /* Types that use __reduce__ for pickling need to set the following
4889 * magical attr in the type dict, with a true value.
4890 */
4891 PyObject *safepickle = PyString_FromString("__safe_for_unpickling__");
4892 if (safepickle == NULL)
4893 return;
4894
4895 m = Py_InitModule3("datetime", module_methods,
4896 "Fast implementation of the datetime type.");
4897
4898 if (PyType_Ready(&PyDateTime_DateType) < 0)
4899 return;
4900 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4901 return;
4902 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4903 return;
4904 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4905 return;
4906 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4907 return;
4908 if (PyType_Ready(&PyDateTime_TimeTZType) < 0)
4909 return;
4910 if (PyType_Ready(&PyDateTime_DateTimeTZType) < 0)
4911 return;
4912
4913 /* Pickling support, via registering functions with copy_reg. */
4914 {
4915 PyObject *pickler;
4916 PyObject *copyreg = PyImport_ImportModule("copy_reg");
4917
4918 if (copyreg == NULL) return;
4919
4920 pickler = PyObject_GetAttrString(m, "_date_pickler");
4921 if (pickler == NULL) return;
4922 date_unpickler_object = PyObject_GetAttrString(m,
4923 "_date_unpickler");
4924 if (date_unpickler_object == NULL) return;
4925 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4926 &PyDateTime_DateType,
4927 pickler,
4928 date_unpickler_object);
4929 if (x == NULL) return;
4930 Py_DECREF(x);
4931 Py_DECREF(pickler);
4932
4933 pickler = PyObject_GetAttrString(m, "_datetime_pickler");
4934 if (pickler == NULL) return;
4935 datetime_unpickler_object = PyObject_GetAttrString(m,
4936 "_datetime_unpickler");
4937 if (datetime_unpickler_object == NULL) return;
4938 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4939 &PyDateTime_DateTimeType,
4940 pickler,
4941 datetime_unpickler_object);
4942 if (x == NULL) return;
4943 Py_DECREF(x);
4944 Py_DECREF(pickler);
4945
4946 pickler = PyObject_GetAttrString(m, "_time_pickler");
4947 if (pickler == NULL) return;
4948 time_unpickler_object = PyObject_GetAttrString(m,
4949 "_time_unpickler");
4950 if (time_unpickler_object == NULL) return;
4951 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4952 &PyDateTime_TimeType,
4953 pickler,
4954 time_unpickler_object);
4955 if (x == NULL) return;
4956 Py_DECREF(x);
4957 Py_DECREF(pickler);
4958
4959 pickler = PyObject_GetAttrString(m, "_timetz_pickler");
4960 if (pickler == NULL) return;
4961 timetz_unpickler_object = PyObject_GetAttrString(m,
4962 "_timetz_unpickler");
4963 if (timetz_unpickler_object == NULL) return;
4964 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4965 &PyDateTime_TimeTZType,
4966 pickler,
4967 timetz_unpickler_object);
4968 if (x == NULL) return;
4969 Py_DECREF(x);
4970 Py_DECREF(pickler);
4971
4972 pickler = PyObject_GetAttrString(m, "_tzinfo_pickler");
4973 if (pickler == NULL) return;
4974 tzinfo_unpickler_object = PyObject_GetAttrString(m,
4975 "_tzinfo_unpickler");
4976 if (tzinfo_unpickler_object == NULL) return;
4977 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4978 &PyDateTime_TZInfoType,
4979 pickler,
4980 tzinfo_unpickler_object);
4981 if (x== NULL) return;
4982 Py_DECREF(x);
4983 Py_DECREF(pickler);
4984
4985 pickler = PyObject_GetAttrString(m, "_datetimetz_pickler");
4986 if (pickler == NULL) return;
4987 datetimetz_unpickler_object = PyObject_GetAttrString(m,
4988 "_datetimetz_unpickler");
4989 if (datetimetz_unpickler_object == NULL) return;
4990 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4991 &PyDateTime_DateTimeTZType,
4992 pickler,
4993 datetimetz_unpickler_object);
4994 if (x== NULL) return;
4995 Py_DECREF(x);
4996 Py_DECREF(pickler);
4997
4998 Py_DECREF(copyreg);
4999 }
5000
5001 /* timedelta values */
5002 d = PyDateTime_DeltaType.tp_dict;
5003
5004 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
5005 return;
5006
5007 x = new_delta(0, 0, 1, 0);
5008 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5009 return;
5010 Py_DECREF(x);
5011
5012 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5013 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5014 return;
5015 Py_DECREF(x);
5016
5017 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5018 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5019 return;
5020 Py_DECREF(x);
5021
5022 /* date values */
5023 d = PyDateTime_DateType.tp_dict;
5024
5025 x = new_date(1, 1, 1);
5026 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5027 return;
5028 Py_DECREF(x);
5029
5030 x = new_date(MAXYEAR, 12, 31);
5031 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5032 return;
5033 Py_DECREF(x);
5034
5035 x = new_delta(1, 0, 0, 0);
5036 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5037 return;
5038 Py_DECREF(x);
5039
5040 /* datetime values */
5041 d = PyDateTime_DateTimeType.tp_dict;
5042
5043 x = new_datetime(1, 1, 1, 0, 0, 0, 0);
5044 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5045 return;
5046 Py_DECREF(x);
5047
5048 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999);
5049 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5050 return;
5051 Py_DECREF(x);
5052
5053 x = new_delta(0, 0, 1, 0);
5054 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5055 return;
5056 Py_DECREF(x);
5057
5058 /* time values */
5059 d = PyDateTime_TimeType.tp_dict;
5060
5061 x = new_time(0, 0, 0, 0);
5062 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5063 return;
5064 Py_DECREF(x);
5065
5066 x = new_time(23, 59, 59, 999999);
5067 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5068 return;
5069 Py_DECREF(x);
5070
5071 x = new_delta(0, 0, 1, 0);
5072 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5073 return;
5074 Py_DECREF(x);
5075
5076 /* timetz values */
5077 d = PyDateTime_TimeTZType.tp_dict;
5078
5079 x = new_timetz(0, 0, 0, 0, Py_None);
5080 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5081 return;
5082 Py_DECREF(x);
5083
5084 x = new_timetz(23, 59, 59, 999999, Py_None);
5085 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5086 return;
5087 Py_DECREF(x);
5088
5089 x = new_delta(0, 0, 1, 0);
5090 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5091 return;
5092 Py_DECREF(x);
5093
5094 /* datetimetz values */
5095 d = PyDateTime_DateTimeTZType.tp_dict;
5096
5097 x = new_datetimetz(1, 1, 1, 0, 0, 0, 0, Py_None);
5098 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5099 return;
5100 Py_DECREF(x);
5101
5102 x = new_datetimetz(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
5103 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5104 return;
5105 Py_DECREF(x);
5106
5107 x = new_delta(0, 0, 1, 0);
5108 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5109 return;
5110 Py_DECREF(x);
5111
5112 Py_DECREF(safepickle);
5113
5114 /* module initialization */
5115 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
5116 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
5117
5118 Py_INCREF(&PyDateTime_DateType);
5119 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
5120
5121 Py_INCREF(&PyDateTime_DateTimeType);
5122 PyModule_AddObject(m, "datetime",
5123 (PyObject *) &PyDateTime_DateTimeType);
5124
5125 Py_INCREF(&PyDateTime_DeltaType);
5126 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
5127
5128 Py_INCREF(&PyDateTime_TimeType);
5129 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
5130
5131 Py_INCREF(&PyDateTime_TZInfoType);
5132 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
5133
5134 Py_INCREF(&PyDateTime_TimeTZType);
5135 PyModule_AddObject(m, "timetz", (PyObject *) &PyDateTime_TimeTZType);
5136
5137 Py_INCREF(&PyDateTime_DateTimeTZType);
5138 PyModule_AddObject(m, "datetimetz",
5139 (PyObject *)&PyDateTime_DateTimeTZType);
5140
5141 /* A 4-year cycle has an extra leap day over what we'd get from
5142 * pasting together 4 single years.
5143 */
5144 assert(DI4Y == 4 * 365 + 1);
5145 assert(DI4Y == days_before_year(4+1));
5146
5147 /* Similarly, a 400-year cycle has an extra leap day over what we'd
5148 * get from pasting together 4 100-year cycles.
5149 */
5150 assert(DI400Y == 4 * DI100Y + 1);
5151 assert(DI400Y == days_before_year(400+1));
5152
5153 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5154 * pasting together 25 4-year cycles.
5155 */
5156 assert(DI100Y == 25 * DI4Y - 1);
5157 assert(DI100Y == days_before_year(100+1));
5158
5159 us_per_us = PyInt_FromLong(1);
5160 us_per_ms = PyInt_FromLong(1000);
5161 us_per_second = PyInt_FromLong(1000000);
5162 us_per_minute = PyInt_FromLong(60000000);
5163 seconds_per_day = PyInt_FromLong(24 * 3600);
5164 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
5165 us_per_minute == NULL || seconds_per_day == NULL)
5166 return;
5167
5168 /* The rest are too big for 32-bit ints, but even
5169 * us_per_week fits in 40 bits, so doubles should be exact.
5170 */
5171 us_per_hour = PyLong_FromDouble(3600000000.0);
5172 us_per_day = PyLong_FromDouble(86400000000.0);
5173 us_per_week = PyLong_FromDouble(604800000000.0);
5174 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5175 return;
5176}