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