blob: 31e006d6fa05ae2ca5345a5cdae547410cd0e290 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
6#include "modsupport.h"
7#include "structmember.h"
8
9#include <time.h>
10
11#include "datetime.h"
12
13/* We require that C int be at least 32 bits, and use int virtually
14 * everywhere. In just a few cases we use a temp long, where a Python
15 * API returns a C long. In such cases, we have to ensure that the
16 * final result fits in a C int (this can be an issue on 64-bit boxes).
17 */
18#if SIZEOF_INT < 4
19# error "datetime.c requires that C int have at least 32 bits"
20#endif
21
22#define MINYEAR 1
23#define MAXYEAR 9999
24
25/* Nine decimal digits is easy to communicate, and leaves enough room
26 * so that two delta days can be added w/o fear of overflowing a signed
27 * 32-bit int, and with plenty of room left over to absorb any possible
28 * carries from adding seconds.
29 */
30#define MAX_DELTA_DAYS 999999999
31
32/* Rename the long macros in datetime.h to more reasonable short names. */
33#define GET_YEAR PyDateTime_GET_YEAR
34#define GET_MONTH PyDateTime_GET_MONTH
35#define GET_DAY PyDateTime_GET_DAY
36#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
37#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
38#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
39#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
40
41/* Date accessors for date and datetime. */
42#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
43 ((o)->data[1] = ((v) & 0x00ff)))
44#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
45#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
46
47/* Date/Time accessors for datetime. */
48#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
49#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
50#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
51#define DATE_SET_MICROSECOND(o, v) \
52 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
53 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
54 ((o)->data[9] = ((v) & 0x0000ff)))
55
56/* Time accessors for time. */
57#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
58#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
59#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
60#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
61#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
62#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
63#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
64#define TIME_SET_MICROSECOND(o, v) \
65 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
66 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
67 ((o)->data[5] = ((v) & 0x0000ff)))
68
69/* Delta accessors for timedelta. */
70#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
71#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
72#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
73
74#define SET_TD_DAYS(o, v) ((o)->days = (v))
75#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
76#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
77
Tim Petersa032d2e2003-01-11 00:15:54 +000078/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
79 * p->hastzinfo.
80 */
81#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
82
Tim Peters2a799bf2002-12-16 20:18:38 +000083/* Forward declarations. */
84static PyTypeObject PyDateTime_DateType;
85static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +000086static PyTypeObject PyDateTime_DeltaType;
87static PyTypeObject PyDateTime_TimeType;
88static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +000089
90/* ---------------------------------------------------------------------------
91 * Math utilities.
92 */
93
94/* k = i+j overflows iff k differs in sign from both inputs,
95 * iff k^i has sign bit set and k^j has sign bit set,
96 * iff (k^i)&(k^j) has sign bit set.
97 */
98#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
99 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
100
101/* Compute Python divmod(x, y), returning the quotient and storing the
102 * remainder into *r. The quotient is the floor of x/y, and that's
103 * the real point of this. C will probably truncate instead (C99
104 * requires truncation; C89 left it implementation-defined).
105 * Simplification: we *require* that y > 0 here. That's appropriate
106 * for all the uses made of it. This simplifies the code and makes
107 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
108 * overflow case).
109 */
110static int
111divmod(int x, int y, int *r)
112{
113 int quo;
114
115 assert(y > 0);
116 quo = x / y;
117 *r = x - quo * y;
118 if (*r < 0) {
119 --quo;
120 *r += y;
121 }
122 assert(0 <= *r && *r < y);
123 return quo;
124}
125
Tim Peters5d644dd2003-01-02 16:32:54 +0000126/* Round a double to the nearest long. |x| must be small enough to fit
127 * in a C long; this is not checked.
128 */
129static long
130round_to_long(double x)
131{
132 if (x >= 0.0)
133 x = floor(x + 0.5);
134 else
135 x = ceil(x - 0.5);
136 return (long)x;
137}
138
Tim Peters2a799bf2002-12-16 20:18:38 +0000139/* ---------------------------------------------------------------------------
140 * General calendrical helper functions
141 */
142
143/* For each month ordinal in 1..12, the number of days in that month,
144 * and the number of days before that month in the same year. These
145 * are correct for non-leap years only.
146 */
147static int _days_in_month[] = {
148 0, /* unused; this vector uses 1-based indexing */
149 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
150};
151
152static int _days_before_month[] = {
153 0, /* unused; this vector uses 1-based indexing */
154 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
155};
156
157/* year -> 1 if leap year, else 0. */
158static int
159is_leap(int year)
160{
161 /* Cast year to unsigned. The result is the same either way, but
162 * C can generate faster code for unsigned mod than for signed
163 * mod (especially for % 4 -- a good compiler should just grab
164 * the last 2 bits when the LHS is unsigned).
165 */
166 const unsigned int ayear = (unsigned int)year;
167 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
168}
169
170/* year, month -> number of days in that month in that year */
171static int
172days_in_month(int year, int month)
173{
174 assert(month >= 1);
175 assert(month <= 12);
176 if (month == 2 && is_leap(year))
177 return 29;
178 else
179 return _days_in_month[month];
180}
181
182/* year, month -> number of days in year preceeding first day of month */
183static int
184days_before_month(int year, int month)
185{
186 int days;
187
188 assert(month >= 1);
189 assert(month <= 12);
190 days = _days_before_month[month];
191 if (month > 2 && is_leap(year))
192 ++days;
193 return days;
194}
195
196/* year -> number of days before January 1st of year. Remember that we
197 * start with year 1, so days_before_year(1) == 0.
198 */
199static int
200days_before_year(int year)
201{
202 int y = year - 1;
203 /* This is incorrect if year <= 0; we really want the floor
204 * here. But so long as MINYEAR is 1, the smallest year this
205 * can see is 0 (this can happen in some normalization endcases),
206 * so we'll just special-case that.
207 */
208 assert (year >= 0);
209 if (y >= 0)
210 return y*365 + y/4 - y/100 + y/400;
211 else {
212 assert(y == -1);
213 return -366;
214 }
215}
216
217/* Number of days in 4, 100, and 400 year cycles. That these have
218 * the correct values is asserted in the module init function.
219 */
220#define DI4Y 1461 /* days_before_year(5); days in 4 years */
221#define DI100Y 36524 /* days_before_year(101); days in 100 years */
222#define DI400Y 146097 /* days_before_year(401); days in 400 years */
223
224/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
225static void
226ord_to_ymd(int ordinal, int *year, int *month, int *day)
227{
228 int n, n1, n4, n100, n400, leapyear, preceding;
229
230 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
231 * leap years repeats exactly every 400 years. The basic strategy is
232 * to find the closest 400-year boundary at or before ordinal, then
233 * work with the offset from that boundary to ordinal. Life is much
234 * clearer if we subtract 1 from ordinal first -- then the values
235 * of ordinal at 400-year boundaries are exactly those divisible
236 * by DI400Y:
237 *
238 * D M Y n n-1
239 * -- --- ---- ---------- ----------------
240 * 31 Dec -400 -DI400Y -DI400Y -1
241 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
242 * ...
243 * 30 Dec 000 -1 -2
244 * 31 Dec 000 0 -1
245 * 1 Jan 001 1 0 400-year boundary
246 * 2 Jan 001 2 1
247 * 3 Jan 001 3 2
248 * ...
249 * 31 Dec 400 DI400Y DI400Y -1
250 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
251 */
252 assert(ordinal >= 1);
253 --ordinal;
254 n400 = ordinal / DI400Y;
255 n = ordinal % DI400Y;
256 *year = n400 * 400 + 1;
257
258 /* Now n is the (non-negative) offset, in days, from January 1 of
259 * year, to the desired date. Now compute how many 100-year cycles
260 * precede n.
261 * Note that it's possible for n100 to equal 4! In that case 4 full
262 * 100-year cycles precede the desired day, which implies the
263 * desired day is December 31 at the end of a 400-year cycle.
264 */
265 n100 = n / DI100Y;
266 n = n % DI100Y;
267
268 /* Now compute how many 4-year cycles precede it. */
269 n4 = n / DI4Y;
270 n = n % DI4Y;
271
272 /* And now how many single years. Again n1 can be 4, and again
273 * meaning that the desired day is December 31 at the end of the
274 * 4-year cycle.
275 */
276 n1 = n / 365;
277 n = n % 365;
278
279 *year += n100 * 100 + n4 * 4 + n1;
280 if (n1 == 4 || n100 == 4) {
281 assert(n == 0);
282 *year -= 1;
283 *month = 12;
284 *day = 31;
285 return;
286 }
287
288 /* Now the year is correct, and n is the offset from January 1. We
289 * find the month via an estimate that's either exact or one too
290 * large.
291 */
292 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
293 assert(leapyear == is_leap(*year));
294 *month = (n + 50) >> 5;
295 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
296 if (preceding > n) {
297 /* estimate is too large */
298 *month -= 1;
299 preceding -= days_in_month(*year, *month);
300 }
301 n -= preceding;
302 assert(0 <= n);
303 assert(n < days_in_month(*year, *month));
304
305 *day = n + 1;
306}
307
308/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
309static int
310ymd_to_ord(int year, int month, int day)
311{
312 return days_before_year(year) + days_before_month(year, month) + day;
313}
314
315/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
316static int
317weekday(int year, int month, int day)
318{
319 return (ymd_to_ord(year, month, day) + 6) % 7;
320}
321
322/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
323 * first calendar week containing a Thursday.
324 */
325static int
326iso_week1_monday(int year)
327{
328 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
329 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
330 int first_weekday = (first_day + 6) % 7;
331 /* ordinal of closest Monday at or before 1/1 */
332 int week1_monday = first_day - first_weekday;
333
334 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
335 week1_monday += 7;
336 return week1_monday;
337}
338
339/* ---------------------------------------------------------------------------
340 * Range checkers.
341 */
342
343/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
344 * If not, raise OverflowError and return -1.
345 */
346static int
347check_delta_day_range(int days)
348{
349 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
350 return 0;
351 PyErr_Format(PyExc_OverflowError,
352 "days=%d; must have magnitude <= %d",
Guido van Rossumbd43e912002-12-16 20:34:55 +0000353 days, MAX_DELTA_DAYS);
Tim Peters2a799bf2002-12-16 20:18:38 +0000354 return -1;
355}
356
357/* Check that date arguments are in range. Return 0 if they are. If they
358 * aren't, raise ValueError and return -1.
359 */
360static int
361check_date_args(int year, int month, int day)
362{
363
364 if (year < MINYEAR || year > MAXYEAR) {
365 PyErr_SetString(PyExc_ValueError,
366 "year is out of range");
367 return -1;
368 }
369 if (month < 1 || month > 12) {
370 PyErr_SetString(PyExc_ValueError,
371 "month must be in 1..12");
372 return -1;
373 }
374 if (day < 1 || day > days_in_month(year, month)) {
375 PyErr_SetString(PyExc_ValueError,
376 "day is out of range for month");
377 return -1;
378 }
379 return 0;
380}
381
382/* Check that time arguments are in range. Return 0 if they are. If they
383 * aren't, raise ValueError and return -1.
384 */
385static int
386check_time_args(int h, int m, int s, int us)
387{
388 if (h < 0 || h > 23) {
389 PyErr_SetString(PyExc_ValueError,
390 "hour must be in 0..23");
391 return -1;
392 }
393 if (m < 0 || m > 59) {
394 PyErr_SetString(PyExc_ValueError,
395 "minute must be in 0..59");
396 return -1;
397 }
398 if (s < 0 || s > 59) {
399 PyErr_SetString(PyExc_ValueError,
400 "second must be in 0..59");
401 return -1;
402 }
403 if (us < 0 || us > 999999) {
404 PyErr_SetString(PyExc_ValueError,
405 "microsecond must be in 0..999999");
406 return -1;
407 }
408 return 0;
409}
410
411/* ---------------------------------------------------------------------------
412 * Normalization utilities.
413 */
414
415/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
416 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
417 * at least factor, enough of *lo is converted into "hi" units so that
418 * 0 <= *lo < factor. The input values must be such that int overflow
419 * is impossible.
420 */
421static void
422normalize_pair(int *hi, int *lo, int factor)
423{
424 assert(factor > 0);
425 assert(lo != hi);
426 if (*lo < 0 || *lo >= factor) {
427 const int num_hi = divmod(*lo, factor, lo);
428 const int new_hi = *hi + num_hi;
429 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
430 *hi = new_hi;
431 }
432 assert(0 <= *lo && *lo < factor);
433}
434
435/* Fiddle days (d), seconds (s), and microseconds (us) so that
436 * 0 <= *s < 24*3600
437 * 0 <= *us < 1000000
438 * The input values must be such that the internals don't overflow.
439 * The way this routine is used, we don't get close.
440 */
441static void
442normalize_d_s_us(int *d, int *s, int *us)
443{
444 if (*us < 0 || *us >= 1000000) {
445 normalize_pair(s, us, 1000000);
446 /* |s| can't be bigger than about
447 * |original s| + |original us|/1000000 now.
448 */
449
450 }
451 if (*s < 0 || *s >= 24*3600) {
452 normalize_pair(d, s, 24*3600);
453 /* |d| can't be bigger than about
454 * |original d| +
455 * (|original s| + |original us|/1000000) / (24*3600) now.
456 */
457 }
458 assert(0 <= *s && *s < 24*3600);
459 assert(0 <= *us && *us < 1000000);
460}
461
462/* Fiddle years (y), months (m), and days (d) so that
463 * 1 <= *m <= 12
464 * 1 <= *d <= days_in_month(*y, *m)
465 * The input values must be such that the internals don't overflow.
466 * The way this routine is used, we don't get close.
467 */
468static void
469normalize_y_m_d(int *y, int *m, int *d)
470{
471 int dim; /* # of days in month */
472
473 /* This gets muddy: the proper range for day can't be determined
474 * without knowing the correct month and year, but if day is, e.g.,
475 * plus or minus a million, the current month and year values make
476 * no sense (and may also be out of bounds themselves).
477 * Saying 12 months == 1 year should be non-controversial.
478 */
479 if (*m < 1 || *m > 12) {
480 --*m;
481 normalize_pair(y, m, 12);
482 ++*m;
483 /* |y| can't be bigger than about
484 * |original y| + |original m|/12 now.
485 */
486 }
487 assert(1 <= *m && *m <= 12);
488
489 /* Now only day can be out of bounds (year may also be out of bounds
490 * for a datetime object, but we don't care about that here).
491 * If day is out of bounds, what to do is arguable, but at least the
492 * method here is principled and explainable.
493 */
494 dim = days_in_month(*y, *m);
495 if (*d < 1 || *d > dim) {
496 /* Move day-1 days from the first of the month. First try to
497 * get off cheap if we're only one day out of range
498 * (adjustments for timezone alone can't be worse than that).
499 */
500 if (*d == 0) {
501 --*m;
502 if (*m > 0)
503 *d = days_in_month(*y, *m);
504 else {
505 --*y;
506 *m = 12;
507 *d = 31;
508 }
509 }
510 else if (*d == dim + 1) {
511 /* move forward a day */
512 ++*m;
513 *d = 1;
514 if (*m > 12) {
515 *m = 1;
516 ++*y;
517 }
518 }
519 else {
520 int ordinal = ymd_to_ord(*y, *m, 1) +
521 *d - 1;
522 ord_to_ymd(ordinal, y, m, d);
523 }
524 }
525 assert(*m > 0);
526 assert(*d > 0);
527}
528
529/* Fiddle out-of-bounds months and days so that the result makes some kind
530 * of sense. The parameters are both inputs and outputs. Returns < 0 on
531 * failure, where failure means the adjusted year is out of bounds.
532 */
533static int
534normalize_date(int *year, int *month, int *day)
535{
536 int result;
537
538 normalize_y_m_d(year, month, day);
539 if (MINYEAR <= *year && *year <= MAXYEAR)
540 result = 0;
541 else {
542 PyErr_SetString(PyExc_OverflowError,
543 "date value out of range");
544 result = -1;
545 }
546 return result;
547}
548
549/* Force all the datetime fields into range. The parameters are both
550 * inputs and outputs. Returns < 0 on error.
551 */
552static int
553normalize_datetime(int *year, int *month, int *day,
554 int *hour, int *minute, int *second,
555 int *microsecond)
556{
557 normalize_pair(second, microsecond, 1000000);
558 normalize_pair(minute, second, 60);
559 normalize_pair(hour, minute, 60);
560 normalize_pair(day, hour, 24);
561 return normalize_date(year, month, day);
562}
563
564/* ---------------------------------------------------------------------------
565 * tzinfo helpers.
566 */
567
Tim Peters855fe882002-12-22 03:43:39 +0000568/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
569 * raise TypeError and return -1.
570 */
571static int
572check_tzinfo_subclass(PyObject *p)
573{
574 if (p == Py_None || PyTZInfo_Check(p))
575 return 0;
576 PyErr_Format(PyExc_TypeError,
577 "tzinfo argument must be None or of a tzinfo subclass, "
578 "not type '%s'",
579 p->ob_type->tp_name);
580 return -1;
581}
582
Tim Petersbad8ff02002-12-30 20:52:32 +0000583/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000584 * If tzinfo is None, returns None.
585 */
586static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000587call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000588{
589 PyObject *result;
590
Tim Petersbad8ff02002-12-30 20:52:32 +0000591 assert(tzinfo && methname && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000592 assert(check_tzinfo_subclass(tzinfo) >= 0);
593 if (tzinfo == Py_None) {
594 result = Py_None;
595 Py_INCREF(result);
596 }
597 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000598 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000599 return result;
600}
601
Tim Peters2a799bf2002-12-16 20:18:38 +0000602/* If self has a tzinfo member, return a BORROWED reference to it. Else
603 * return NULL, which is NOT AN ERROR. There are no error returns here,
604 * and the caller must not decref the result.
605 */
606static PyObject *
607get_tzinfo_member(PyObject *self)
608{
609 PyObject *tzinfo = NULL;
610
Tim Petersa9bc1682003-01-11 03:39:11 +0000611 if (PyDateTime_Check(self) && HASTZINFO(self))
612 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
Tim Petersa032d2e2003-01-11 00:15:54 +0000613 else if (PyTime_Check(self) && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +0000614 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000615
616 return tzinfo;
617}
618
Tim Petersbad8ff02002-12-30 20:52:32 +0000619/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000620 * result. tzinfo must be an instance of the tzinfo class. If the method
621 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000622 * return None or timedelta, TypeError is raised and this returns -1. If it
623 * returnsa timedelta and the value is out of range or isn't a whole number
624 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000625 * Else *none is set to 0 and the integer method result is returned.
626 */
627static int
628call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
629 int *none)
630{
631 PyObject *u;
Tim Peters397301e2003-01-02 21:28:08 +0000632 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000633
634 assert(tzinfo != NULL);
635 assert(PyTZInfo_Check(tzinfo));
636 assert(tzinfoarg != NULL);
637
638 *none = 0;
Tim Petersbad8ff02002-12-30 20:52:32 +0000639 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000640 if (u == NULL)
641 return -1;
642
Tim Peters27362852002-12-23 16:17:39 +0000643 else if (u == Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +0000644 result = 0;
645 *none = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000646 }
Tim Peters855fe882002-12-22 03:43:39 +0000647 else if (PyDelta_Check(u)) {
648 const int days = GET_TD_DAYS(u);
649 if (days < -1 || days > 0)
650 result = 24*60; /* trigger ValueError below */
651 else {
652 /* next line can't overflow because we know days
653 * is -1 or 0 now
654 */
655 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
656 result = divmod(ss, 60, &ss);
657 if (ss || GET_TD_MICROSECONDS(u)) {
658 PyErr_Format(PyExc_ValueError,
659 "tzinfo.%s() must return a "
660 "whole number of minutes",
661 name);
662 result = -1;
Tim Peters855fe882002-12-22 03:43:39 +0000663 }
664 }
665 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000666 else {
667 PyErr_Format(PyExc_TypeError,
Tim Peters397301e2003-01-02 21:28:08 +0000668 "tzinfo.%s() must return None or "
Tim Peters855fe882002-12-22 03:43:39 +0000669 "timedelta, not '%s'",
670 name, u->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000671 }
672
Tim Peters2a799bf2002-12-16 20:18:38 +0000673 Py_DECREF(u);
674 if (result < -1439 || result > 1439) {
675 PyErr_Format(PyExc_ValueError,
Neal Norwitz506a2242003-01-04 01:02:25 +0000676 "tzinfo.%s() returned %d; must be in "
Tim Peters2a799bf2002-12-16 20:18:38 +0000677 "-1439 .. 1439",
678 name, result);
679 result = -1;
680 }
Tim Peters397301e2003-01-02 21:28:08 +0000681 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000682}
683
684/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
685 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
686 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000687 * doesn't return None or timedelta, TypeError is raised and this returns -1.
688 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
689 * # of minutes), ValueError is raised and this returns -1. Else *none is
690 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000691 */
692static int
693call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
694{
695 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
696}
697
Tim Peters855fe882002-12-22 03:43:39 +0000698static PyObject *new_delta(int d, int sec, int usec, int normalize);
699
Tim Petersbad8ff02002-12-30 20:52:32 +0000700/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
701 */
Tim Peters855fe882002-12-22 03:43:39 +0000702static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000703offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Tim Peters855fe882002-12-22 03:43:39 +0000704 PyObject *result;
705
Tim Petersbad8ff02002-12-30 20:52:32 +0000706 assert(tzinfo && name && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000707 if (tzinfo == Py_None) {
708 result = Py_None;
709 Py_INCREF(result);
710 }
711 else {
712 int none;
Tim Petersbad8ff02002-12-30 20:52:32 +0000713 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
714 &none);
Tim Peters855fe882002-12-22 03:43:39 +0000715 if (offset < 0 && PyErr_Occurred())
716 return NULL;
717 if (none) {
718 result = Py_None;
719 Py_INCREF(result);
720 }
721 else
722 result = new_delta(0, offset * 60, 0, 1);
723 }
724 return result;
725}
726
Tim Peters2a799bf2002-12-16 20:18:38 +0000727/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
728 * result. tzinfo must be an instance of the tzinfo class. If dst()
729 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000730 & doesn't return None or timedelta, TypeError is raised and this
731 * returns -1. If dst() returns an invalid timedelta for for a UTC offset,
732 * ValueError is raised and this returns -1. Else *none is set to 0 and
733 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000734 */
735static int
736call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
737{
738 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
739}
740
Tim Petersbad8ff02002-12-30 20:52:32 +0000741/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000742 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000743 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000744 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000745 */
746static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000747call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000748{
749 PyObject *result;
750
751 assert(tzinfo != NULL);
Tim Peters855fe882002-12-22 03:43:39 +0000752 assert(check_tzinfo_subclass(tzinfo) >= 0);
Tim Petersbad8ff02002-12-30 20:52:32 +0000753 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000754
Tim Peters855fe882002-12-22 03:43:39 +0000755 if (tzinfo == Py_None) {
756 result = Py_None;
757 Py_INCREF(result);
758 }
759 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000760 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000761
762 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
763 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
Tim Peters2a799bf2002-12-16 20:18:38 +0000764 "return None or a string, not '%s'",
765 result->ob_type->tp_name);
766 Py_DECREF(result);
767 result = NULL;
768 }
769 return result;
770}
771
772typedef enum {
773 /* an exception has been set; the caller should pass it on */
774 OFFSET_ERROR,
775
Tim Petersa9bc1682003-01-11 03:39:11 +0000776 /* type isn't date, datetime, or time subclass */
Tim Peters2a799bf2002-12-16 20:18:38 +0000777 OFFSET_UNKNOWN,
778
779 /* date,
Tim Petersa9bc1682003-01-11 03:39:11 +0000780 * datetime with !hastzinfo
781 * datetime with None tzinfo,
782 * datetime where utcoffset() returns None
Tim Peters37f39822003-01-10 03:49:02 +0000783 * time with !hastzinfo
784 * time with None tzinfo,
785 * time where utcoffset() returns None
Tim Peters2a799bf2002-12-16 20:18:38 +0000786 */
787 OFFSET_NAIVE,
788
Tim Petersa9bc1682003-01-11 03:39:11 +0000789 /* time or datetime where utcoffset() doesn't return None */
Tim Peters2a799bf2002-12-16 20:18:38 +0000790 OFFSET_AWARE,
791} naivety;
792
Tim Peters14b69412002-12-22 18:10:22 +0000793/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000794 * the "naivety" typedef for details. If the type is aware, *offset is set
795 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000796 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000797 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000798 */
799static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000800classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000801{
802 int none;
803 PyObject *tzinfo;
804
Tim Peterse39a80c2002-12-30 21:28:52 +0000805 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000806 *offset = 0;
Tim Peters14b69412002-12-22 18:10:22 +0000807 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
Tim Peters2a799bf2002-12-16 20:18:38 +0000808 if (tzinfo == Py_None)
809 return OFFSET_NAIVE;
Tim Peters14b69412002-12-22 18:10:22 +0000810 if (tzinfo == NULL) {
811 /* note that a datetime passes the PyDate_Check test */
812 return (PyTime_Check(op) || PyDate_Check(op)) ?
813 OFFSET_NAIVE : OFFSET_UNKNOWN;
814 }
Tim Peterse39a80c2002-12-30 21:28:52 +0000815 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000816 if (*offset == -1 && PyErr_Occurred())
817 return OFFSET_ERROR;
818 return none ? OFFSET_NAIVE : OFFSET_AWARE;
819}
820
Tim Peters00237032002-12-27 02:21:51 +0000821/* Classify two objects as to whether they're naive or offset-aware.
822 * This isn't quite the same as calling classify_utcoffset() twice: for
823 * binary operations (comparison and subtraction), we generally want to
824 * ignore the tzinfo members if they're identical. This is by design,
825 * so that results match "naive" expectations when mixing objects from a
826 * single timezone. So in that case, this sets both offsets to 0 and
827 * both naiveties to OFFSET_NAIVE.
828 * The function returns 0 if everything's OK, and -1 on error.
829 */
830static int
831classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Tim Peterse39a80c2002-12-30 21:28:52 +0000832 PyObject *tzinfoarg1,
833 PyObject *o2, int *offset2, naivety *n2,
834 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +0000835{
836 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
837 *offset1 = *offset2 = 0;
838 *n1 = *n2 = OFFSET_NAIVE;
839 }
840 else {
Tim Peterse39a80c2002-12-30 21:28:52 +0000841 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
Tim Peters00237032002-12-27 02:21:51 +0000842 if (*n1 == OFFSET_ERROR)
843 return -1;
Tim Peterse39a80c2002-12-30 21:28:52 +0000844 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
Tim Peters00237032002-12-27 02:21:51 +0000845 if (*n2 == OFFSET_ERROR)
846 return -1;
847 }
848 return 0;
849}
850
Tim Peters2a799bf2002-12-16 20:18:38 +0000851/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
852 * stuff
853 * ", tzinfo=" + repr(tzinfo)
854 * before the closing ")".
855 */
856static PyObject *
857append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
858{
859 PyObject *temp;
860
861 assert(PyString_Check(repr));
862 assert(tzinfo);
863 if (tzinfo == Py_None)
864 return repr;
865 /* Get rid of the trailing ')'. */
866 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
867 temp = PyString_FromStringAndSize(PyString_AsString(repr),
868 PyString_Size(repr) - 1);
869 Py_DECREF(repr);
870 if (temp == NULL)
871 return NULL;
872 repr = temp;
873
874 /* Append ", tzinfo=". */
875 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
876
877 /* Append repr(tzinfo). */
878 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
879
880 /* Add a closing paren. */
881 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
882 return repr;
883}
884
885/* ---------------------------------------------------------------------------
886 * String format helpers.
887 */
888
889static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +0000890format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000891{
892 static char *DayNames[] = {
893 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
894 };
895 static char *MonthNames[] = {
896 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
897 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
898 };
899
900 char buffer[128];
901 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
902
903 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
904 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
905 GET_DAY(date), hours, minutes, seconds,
906 GET_YEAR(date));
907 return PyString_FromString(buffer);
908}
909
910/* Add an hours & minutes UTC offset string to buf. buf has no more than
911 * buflen bytes remaining. The UTC offset is gotten by calling
912 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
913 * *buf, and that's all. Else the returned value is checked for sanity (an
914 * integer in range), and if that's OK it's converted to an hours & minutes
915 * string of the form
916 * sign HH sep MM
917 * Returns 0 if everything is OK. If the return value from utcoffset() is
918 * bogus, an appropriate exception is set and -1 is returned.
919 */
920static int
Tim Peters328fff72002-12-20 01:31:27 +0000921format_utcoffset(char *buf, size_t buflen, const char *sep,
Tim Peters2a799bf2002-12-16 20:18:38 +0000922 PyObject *tzinfo, PyObject *tzinfoarg)
923{
924 int offset;
925 int hours;
926 int minutes;
927 char sign;
928 int none;
929
930 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
931 if (offset == -1 && PyErr_Occurred())
932 return -1;
933 if (none) {
934 *buf = '\0';
935 return 0;
936 }
937 sign = '+';
938 if (offset < 0) {
939 sign = '-';
940 offset = - offset;
941 }
942 hours = divmod(offset, 60, &minutes);
943 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
944 return 0;
945}
946
947/* I sure don't want to reproduce the strftime code from the time module,
948 * so this imports the module and calls it. All the hair is due to
949 * giving special meanings to the %z and %Z format codes via a preprocessing
950 * step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +0000951 * tzinfoarg is the argument to pass to the object's tzinfo method, if
952 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +0000953 */
954static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000955wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
956 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000957{
958 PyObject *result = NULL; /* guilty until proved innocent */
959
960 PyObject *zreplacement = NULL; /* py string, replacement for %z */
961 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
962
963 char *pin; /* pointer to next char in input format */
964 char ch; /* next char in input format */
965
966 PyObject *newfmt = NULL; /* py string, the output format */
967 char *pnew; /* pointer to available byte in output format */
968 char totalnew; /* number bytes total in output format buffer,
969 exclusive of trailing \0 */
970 char usednew; /* number bytes used so far in output format buffer */
971
972 char *ptoappend; /* pointer to string to append to output buffer */
973 int ntoappend; /* # of bytes to append to output buffer */
974
Tim Peters2a799bf2002-12-16 20:18:38 +0000975 assert(object && format && timetuple);
976 assert(PyString_Check(format));
977
Tim Petersd6844152002-12-22 20:58:42 +0000978 /* Give up if the year is before 1900.
979 * Python strftime() plays games with the year, and different
980 * games depending on whether envar PYTHON2K is set. This makes
981 * years before 1900 a nightmare, even if the platform strftime
982 * supports them (and not all do).
983 * We could get a lot farther here by avoiding Python's strftime
984 * wrapper and calling the C strftime() directly, but that isn't
985 * an option in the Python implementation of this module.
986 */
987 {
988 long year;
989 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
990 if (pyyear == NULL) return NULL;
991 assert(PyInt_Check(pyyear));
992 year = PyInt_AsLong(pyyear);
993 Py_DECREF(pyyear);
994 if (year < 1900) {
995 PyErr_Format(PyExc_ValueError, "year=%ld is before "
996 "1900; the datetime strftime() "
997 "methods require year >= 1900",
998 year);
999 return NULL;
1000 }
1001 }
1002
Tim Peters2a799bf2002-12-16 20:18:38 +00001003 /* Scan the input format, looking for %z and %Z escapes, building
Tim Peters328fff72002-12-20 01:31:27 +00001004 * a new format. Since computing the replacements for those codes
1005 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +00001006 */
1007 totalnew = PyString_Size(format); /* realistic if no %z/%Z */
1008 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1009 if (newfmt == NULL) goto Done;
1010 pnew = PyString_AsString(newfmt);
1011 usednew = 0;
1012
1013 pin = PyString_AsString(format);
1014 while ((ch = *pin++) != '\0') {
1015 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +00001016 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001017 ntoappend = 1;
1018 }
1019 else if ((ch = *pin++) == '\0') {
1020 /* There's a lone trailing %; doesn't make sense. */
1021 PyErr_SetString(PyExc_ValueError, "strftime format "
1022 "ends with raw %");
1023 goto Done;
1024 }
1025 /* A % has been seen and ch is the character after it. */
1026 else if (ch == 'z') {
1027 if (zreplacement == NULL) {
1028 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +00001029 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +00001030 PyObject *tzinfo = get_tzinfo_member(object);
1031 zreplacement = PyString_FromString("");
1032 if (zreplacement == NULL) goto Done;
1033 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001034 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001035 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001036 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001037 "",
1038 tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00001039 tzinfoarg) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001040 goto Done;
1041 Py_DECREF(zreplacement);
1042 zreplacement = PyString_FromString(buf);
1043 if (zreplacement == NULL) goto Done;
1044 }
1045 }
1046 assert(zreplacement != NULL);
1047 ptoappend = PyString_AsString(zreplacement);
1048 ntoappend = PyString_Size(zreplacement);
1049 }
1050 else if (ch == 'Z') {
1051 /* format tzname */
1052 if (Zreplacement == NULL) {
1053 PyObject *tzinfo = get_tzinfo_member(object);
1054 Zreplacement = PyString_FromString("");
1055 if (Zreplacement == NULL) goto Done;
1056 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001057 PyObject *temp;
1058 assert(tzinfoarg != NULL);
1059 temp = call_tzname(tzinfo, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001060 if (temp == NULL) goto Done;
1061 if (temp != Py_None) {
1062 assert(PyString_Check(temp));
1063 /* Since the tzname is getting
1064 * stuffed into the format, we
1065 * have to double any % signs
1066 * so that strftime doesn't
1067 * treat them as format codes.
1068 */
1069 Py_DECREF(Zreplacement);
1070 Zreplacement = PyObject_CallMethod(
1071 temp, "replace",
1072 "ss", "%", "%%");
1073 Py_DECREF(temp);
1074 if (Zreplacement == NULL)
1075 goto Done;
1076 }
1077 else
1078 Py_DECREF(temp);
1079 }
1080 }
1081 assert(Zreplacement != NULL);
1082 ptoappend = PyString_AsString(Zreplacement);
1083 ntoappend = PyString_Size(Zreplacement);
1084 }
1085 else {
Tim Peters328fff72002-12-20 01:31:27 +00001086 /* percent followed by neither z nor Z */
1087 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001088 ntoappend = 2;
1089 }
1090
1091 /* Append the ntoappend chars starting at ptoappend to
1092 * the new format.
1093 */
1094 assert(ntoappend >= 0);
1095 if (ntoappend == 0)
1096 continue;
1097 while (usednew + ntoappend > totalnew) {
1098 int bigger = totalnew << 1;
1099 if ((bigger >> 1) != totalnew) { /* overflow */
1100 PyErr_NoMemory();
1101 goto Done;
1102 }
1103 if (_PyString_Resize(&newfmt, bigger) < 0)
1104 goto Done;
1105 totalnew = bigger;
1106 pnew = PyString_AsString(newfmt) + usednew;
1107 }
1108 memcpy(pnew, ptoappend, ntoappend);
1109 pnew += ntoappend;
1110 usednew += ntoappend;
1111 assert(usednew <= totalnew);
1112 } /* end while() */
1113
1114 if (_PyString_Resize(&newfmt, usednew) < 0)
1115 goto Done;
1116 {
1117 PyObject *time = PyImport_ImportModule("time");
1118 if (time == NULL)
1119 goto Done;
1120 result = PyObject_CallMethod(time, "strftime", "OO",
1121 newfmt, timetuple);
1122 Py_DECREF(time);
1123 }
1124 Done:
1125 Py_XDECREF(zreplacement);
1126 Py_XDECREF(Zreplacement);
1127 Py_XDECREF(newfmt);
1128 return result;
1129}
1130
1131static char *
1132isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1133{
1134 int x;
1135 x = PyOS_snprintf(buffer, bufflen,
1136 "%04d-%02d-%02d",
1137 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1138 return buffer + x;
1139}
1140
1141static void
1142isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1143{
1144 int us = DATE_GET_MICROSECOND(dt);
1145
1146 PyOS_snprintf(buffer, bufflen,
1147 "%02d:%02d:%02d", /* 8 characters */
1148 DATE_GET_HOUR(dt),
1149 DATE_GET_MINUTE(dt),
1150 DATE_GET_SECOND(dt));
1151 if (us)
1152 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1153}
1154
1155/* ---------------------------------------------------------------------------
1156 * Wrap functions from the time module. These aren't directly available
1157 * from C. Perhaps they should be.
1158 */
1159
1160/* Call time.time() and return its result (a Python float). */
1161static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001162time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001163{
1164 PyObject *result = NULL;
1165 PyObject *time = PyImport_ImportModule("time");
1166
1167 if (time != NULL) {
1168 result = PyObject_CallMethod(time, "time", "()");
1169 Py_DECREF(time);
1170 }
1171 return result;
1172}
1173
1174/* Build a time.struct_time. The weekday and day number are automatically
1175 * computed from the y,m,d args.
1176 */
1177static PyObject *
1178build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1179{
1180 PyObject *time;
1181 PyObject *result = NULL;
1182
1183 time = PyImport_ImportModule("time");
1184 if (time != NULL) {
1185 result = PyObject_CallMethod(time, "struct_time",
1186 "((iiiiiiiii))",
1187 y, m, d,
1188 hh, mm, ss,
1189 weekday(y, m, d),
1190 days_before_month(y, m) + d,
1191 dstflag);
1192 Py_DECREF(time);
1193 }
1194 return result;
1195}
1196
1197/* ---------------------------------------------------------------------------
1198 * Miscellaneous helpers.
1199 */
1200
1201/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1202 * The comparisons here all most naturally compute a cmp()-like result.
1203 * This little helper turns that into a bool result for rich comparisons.
1204 */
1205static PyObject *
1206diff_to_bool(int diff, int op)
1207{
1208 PyObject *result;
1209 int istrue;
1210
1211 switch (op) {
1212 case Py_EQ: istrue = diff == 0; break;
1213 case Py_NE: istrue = diff != 0; break;
1214 case Py_LE: istrue = diff <= 0; break;
1215 case Py_GE: istrue = diff >= 0; break;
1216 case Py_LT: istrue = diff < 0; break;
1217 case Py_GT: istrue = diff > 0; break;
1218 default:
1219 assert(! "op unknown");
1220 istrue = 0; /* To shut up compiler */
1221 }
1222 result = istrue ? Py_True : Py_False;
1223 Py_INCREF(result);
1224 return result;
1225}
1226
1227/* ---------------------------------------------------------------------------
1228 * Helpers for setting object fields. These work on pointers to the
1229 * appropriate base class.
1230 */
1231
Tim Petersa9bc1682003-01-11 03:39:11 +00001232/* For date and datetime. */
Tim Peters2a799bf2002-12-16 20:18:38 +00001233static void
1234set_date_fields(PyDateTime_Date *self, int y, int m, int d)
1235{
1236 self->hashcode = -1;
1237 SET_YEAR(self, y);
1238 SET_MONTH(self, m);
1239 SET_DAY(self, d);
1240}
1241
Tim Peters2a799bf2002-12-16 20:18:38 +00001242/* ---------------------------------------------------------------------------
1243 * Create various objects, mostly without range checking.
1244 */
1245
1246/* Create a date instance with no range checking. */
1247static PyObject *
1248new_date(int year, int month, int day)
1249{
1250 PyDateTime_Date *self;
1251
1252 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
1253 if (self != NULL)
1254 set_date_fields(self, year, month, day);
1255 return (PyObject *) self;
1256}
1257
1258/* Create a datetime instance with no range checking. */
1259static PyObject *
1260new_datetime(int year, int month, int day, int hour, int minute,
Tim Petersa9bc1682003-01-11 03:39:11 +00001261 int second, int usecond, PyObject *tzinfo)
Tim Peters2a799bf2002-12-16 20:18:38 +00001262{
1263 PyDateTime_DateTime *self;
Tim Petersa9bc1682003-01-11 03:39:11 +00001264 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001265
Tim Petersa9bc1682003-01-11 03:39:11 +00001266 self = (PyDateTime_DateTime *)PyObject_MALLOC(aware ?
1267 sizeof(PyDateTime_DateTime) :
1268 sizeof(_PyDateTime_BaseDateTime));
1269 if (self == NULL)
1270 return PyErr_NoMemory();
1271 self->hastzinfo = aware;
1272 set_date_fields((PyDateTime_Date *)self, year, month, day);
1273 DATE_SET_HOUR(self, hour);
1274 DATE_SET_MINUTE(self, minute);
1275 DATE_SET_SECOND(self, second);
1276 DATE_SET_MICROSECOND(self, usecond);
1277 if (aware) {
Tim Peters2a799bf2002-12-16 20:18:38 +00001278 Py_INCREF(tzinfo);
1279 self->tzinfo = tzinfo;
1280 }
Tim Petersa9bc1682003-01-11 03:39:11 +00001281 return (PyObject *)PyObject_INIT(self, &PyDateTime_DateTimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00001282}
1283
1284/* Create a time instance with no range checking. */
1285static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00001286new_time(int hour, int minute, int second, int usecond, PyObject *tzinfo)
Tim Peters2a799bf2002-12-16 20:18:38 +00001287{
1288 PyDateTime_Time *self;
Tim Peters37f39822003-01-10 03:49:02 +00001289 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001290
Tim Peters37f39822003-01-10 03:49:02 +00001291 self = (PyDateTime_Time *)PyObject_MALLOC(aware ?
1292 sizeof(PyDateTime_Time) :
1293 sizeof(_PyDateTime_BaseTime));
1294 if (self == NULL)
1295 return PyErr_NoMemory();
1296 self->hastzinfo = aware;
Tim Petersa9bc1682003-01-11 03:39:11 +00001297 self->hashcode = -1;
1298 TIME_SET_HOUR(self, hour);
1299 TIME_SET_MINUTE(self, minute);
1300 TIME_SET_SECOND(self, second);
1301 TIME_SET_MICROSECOND(self, usecond);
Tim Peters37f39822003-01-10 03:49:02 +00001302 if (aware) {
Tim Peters2a799bf2002-12-16 20:18:38 +00001303 Py_INCREF(tzinfo);
1304 self->tzinfo = tzinfo;
1305 }
Tim Peters37f39822003-01-10 03:49:02 +00001306 return (PyObject *)PyObject_INIT(self, &PyDateTime_TimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00001307}
1308
1309/* Create a timedelta instance. Normalize the members iff normalize is
1310 * true. Passing false is a speed optimization, if you know for sure
1311 * that seconds and microseconds are already in their proper ranges. In any
1312 * case, raises OverflowError and returns NULL if the normalized days is out
1313 * of range).
1314 */
1315static PyObject *
1316new_delta(int days, int seconds, int microseconds, int normalize)
1317{
1318 PyDateTime_Delta *self;
1319
1320 if (normalize)
1321 normalize_d_s_us(&days, &seconds, &microseconds);
1322 assert(0 <= seconds && seconds < 24*3600);
1323 assert(0 <= microseconds && microseconds < 1000000);
1324
1325 if (check_delta_day_range(days) < 0)
1326 return NULL;
1327
1328 self = PyObject_New(PyDateTime_Delta, &PyDateTime_DeltaType);
1329 if (self != NULL) {
1330 self->hashcode = -1;
1331 SET_TD_DAYS(self, days);
1332 SET_TD_SECONDS(self, seconds);
1333 SET_TD_MICROSECONDS(self, microseconds);
1334 }
1335 return (PyObject *) self;
1336}
1337
1338
1339/* ---------------------------------------------------------------------------
1340 * Cached Python objects; these are set by the module init function.
1341 */
1342
1343/* Conversion factors. */
1344static PyObject *us_per_us = NULL; /* 1 */
1345static PyObject *us_per_ms = NULL; /* 1000 */
1346static PyObject *us_per_second = NULL; /* 1000000 */
1347static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1348static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1349static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1350static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1351static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1352
1353/* Callables to support unpickling. */
1354static PyObject *date_unpickler_object = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00001355static PyObject *datetime_unpickler_object = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001356static PyObject *tzinfo_unpickler_object = NULL;
Tim Peters37f39822003-01-10 03:49:02 +00001357static PyObject *time_unpickler_object = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001358
1359/* ---------------------------------------------------------------------------
1360 * Class implementations.
1361 */
1362
1363/*
1364 * PyDateTime_Delta implementation.
1365 */
1366
1367/* Convert a timedelta to a number of us,
1368 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1369 * as a Python int or long.
1370 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1371 * due to ubiquitous overflow possibilities.
1372 */
1373static PyObject *
1374delta_to_microseconds(PyDateTime_Delta *self)
1375{
1376 PyObject *x1 = NULL;
1377 PyObject *x2 = NULL;
1378 PyObject *x3 = NULL;
1379 PyObject *result = NULL;
1380
1381 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1382 if (x1 == NULL)
1383 goto Done;
1384 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1385 if (x2 == NULL)
1386 goto Done;
1387 Py_DECREF(x1);
1388 x1 = NULL;
1389
1390 /* x2 has days in seconds */
1391 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1392 if (x1 == NULL)
1393 goto Done;
1394 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1395 if (x3 == NULL)
1396 goto Done;
1397 Py_DECREF(x1);
1398 Py_DECREF(x2);
1399 x1 = x2 = NULL;
1400
1401 /* x3 has days+seconds in seconds */
1402 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1403 if (x1 == NULL)
1404 goto Done;
1405 Py_DECREF(x3);
1406 x3 = NULL;
1407
1408 /* x1 has days+seconds in us */
1409 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1410 if (x2 == NULL)
1411 goto Done;
1412 result = PyNumber_Add(x1, x2);
1413
1414Done:
1415 Py_XDECREF(x1);
1416 Py_XDECREF(x2);
1417 Py_XDECREF(x3);
1418 return result;
1419}
1420
1421/* Convert a number of us (as a Python int or long) to a timedelta.
1422 */
1423static PyObject *
1424microseconds_to_delta(PyObject *pyus)
1425{
1426 int us;
1427 int s;
1428 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001429 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001430
1431 PyObject *tuple = NULL;
1432 PyObject *num = NULL;
1433 PyObject *result = NULL;
1434
1435 tuple = PyNumber_Divmod(pyus, us_per_second);
1436 if (tuple == NULL)
1437 goto Done;
1438
1439 num = PyTuple_GetItem(tuple, 1); /* us */
1440 if (num == NULL)
1441 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001442 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001443 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001444 if (temp == -1 && PyErr_Occurred())
1445 goto Done;
1446 assert(0 <= temp && temp < 1000000);
1447 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001448 if (us < 0) {
1449 /* The divisor was positive, so this must be an error. */
1450 assert(PyErr_Occurred());
1451 goto Done;
1452 }
1453
1454 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1455 if (num == NULL)
1456 goto Done;
1457 Py_INCREF(num);
1458 Py_DECREF(tuple);
1459
1460 tuple = PyNumber_Divmod(num, seconds_per_day);
1461 if (tuple == NULL)
1462 goto Done;
1463 Py_DECREF(num);
1464
1465 num = PyTuple_GetItem(tuple, 1); /* seconds */
1466 if (num == NULL)
1467 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001468 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001469 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001470 if (temp == -1 && PyErr_Occurred())
1471 goto Done;
1472 assert(0 <= temp && temp < 24*3600);
1473 s = (int)temp;
1474
Tim Peters2a799bf2002-12-16 20:18:38 +00001475 if (s < 0) {
1476 /* The divisor was positive, so this must be an error. */
1477 assert(PyErr_Occurred());
1478 goto Done;
1479 }
1480
1481 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1482 if (num == NULL)
1483 goto Done;
1484 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001485 temp = PyLong_AsLong(num);
1486 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001487 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001488 d = (int)temp;
1489 if ((long)d != temp) {
1490 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1491 "large to fit in a C int");
1492 goto Done;
1493 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001494 result = new_delta(d, s, us, 0);
1495
1496Done:
1497 Py_XDECREF(tuple);
1498 Py_XDECREF(num);
1499 return result;
1500}
1501
1502static PyObject *
1503multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1504{
1505 PyObject *pyus_in;
1506 PyObject *pyus_out;
1507 PyObject *result;
1508
1509 pyus_in = delta_to_microseconds(delta);
1510 if (pyus_in == NULL)
1511 return NULL;
1512
1513 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1514 Py_DECREF(pyus_in);
1515 if (pyus_out == NULL)
1516 return NULL;
1517
1518 result = microseconds_to_delta(pyus_out);
1519 Py_DECREF(pyus_out);
1520 return result;
1521}
1522
1523static PyObject *
1524divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1525{
1526 PyObject *pyus_in;
1527 PyObject *pyus_out;
1528 PyObject *result;
1529
1530 pyus_in = delta_to_microseconds(delta);
1531 if (pyus_in == NULL)
1532 return NULL;
1533
1534 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1535 Py_DECREF(pyus_in);
1536 if (pyus_out == NULL)
1537 return NULL;
1538
1539 result = microseconds_to_delta(pyus_out);
1540 Py_DECREF(pyus_out);
1541 return result;
1542}
1543
1544static PyObject *
1545delta_add(PyObject *left, PyObject *right)
1546{
1547 PyObject *result = Py_NotImplemented;
1548
1549 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1550 /* delta + delta */
1551 /* The C-level additions can't overflow because of the
1552 * invariant bounds.
1553 */
1554 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1555 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1556 int microseconds = GET_TD_MICROSECONDS(left) +
1557 GET_TD_MICROSECONDS(right);
1558 result = new_delta(days, seconds, microseconds, 1);
1559 }
1560
1561 if (result == Py_NotImplemented)
1562 Py_INCREF(result);
1563 return result;
1564}
1565
1566static PyObject *
1567delta_negative(PyDateTime_Delta *self)
1568{
1569 return new_delta(-GET_TD_DAYS(self),
1570 -GET_TD_SECONDS(self),
1571 -GET_TD_MICROSECONDS(self),
1572 1);
1573}
1574
1575static PyObject *
1576delta_positive(PyDateTime_Delta *self)
1577{
1578 /* Could optimize this (by returning self) if this isn't a
1579 * subclass -- but who uses unary + ? Approximately nobody.
1580 */
1581 return new_delta(GET_TD_DAYS(self),
1582 GET_TD_SECONDS(self),
1583 GET_TD_MICROSECONDS(self),
1584 0);
1585}
1586
1587static PyObject *
1588delta_abs(PyDateTime_Delta *self)
1589{
1590 PyObject *result;
1591
1592 assert(GET_TD_MICROSECONDS(self) >= 0);
1593 assert(GET_TD_SECONDS(self) >= 0);
1594
1595 if (GET_TD_DAYS(self) < 0)
1596 result = delta_negative(self);
1597 else
1598 result = delta_positive(self);
1599
1600 return result;
1601}
1602
1603static PyObject *
1604delta_subtract(PyObject *left, PyObject *right)
1605{
1606 PyObject *result = Py_NotImplemented;
1607
1608 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1609 /* delta - delta */
1610 PyObject *minus_right = PyNumber_Negative(right);
1611 if (minus_right) {
1612 result = delta_add(left, minus_right);
1613 Py_DECREF(minus_right);
1614 }
1615 else
1616 result = NULL;
1617 }
1618
1619 if (result == Py_NotImplemented)
1620 Py_INCREF(result);
1621 return result;
1622}
1623
1624/* This is more natural as a tp_compare, but doesn't work then: for whatever
1625 * reason, Python's try_3way_compare ignores tp_compare unless
1626 * PyInstance_Check returns true, but these aren't old-style classes.
1627 */
1628static PyObject *
1629delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1630{
1631 int diff;
1632
1633 if (! PyDelta_CheckExact(other)) {
1634 PyErr_Format(PyExc_TypeError,
1635 "can't compare %s to %s instance",
1636 self->ob_type->tp_name, other->ob_type->tp_name);
1637 return NULL;
1638 }
1639 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1640 if (diff == 0) {
1641 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1642 if (diff == 0)
1643 diff = GET_TD_MICROSECONDS(self) -
1644 GET_TD_MICROSECONDS(other);
1645 }
1646 return diff_to_bool(diff, op);
1647}
1648
1649static PyObject *delta_getstate(PyDateTime_Delta *self);
1650
1651static long
1652delta_hash(PyDateTime_Delta *self)
1653{
1654 if (self->hashcode == -1) {
1655 PyObject *temp = delta_getstate(self);
1656 if (temp != NULL) {
1657 self->hashcode = PyObject_Hash(temp);
1658 Py_DECREF(temp);
1659 }
1660 }
1661 return self->hashcode;
1662}
1663
1664static PyObject *
1665delta_multiply(PyObject *left, PyObject *right)
1666{
1667 PyObject *result = Py_NotImplemented;
1668
1669 if (PyDelta_Check(left)) {
1670 /* delta * ??? */
1671 if (PyInt_Check(right) || PyLong_Check(right))
1672 result = multiply_int_timedelta(right,
1673 (PyDateTime_Delta *) left);
1674 }
1675 else if (PyInt_Check(left) || PyLong_Check(left))
1676 result = multiply_int_timedelta(left,
1677 (PyDateTime_Delta *) right);
1678
1679 if (result == Py_NotImplemented)
1680 Py_INCREF(result);
1681 return result;
1682}
1683
1684static PyObject *
1685delta_divide(PyObject *left, PyObject *right)
1686{
1687 PyObject *result = Py_NotImplemented;
1688
1689 if (PyDelta_Check(left)) {
1690 /* delta * ??? */
1691 if (PyInt_Check(right) || PyLong_Check(right))
1692 result = divide_timedelta_int(
1693 (PyDateTime_Delta *)left,
1694 right);
1695 }
1696
1697 if (result == Py_NotImplemented)
1698 Py_INCREF(result);
1699 return result;
1700}
1701
1702/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1703 * timedelta constructor. sofar is the # of microseconds accounted for
1704 * so far, and there are factor microseconds per current unit, the number
1705 * of which is given by num. num * factor is added to sofar in a
1706 * numerically careful way, and that's the result. Any fractional
1707 * microseconds left over (this can happen if num is a float type) are
1708 * added into *leftover.
1709 * Note that there are many ways this can give an error (NULL) return.
1710 */
1711static PyObject *
1712accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1713 double *leftover)
1714{
1715 PyObject *prod;
1716 PyObject *sum;
1717
1718 assert(num != NULL);
1719
1720 if (PyInt_Check(num) || PyLong_Check(num)) {
1721 prod = PyNumber_Multiply(num, factor);
1722 if (prod == NULL)
1723 return NULL;
1724 sum = PyNumber_Add(sofar, prod);
1725 Py_DECREF(prod);
1726 return sum;
1727 }
1728
1729 if (PyFloat_Check(num)) {
1730 double dnum;
1731 double fracpart;
1732 double intpart;
1733 PyObject *x;
1734 PyObject *y;
1735
1736 /* The Plan: decompose num into an integer part and a
1737 * fractional part, num = intpart + fracpart.
1738 * Then num * factor ==
1739 * intpart * factor + fracpart * factor
1740 * and the LHS can be computed exactly in long arithmetic.
1741 * The RHS is again broken into an int part and frac part.
1742 * and the frac part is added into *leftover.
1743 */
1744 dnum = PyFloat_AsDouble(num);
1745 if (dnum == -1.0 && PyErr_Occurred())
1746 return NULL;
1747 fracpart = modf(dnum, &intpart);
1748 x = PyLong_FromDouble(intpart);
1749 if (x == NULL)
1750 return NULL;
1751
1752 prod = PyNumber_Multiply(x, factor);
1753 Py_DECREF(x);
1754 if (prod == NULL)
1755 return NULL;
1756
1757 sum = PyNumber_Add(sofar, prod);
1758 Py_DECREF(prod);
1759 if (sum == NULL)
1760 return NULL;
1761
1762 if (fracpart == 0.0)
1763 return sum;
1764 /* So far we've lost no information. Dealing with the
1765 * fractional part requires float arithmetic, and may
1766 * lose a little info.
1767 */
1768 assert(PyInt_Check(factor) || PyLong_Check(factor));
1769 if (PyInt_Check(factor))
1770 dnum = (double)PyInt_AsLong(factor);
1771 else
1772 dnum = PyLong_AsDouble(factor);
1773
1774 dnum *= fracpart;
1775 fracpart = modf(dnum, &intpart);
1776 x = PyLong_FromDouble(intpart);
1777 if (x == NULL) {
1778 Py_DECREF(sum);
1779 return NULL;
1780 }
1781
1782 y = PyNumber_Add(sum, x);
1783 Py_DECREF(sum);
1784 Py_DECREF(x);
1785 *leftover += fracpart;
1786 return y;
1787 }
1788
1789 PyErr_Format(PyExc_TypeError,
1790 "unsupported type for timedelta %s component: %s",
1791 tag, num->ob_type->tp_name);
1792 return NULL;
1793}
1794
1795static PyObject *
1796delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1797{
1798 PyObject *self = NULL;
1799
1800 /* Argument objects. */
1801 PyObject *day = NULL;
1802 PyObject *second = NULL;
1803 PyObject *us = NULL;
1804 PyObject *ms = NULL;
1805 PyObject *minute = NULL;
1806 PyObject *hour = NULL;
1807 PyObject *week = NULL;
1808
1809 PyObject *x = NULL; /* running sum of microseconds */
1810 PyObject *y = NULL; /* temp sum of microseconds */
1811 double leftover_us = 0.0;
1812
1813 static char *keywords[] = {
1814 "days", "seconds", "microseconds", "milliseconds",
1815 "minutes", "hours", "weeks", NULL
1816 };
1817
1818 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1819 keywords,
1820 &day, &second, &us,
1821 &ms, &minute, &hour, &week) == 0)
1822 goto Done;
1823
1824 x = PyInt_FromLong(0);
1825 if (x == NULL)
1826 goto Done;
1827
1828#define CLEANUP \
1829 Py_DECREF(x); \
1830 x = y; \
1831 if (x == NULL) \
1832 goto Done
1833
1834 if (us) {
1835 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1836 CLEANUP;
1837 }
1838 if (ms) {
1839 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1840 CLEANUP;
1841 }
1842 if (second) {
1843 y = accum("seconds", x, second, us_per_second, &leftover_us);
1844 CLEANUP;
1845 }
1846 if (minute) {
1847 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1848 CLEANUP;
1849 }
1850 if (hour) {
1851 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1852 CLEANUP;
1853 }
1854 if (day) {
1855 y = accum("days", x, day, us_per_day, &leftover_us);
1856 CLEANUP;
1857 }
1858 if (week) {
1859 y = accum("weeks", x, week, us_per_week, &leftover_us);
1860 CLEANUP;
1861 }
1862 if (leftover_us) {
1863 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001864 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001865 if (temp == NULL) {
1866 Py_DECREF(x);
1867 goto Done;
1868 }
1869 y = PyNumber_Add(x, temp);
1870 Py_DECREF(temp);
1871 CLEANUP;
1872 }
1873
1874 self = microseconds_to_delta(x);
1875 Py_DECREF(x);
1876Done:
1877 return self;
1878
1879#undef CLEANUP
1880}
1881
1882static int
1883delta_nonzero(PyDateTime_Delta *self)
1884{
1885 return (GET_TD_DAYS(self) != 0
1886 || GET_TD_SECONDS(self) != 0
1887 || GET_TD_MICROSECONDS(self) != 0);
1888}
1889
1890static PyObject *
1891delta_repr(PyDateTime_Delta *self)
1892{
1893 if (GET_TD_MICROSECONDS(self) != 0)
1894 return PyString_FromFormat("%s(%d, %d, %d)",
1895 self->ob_type->tp_name,
1896 GET_TD_DAYS(self),
1897 GET_TD_SECONDS(self),
1898 GET_TD_MICROSECONDS(self));
1899 if (GET_TD_SECONDS(self) != 0)
1900 return PyString_FromFormat("%s(%d, %d)",
1901 self->ob_type->tp_name,
1902 GET_TD_DAYS(self),
1903 GET_TD_SECONDS(self));
1904
1905 return PyString_FromFormat("%s(%d)",
1906 self->ob_type->tp_name,
1907 GET_TD_DAYS(self));
1908}
1909
1910static PyObject *
1911delta_str(PyDateTime_Delta *self)
1912{
1913 int days = GET_TD_DAYS(self);
1914 int seconds = GET_TD_SECONDS(self);
1915 int us = GET_TD_MICROSECONDS(self);
1916 int hours;
1917 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001918 char buf[100];
1919 char *pbuf = buf;
1920 size_t buflen = sizeof(buf);
1921 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001922
1923 minutes = divmod(seconds, 60, &seconds);
1924 hours = divmod(minutes, 60, &minutes);
1925
1926 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00001927 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
1928 (days == 1 || days == -1) ? "" : "s");
1929 if (n < 0 || (size_t)n >= buflen)
1930 goto Fail;
1931 pbuf += n;
1932 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001933 }
1934
Tim Petersba873472002-12-18 20:19:21 +00001935 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
1936 hours, minutes, seconds);
1937 if (n < 0 || (size_t)n >= buflen)
1938 goto Fail;
1939 pbuf += n;
1940 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001941
1942 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00001943 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
1944 if (n < 0 || (size_t)n >= buflen)
1945 goto Fail;
1946 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001947 }
1948
Tim Petersba873472002-12-18 20:19:21 +00001949 return PyString_FromStringAndSize(buf, pbuf - buf);
1950
1951 Fail:
1952 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
1953 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001954}
1955
1956/* Pickle support. Quite a maze! While __getstate__/__setstate__ sufficed
1957 * in the Python implementation, the C implementation also requires
1958 * __reduce__, and a __safe_for_unpickling__ attr in the type object.
1959 */
1960static PyObject *
1961delta_getstate(PyDateTime_Delta *self)
1962{
1963 return Py_BuildValue("iii", GET_TD_DAYS(self),
1964 GET_TD_SECONDS(self),
1965 GET_TD_MICROSECONDS(self));
1966}
1967
1968static PyObject *
1969delta_setstate(PyDateTime_Delta *self, PyObject *state)
1970{
1971 int day;
1972 int second;
1973 int us;
1974
1975 if (!PyArg_ParseTuple(state, "iii:__setstate__", &day, &second, &us))
1976 return NULL;
1977
1978 self->hashcode = -1;
1979 SET_TD_DAYS(self, day);
1980 SET_TD_SECONDS(self, second);
1981 SET_TD_MICROSECONDS(self, us);
1982
1983 Py_INCREF(Py_None);
1984 return Py_None;
1985}
1986
1987static PyObject *
1988delta_reduce(PyDateTime_Delta* self)
1989{
1990 PyObject* result = NULL;
1991 PyObject* state = delta_getstate(self);
1992
1993 if (state != NULL) {
1994 /* The funky "()" in the format string creates an empty
1995 * tuple as the 2nd component of the result 3-tuple.
1996 */
1997 result = Py_BuildValue("O()O", self->ob_type, state);
1998 Py_DECREF(state);
1999 }
2000 return result;
2001}
2002
2003#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2004
2005static PyMemberDef delta_members[] = {
Neal Norwitzdfb80862002-12-19 02:30:56 +00002006 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002007 PyDoc_STR("Number of days.")},
2008
Neal Norwitzdfb80862002-12-19 02:30:56 +00002009 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002010 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2011
Neal Norwitzdfb80862002-12-19 02:30:56 +00002012 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002013 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2014 {NULL}
2015};
2016
2017static PyMethodDef delta_methods[] = {
2018 {"__setstate__", (PyCFunction)delta_setstate, METH_O,
2019 PyDoc_STR("__setstate__(state)")},
2020
2021 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2022 PyDoc_STR("__setstate__(state)")},
2023
2024 {"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS,
2025 PyDoc_STR("__getstate__() -> state")},
2026 {NULL, NULL},
2027};
2028
2029static char delta_doc[] =
2030PyDoc_STR("Difference between two datetime values.");
2031
2032static PyNumberMethods delta_as_number = {
2033 delta_add, /* nb_add */
2034 delta_subtract, /* nb_subtract */
2035 delta_multiply, /* nb_multiply */
2036 delta_divide, /* nb_divide */
2037 0, /* nb_remainder */
2038 0, /* nb_divmod */
2039 0, /* nb_power */
2040 (unaryfunc)delta_negative, /* nb_negative */
2041 (unaryfunc)delta_positive, /* nb_positive */
2042 (unaryfunc)delta_abs, /* nb_absolute */
2043 (inquiry)delta_nonzero, /* nb_nonzero */
2044 0, /*nb_invert*/
2045 0, /*nb_lshift*/
2046 0, /*nb_rshift*/
2047 0, /*nb_and*/
2048 0, /*nb_xor*/
2049 0, /*nb_or*/
2050 0, /*nb_coerce*/
2051 0, /*nb_int*/
2052 0, /*nb_long*/
2053 0, /*nb_float*/
2054 0, /*nb_oct*/
2055 0, /*nb_hex*/
2056 0, /*nb_inplace_add*/
2057 0, /*nb_inplace_subtract*/
2058 0, /*nb_inplace_multiply*/
2059 0, /*nb_inplace_divide*/
2060 0, /*nb_inplace_remainder*/
2061 0, /*nb_inplace_power*/
2062 0, /*nb_inplace_lshift*/
2063 0, /*nb_inplace_rshift*/
2064 0, /*nb_inplace_and*/
2065 0, /*nb_inplace_xor*/
2066 0, /*nb_inplace_or*/
2067 delta_divide, /* nb_floor_divide */
2068 0, /* nb_true_divide */
2069 0, /* nb_inplace_floor_divide */
2070 0, /* nb_inplace_true_divide */
2071};
2072
2073static PyTypeObject PyDateTime_DeltaType = {
2074 PyObject_HEAD_INIT(NULL)
2075 0, /* ob_size */
2076 "datetime.timedelta", /* tp_name */
2077 sizeof(PyDateTime_Delta), /* tp_basicsize */
2078 0, /* tp_itemsize */
2079 0, /* tp_dealloc */
2080 0, /* tp_print */
2081 0, /* tp_getattr */
2082 0, /* tp_setattr */
2083 0, /* tp_compare */
2084 (reprfunc)delta_repr, /* tp_repr */
2085 &delta_as_number, /* tp_as_number */
2086 0, /* tp_as_sequence */
2087 0, /* tp_as_mapping */
2088 (hashfunc)delta_hash, /* tp_hash */
2089 0, /* tp_call */
2090 (reprfunc)delta_str, /* tp_str */
2091 PyObject_GenericGetAttr, /* tp_getattro */
2092 0, /* tp_setattro */
2093 0, /* tp_as_buffer */
2094 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
2095 delta_doc, /* tp_doc */
2096 0, /* tp_traverse */
2097 0, /* tp_clear */
2098 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2099 0, /* tp_weaklistoffset */
2100 0, /* tp_iter */
2101 0, /* tp_iternext */
2102 delta_methods, /* tp_methods */
2103 delta_members, /* tp_members */
2104 0, /* tp_getset */
2105 0, /* tp_base */
2106 0, /* tp_dict */
2107 0, /* tp_descr_get */
2108 0, /* tp_descr_set */
2109 0, /* tp_dictoffset */
2110 0, /* tp_init */
2111 0, /* tp_alloc */
2112 delta_new, /* tp_new */
2113 _PyObject_Del, /* tp_free */
2114};
2115
2116/*
2117 * PyDateTime_Date implementation.
2118 */
2119
2120/* Accessor properties. */
2121
2122static PyObject *
2123date_year(PyDateTime_Date *self, void *unused)
2124{
2125 return PyInt_FromLong(GET_YEAR(self));
2126}
2127
2128static PyObject *
2129date_month(PyDateTime_Date *self, void *unused)
2130{
2131 return PyInt_FromLong(GET_MONTH(self));
2132}
2133
2134static PyObject *
2135date_day(PyDateTime_Date *self, void *unused)
2136{
2137 return PyInt_FromLong(GET_DAY(self));
2138}
2139
2140static PyGetSetDef date_getset[] = {
2141 {"year", (getter)date_year},
2142 {"month", (getter)date_month},
2143 {"day", (getter)date_day},
2144 {NULL}
2145};
2146
2147/* Constructors. */
2148
Tim Peters12bf3392002-12-24 05:41:27 +00002149static char *date_kws[] = {"year", "month", "day", NULL};
2150
Tim Peters2a799bf2002-12-16 20:18:38 +00002151static PyObject *
2152date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2153{
2154 PyObject *self = NULL;
2155 int year;
2156 int month;
2157 int day;
2158
Tim Peters12bf3392002-12-24 05:41:27 +00002159 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002160 &year, &month, &day)) {
2161 if (check_date_args(year, month, day) < 0)
2162 return NULL;
2163 self = new_date(year, month, day);
2164 }
2165 return self;
2166}
2167
2168/* Return new date from localtime(t). */
2169static PyObject *
2170date_local_from_time_t(PyObject *cls, time_t t)
2171{
2172 struct tm *tm;
2173 PyObject *result = NULL;
2174
2175 tm = localtime(&t);
2176 if (tm)
2177 result = PyObject_CallFunction(cls, "iii",
2178 tm->tm_year + 1900,
2179 tm->tm_mon + 1,
2180 tm->tm_mday);
2181 else
2182 PyErr_SetString(PyExc_ValueError,
2183 "timestamp out of range for "
2184 "platform localtime() function");
2185 return result;
2186}
2187
2188/* Return new date from current time.
2189 * We say this is equivalent to fromtimestamp(time.time()), and the
2190 * only way to be sure of that is to *call* time.time(). That's not
2191 * generally the same as calling C's time.
2192 */
2193static PyObject *
2194date_today(PyObject *cls, PyObject *dummy)
2195{
2196 PyObject *time;
2197 PyObject *result;
2198
2199 time = time_time();
2200 if (time == NULL)
2201 return NULL;
2202
2203 /* Note well: today() is a class method, so this may not call
2204 * date.fromtimestamp. For example, it may call
2205 * datetime.fromtimestamp. That's why we need all the accuracy
2206 * time.time() delivers; if someone were gonzo about optimization,
2207 * date.today() could get away with plain C time().
2208 */
2209 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2210 Py_DECREF(time);
2211 return result;
2212}
2213
2214/* Return new date from given timestamp (Python timestamp -- a double). */
2215static PyObject *
2216date_fromtimestamp(PyObject *cls, PyObject *args)
2217{
2218 double timestamp;
2219 PyObject *result = NULL;
2220
2221 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2222 result = date_local_from_time_t(cls, (time_t)timestamp);
2223 return result;
2224}
2225
2226/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2227 * the ordinal is out of range.
2228 */
2229static PyObject *
2230date_fromordinal(PyObject *cls, PyObject *args)
2231{
2232 PyObject *result = NULL;
2233 int ordinal;
2234
2235 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2236 int year;
2237 int month;
2238 int day;
2239
2240 if (ordinal < 1)
2241 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2242 ">= 1");
2243 else {
2244 ord_to_ymd(ordinal, &year, &month, &day);
2245 result = PyObject_CallFunction(cls, "iii",
2246 year, month, day);
2247 }
2248 }
2249 return result;
2250}
2251
2252/*
2253 * Date arithmetic.
2254 */
2255
2256/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2257 * instead.
2258 */
2259static PyObject *
2260add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2261{
2262 PyObject *result = NULL;
2263 int year = GET_YEAR(date);
2264 int month = GET_MONTH(date);
2265 int deltadays = GET_TD_DAYS(delta);
2266 /* C-level overflow is impossible because |deltadays| < 1e9. */
2267 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2268
2269 if (normalize_date(&year, &month, &day) >= 0)
2270 result = new_date(year, month, day);
2271 return result;
2272}
2273
2274static PyObject *
2275date_add(PyObject *left, PyObject *right)
2276{
2277 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2278 Py_INCREF(Py_NotImplemented);
2279 return Py_NotImplemented;
2280 }
2281 if (PyDate_CheckExact(left)) {
2282 /* date + ??? */
2283 if (PyDelta_Check(right))
2284 /* date + delta */
2285 return add_date_timedelta((PyDateTime_Date *) left,
2286 (PyDateTime_Delta *) right,
2287 0);
2288 }
2289 else {
2290 /* ??? + date
2291 * 'right' must be one of us, or we wouldn't have been called
2292 */
2293 if (PyDelta_Check(left))
2294 /* delta + date */
2295 return add_date_timedelta((PyDateTime_Date *) right,
2296 (PyDateTime_Delta *) left,
2297 0);
2298 }
2299 Py_INCREF(Py_NotImplemented);
2300 return Py_NotImplemented;
2301}
2302
2303static PyObject *
2304date_subtract(PyObject *left, PyObject *right)
2305{
2306 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2307 Py_INCREF(Py_NotImplemented);
2308 return Py_NotImplemented;
2309 }
2310 if (PyDate_CheckExact(left)) {
2311 if (PyDate_CheckExact(right)) {
2312 /* date - date */
2313 int left_ord = ymd_to_ord(GET_YEAR(left),
2314 GET_MONTH(left),
2315 GET_DAY(left));
2316 int right_ord = ymd_to_ord(GET_YEAR(right),
2317 GET_MONTH(right),
2318 GET_DAY(right));
2319 return new_delta(left_ord - right_ord, 0, 0, 0);
2320 }
2321 if (PyDelta_Check(right)) {
2322 /* date - delta */
2323 return add_date_timedelta((PyDateTime_Date *) left,
2324 (PyDateTime_Delta *) right,
2325 1);
2326 }
2327 }
2328 Py_INCREF(Py_NotImplemented);
2329 return Py_NotImplemented;
2330}
2331
2332
2333/* Various ways to turn a date into a string. */
2334
2335static PyObject *
2336date_repr(PyDateTime_Date *self)
2337{
2338 char buffer[1028];
2339 char *typename;
2340
2341 typename = self->ob_type->tp_name;
2342 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2343 typename,
2344 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2345
2346 return PyString_FromString(buffer);
2347}
2348
2349static PyObject *
2350date_isoformat(PyDateTime_Date *self)
2351{
2352 char buffer[128];
2353
2354 isoformat_date(self, buffer, sizeof(buffer));
2355 return PyString_FromString(buffer);
2356}
2357
2358/* str() calls the appropriate isofomat() method. */
2359static PyObject *
2360date_str(PyDateTime_Date *self)
2361{
2362 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2363}
2364
2365
2366static PyObject *
2367date_ctime(PyDateTime_Date *self)
2368{
2369 return format_ctime(self, 0, 0, 0);
2370}
2371
2372static PyObject *
2373date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2374{
2375 /* This method can be inherited, and needs to call the
2376 * timetuple() method appropriate to self's class.
2377 */
2378 PyObject *result;
2379 PyObject *format;
2380 PyObject *tuple;
2381 static char *keywords[] = {"format", NULL};
2382
2383 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2384 &PyString_Type, &format))
2385 return NULL;
2386
2387 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2388 if (tuple == NULL)
2389 return NULL;
Tim Petersbad8ff02002-12-30 20:52:32 +00002390 result = wrap_strftime((PyObject *)self, format, tuple,
2391 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002392 Py_DECREF(tuple);
2393 return result;
2394}
2395
2396/* ISO methods. */
2397
2398static PyObject *
2399date_isoweekday(PyDateTime_Date *self)
2400{
2401 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2402
2403 return PyInt_FromLong(dow + 1);
2404}
2405
2406static PyObject *
2407date_isocalendar(PyDateTime_Date *self)
2408{
2409 int year = GET_YEAR(self);
2410 int week1_monday = iso_week1_monday(year);
2411 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2412 int week;
2413 int day;
2414
2415 week = divmod(today - week1_monday, 7, &day);
2416 if (week < 0) {
2417 --year;
2418 week1_monday = iso_week1_monday(year);
2419 week = divmod(today - week1_monday, 7, &day);
2420 }
2421 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2422 ++year;
2423 week = 0;
2424 }
2425 return Py_BuildValue("iii", year, week + 1, day + 1);
2426}
2427
2428/* Miscellaneous methods. */
2429
2430/* This is more natural as a tp_compare, but doesn't work then: for whatever
2431 * reason, Python's try_3way_compare ignores tp_compare unless
2432 * PyInstance_Check returns true, but these aren't old-style classes.
2433 */
2434static PyObject *
2435date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2436{
2437 int diff;
2438
2439 if (! PyDate_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00002440 if (PyObject_HasAttrString(other, "timetuple")) {
2441 /* A hook for other kinds of date objects. */
2442 Py_INCREF(Py_NotImplemented);
2443 return Py_NotImplemented;
2444 }
2445 /* Stop this from falling back to address comparison. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002446 PyErr_Format(PyExc_TypeError,
Tim Peters8d81a012003-01-24 22:36:34 +00002447 "can't compare '%s' to '%s'",
2448 self->ob_type->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002449 other->ob_type->tp_name);
2450 return NULL;
2451 }
2452 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2453 _PyDateTime_DATE_DATASIZE);
2454 return diff_to_bool(diff, op);
2455}
2456
2457static PyObject *
2458date_timetuple(PyDateTime_Date *self)
2459{
2460 return build_struct_time(GET_YEAR(self),
2461 GET_MONTH(self),
2462 GET_DAY(self),
2463 0, 0, 0, -1);
2464}
2465
Tim Peters12bf3392002-12-24 05:41:27 +00002466static PyObject *
2467date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2468{
2469 PyObject *clone;
2470 PyObject *tuple;
2471 int year = GET_YEAR(self);
2472 int month = GET_MONTH(self);
2473 int day = GET_DAY(self);
2474
2475 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2476 &year, &month, &day))
2477 return NULL;
2478 tuple = Py_BuildValue("iii", year, month, day);
2479 if (tuple == NULL)
2480 return NULL;
2481 clone = date_new(self->ob_type, tuple, NULL);
2482 Py_DECREF(tuple);
2483 return clone;
2484}
2485
Tim Peters2a799bf2002-12-16 20:18:38 +00002486static PyObject *date_getstate(PyDateTime_Date *self);
2487
2488static long
2489date_hash(PyDateTime_Date *self)
2490{
2491 if (self->hashcode == -1) {
2492 PyObject *temp = date_getstate(self);
2493 if (temp != NULL) {
2494 self->hashcode = PyObject_Hash(temp);
2495 Py_DECREF(temp);
2496 }
2497 }
2498 return self->hashcode;
2499}
2500
2501static PyObject *
2502date_toordinal(PyDateTime_Date *self)
2503{
2504 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2505 GET_DAY(self)));
2506}
2507
2508static PyObject *
2509date_weekday(PyDateTime_Date *self)
2510{
2511 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2512
2513 return PyInt_FromLong(dow);
2514}
2515
2516/* Pickle support. Quite a maze! */
2517
2518static PyObject *
2519date_getstate(PyDateTime_Date *self)
2520{
Jack Jansenb8941f22003-01-08 16:28:45 +00002521 return PyString_FromStringAndSize((char *)self->data,
Tim Peters2a799bf2002-12-16 20:18:38 +00002522 _PyDateTime_DATE_DATASIZE);
2523}
2524
2525static PyObject *
2526date_setstate(PyDateTime_Date *self, PyObject *state)
2527{
2528 const int len = PyString_Size(state);
2529 unsigned char *pdata = (unsigned char*)PyString_AsString(state);
2530
2531 if (! PyString_Check(state) ||
2532 len != _PyDateTime_DATE_DATASIZE) {
2533 PyErr_SetString(PyExc_TypeError,
2534 "bad argument to date.__setstate__");
2535 return NULL;
2536 }
2537 memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE);
2538 self->hashcode = -1;
2539
2540 Py_INCREF(Py_None);
2541 return Py_None;
2542}
2543
2544/* XXX This seems a ridiculously inefficient way to pickle a short string. */
2545static PyObject *
2546date_pickler(PyObject *module, PyDateTime_Date *date)
2547{
2548 PyObject *state;
2549 PyObject *result = NULL;
2550
2551 if (! PyDate_CheckExact(date)) {
2552 PyErr_Format(PyExc_TypeError,
2553 "bad type passed to date pickler: %s",
2554 date->ob_type->tp_name);
2555 return NULL;
2556 }
2557 state = date_getstate(date);
2558 if (state) {
2559 result = Py_BuildValue("O(O)", date_unpickler_object, state);
2560 Py_DECREF(state);
2561 }
2562 return result;
2563}
2564
2565static PyObject *
2566date_unpickler(PyObject *module, PyObject *arg)
2567{
2568 PyDateTime_Date *self;
2569
2570 if (! PyString_CheckExact(arg)) {
2571 PyErr_Format(PyExc_TypeError,
2572 "bad type passed to date unpickler: %s",
2573 arg->ob_type->tp_name);
2574 return NULL;
2575 }
2576 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
2577 if (self != NULL) {
2578 PyObject *res = date_setstate(self, arg);
2579 if (res == NULL) {
2580 Py_DECREF(self);
2581 return NULL;
2582 }
2583 Py_DECREF(res);
2584 }
2585 return (PyObject *)self;
2586}
2587
2588static PyMethodDef date_methods[] = {
2589 /* Class methods: */
2590 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2591 METH_CLASS,
2592 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2593 "time.time()).")},
2594
2595 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2596 METH_CLASS,
2597 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2598 "ordinal.")},
2599
2600 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2601 PyDoc_STR("Current date or datetime: same as "
2602 "self.__class__.fromtimestamp(time.time()).")},
2603
2604 /* Instance methods: */
2605
2606 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2607 PyDoc_STR("Return ctime() style string.")},
2608
2609 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2610 PyDoc_STR("format -> strftime() style string.")},
2611
2612 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2613 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2614
2615 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2616 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2617 "weekday.")},
2618
2619 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2620 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2621
2622 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2623 PyDoc_STR("Return the day of the week represented by the date.\n"
2624 "Monday == 1 ... Sunday == 7")},
2625
2626 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2627 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2628 "1 is day 1.")},
2629
2630 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2631 PyDoc_STR("Return the day of the week represented by the date.\n"
2632 "Monday == 0 ... Sunday == 6")},
2633
Tim Peters12bf3392002-12-24 05:41:27 +00002634 {"replace", (PyCFunction)date_replace, METH_KEYWORDS,
2635 PyDoc_STR("Return date with new specified fields.")},
2636
Tim Peters2a799bf2002-12-16 20:18:38 +00002637 {"__setstate__", (PyCFunction)date_setstate, METH_O,
2638 PyDoc_STR("__setstate__(state)")},
2639
2640 {"__getstate__", (PyCFunction)date_getstate, METH_NOARGS,
2641 PyDoc_STR("__getstate__() -> state")},
2642
2643 {NULL, NULL}
2644};
2645
2646static char date_doc[] =
2647PyDoc_STR("Basic date type.");
2648
2649static PyNumberMethods date_as_number = {
2650 date_add, /* nb_add */
2651 date_subtract, /* nb_subtract */
2652 0, /* nb_multiply */
2653 0, /* nb_divide */
2654 0, /* nb_remainder */
2655 0, /* nb_divmod */
2656 0, /* nb_power */
2657 0, /* nb_negative */
2658 0, /* nb_positive */
2659 0, /* nb_absolute */
2660 0, /* nb_nonzero */
2661};
2662
2663static PyTypeObject PyDateTime_DateType = {
2664 PyObject_HEAD_INIT(NULL)
2665 0, /* ob_size */
2666 "datetime.date", /* tp_name */
2667 sizeof(PyDateTime_Date), /* tp_basicsize */
2668 0, /* tp_itemsize */
2669 (destructor)PyObject_Del, /* tp_dealloc */
2670 0, /* tp_print */
2671 0, /* tp_getattr */
2672 0, /* tp_setattr */
2673 0, /* tp_compare */
2674 (reprfunc)date_repr, /* tp_repr */
2675 &date_as_number, /* tp_as_number */
2676 0, /* tp_as_sequence */
2677 0, /* tp_as_mapping */
2678 (hashfunc)date_hash, /* tp_hash */
2679 0, /* tp_call */
2680 (reprfunc)date_str, /* tp_str */
2681 PyObject_GenericGetAttr, /* tp_getattro */
2682 0, /* tp_setattro */
2683 0, /* tp_as_buffer */
2684 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2685 Py_TPFLAGS_BASETYPE, /* tp_flags */
2686 date_doc, /* tp_doc */
2687 0, /* tp_traverse */
2688 0, /* tp_clear */
2689 (richcmpfunc)date_richcompare, /* tp_richcompare */
2690 0, /* tp_weaklistoffset */
2691 0, /* tp_iter */
2692 0, /* tp_iternext */
2693 date_methods, /* tp_methods */
2694 0, /* tp_members */
2695 date_getset, /* tp_getset */
2696 0, /* tp_base */
2697 0, /* tp_dict */
2698 0, /* tp_descr_get */
2699 0, /* tp_descr_set */
2700 0, /* tp_dictoffset */
2701 0, /* tp_init */
2702 0, /* tp_alloc */
2703 date_new, /* tp_new */
2704 _PyObject_Del, /* tp_free */
2705};
2706
2707/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002708 * PyDateTime_TZInfo implementation.
2709 */
2710
2711/* This is a pure abstract base class, so doesn't do anything beyond
2712 * raising NotImplemented exceptions. Real tzinfo classes need
2713 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002714 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002715 * be subclasses of this tzinfo class, which is easy and quick to check).
2716 *
2717 * Note: For reasons having to do with pickling of subclasses, we have
2718 * to allow tzinfo objects to be instantiated. This wasn't an issue
2719 * in the Python implementation (__init__() could raise NotImplementedError
2720 * there without ill effect), but doing so in the C implementation hit a
2721 * brick wall.
2722 */
2723
2724static PyObject *
2725tzinfo_nogo(const char* methodname)
2726{
2727 PyErr_Format(PyExc_NotImplementedError,
2728 "a tzinfo subclass must implement %s()",
2729 methodname);
2730 return NULL;
2731}
2732
2733/* Methods. A subclass must implement these. */
2734
Tim Peters52dcce22003-01-23 16:36:11 +00002735static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002736tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2737{
2738 return tzinfo_nogo("tzname");
2739}
2740
Tim Peters52dcce22003-01-23 16:36:11 +00002741static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002742tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2743{
2744 return tzinfo_nogo("utcoffset");
2745}
2746
Tim Peters52dcce22003-01-23 16:36:11 +00002747static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002748tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2749{
2750 return tzinfo_nogo("dst");
2751}
2752
Tim Peters52dcce22003-01-23 16:36:11 +00002753static PyObject *
2754tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2755{
2756 int y, m, d, hh, mm, ss, us;
2757
2758 PyObject *result;
2759 int off, dst;
2760 int none;
2761 int delta;
2762
2763 if (! PyDateTime_Check(dt)) {
2764 PyErr_SetString(PyExc_TypeError,
2765 "fromutc: argument must be a datetime");
2766 return NULL;
2767 }
2768 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2769 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2770 "is not self");
2771 return NULL;
2772 }
2773
2774 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2775 if (off == -1 && PyErr_Occurred())
2776 return NULL;
2777 if (none) {
2778 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2779 "utcoffset() result required");
2780 return NULL;
2781 }
2782
2783 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2784 if (dst == -1 && PyErr_Occurred())
2785 return NULL;
2786 if (none) {
2787 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2788 "dst() result required");
2789 return NULL;
2790 }
2791
2792 y = GET_YEAR(dt);
2793 m = GET_MONTH(dt);
2794 d = GET_DAY(dt);
2795 hh = DATE_GET_HOUR(dt);
2796 mm = DATE_GET_MINUTE(dt);
2797 ss = DATE_GET_SECOND(dt);
2798 us = DATE_GET_MICROSECOND(dt);
2799
2800 delta = off - dst;
2801 mm += delta;
2802 if ((mm < 0 || mm >= 60) &&
2803 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002804 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002805 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2806 if (result == NULL)
2807 return result;
2808
2809 dst = call_dst(dt->tzinfo, result, &none);
2810 if (dst == -1 && PyErr_Occurred())
2811 goto Fail;
2812 if (none)
2813 goto Inconsistent;
2814 if (dst == 0)
2815 return result;
2816
2817 mm += dst;
2818 if ((mm < 0 || mm >= 60) &&
2819 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2820 goto Fail;
2821 Py_DECREF(result);
2822 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2823 return result;
2824
2825Inconsistent:
2826 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2827 "inconsistent results; cannot convert");
2828
2829 /* fall thru to failure */
2830Fail:
2831 Py_DECREF(result);
2832 return NULL;
2833}
2834
Tim Peters2a799bf2002-12-16 20:18:38 +00002835/*
2836 * Pickle support. This is solely so that tzinfo subclasses can use
2837 * pickling -- tzinfo itself is supposed to be uninstantiable. The
2838 * pickler and unpickler functions are given module-level private
2839 * names, and registered with copy_reg, by the module init function.
2840 */
2841
2842static PyObject*
2843tzinfo_pickler(PyDateTime_TZInfo *self) {
2844 return Py_BuildValue("O()", tzinfo_unpickler_object);
2845}
2846
2847static PyObject*
2848tzinfo_unpickler(PyObject * unused) {
2849 return PyType_GenericNew(&PyDateTime_TZInfoType, NULL, NULL);
2850}
2851
2852
2853static PyMethodDef tzinfo_methods[] = {
2854 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2855 PyDoc_STR("datetime -> string name of time zone.")},
2856
2857 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2858 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2859 "west of UTC).")},
2860
2861 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2862 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2863
Tim Peters52dcce22003-01-23 16:36:11 +00002864 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2865 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2866
Tim Peters2a799bf2002-12-16 20:18:38 +00002867 {NULL, NULL}
2868};
2869
2870static char tzinfo_doc[] =
2871PyDoc_STR("Abstract base class for time zone info objects.");
2872
2873 statichere PyTypeObject PyDateTime_TZInfoType = {
2874 PyObject_HEAD_INIT(NULL)
2875 0, /* ob_size */
2876 "datetime.tzinfo", /* tp_name */
2877 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2878 0, /* tp_itemsize */
2879 0, /* tp_dealloc */
2880 0, /* tp_print */
2881 0, /* tp_getattr */
2882 0, /* tp_setattr */
2883 0, /* tp_compare */
2884 0, /* tp_repr */
2885 0, /* tp_as_number */
2886 0, /* tp_as_sequence */
2887 0, /* tp_as_mapping */
2888 0, /* tp_hash */
2889 0, /* tp_call */
2890 0, /* tp_str */
2891 PyObject_GenericGetAttr, /* tp_getattro */
2892 0, /* tp_setattro */
2893 0, /* tp_as_buffer */
2894 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2895 Py_TPFLAGS_BASETYPE, /* tp_flags */
2896 tzinfo_doc, /* tp_doc */
2897 0, /* tp_traverse */
2898 0, /* tp_clear */
2899 0, /* tp_richcompare */
2900 0, /* tp_weaklistoffset */
2901 0, /* tp_iter */
2902 0, /* tp_iternext */
2903 tzinfo_methods, /* tp_methods */
2904 0, /* tp_members */
2905 0, /* tp_getset */
2906 0, /* tp_base */
2907 0, /* tp_dict */
2908 0, /* tp_descr_get */
2909 0, /* tp_descr_set */
2910 0, /* tp_dictoffset */
2911 0, /* tp_init */
2912 0, /* tp_alloc */
2913 PyType_GenericNew, /* tp_new */
2914 0, /* tp_free */
2915};
2916
2917/*
Tim Peters37f39822003-01-10 03:49:02 +00002918 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00002919 */
2920
Tim Peters37f39822003-01-10 03:49:02 +00002921/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00002922 */
2923
2924static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002925time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00002926{
Tim Peters37f39822003-01-10 03:49:02 +00002927 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002928}
2929
Tim Peters37f39822003-01-10 03:49:02 +00002930static PyObject *
2931time_minute(PyDateTime_Time *self, void *unused)
2932{
2933 return PyInt_FromLong(TIME_GET_MINUTE(self));
2934}
2935
2936/* The name time_second conflicted with some platform header file. */
2937static PyObject *
2938py_time_second(PyDateTime_Time *self, void *unused)
2939{
2940 return PyInt_FromLong(TIME_GET_SECOND(self));
2941}
2942
2943static PyObject *
2944time_microsecond(PyDateTime_Time *self, void *unused)
2945{
2946 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
2947}
2948
2949static PyObject *
2950time_tzinfo(PyDateTime_Time *self, void *unused)
2951{
Tim Petersa032d2e2003-01-11 00:15:54 +00002952 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00002953 Py_INCREF(result);
2954 return result;
2955}
2956
2957static PyGetSetDef time_getset[] = {
2958 {"hour", (getter)time_hour},
2959 {"minute", (getter)time_minute},
2960 {"second", (getter)py_time_second},
2961 {"microsecond", (getter)time_microsecond},
2962 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00002963 {NULL}
2964};
2965
2966/*
2967 * Constructors.
2968 */
2969
Tim Peters37f39822003-01-10 03:49:02 +00002970static char *time_kws[] = {"hour", "minute", "second", "microsecond",
2971 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002972
Tim Peters2a799bf2002-12-16 20:18:38 +00002973static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002974time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00002975{
2976 PyObject *self = NULL;
2977 int hour = 0;
2978 int minute = 0;
2979 int second = 0;
2980 int usecond = 0;
2981 PyObject *tzinfo = Py_None;
2982
Tim Peters37f39822003-01-10 03:49:02 +00002983 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002984 &hour, &minute, &second, &usecond,
2985 &tzinfo)) {
2986 if (check_time_args(hour, minute, second, usecond) < 0)
2987 return NULL;
2988 if (check_tzinfo_subclass(tzinfo) < 0)
2989 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00002990 self = new_time(hour, minute, second, usecond, tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00002991 }
2992 return self;
2993}
2994
2995/*
2996 * Destructor.
2997 */
2998
2999static void
Tim Peters37f39822003-01-10 03:49:02 +00003000time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003001{
Tim Petersa032d2e2003-01-11 00:15:54 +00003002 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003003 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003004 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003005 self->ob_type->tp_free((PyObject *)self);
3006}
3007
3008/*
Tim Peters855fe882002-12-22 03:43:39 +00003009 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003010 */
3011
Tim Peters2a799bf2002-12-16 20:18:38 +00003012/* These are all METH_NOARGS, so don't need to check the arglist. */
3013static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003014time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003015 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003016 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003017}
3018
3019static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003020time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003021 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003022 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003023}
3024
3025static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003026time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003027 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003028 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003029}
3030
3031/*
Tim Peters37f39822003-01-10 03:49:02 +00003032 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003033 */
3034
3035static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003036time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003037{
Tim Peters37f39822003-01-10 03:49:02 +00003038 char buffer[100];
3039 char *typename = self->ob_type->tp_name;
3040 int h = TIME_GET_HOUR(self);
3041 int m = TIME_GET_MINUTE(self);
3042 int s = TIME_GET_SECOND(self);
3043 int us = TIME_GET_MICROSECOND(self);
3044 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003045
Tim Peters37f39822003-01-10 03:49:02 +00003046 if (us)
3047 PyOS_snprintf(buffer, sizeof(buffer),
3048 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3049 else if (s)
3050 PyOS_snprintf(buffer, sizeof(buffer),
3051 "%s(%d, %d, %d)", typename, h, m, s);
3052 else
3053 PyOS_snprintf(buffer, sizeof(buffer),
3054 "%s(%d, %d)", typename, h, m);
3055 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003056 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003057 result = append_keyword_tzinfo(result, self->tzinfo);
3058 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003059}
3060
Tim Peters37f39822003-01-10 03:49:02 +00003061static PyObject *
3062time_str(PyDateTime_Time *self)
3063{
3064 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3065}
Tim Peters2a799bf2002-12-16 20:18:38 +00003066
3067static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003068time_isoformat(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003069{
3070 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003071 PyObject *result;
3072 /* Reuse the time format code from the datetime type. */
3073 PyDateTime_DateTime datetime;
3074 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003075
Tim Peters37f39822003-01-10 03:49:02 +00003076 /* Copy over just the time bytes. */
3077 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3078 self->data,
3079 _PyDateTime_TIME_DATASIZE);
3080
3081 isoformat_time(pdatetime, buf, sizeof(buf));
3082 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003083 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003084 return result;
3085
3086 /* We need to append the UTC offset. */
3087 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003088 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003089 Py_DECREF(result);
3090 return NULL;
3091 }
3092 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3093 return result;
3094}
3095
Tim Peters37f39822003-01-10 03:49:02 +00003096static PyObject *
3097time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3098{
3099 PyObject *result;
3100 PyObject *format;
3101 PyObject *tuple;
3102 static char *keywords[] = {"format", NULL};
3103
3104 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3105 &PyString_Type, &format))
3106 return NULL;
3107
3108 /* Python's strftime does insane things with the year part of the
3109 * timetuple. The year is forced to (the otherwise nonsensical)
3110 * 1900 to worm around that.
3111 */
3112 tuple = Py_BuildValue("iiiiiiiii",
3113 1900, 0, 0, /* year, month, day */
3114 TIME_GET_HOUR(self),
3115 TIME_GET_MINUTE(self),
3116 TIME_GET_SECOND(self),
3117 0, 0, -1); /* weekday, daynum, dst */
3118 if (tuple == NULL)
3119 return NULL;
3120 assert(PyTuple_Size(tuple) == 9);
3121 result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
3122 Py_DECREF(tuple);
3123 return result;
3124}
Tim Peters2a799bf2002-12-16 20:18:38 +00003125
3126/*
3127 * Miscellaneous methods.
3128 */
3129
Tim Peters37f39822003-01-10 03:49:02 +00003130/* This is more natural as a tp_compare, but doesn't work then: for whatever
3131 * reason, Python's try_3way_compare ignores tp_compare unless
3132 * PyInstance_Check returns true, but these aren't old-style classes.
3133 */
3134static PyObject *
3135time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3136{
3137 int diff;
3138 naivety n1, n2;
3139 int offset1, offset2;
3140
3141 if (! PyTime_Check(other)) {
3142 /* Stop this from falling back to address comparison. */
3143 PyErr_Format(PyExc_TypeError,
3144 "can't compare '%s' to '%s'",
3145 self->ob_type->tp_name,
3146 other->ob_type->tp_name);
3147 return NULL;
3148 }
3149 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3150 other, &offset2, &n2, Py_None) < 0)
3151 return NULL;
3152 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3153 /* If they're both naive, or both aware and have the same offsets,
3154 * we get off cheap. Note that if they're both naive, offset1 ==
3155 * offset2 == 0 at this point.
3156 */
3157 if (n1 == n2 && offset1 == offset2) {
3158 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3159 _PyDateTime_TIME_DATASIZE);
3160 return diff_to_bool(diff, op);
3161 }
3162
3163 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3164 assert(offset1 != offset2); /* else last "if" handled it */
3165 /* Convert everything except microseconds to seconds. These
3166 * can't overflow (no more than the # of seconds in 2 days).
3167 */
3168 offset1 = TIME_GET_HOUR(self) * 3600 +
3169 (TIME_GET_MINUTE(self) - offset1) * 60 +
3170 TIME_GET_SECOND(self);
3171 offset2 = TIME_GET_HOUR(other) * 3600 +
3172 (TIME_GET_MINUTE(other) - offset2) * 60 +
3173 TIME_GET_SECOND(other);
3174 diff = offset1 - offset2;
3175 if (diff == 0)
3176 diff = TIME_GET_MICROSECOND(self) -
3177 TIME_GET_MICROSECOND(other);
3178 return diff_to_bool(diff, op);
3179 }
3180
3181 assert(n1 != n2);
3182 PyErr_SetString(PyExc_TypeError,
3183 "can't compare offset-naive and "
3184 "offset-aware times");
3185 return NULL;
3186}
3187
3188static long
3189time_hash(PyDateTime_Time *self)
3190{
3191 if (self->hashcode == -1) {
3192 naivety n;
3193 int offset;
3194 PyObject *temp;
3195
3196 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3197 assert(n != OFFSET_UNKNOWN);
3198 if (n == OFFSET_ERROR)
3199 return -1;
3200
3201 /* Reduce this to a hash of another object. */
3202 if (offset == 0)
3203 temp = PyString_FromStringAndSize((char *)self->data,
3204 _PyDateTime_TIME_DATASIZE);
3205 else {
3206 int hour;
3207 int minute;
3208
3209 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003210 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003211 hour = divmod(TIME_GET_HOUR(self) * 60 +
3212 TIME_GET_MINUTE(self) - offset,
3213 60,
3214 &minute);
3215 if (0 <= hour && hour < 24)
3216 temp = new_time(hour, minute,
3217 TIME_GET_SECOND(self),
3218 TIME_GET_MICROSECOND(self),
3219 Py_None);
3220 else
3221 temp = Py_BuildValue("iiii",
3222 hour, minute,
3223 TIME_GET_SECOND(self),
3224 TIME_GET_MICROSECOND(self));
3225 }
3226 if (temp != NULL) {
3227 self->hashcode = PyObject_Hash(temp);
3228 Py_DECREF(temp);
3229 }
3230 }
3231 return self->hashcode;
3232}
Tim Peters2a799bf2002-12-16 20:18:38 +00003233
Tim Peters12bf3392002-12-24 05:41:27 +00003234static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003235time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003236{
3237 PyObject *clone;
3238 PyObject *tuple;
3239 int hh = TIME_GET_HOUR(self);
3240 int mm = TIME_GET_MINUTE(self);
3241 int ss = TIME_GET_SECOND(self);
3242 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003243 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003244
3245 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003246 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003247 &hh, &mm, &ss, &us, &tzinfo))
3248 return NULL;
3249 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3250 if (tuple == NULL)
3251 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003252 clone = time_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003253 Py_DECREF(tuple);
3254 return clone;
3255}
3256
Tim Peters2a799bf2002-12-16 20:18:38 +00003257static int
Tim Peters37f39822003-01-10 03:49:02 +00003258time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003259{
3260 int offset;
3261 int none;
3262
3263 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3264 /* Since utcoffset is in whole minutes, nothing can
3265 * alter the conclusion that this is nonzero.
3266 */
3267 return 1;
3268 }
3269 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003270 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003271 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003272 if (offset == -1 && PyErr_Occurred())
3273 return -1;
3274 }
3275 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3276}
3277
3278/*
3279 * Pickle support. Quite a maze!
3280 */
3281
Tim Peters33e0f382003-01-10 02:05:14 +00003282/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003283 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3284 * So it's a tuple in any (non-error) case.
3285 */
3286static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003287time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003288{
3289 PyObject *basestate;
3290 PyObject *result = NULL;
3291
Tim Peters33e0f382003-01-10 02:05:14 +00003292 basestate = PyString_FromStringAndSize((char *)self->data,
3293 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003294 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003295 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003296 result = Py_BuildValue("(O)", basestate);
3297 else
3298 result = Py_BuildValue("OO", basestate, self->tzinfo);
3299 Py_DECREF(basestate);
3300 }
3301 return result;
3302}
3303
3304static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003305time_setstate(PyDateTime_Time *self, PyObject *state)
Tim Peters2a799bf2002-12-16 20:18:38 +00003306{
Tim Peters2a799bf2002-12-16 20:18:38 +00003307 PyObject *basestate;
3308 PyObject *tzinfo = Py_None;
3309
3310 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
3311 &PyString_Type, &basestate,
3312 &tzinfo))
3313 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00003314 if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE ||
3315 check_tzinfo_subclass(tzinfo) < 0) {
3316 PyErr_SetString(PyExc_TypeError,
3317 "bad argument to time.__setstate__");
Tim Peters2a799bf2002-12-16 20:18:38 +00003318 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00003319 }
Tim Petersa032d2e2003-01-11 00:15:54 +00003320 if (tzinfo != Py_None && ! HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003321 PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't "
3322 "add a non-None tzinfo to a time object that "
3323 "doesn't have one already");
3324 return NULL;
3325 }
Tim Peters33e0f382003-01-10 02:05:14 +00003326 memcpy((char *)self->data,
3327 PyString_AsString(basestate),
3328 _PyDateTime_TIME_DATASIZE);
3329 self->hashcode = -1;
Tim Petersa032d2e2003-01-11 00:15:54 +00003330 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003331 Py_INCREF(tzinfo);
3332 Py_XDECREF(self->tzinfo);
3333 self->tzinfo = tzinfo;
3334 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003335 Py_INCREF(Py_None);
3336 return Py_None;
3337}
3338
3339static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003340time_pickler(PyObject *module, PyDateTime_Time *time)
Tim Peters2a799bf2002-12-16 20:18:38 +00003341{
3342 PyObject *state;
3343 PyObject *result = NULL;
3344
Tim Peters37f39822003-01-10 03:49:02 +00003345 if (! PyTime_CheckExact(time)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003346 PyErr_Format(PyExc_TypeError,
Tim Peters37f39822003-01-10 03:49:02 +00003347 "bad type passed to time pickler: %s",
3348 time->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00003349 return NULL;
3350 }
Tim Peters37f39822003-01-10 03:49:02 +00003351 state = time_getstate(time);
Tim Peters2a799bf2002-12-16 20:18:38 +00003352 if (state) {
3353 result = Py_BuildValue("O(O)",
Tim Peters37f39822003-01-10 03:49:02 +00003354 time_unpickler_object,
Tim Peters2a799bf2002-12-16 20:18:38 +00003355 state);
3356 Py_DECREF(state);
3357 }
3358 return result;
3359}
3360
3361static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003362time_unpickler(PyObject *module, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003363{
Tim Peters37f39822003-01-10 03:49:02 +00003364 PyDateTime_Time *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003365
Tim Peters37f39822003-01-10 03:49:02 +00003366 /* We don't want to allocate space for tzinfo if it's not needed.
3367 * Figuring that out in advance is irritating, so for now we
3368 * realloc later.
3369 */
3370 self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00003371 if (self != NULL) {
3372 PyObject *res;
3373
Tim Peters37f39822003-01-10 03:49:02 +00003374 self->tzinfo = Py_None;
3375 Py_INCREF(self->tzinfo);
3376 self->hastzinfo = (char)1; /* true */
3377 res = time_setstate(self, arg);
Tim Peters2a799bf2002-12-16 20:18:38 +00003378 if (res == NULL) {
3379 Py_DECREF(self);
3380 return NULL;
3381 }
3382 Py_DECREF(res);
Tim Peters37f39822003-01-10 03:49:02 +00003383 if (self->tzinfo == Py_None) {
3384 /* shrinking; can't fail */
3385 Py_DECREF(self->tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003386 self = (PyDateTime_Time *)PyObject_Realloc(self,
3387 sizeof(_PyDateTime_BaseTime));
3388 assert(self != NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003389 self->hastzinfo = (char)0;
3390 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003391 }
3392 return (PyObject *)self;
3393}
3394
Tim Peters37f39822003-01-10 03:49:02 +00003395static PyMethodDef time_methods[] = {
3396 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003397 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3398 "[+HH:MM].")},
3399
Tim Peters37f39822003-01-10 03:49:02 +00003400 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3401 PyDoc_STR("format -> strftime() style string.")},
3402
3403 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003404 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3405
Tim Peters37f39822003-01-10 03:49:02 +00003406 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003407 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3408
Tim Peters37f39822003-01-10 03:49:02 +00003409 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003410 PyDoc_STR("Return self.tzinfo.dst(self).")},
3411
Tim Peters37f39822003-01-10 03:49:02 +00003412 {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
3413 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003414
Tim Peters37f39822003-01-10 03:49:02 +00003415 {"__setstate__", (PyCFunction)time_setstate, METH_O,
Tim Peters2a799bf2002-12-16 20:18:38 +00003416 PyDoc_STR("__setstate__(state)")},
3417
Tim Peters37f39822003-01-10 03:49:02 +00003418 {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003419 PyDoc_STR("__getstate__() -> state")},
3420 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003421};
3422
Tim Peters37f39822003-01-10 03:49:02 +00003423static char time_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003424PyDoc_STR("Time type.");
3425
Tim Peters37f39822003-01-10 03:49:02 +00003426static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003427 0, /* nb_add */
3428 0, /* nb_subtract */
3429 0, /* nb_multiply */
3430 0, /* nb_divide */
3431 0, /* nb_remainder */
3432 0, /* nb_divmod */
3433 0, /* nb_power */
3434 0, /* nb_negative */
3435 0, /* nb_positive */
3436 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003437 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003438};
3439
Tim Peters37f39822003-01-10 03:49:02 +00003440statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003441 PyObject_HEAD_INIT(NULL)
3442 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003443 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003444 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003445 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003446 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003447 0, /* tp_print */
3448 0, /* tp_getattr */
3449 0, /* tp_setattr */
3450 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003451 (reprfunc)time_repr, /* tp_repr */
3452 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003453 0, /* tp_as_sequence */
3454 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003455 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003456 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003457 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003458 PyObject_GenericGetAttr, /* tp_getattro */
3459 0, /* tp_setattro */
3460 0, /* tp_as_buffer */
3461 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3462 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003463 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003464 0, /* tp_traverse */
3465 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003466 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003467 0, /* tp_weaklistoffset */
3468 0, /* tp_iter */
3469 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003470 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003471 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003472 time_getset, /* tp_getset */
3473 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003474 0, /* tp_dict */
3475 0, /* tp_descr_get */
3476 0, /* tp_descr_set */
3477 0, /* tp_dictoffset */
3478 0, /* tp_init */
3479 0, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003480 time_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00003481 _PyObject_Del, /* tp_free */
3482};
3483
3484/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003485 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003486 */
3487
Tim Petersa9bc1682003-01-11 03:39:11 +00003488/* Accessor properties. Properties for day, month, and year are inherited
3489 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003490 */
3491
3492static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003493datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003494{
Tim Petersa9bc1682003-01-11 03:39:11 +00003495 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003496}
3497
Tim Petersa9bc1682003-01-11 03:39:11 +00003498static PyObject *
3499datetime_minute(PyDateTime_DateTime *self, void *unused)
3500{
3501 return PyInt_FromLong(DATE_GET_MINUTE(self));
3502}
3503
3504static PyObject *
3505datetime_second(PyDateTime_DateTime *self, void *unused)
3506{
3507 return PyInt_FromLong(DATE_GET_SECOND(self));
3508}
3509
3510static PyObject *
3511datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3512{
3513 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3514}
3515
3516static PyObject *
3517datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3518{
3519 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3520 Py_INCREF(result);
3521 return result;
3522}
3523
3524static PyGetSetDef datetime_getset[] = {
3525 {"hour", (getter)datetime_hour},
3526 {"minute", (getter)datetime_minute},
3527 {"second", (getter)datetime_second},
3528 {"microsecond", (getter)datetime_microsecond},
3529 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003530 {NULL}
3531};
3532
3533/*
3534 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003535 */
3536
Tim Petersa9bc1682003-01-11 03:39:11 +00003537static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003538 "year", "month", "day", "hour", "minute", "second",
3539 "microsecond", "tzinfo", NULL
3540};
3541
Tim Peters2a799bf2002-12-16 20:18:38 +00003542static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003543datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003544{
3545 PyObject *self = NULL;
3546 int year;
3547 int month;
3548 int day;
3549 int hour = 0;
3550 int minute = 0;
3551 int second = 0;
3552 int usecond = 0;
3553 PyObject *tzinfo = Py_None;
3554
Tim Petersa9bc1682003-01-11 03:39:11 +00003555 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003556 &year, &month, &day, &hour, &minute,
3557 &second, &usecond, &tzinfo)) {
3558 if (check_date_args(year, month, day) < 0)
3559 return NULL;
3560 if (check_time_args(hour, minute, second, usecond) < 0)
3561 return NULL;
3562 if (check_tzinfo_subclass(tzinfo) < 0)
3563 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003564 self = new_datetime(year, month, day,
3565 hour, minute, second, usecond,
3566 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003567 }
3568 return self;
3569}
3570
Tim Petersa9bc1682003-01-11 03:39:11 +00003571/* TM_FUNC is the shared type of localtime() and gmtime(). */
3572typedef struct tm *(*TM_FUNC)(const time_t *timer);
3573
3574/* Internal helper.
3575 * Build datetime from a time_t and a distinct count of microseconds.
3576 * Pass localtime or gmtime for f, to control the interpretation of timet.
3577 */
3578static PyObject *
3579datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3580 PyObject *tzinfo)
3581{
3582 struct tm *tm;
3583 PyObject *result = NULL;
3584
3585 tm = f(&timet);
3586 if (tm) {
3587 /* The platform localtime/gmtime may insert leap seconds,
3588 * indicated by tm->tm_sec > 59. We don't care about them,
3589 * except to the extent that passing them on to the datetime
3590 * constructor would raise ValueError for a reason that
3591 * made no sense to the user.
3592 */
3593 if (tm->tm_sec > 59)
3594 tm->tm_sec = 59;
3595 result = PyObject_CallFunction(cls, "iiiiiiiO",
3596 tm->tm_year + 1900,
3597 tm->tm_mon + 1,
3598 tm->tm_mday,
3599 tm->tm_hour,
3600 tm->tm_min,
3601 tm->tm_sec,
3602 us,
3603 tzinfo);
3604 }
3605 else
3606 PyErr_SetString(PyExc_ValueError,
3607 "timestamp out of range for "
3608 "platform localtime()/gmtime() function");
3609 return result;
3610}
3611
3612/* Internal helper.
3613 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3614 * to control the interpretation of the timestamp. Since a double doesn't
3615 * have enough bits to cover a datetime's full range of precision, it's
3616 * better to call datetime_from_timet_and_us provided you have a way
3617 * to get that much precision (e.g., C time() isn't good enough).
3618 */
3619static PyObject *
3620datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3621 PyObject *tzinfo)
3622{
3623 time_t timet = (time_t)timestamp;
3624 double fraction = timestamp - (double)timet;
3625 int us = (int)round_to_long(fraction * 1e6);
3626
3627 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3628}
3629
3630/* Internal helper.
3631 * Build most accurate possible datetime for current time. Pass localtime or
3632 * gmtime for f as appropriate.
3633 */
3634static PyObject *
3635datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3636{
3637#ifdef HAVE_GETTIMEOFDAY
3638 struct timeval t;
3639
3640#ifdef GETTIMEOFDAY_NO_TZ
3641 gettimeofday(&t);
3642#else
3643 gettimeofday(&t, (struct timezone *)NULL);
3644#endif
3645 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3646 tzinfo);
3647
3648#else /* ! HAVE_GETTIMEOFDAY */
3649 /* No flavor of gettimeofday exists on this platform. Python's
3650 * time.time() does a lot of other platform tricks to get the
3651 * best time it can on the platform, and we're not going to do
3652 * better than that (if we could, the better code would belong
3653 * in time.time()!) We're limited by the precision of a double,
3654 * though.
3655 */
3656 PyObject *time;
3657 double dtime;
3658
3659 time = time_time();
3660 if (time == NULL)
3661 return NULL;
3662 dtime = PyFloat_AsDouble(time);
3663 Py_DECREF(time);
3664 if (dtime == -1.0 && PyErr_Occurred())
3665 return NULL;
3666 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3667#endif /* ! HAVE_GETTIMEOFDAY */
3668}
3669
Tim Peters2a799bf2002-12-16 20:18:38 +00003670/* Return best possible local time -- this isn't constrained by the
3671 * precision of a timestamp.
3672 */
3673static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003674datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003675{
Tim Peters10cadce2003-01-23 19:58:02 +00003676 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003677 PyObject *tzinfo = Py_None;
Tim Peters10cadce2003-01-23 19:58:02 +00003678 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003679
Tim Peters10cadce2003-01-23 19:58:02 +00003680 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3681 &tzinfo))
3682 return NULL;
3683 if (check_tzinfo_subclass(tzinfo) < 0)
3684 return NULL;
3685
3686 self = datetime_best_possible(cls,
3687 tzinfo == Py_None ? localtime : gmtime,
3688 tzinfo);
3689 if (self != NULL && tzinfo != Py_None) {
3690 /* Convert UTC to tzinfo's zone. */
3691 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003692 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003693 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003694 }
3695 return self;
3696}
3697
Tim Petersa9bc1682003-01-11 03:39:11 +00003698/* Return best possible UTC time -- this isn't constrained by the
3699 * precision of a timestamp.
3700 */
3701static PyObject *
3702datetime_utcnow(PyObject *cls, PyObject *dummy)
3703{
3704 return datetime_best_possible(cls, gmtime, Py_None);
3705}
3706
Tim Peters2a799bf2002-12-16 20:18:38 +00003707/* Return new local datetime from timestamp (Python timestamp -- a double). */
3708static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003709datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003710{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003711 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003712 double timestamp;
3713 PyObject *tzinfo = Py_None;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003714 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003715
Tim Peters2a44a8d2003-01-23 20:53:10 +00003716 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3717 keywords, &timestamp, &tzinfo))
3718 return NULL;
3719 if (check_tzinfo_subclass(tzinfo) < 0)
3720 return NULL;
3721
3722 self = datetime_from_timestamp(cls,
3723 tzinfo == Py_None ? localtime : gmtime,
3724 timestamp,
3725 tzinfo);
3726 if (self != NULL && tzinfo != Py_None) {
3727 /* Convert UTC to tzinfo's zone. */
3728 PyObject *temp = self;
3729 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3730 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003731 }
3732 return self;
3733}
3734
Tim Petersa9bc1682003-01-11 03:39:11 +00003735/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3736static PyObject *
3737datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3738{
3739 double timestamp;
3740 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003741
Tim Petersa9bc1682003-01-11 03:39:11 +00003742 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3743 result = datetime_from_timestamp(cls, gmtime, timestamp,
3744 Py_None);
3745 return result;
3746}
3747
3748/* Return new datetime from date/datetime and time arguments. */
3749static PyObject *
3750datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3751{
3752 static char *keywords[] = {"date", "time", NULL};
3753 PyObject *date;
3754 PyObject *time;
3755 PyObject *result = NULL;
3756
3757 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3758 &PyDateTime_DateType, &date,
3759 &PyDateTime_TimeType, &time)) {
3760 PyObject *tzinfo = Py_None;
3761
3762 if (HASTZINFO(time))
3763 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3764 result = PyObject_CallFunction(cls, "iiiiiiiO",
3765 GET_YEAR(date),
3766 GET_MONTH(date),
3767 GET_DAY(date),
3768 TIME_GET_HOUR(time),
3769 TIME_GET_MINUTE(time),
3770 TIME_GET_SECOND(time),
3771 TIME_GET_MICROSECOND(time),
3772 tzinfo);
3773 }
3774 return result;
3775}
Tim Peters2a799bf2002-12-16 20:18:38 +00003776
3777/*
3778 * Destructor.
3779 */
3780
3781static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003782datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003783{
Tim Petersa9bc1682003-01-11 03:39:11 +00003784 if (HASTZINFO(self)) {
3785 Py_XDECREF(self->tzinfo);
3786 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003787 self->ob_type->tp_free((PyObject *)self);
3788}
3789
3790/*
3791 * Indirect access to tzinfo methods.
3792 */
3793
Tim Peters2a799bf2002-12-16 20:18:38 +00003794/* These are all METH_NOARGS, so don't need to check the arglist. */
3795static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003796datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3797 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3798 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003799}
3800
3801static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003802datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3803 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3804 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003805}
3806
3807static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003808datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3809 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3810 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003811}
3812
3813/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003814 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003815 */
3816
Tim Petersa9bc1682003-01-11 03:39:11 +00003817/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3818 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003819 */
3820static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003821add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3822 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003823{
Tim Petersa9bc1682003-01-11 03:39:11 +00003824 /* Note that the C-level additions can't overflow, because of
3825 * invariant bounds on the member values.
3826 */
3827 int year = GET_YEAR(date);
3828 int month = GET_MONTH(date);
3829 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3830 int hour = DATE_GET_HOUR(date);
3831 int minute = DATE_GET_MINUTE(date);
3832 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3833 int microsecond = DATE_GET_MICROSECOND(date) +
3834 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003835
Tim Petersa9bc1682003-01-11 03:39:11 +00003836 assert(factor == 1 || factor == -1);
3837 if (normalize_datetime(&year, &month, &day,
3838 &hour, &minute, &second, &microsecond) < 0)
3839 return NULL;
3840 else
3841 return new_datetime(year, month, day,
3842 hour, minute, second, microsecond,
3843 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003844}
3845
3846static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003847datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003848{
Tim Petersa9bc1682003-01-11 03:39:11 +00003849 if (PyDateTime_Check(left)) {
3850 /* datetime + ??? */
3851 if (PyDelta_Check(right))
3852 /* datetime + delta */
3853 return add_datetime_timedelta(
3854 (PyDateTime_DateTime *)left,
3855 (PyDateTime_Delta *)right,
3856 1);
3857 }
3858 else if (PyDelta_Check(left)) {
3859 /* delta + datetime */
3860 return add_datetime_timedelta((PyDateTime_DateTime *) right,
3861 (PyDateTime_Delta *) left,
3862 1);
3863 }
3864 Py_INCREF(Py_NotImplemented);
3865 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00003866}
3867
3868static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003869datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003870{
3871 PyObject *result = Py_NotImplemented;
3872
3873 if (PyDateTime_Check(left)) {
3874 /* datetime - ??? */
3875 if (PyDateTime_Check(right)) {
3876 /* datetime - datetime */
3877 naivety n1, n2;
3878 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00003879 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00003880
Tim Peterse39a80c2002-12-30 21:28:52 +00003881 if (classify_two_utcoffsets(left, &offset1, &n1, left,
3882 right, &offset2, &n2,
3883 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00003884 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00003885 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00003886 if (n1 != n2) {
3887 PyErr_SetString(PyExc_TypeError,
3888 "can't subtract offset-naive and "
3889 "offset-aware datetimes");
3890 return NULL;
3891 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003892 delta_d = ymd_to_ord(GET_YEAR(left),
3893 GET_MONTH(left),
3894 GET_DAY(left)) -
3895 ymd_to_ord(GET_YEAR(right),
3896 GET_MONTH(right),
3897 GET_DAY(right));
3898 /* These can't overflow, since the values are
3899 * normalized. At most this gives the number of
3900 * seconds in one day.
3901 */
3902 delta_s = (DATE_GET_HOUR(left) -
3903 DATE_GET_HOUR(right)) * 3600 +
3904 (DATE_GET_MINUTE(left) -
3905 DATE_GET_MINUTE(right)) * 60 +
3906 (DATE_GET_SECOND(left) -
3907 DATE_GET_SECOND(right));
3908 delta_us = DATE_GET_MICROSECOND(left) -
3909 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00003910 /* (left - offset1) - (right - offset2) =
3911 * (left - right) + (offset2 - offset1)
3912 */
Tim Petersa9bc1682003-01-11 03:39:11 +00003913 delta_s += (offset2 - offset1) * 60;
3914 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003915 }
3916 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00003917 /* datetime - delta */
3918 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00003919 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00003920 (PyDateTime_Delta *)right,
3921 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003922 }
3923 }
3924
3925 if (result == Py_NotImplemented)
3926 Py_INCREF(result);
3927 return result;
3928}
3929
3930/* Various ways to turn a datetime into a string. */
3931
3932static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003933datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003934{
Tim Petersa9bc1682003-01-11 03:39:11 +00003935 char buffer[1000];
3936 char *typename = self->ob_type->tp_name;
3937 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003938
Tim Petersa9bc1682003-01-11 03:39:11 +00003939 if (DATE_GET_MICROSECOND(self)) {
3940 PyOS_snprintf(buffer, sizeof(buffer),
3941 "%s(%d, %d, %d, %d, %d, %d, %d)",
3942 typename,
3943 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3944 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3945 DATE_GET_SECOND(self),
3946 DATE_GET_MICROSECOND(self));
3947 }
3948 else if (DATE_GET_SECOND(self)) {
3949 PyOS_snprintf(buffer, sizeof(buffer),
3950 "%s(%d, %d, %d, %d, %d, %d)",
3951 typename,
3952 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3953 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3954 DATE_GET_SECOND(self));
3955 }
3956 else {
3957 PyOS_snprintf(buffer, sizeof(buffer),
3958 "%s(%d, %d, %d, %d, %d)",
3959 typename,
3960 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3961 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
3962 }
3963 baserepr = PyString_FromString(buffer);
3964 if (baserepr == NULL || ! HASTZINFO(self))
3965 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003966 return append_keyword_tzinfo(baserepr, self->tzinfo);
3967}
3968
Tim Petersa9bc1682003-01-11 03:39:11 +00003969static PyObject *
3970datetime_str(PyDateTime_DateTime *self)
3971{
3972 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
3973}
Tim Peters2a799bf2002-12-16 20:18:38 +00003974
3975static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003976datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003977{
Tim Petersa9bc1682003-01-11 03:39:11 +00003978 char sep = 'T';
3979 static char *keywords[] = {"sep", NULL};
3980 char buffer[100];
3981 char *cp;
3982 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003983
Tim Petersa9bc1682003-01-11 03:39:11 +00003984 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
3985 &sep))
3986 return NULL;
3987 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
3988 assert(cp != NULL);
3989 *cp++ = sep;
3990 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
3991 result = PyString_FromString(buffer);
3992 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00003993 return result;
3994
3995 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00003996 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00003997 (PyObject *)self) < 0) {
3998 Py_DECREF(result);
3999 return NULL;
4000 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004001 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00004002 return result;
4003}
4004
Tim Petersa9bc1682003-01-11 03:39:11 +00004005static PyObject *
4006datetime_ctime(PyDateTime_DateTime *self)
4007{
4008 return format_ctime((PyDateTime_Date *)self,
4009 DATE_GET_HOUR(self),
4010 DATE_GET_MINUTE(self),
4011 DATE_GET_SECOND(self));
4012}
4013
Tim Peters2a799bf2002-12-16 20:18:38 +00004014/* Miscellaneous methods. */
4015
Tim Petersa9bc1682003-01-11 03:39:11 +00004016/* This is more natural as a tp_compare, but doesn't work then: for whatever
4017 * reason, Python's try_3way_compare ignores tp_compare unless
4018 * PyInstance_Check returns true, but these aren't old-style classes.
4019 */
4020static PyObject *
4021datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4022{
4023 int diff;
4024 naivety n1, n2;
4025 int offset1, offset2;
4026
4027 if (! PyDateTime_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004028 if (PyObject_HasAttrString(other, "timetuple")) {
4029 /* A hook for other kinds of datetime objects. */
4030 Py_INCREF(Py_NotImplemented);
4031 return Py_NotImplemented;
4032 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004033 /* Stop this from falling back to address comparison. */
4034 PyErr_Format(PyExc_TypeError,
4035 "can't compare '%s' to '%s'",
4036 self->ob_type->tp_name,
4037 other->ob_type->tp_name);
4038 return NULL;
4039 }
4040
4041 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4042 (PyObject *)self,
4043 other, &offset2, &n2,
4044 other) < 0)
4045 return NULL;
4046 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4047 /* If they're both naive, or both aware and have the same offsets,
4048 * we get off cheap. Note that if they're both naive, offset1 ==
4049 * offset2 == 0 at this point.
4050 */
4051 if (n1 == n2 && offset1 == offset2) {
4052 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4053 _PyDateTime_DATETIME_DATASIZE);
4054 return diff_to_bool(diff, op);
4055 }
4056
4057 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4058 PyDateTime_Delta *delta;
4059
4060 assert(offset1 != offset2); /* else last "if" handled it */
4061 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4062 other);
4063 if (delta == NULL)
4064 return NULL;
4065 diff = GET_TD_DAYS(delta);
4066 if (diff == 0)
4067 diff = GET_TD_SECONDS(delta) |
4068 GET_TD_MICROSECONDS(delta);
4069 Py_DECREF(delta);
4070 return diff_to_bool(diff, op);
4071 }
4072
4073 assert(n1 != n2);
4074 PyErr_SetString(PyExc_TypeError,
4075 "can't compare offset-naive and "
4076 "offset-aware datetimes");
4077 return NULL;
4078}
4079
4080static long
4081datetime_hash(PyDateTime_DateTime *self)
4082{
4083 if (self->hashcode == -1) {
4084 naivety n;
4085 int offset;
4086 PyObject *temp;
4087
4088 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4089 &offset);
4090 assert(n != OFFSET_UNKNOWN);
4091 if (n == OFFSET_ERROR)
4092 return -1;
4093
4094 /* Reduce this to a hash of another object. */
4095 if (n == OFFSET_NAIVE)
4096 temp = PyString_FromStringAndSize(
4097 (char *)self->data,
4098 _PyDateTime_DATETIME_DATASIZE);
4099 else {
4100 int days;
4101 int seconds;
4102
4103 assert(n == OFFSET_AWARE);
4104 assert(HASTZINFO(self));
4105 days = ymd_to_ord(GET_YEAR(self),
4106 GET_MONTH(self),
4107 GET_DAY(self));
4108 seconds = DATE_GET_HOUR(self) * 3600 +
4109 (DATE_GET_MINUTE(self) - offset) * 60 +
4110 DATE_GET_SECOND(self);
4111 temp = new_delta(days,
4112 seconds,
4113 DATE_GET_MICROSECOND(self),
4114 1);
4115 }
4116 if (temp != NULL) {
4117 self->hashcode = PyObject_Hash(temp);
4118 Py_DECREF(temp);
4119 }
4120 }
4121 return self->hashcode;
4122}
Tim Peters2a799bf2002-12-16 20:18:38 +00004123
4124static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004125datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004126{
4127 PyObject *clone;
4128 PyObject *tuple;
4129 int y = GET_YEAR(self);
4130 int m = GET_MONTH(self);
4131 int d = GET_DAY(self);
4132 int hh = DATE_GET_HOUR(self);
4133 int mm = DATE_GET_MINUTE(self);
4134 int ss = DATE_GET_SECOND(self);
4135 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004136 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004137
4138 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004139 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004140 &y, &m, &d, &hh, &mm, &ss, &us,
4141 &tzinfo))
4142 return NULL;
4143 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4144 if (tuple == NULL)
4145 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004146 clone = datetime_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004147 Py_DECREF(tuple);
4148 return clone;
4149}
4150
4151static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004152datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004153{
Tim Peters52dcce22003-01-23 16:36:11 +00004154 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004155 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004156 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004157
Tim Peters80475bb2002-12-25 07:40:55 +00004158 PyObject *tzinfo;
4159 static char *keywords[] = {"tz", NULL};
4160
Tim Peters52dcce22003-01-23 16:36:11 +00004161 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4162 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004163 return NULL;
4164
Tim Peters52dcce22003-01-23 16:36:11 +00004165 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4166 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004167
Tim Peters52dcce22003-01-23 16:36:11 +00004168 /* Conversion to self's own time zone is a NOP. */
4169 if (self->tzinfo == tzinfo) {
4170 Py_INCREF(self);
4171 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004172 }
Tim Peters521fc152002-12-31 17:36:56 +00004173
Tim Peters52dcce22003-01-23 16:36:11 +00004174 /* Convert self to UTC. */
4175 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4176 if (offset == -1 && PyErr_Occurred())
4177 return NULL;
4178 if (none)
4179 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004180
Tim Peters52dcce22003-01-23 16:36:11 +00004181 y = GET_YEAR(self);
4182 m = GET_MONTH(self);
4183 d = GET_DAY(self);
4184 hh = DATE_GET_HOUR(self);
4185 mm = DATE_GET_MINUTE(self);
4186 ss = DATE_GET_SECOND(self);
4187 us = DATE_GET_MICROSECOND(self);
4188
4189 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004190 if ((mm < 0 || mm >= 60) &&
4191 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004192 return NULL;
4193
4194 /* Attach new tzinfo and let fromutc() do the rest. */
4195 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4196 if (result != NULL) {
4197 PyObject *temp = result;
4198
4199 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4200 Py_DECREF(temp);
4201 }
Tim Petersadf64202003-01-04 06:03:15 +00004202 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004203
Tim Peters52dcce22003-01-23 16:36:11 +00004204NeedAware:
4205 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4206 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004207 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004208}
4209
4210static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004211datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004212{
4213 int dstflag = -1;
4214
Tim Petersa9bc1682003-01-11 03:39:11 +00004215 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004216 int none;
4217
4218 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4219 if (dstflag == -1 && PyErr_Occurred())
4220 return NULL;
4221
4222 if (none)
4223 dstflag = -1;
4224 else if (dstflag != 0)
4225 dstflag = 1;
4226
4227 }
4228 return build_struct_time(GET_YEAR(self),
4229 GET_MONTH(self),
4230 GET_DAY(self),
4231 DATE_GET_HOUR(self),
4232 DATE_GET_MINUTE(self),
4233 DATE_GET_SECOND(self),
4234 dstflag);
4235}
4236
4237static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004238datetime_getdate(PyDateTime_DateTime *self)
4239{
4240 return new_date(GET_YEAR(self),
4241 GET_MONTH(self),
4242 GET_DAY(self));
4243}
4244
4245static PyObject *
4246datetime_gettime(PyDateTime_DateTime *self)
4247{
4248 return new_time(DATE_GET_HOUR(self),
4249 DATE_GET_MINUTE(self),
4250 DATE_GET_SECOND(self),
4251 DATE_GET_MICROSECOND(self),
4252 Py_None);
4253}
4254
4255static PyObject *
4256datetime_gettimetz(PyDateTime_DateTime *self)
4257{
4258 return new_time(DATE_GET_HOUR(self),
4259 DATE_GET_MINUTE(self),
4260 DATE_GET_SECOND(self),
4261 DATE_GET_MICROSECOND(self),
4262 HASTZINFO(self) ? self->tzinfo : Py_None);
4263}
4264
4265static PyObject *
4266datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004267{
4268 int y = GET_YEAR(self);
4269 int m = GET_MONTH(self);
4270 int d = GET_DAY(self);
4271 int hh = DATE_GET_HOUR(self);
4272 int mm = DATE_GET_MINUTE(self);
4273 int ss = DATE_GET_SECOND(self);
4274 int us = 0; /* microseconds are ignored in a timetuple */
4275 int offset = 0;
4276
Tim Petersa9bc1682003-01-11 03:39:11 +00004277 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004278 int none;
4279
4280 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4281 if (offset == -1 && PyErr_Occurred())
4282 return NULL;
4283 }
4284 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4285 * 0 in a UTC timetuple regardless of what dst() says.
4286 */
4287 if (offset) {
4288 /* Subtract offset minutes & normalize. */
4289 int stat;
4290
4291 mm -= offset;
4292 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4293 if (stat < 0) {
4294 /* At the edges, it's possible we overflowed
4295 * beyond MINYEAR or MAXYEAR.
4296 */
4297 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4298 PyErr_Clear();
4299 else
4300 return NULL;
4301 }
4302 }
4303 return build_struct_time(y, m, d, hh, mm, ss, 0);
4304}
4305
Tim Peters33e0f382003-01-10 02:05:14 +00004306/* Pickle support. Quite a maze! */
4307
Tim Petersa9bc1682003-01-11 03:39:11 +00004308/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004309 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4310 * So it's a tuple in any (non-error) case.
4311 */
4312static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004313datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004314{
4315 PyObject *basestate;
4316 PyObject *result = NULL;
4317
Tim Peters33e0f382003-01-10 02:05:14 +00004318 basestate = PyString_FromStringAndSize((char *)self->data,
4319 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004320 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004321 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00004322 result = Py_BuildValue("(O)", basestate);
4323 else
4324 result = Py_BuildValue("OO", basestate, self->tzinfo);
4325 Py_DECREF(basestate);
4326 }
4327 return result;
4328}
4329
4330static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004331datetime_setstate(PyDateTime_DateTime *self, PyObject *state)
Tim Peters2a799bf2002-12-16 20:18:38 +00004332{
Tim Peters2a799bf2002-12-16 20:18:38 +00004333 PyObject *basestate;
4334 PyObject *tzinfo = Py_None;
4335
4336 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
4337 &PyString_Type, &basestate,
4338 &tzinfo))
4339 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00004340 if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE ||
4341 check_tzinfo_subclass(tzinfo) < 0) {
4342 PyErr_SetString(PyExc_TypeError,
4343 "bad argument to datetime.__setstate__");
Tim Peters2a799bf2002-12-16 20:18:38 +00004344 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00004345 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004346 if (tzinfo != Py_None && ! HASTZINFO(self)) {
4347 PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ "
4348 "can't add a non-None tzinfo to a datetime "
4349 "object that doesn't have one already");
4350 return NULL;
4351 }
Tim Peters33e0f382003-01-10 02:05:14 +00004352 memcpy((char *)self->data,
4353 PyString_AsString(basestate),
4354 _PyDateTime_DATETIME_DATASIZE);
4355 self->hashcode = -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004356 if (HASTZINFO(self)) {
4357 Py_INCREF(tzinfo);
4358 Py_XDECREF(self->tzinfo);
4359 self->tzinfo = tzinfo;
4360 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004361 Py_INCREF(Py_None);
4362 return Py_None;
4363}
4364
4365static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004366datetime_pickler(PyObject *module, PyDateTime_DateTime *datetime)
Tim Peters2a799bf2002-12-16 20:18:38 +00004367{
4368 PyObject *state;
4369 PyObject *result = NULL;
4370
Tim Petersa9bc1682003-01-11 03:39:11 +00004371 if (! PyDateTime_CheckExact(datetime)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004372 PyErr_Format(PyExc_TypeError,
Tim Petersa9bc1682003-01-11 03:39:11 +00004373 "bad type passed to datetime pickler: %s",
4374 datetime->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00004375 return NULL;
4376 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004377 state = datetime_getstate(datetime);
Tim Peters2a799bf2002-12-16 20:18:38 +00004378 if (state) {
4379 result = Py_BuildValue("O(O)",
Tim Petersa9bc1682003-01-11 03:39:11 +00004380 datetime_unpickler_object,
Tim Peters2a799bf2002-12-16 20:18:38 +00004381 state);
4382 Py_DECREF(state);
4383 }
4384 return result;
4385}
4386
4387static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004388datetime_unpickler(PyObject *module, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004389{
Tim Petersa9bc1682003-01-11 03:39:11 +00004390 PyDateTime_DateTime *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004391
Tim Petersa9bc1682003-01-11 03:39:11 +00004392 /* We don't want to allocate space for tzinfo if it's not needed.
4393 * Figuring that out in advance is irritating, so for now we
4394 * realloc later.
4395 */
4396 self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004397 if (self != NULL) {
4398 PyObject *res;
4399
Tim Petersa9bc1682003-01-11 03:39:11 +00004400 self->tzinfo = Py_None;
4401 Py_INCREF(self->tzinfo);
4402 self->hastzinfo = (char)1; /* true */
4403 res = datetime_setstate(self, arg);
Tim Peters2a799bf2002-12-16 20:18:38 +00004404 if (res == NULL) {
4405 Py_DECREF(self);
4406 return NULL;
4407 }
4408 Py_DECREF(res);
Tim Petersa9bc1682003-01-11 03:39:11 +00004409 if (self->tzinfo == Py_None) {
4410 /* shrinking; can't fail */
4411 Py_DECREF(self->tzinfo);
4412 self = (PyDateTime_DateTime *)PyObject_Realloc(self,
4413 sizeof(_PyDateTime_BaseDateTime));
4414 assert(self != NULL);
4415 self->hastzinfo = (char)0;
4416 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004417 }
4418 return (PyObject *)self;
4419}
4420
4421
Tim Petersa9bc1682003-01-11 03:39:11 +00004422static PyMethodDef datetime_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004423 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004424
Tim Petersa9bc1682003-01-11 03:39:11 +00004425 {"now", (PyCFunction)datetime_now,
Tim Peters2a799bf2002-12-16 20:18:38 +00004426 METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004427 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004428
Tim Petersa9bc1682003-01-11 03:39:11 +00004429 {"utcnow", (PyCFunction)datetime_utcnow,
4430 METH_NOARGS | METH_CLASS,
4431 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4432
4433 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Tim Peters2a799bf2002-12-16 20:18:38 +00004434 METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004435 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004436
Tim Petersa9bc1682003-01-11 03:39:11 +00004437 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4438 METH_VARARGS | METH_CLASS,
4439 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4440 "(like time.time()).")},
4441
4442 {"combine", (PyCFunction)datetime_combine,
4443 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4444 PyDoc_STR("date, time -> datetime with same date and time fields")},
4445
Tim Peters2a799bf2002-12-16 20:18:38 +00004446 /* Instance methods: */
Tim Petersa9bc1682003-01-11 03:39:11 +00004447 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4448 PyDoc_STR("Return date object with same year, month and day.")},
4449
4450 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4451 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4452
4453 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4454 PyDoc_STR("Return time object with same time and tzinfo.")},
4455
4456 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4457 PyDoc_STR("Return ctime() style string.")},
4458
4459 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004460 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4461
Tim Petersa9bc1682003-01-11 03:39:11 +00004462 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004463 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4464
Tim Petersa9bc1682003-01-11 03:39:11 +00004465 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004466 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4467 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4468 "sep is used to separate the year from the time, and "
4469 "defaults to 'T'.")},
4470
Tim Petersa9bc1682003-01-11 03:39:11 +00004471 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004472 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4473
Tim Petersa9bc1682003-01-11 03:39:11 +00004474 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004475 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4476
Tim Petersa9bc1682003-01-11 03:39:11 +00004477 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004478 PyDoc_STR("Return self.tzinfo.dst(self).")},
4479
Tim Petersa9bc1682003-01-11 03:39:11 +00004480 {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
4481 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004482
Tim Petersa9bc1682003-01-11 03:39:11 +00004483 {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004484 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4485
Tim Petersa9bc1682003-01-11 03:39:11 +00004486 {"__setstate__", (PyCFunction)datetime_setstate, METH_O,
Tim Peters2a799bf2002-12-16 20:18:38 +00004487 PyDoc_STR("__setstate__(state)")},
4488
Tim Petersa9bc1682003-01-11 03:39:11 +00004489 {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004490 PyDoc_STR("__getstate__() -> state")},
4491 {NULL, NULL}
4492};
4493
Tim Petersa9bc1682003-01-11 03:39:11 +00004494static char datetime_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00004495PyDoc_STR("date/time type.");
4496
Tim Petersa9bc1682003-01-11 03:39:11 +00004497static PyNumberMethods datetime_as_number = {
4498 datetime_add, /* nb_add */
4499 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004500 0, /* nb_multiply */
4501 0, /* nb_divide */
4502 0, /* nb_remainder */
4503 0, /* nb_divmod */
4504 0, /* nb_power */
4505 0, /* nb_negative */
4506 0, /* nb_positive */
4507 0, /* nb_absolute */
4508 0, /* nb_nonzero */
4509};
4510
Tim Petersa9bc1682003-01-11 03:39:11 +00004511statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004512 PyObject_HEAD_INIT(NULL)
4513 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004514 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004515 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004516 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004517 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004518 0, /* tp_print */
4519 0, /* tp_getattr */
4520 0, /* tp_setattr */
4521 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004522 (reprfunc)datetime_repr, /* tp_repr */
4523 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004524 0, /* tp_as_sequence */
4525 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004526 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004527 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004528 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004529 PyObject_GenericGetAttr, /* tp_getattro */
4530 0, /* tp_setattro */
4531 0, /* tp_as_buffer */
4532 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4533 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004534 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004535 0, /* tp_traverse */
4536 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004537 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004538 0, /* tp_weaklistoffset */
4539 0, /* tp_iter */
4540 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004541 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004542 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004543 datetime_getset, /* tp_getset */
4544 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004545 0, /* tp_dict */
4546 0, /* tp_descr_get */
4547 0, /* tp_descr_set */
4548 0, /* tp_dictoffset */
4549 0, /* tp_init */
4550 0, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004551 datetime_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00004552 _PyObject_Del, /* tp_free */
4553};
4554
4555/* ---------------------------------------------------------------------------
4556 * Module methods and initialization.
4557 */
4558
4559static PyMethodDef module_methods[] = {
4560 /* Private functions for pickling support, registered with the
4561 * copy_reg module by the module init function.
4562 */
4563 {"_date_pickler", (PyCFunction)date_pickler, METH_O, NULL},
4564 {"_date_unpickler", (PyCFunction)date_unpickler, METH_O, NULL},
Tim Petersa9bc1682003-01-11 03:39:11 +00004565 {"_datetime_pickler", (PyCFunction)datetime_pickler, METH_O, NULL},
4566 {"_datetime_unpickler", (PyCFunction)datetime_unpickler,METH_O, NULL},
Tim Peters37f39822003-01-10 03:49:02 +00004567 {"_time_pickler", (PyCFunction)time_pickler, METH_O, NULL},
4568 {"_time_unpickler", (PyCFunction)time_unpickler, METH_O, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00004569 {"_tzinfo_pickler", (PyCFunction)tzinfo_pickler, METH_O, NULL},
4570 {"_tzinfo_unpickler", (PyCFunction)tzinfo_unpickler, METH_NOARGS,
4571 NULL},
4572 {NULL, NULL}
4573};
4574
4575PyMODINIT_FUNC
4576initdatetime(void)
4577{
4578 PyObject *m; /* a module object */
4579 PyObject *d; /* its dict */
4580 PyObject *x;
4581
4582 /* Types that use __reduce__ for pickling need to set the following
4583 * magical attr in the type dict, with a true value.
4584 */
4585 PyObject *safepickle = PyString_FromString("__safe_for_unpickling__");
4586 if (safepickle == NULL)
4587 return;
4588
4589 m = Py_InitModule3("datetime", module_methods,
4590 "Fast implementation of the datetime type.");
4591
4592 if (PyType_Ready(&PyDateTime_DateType) < 0)
4593 return;
4594 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4595 return;
4596 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4597 return;
4598 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4599 return;
4600 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4601 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004602
4603 /* Pickling support, via registering functions with copy_reg. */
4604 {
4605 PyObject *pickler;
4606 PyObject *copyreg = PyImport_ImportModule("copy_reg");
4607
4608 if (copyreg == NULL) return;
4609
4610 pickler = PyObject_GetAttrString(m, "_date_pickler");
4611 if (pickler == NULL) return;
4612 date_unpickler_object = PyObject_GetAttrString(m,
4613 "_date_unpickler");
4614 if (date_unpickler_object == NULL) return;
4615 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4616 &PyDateTime_DateType,
4617 pickler,
4618 date_unpickler_object);
4619 if (x == NULL) return;
4620 Py_DECREF(x);
4621 Py_DECREF(pickler);
4622
Tim Peters37f39822003-01-10 03:49:02 +00004623 pickler = PyObject_GetAttrString(m, "_time_pickler");
Tim Peters2a799bf2002-12-16 20:18:38 +00004624 if (pickler == NULL) return;
Tim Peters37f39822003-01-10 03:49:02 +00004625 time_unpickler_object = PyObject_GetAttrString(m,
4626 "_time_unpickler");
4627 if (time_unpickler_object == NULL) return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004628 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
Tim Peters37f39822003-01-10 03:49:02 +00004629 &PyDateTime_TimeType,
Tim Peters2a799bf2002-12-16 20:18:38 +00004630 pickler,
Tim Peters37f39822003-01-10 03:49:02 +00004631 time_unpickler_object);
Tim Peters2a799bf2002-12-16 20:18:38 +00004632 if (x == NULL) return;
4633 Py_DECREF(x);
4634 Py_DECREF(pickler);
4635
4636 pickler = PyObject_GetAttrString(m, "_tzinfo_pickler");
4637 if (pickler == NULL) return;
4638 tzinfo_unpickler_object = PyObject_GetAttrString(m,
4639 "_tzinfo_unpickler");
4640 if (tzinfo_unpickler_object == NULL) return;
4641 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4642 &PyDateTime_TZInfoType,
4643 pickler,
4644 tzinfo_unpickler_object);
4645 if (x== NULL) return;
4646 Py_DECREF(x);
4647 Py_DECREF(pickler);
4648
Tim Petersa9bc1682003-01-11 03:39:11 +00004649 pickler = PyObject_GetAttrString(m, "_datetime_pickler");
Tim Peters2a799bf2002-12-16 20:18:38 +00004650 if (pickler == NULL) return;
Tim Petersa9bc1682003-01-11 03:39:11 +00004651 datetime_unpickler_object = PyObject_GetAttrString(m,
4652 "_datetime_unpickler");
4653 if (datetime_unpickler_object == NULL) return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004654 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
Tim Petersa9bc1682003-01-11 03:39:11 +00004655 &PyDateTime_DateTimeType,
Tim Peters2a799bf2002-12-16 20:18:38 +00004656 pickler,
Tim Petersa9bc1682003-01-11 03:39:11 +00004657 datetime_unpickler_object);
Tim Peters2a799bf2002-12-16 20:18:38 +00004658 if (x== NULL) return;
4659 Py_DECREF(x);
4660 Py_DECREF(pickler);
4661
4662 Py_DECREF(copyreg);
4663 }
4664
4665 /* timedelta values */
4666 d = PyDateTime_DeltaType.tp_dict;
4667
4668 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
4669 return;
4670
4671 x = new_delta(0, 0, 1, 0);
4672 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4673 return;
4674 Py_DECREF(x);
4675
4676 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4677 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4678 return;
4679 Py_DECREF(x);
4680
4681 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4682 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4683 return;
4684 Py_DECREF(x);
4685
4686 /* date values */
4687 d = PyDateTime_DateType.tp_dict;
4688
4689 x = new_date(1, 1, 1);
4690 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4691 return;
4692 Py_DECREF(x);
4693
4694 x = new_date(MAXYEAR, 12, 31);
4695 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4696 return;
4697 Py_DECREF(x);
4698
4699 x = new_delta(1, 0, 0, 0);
4700 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4701 return;
4702 Py_DECREF(x);
4703
Tim Peters37f39822003-01-10 03:49:02 +00004704 /* time values */
4705 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004706
Tim Peters37f39822003-01-10 03:49:02 +00004707 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004708 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4709 return;
4710 Py_DECREF(x);
4711
Tim Peters37f39822003-01-10 03:49:02 +00004712 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004713 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4714 return;
4715 Py_DECREF(x);
4716
4717 x = new_delta(0, 0, 1, 0);
4718 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4719 return;
4720 Py_DECREF(x);
4721
Tim Petersa9bc1682003-01-11 03:39:11 +00004722 /* datetime values */
4723 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004724
Tim Petersa9bc1682003-01-11 03:39:11 +00004725 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004726 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4727 return;
4728 Py_DECREF(x);
4729
Tim Petersa9bc1682003-01-11 03:39:11 +00004730 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004731 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4732 return;
4733 Py_DECREF(x);
4734
4735 x = new_delta(0, 0, 1, 0);
4736 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4737 return;
4738 Py_DECREF(x);
4739
4740 Py_DECREF(safepickle);
4741
4742 /* module initialization */
4743 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4744 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4745
4746 Py_INCREF(&PyDateTime_DateType);
4747 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4748
Tim Petersa9bc1682003-01-11 03:39:11 +00004749 Py_INCREF(&PyDateTime_DateTimeType);
4750 PyModule_AddObject(m, "datetime",
4751 (PyObject *)&PyDateTime_DateTimeType);
4752
4753 Py_INCREF(&PyDateTime_TimeType);
4754 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4755
Tim Peters2a799bf2002-12-16 20:18:38 +00004756 Py_INCREF(&PyDateTime_DeltaType);
4757 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4758
Tim Peters2a799bf2002-12-16 20:18:38 +00004759 Py_INCREF(&PyDateTime_TZInfoType);
4760 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4761
Tim Peters2a799bf2002-12-16 20:18:38 +00004762 /* A 4-year cycle has an extra leap day over what we'd get from
4763 * pasting together 4 single years.
4764 */
4765 assert(DI4Y == 4 * 365 + 1);
4766 assert(DI4Y == days_before_year(4+1));
4767
4768 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4769 * get from pasting together 4 100-year cycles.
4770 */
4771 assert(DI400Y == 4 * DI100Y + 1);
4772 assert(DI400Y == days_before_year(400+1));
4773
4774 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4775 * pasting together 25 4-year cycles.
4776 */
4777 assert(DI100Y == 25 * DI4Y - 1);
4778 assert(DI100Y == days_before_year(100+1));
4779
4780 us_per_us = PyInt_FromLong(1);
4781 us_per_ms = PyInt_FromLong(1000);
4782 us_per_second = PyInt_FromLong(1000000);
4783 us_per_minute = PyInt_FromLong(60000000);
4784 seconds_per_day = PyInt_FromLong(24 * 3600);
4785 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4786 us_per_minute == NULL || seconds_per_day == NULL)
4787 return;
4788
4789 /* The rest are too big for 32-bit ints, but even
4790 * us_per_week fits in 40 bits, so doubles should be exact.
4791 */
4792 us_per_hour = PyLong_FromDouble(3600000000.0);
4793 us_per_day = PyLong_FromDouble(86400000000.0);
4794 us_per_week = PyLong_FromDouble(604800000000.0);
4795 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4796 return;
4797}
Tim Petersf3615152003-01-01 21:51:37 +00004798
4799/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004800Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004801 x.n = x stripped of its timezone -- its naive time.
4802 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4803 return None
4804 x.d = x.dst(), and assuming that doesn't raise an exception or
4805 return None
4806 x.s = x's standard offset, x.o - x.d
4807
4808Now some derived rules, where k is a duration (timedelta).
4809
48101. x.o = x.s + x.d
4811 This follows from the definition of x.s.
4812
Tim Petersc5dc4da2003-01-02 17:55:03 +000048132. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004814 This is actually a requirement, an assumption we need to make about
4815 sane tzinfo classes.
4816
48173. The naive UTC time corresponding to x is x.n - x.o.
4818 This is again a requirement for a sane tzinfo class.
4819
48204. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004821 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004822
Tim Petersc5dc4da2003-01-02 17:55:03 +000048235. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004824 Again follows from how arithmetic is defined.
4825
Tim Peters8bb5ad22003-01-24 02:44:45 +00004826Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004827(meaning that the various tzinfo methods exist, and don't blow up or return
4828None when called).
4829
Tim Petersa9bc1682003-01-11 03:39:11 +00004830The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004831x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004832
4833By #3, we want
4834
Tim Peters8bb5ad22003-01-24 02:44:45 +00004835 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004836
4837The algorithm starts by attaching tz to x.n, and calling that y. So
4838x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4839becomes true; in effect, we want to solve [2] for k:
4840
Tim Peters8bb5ad22003-01-24 02:44:45 +00004841 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004842
4843By #1, this is the same as
4844
Tim Peters8bb5ad22003-01-24 02:44:45 +00004845 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004846
4847By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4848Substituting that into [3],
4849
Tim Peters8bb5ad22003-01-24 02:44:45 +00004850 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4851 k - (y+k).s - (y+k).d = 0; rearranging,
4852 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4853 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004854
Tim Peters8bb5ad22003-01-24 02:44:45 +00004855On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4856approximate k by ignoring the (y+k).d term at first. Note that k can't be
4857very large, since all offset-returning methods return a duration of magnitude
4858less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4859be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004860
4861In any case, the new value is
4862
Tim Peters8bb5ad22003-01-24 02:44:45 +00004863 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004864
Tim Peters8bb5ad22003-01-24 02:44:45 +00004865It's helpful to step back at look at [4] from a higher level: it's simply
4866mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004867
4868At this point, if
4869
Tim Peters8bb5ad22003-01-24 02:44:45 +00004870 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004871
4872we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004873at the start of daylight time. Picture US Eastern for concreteness. The wall
4874time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
Tim Peters8bb5ad22003-01-24 02:44:45 +00004875sense then. The docs ask that an Eastern tzinfo class consider such a time to
4876be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4877on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004878the only spelling that makes sense on the local wall clock.
4879
Tim Petersc5dc4da2003-01-02 17:55:03 +00004880In fact, if [5] holds at this point, we do have the standard-time spelling,
4881but that takes a bit of proof. We first prove a stronger result. What's the
4882difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004883
Tim Peters8bb5ad22003-01-24 02:44:45 +00004884 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004885
Tim Petersc5dc4da2003-01-02 17:55:03 +00004886Now
4887 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004888 (y + y.s).n = by #5
4889 y.n + y.s = since y.n = x.n
4890 x.n + y.s = since z and y are have the same tzinfo member,
4891 y.s = z.s by #2
4892 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004893
Tim Petersc5dc4da2003-01-02 17:55:03 +00004894Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004895
Tim Petersc5dc4da2003-01-02 17:55:03 +00004896 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004897 x.n - ((x.n + z.s) - z.o) = expanding
4898 x.n - x.n - z.s + z.o = cancelling
4899 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004900 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004901
Tim Petersc5dc4da2003-01-02 17:55:03 +00004902So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004903
Tim Petersc5dc4da2003-01-02 17:55:03 +00004904If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004905spelling we wanted in the endcase described above. We're done. Contrarily,
4906if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004907
Tim Petersc5dc4da2003-01-02 17:55:03 +00004908If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4909add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00004910local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004911
Tim Petersc5dc4da2003-01-02 17:55:03 +00004912Let
Tim Petersf3615152003-01-01 21:51:37 +00004913
Tim Peters4fede1a2003-01-04 00:26:59 +00004914 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004915
Tim Peters4fede1a2003-01-04 00:26:59 +00004916and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004917
Tim Peters8bb5ad22003-01-24 02:44:45 +00004918 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004919
Tim Peters8bb5ad22003-01-24 02:44:45 +00004920If so, we're done. If not, the tzinfo class is insane, according to the
4921assumptions we've made. This also requires a bit of proof. As before, let's
4922compute the difference between the LHS and RHS of [8] (and skipping some of
4923the justifications for the kinds of substitutions we've done several times
4924already):
Tim Peters4fede1a2003-01-04 00:26:59 +00004925
Tim Peters8bb5ad22003-01-24 02:44:45 +00004926 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
4927 x.n - (z.n + diff - z'.o) = replacing diff via [6]
4928 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
4929 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
4930 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00004931 - z.o + z'.o = #1 twice
4932 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4933 z'.d - z.d
4934
4935So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
Tim Peters8bb5ad22003-01-24 02:44:45 +00004936we've found the UTC-equivalent so are done. In fact, we stop with [7] and
4937return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00004938
Tim Peters8bb5ad22003-01-24 02:44:45 +00004939How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
4940a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
4941would have to change the result dst() returns: we start in DST, and moving
4942a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00004943
Tim Peters8bb5ad22003-01-24 02:44:45 +00004944There isn't a sane case where this can happen. The closest it gets is at
4945the end of DST, where there's an hour in UTC with no spelling in a hybrid
4946tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
4947that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
4948UTC) because the docs insist on that, but 0:MM is taken as being in daylight
4949time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
4950clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
4951standard time. Since that's what the local clock *does*, we want to map both
4952UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00004953in local time, but so it goes -- it's the way the local clock works.
4954
Tim Peters8bb5ad22003-01-24 02:44:45 +00004955When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4956so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4957z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
Tim Peters4fede1a2003-01-04 00:26:59 +00004958(correctly) concludes that z' is not UTC-equivalent to x.
4959
4960Because we know z.d said z was in daylight time (else [5] would have held and
4961we would have stopped then), and we know z.d != z'.d (else [8] would have held
4962and we we have stopped then), and there are only 2 possible values dst() can
4963return in Eastern, it follows that z'.d must be 0 (which it is in the example,
4964but the reasoning doesn't depend on the example -- it depends on there being
4965two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00004966z' must be in standard time, and is the spelling we want in this case.
4967
4968Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
4969concerned (because it takes z' as being in standard time rather than the
4970daylight time we intend here), but returning it gives the real-life "local
4971clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
4972tz.
4973
4974When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
4975the 1:MM standard time spelling we want.
4976
4977So how can this break? One of the assumptions must be violated. Two
4978possibilities:
4979
49801) [2] effectively says that y.s is invariant across all y belong to a given
4981 time zone. This isn't true if, for political reasons or continental drift,
4982 a region decides to change its base offset from UTC.
4983
49842) There may be versions of "double daylight" time where the tail end of
4985 the analysis gives up a step too early. I haven't thought about that
4986 enough to say.
4987
4988In any case, it's clear that the default fromutc() is strong enough to handle
4989"almost all" time zones: so long as the standard offset is invariant, it
4990doesn't matter if daylight time transition points change from year to year, or
4991if daylight time is skipped in some years; it doesn't matter how large or
4992small dst() may get within its bounds; and it doesn't even matter if some
4993perverse time zone returns a negative dst()). So a breaking case must be
4994pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00004995--------------------------------------------------------------------------- */