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