blob: 3ba2d18b967c8f42ba4d1cf0e6e4aeea65df6263 [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
Tim Peters2a799bf2002-12-16 20:18:38 +00001353/* ---------------------------------------------------------------------------
1354 * Class implementations.
1355 */
1356
1357/*
1358 * PyDateTime_Delta implementation.
1359 */
1360
1361/* Convert a timedelta to a number of us,
1362 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1363 * as a Python int or long.
1364 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1365 * due to ubiquitous overflow possibilities.
1366 */
1367static PyObject *
1368delta_to_microseconds(PyDateTime_Delta *self)
1369{
1370 PyObject *x1 = NULL;
1371 PyObject *x2 = NULL;
1372 PyObject *x3 = NULL;
1373 PyObject *result = NULL;
1374
1375 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1376 if (x1 == NULL)
1377 goto Done;
1378 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1379 if (x2 == NULL)
1380 goto Done;
1381 Py_DECREF(x1);
1382 x1 = NULL;
1383
1384 /* x2 has days in seconds */
1385 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1386 if (x1 == NULL)
1387 goto Done;
1388 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1389 if (x3 == NULL)
1390 goto Done;
1391 Py_DECREF(x1);
1392 Py_DECREF(x2);
1393 x1 = x2 = NULL;
1394
1395 /* x3 has days+seconds in seconds */
1396 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1397 if (x1 == NULL)
1398 goto Done;
1399 Py_DECREF(x3);
1400 x3 = NULL;
1401
1402 /* x1 has days+seconds in us */
1403 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1404 if (x2 == NULL)
1405 goto Done;
1406 result = PyNumber_Add(x1, x2);
1407
1408Done:
1409 Py_XDECREF(x1);
1410 Py_XDECREF(x2);
1411 Py_XDECREF(x3);
1412 return result;
1413}
1414
1415/* Convert a number of us (as a Python int or long) to a timedelta.
1416 */
1417static PyObject *
1418microseconds_to_delta(PyObject *pyus)
1419{
1420 int us;
1421 int s;
1422 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001423 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001424
1425 PyObject *tuple = NULL;
1426 PyObject *num = NULL;
1427 PyObject *result = NULL;
1428
1429 tuple = PyNumber_Divmod(pyus, us_per_second);
1430 if (tuple == NULL)
1431 goto Done;
1432
1433 num = PyTuple_GetItem(tuple, 1); /* us */
1434 if (num == NULL)
1435 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001436 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001437 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001438 if (temp == -1 && PyErr_Occurred())
1439 goto Done;
1440 assert(0 <= temp && temp < 1000000);
1441 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001442 if (us < 0) {
1443 /* The divisor was positive, so this must be an error. */
1444 assert(PyErr_Occurred());
1445 goto Done;
1446 }
1447
1448 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1449 if (num == NULL)
1450 goto Done;
1451 Py_INCREF(num);
1452 Py_DECREF(tuple);
1453
1454 tuple = PyNumber_Divmod(num, seconds_per_day);
1455 if (tuple == NULL)
1456 goto Done;
1457 Py_DECREF(num);
1458
1459 num = PyTuple_GetItem(tuple, 1); /* seconds */
1460 if (num == NULL)
1461 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001462 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001463 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001464 if (temp == -1 && PyErr_Occurred())
1465 goto Done;
1466 assert(0 <= temp && temp < 24*3600);
1467 s = (int)temp;
1468
Tim Peters2a799bf2002-12-16 20:18:38 +00001469 if (s < 0) {
1470 /* The divisor was positive, so this must be an error. */
1471 assert(PyErr_Occurred());
1472 goto Done;
1473 }
1474
1475 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1476 if (num == NULL)
1477 goto Done;
1478 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001479 temp = PyLong_AsLong(num);
1480 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001481 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001482 d = (int)temp;
1483 if ((long)d != temp) {
1484 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1485 "large to fit in a C int");
1486 goto Done;
1487 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001488 result = new_delta(d, s, us, 0);
1489
1490Done:
1491 Py_XDECREF(tuple);
1492 Py_XDECREF(num);
1493 return result;
1494}
1495
1496static PyObject *
1497multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1498{
1499 PyObject *pyus_in;
1500 PyObject *pyus_out;
1501 PyObject *result;
1502
1503 pyus_in = delta_to_microseconds(delta);
1504 if (pyus_in == NULL)
1505 return NULL;
1506
1507 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1508 Py_DECREF(pyus_in);
1509 if (pyus_out == NULL)
1510 return NULL;
1511
1512 result = microseconds_to_delta(pyus_out);
1513 Py_DECREF(pyus_out);
1514 return result;
1515}
1516
1517static PyObject *
1518divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1519{
1520 PyObject *pyus_in;
1521 PyObject *pyus_out;
1522 PyObject *result;
1523
1524 pyus_in = delta_to_microseconds(delta);
1525 if (pyus_in == NULL)
1526 return NULL;
1527
1528 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1529 Py_DECREF(pyus_in);
1530 if (pyus_out == NULL)
1531 return NULL;
1532
1533 result = microseconds_to_delta(pyus_out);
1534 Py_DECREF(pyus_out);
1535 return result;
1536}
1537
1538static PyObject *
1539delta_add(PyObject *left, PyObject *right)
1540{
1541 PyObject *result = Py_NotImplemented;
1542
1543 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1544 /* delta + delta */
1545 /* The C-level additions can't overflow because of the
1546 * invariant bounds.
1547 */
1548 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1549 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1550 int microseconds = GET_TD_MICROSECONDS(left) +
1551 GET_TD_MICROSECONDS(right);
1552 result = new_delta(days, seconds, microseconds, 1);
1553 }
1554
1555 if (result == Py_NotImplemented)
1556 Py_INCREF(result);
1557 return result;
1558}
1559
1560static PyObject *
1561delta_negative(PyDateTime_Delta *self)
1562{
1563 return new_delta(-GET_TD_DAYS(self),
1564 -GET_TD_SECONDS(self),
1565 -GET_TD_MICROSECONDS(self),
1566 1);
1567}
1568
1569static PyObject *
1570delta_positive(PyDateTime_Delta *self)
1571{
1572 /* Could optimize this (by returning self) if this isn't a
1573 * subclass -- but who uses unary + ? Approximately nobody.
1574 */
1575 return new_delta(GET_TD_DAYS(self),
1576 GET_TD_SECONDS(self),
1577 GET_TD_MICROSECONDS(self),
1578 0);
1579}
1580
1581static PyObject *
1582delta_abs(PyDateTime_Delta *self)
1583{
1584 PyObject *result;
1585
1586 assert(GET_TD_MICROSECONDS(self) >= 0);
1587 assert(GET_TD_SECONDS(self) >= 0);
1588
1589 if (GET_TD_DAYS(self) < 0)
1590 result = delta_negative(self);
1591 else
1592 result = delta_positive(self);
1593
1594 return result;
1595}
1596
1597static PyObject *
1598delta_subtract(PyObject *left, PyObject *right)
1599{
1600 PyObject *result = Py_NotImplemented;
1601
1602 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1603 /* delta - delta */
1604 PyObject *minus_right = PyNumber_Negative(right);
1605 if (minus_right) {
1606 result = delta_add(left, minus_right);
1607 Py_DECREF(minus_right);
1608 }
1609 else
1610 result = NULL;
1611 }
1612
1613 if (result == Py_NotImplemented)
1614 Py_INCREF(result);
1615 return result;
1616}
1617
1618/* This is more natural as a tp_compare, but doesn't work then: for whatever
1619 * reason, Python's try_3way_compare ignores tp_compare unless
1620 * PyInstance_Check returns true, but these aren't old-style classes.
1621 */
1622static PyObject *
1623delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1624{
1625 int diff;
1626
1627 if (! PyDelta_CheckExact(other)) {
1628 PyErr_Format(PyExc_TypeError,
1629 "can't compare %s to %s instance",
1630 self->ob_type->tp_name, other->ob_type->tp_name);
1631 return NULL;
1632 }
1633 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1634 if (diff == 0) {
1635 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1636 if (diff == 0)
1637 diff = GET_TD_MICROSECONDS(self) -
1638 GET_TD_MICROSECONDS(other);
1639 }
1640 return diff_to_bool(diff, op);
1641}
1642
1643static PyObject *delta_getstate(PyDateTime_Delta *self);
1644
1645static long
1646delta_hash(PyDateTime_Delta *self)
1647{
1648 if (self->hashcode == -1) {
1649 PyObject *temp = delta_getstate(self);
1650 if (temp != NULL) {
1651 self->hashcode = PyObject_Hash(temp);
1652 Py_DECREF(temp);
1653 }
1654 }
1655 return self->hashcode;
1656}
1657
1658static PyObject *
1659delta_multiply(PyObject *left, PyObject *right)
1660{
1661 PyObject *result = Py_NotImplemented;
1662
1663 if (PyDelta_Check(left)) {
1664 /* delta * ??? */
1665 if (PyInt_Check(right) || PyLong_Check(right))
1666 result = multiply_int_timedelta(right,
1667 (PyDateTime_Delta *) left);
1668 }
1669 else if (PyInt_Check(left) || PyLong_Check(left))
1670 result = multiply_int_timedelta(left,
1671 (PyDateTime_Delta *) right);
1672
1673 if (result == Py_NotImplemented)
1674 Py_INCREF(result);
1675 return result;
1676}
1677
1678static PyObject *
1679delta_divide(PyObject *left, PyObject *right)
1680{
1681 PyObject *result = Py_NotImplemented;
1682
1683 if (PyDelta_Check(left)) {
1684 /* delta * ??? */
1685 if (PyInt_Check(right) || PyLong_Check(right))
1686 result = divide_timedelta_int(
1687 (PyDateTime_Delta *)left,
1688 right);
1689 }
1690
1691 if (result == Py_NotImplemented)
1692 Py_INCREF(result);
1693 return result;
1694}
1695
1696/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1697 * timedelta constructor. sofar is the # of microseconds accounted for
1698 * so far, and there are factor microseconds per current unit, the number
1699 * of which is given by num. num * factor is added to sofar in a
1700 * numerically careful way, and that's the result. Any fractional
1701 * microseconds left over (this can happen if num is a float type) are
1702 * added into *leftover.
1703 * Note that there are many ways this can give an error (NULL) return.
1704 */
1705static PyObject *
1706accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1707 double *leftover)
1708{
1709 PyObject *prod;
1710 PyObject *sum;
1711
1712 assert(num != NULL);
1713
1714 if (PyInt_Check(num) || PyLong_Check(num)) {
1715 prod = PyNumber_Multiply(num, factor);
1716 if (prod == NULL)
1717 return NULL;
1718 sum = PyNumber_Add(sofar, prod);
1719 Py_DECREF(prod);
1720 return sum;
1721 }
1722
1723 if (PyFloat_Check(num)) {
1724 double dnum;
1725 double fracpart;
1726 double intpart;
1727 PyObject *x;
1728 PyObject *y;
1729
1730 /* The Plan: decompose num into an integer part and a
1731 * fractional part, num = intpart + fracpart.
1732 * Then num * factor ==
1733 * intpart * factor + fracpart * factor
1734 * and the LHS can be computed exactly in long arithmetic.
1735 * The RHS is again broken into an int part and frac part.
1736 * and the frac part is added into *leftover.
1737 */
1738 dnum = PyFloat_AsDouble(num);
1739 if (dnum == -1.0 && PyErr_Occurred())
1740 return NULL;
1741 fracpart = modf(dnum, &intpart);
1742 x = PyLong_FromDouble(intpart);
1743 if (x == NULL)
1744 return NULL;
1745
1746 prod = PyNumber_Multiply(x, factor);
1747 Py_DECREF(x);
1748 if (prod == NULL)
1749 return NULL;
1750
1751 sum = PyNumber_Add(sofar, prod);
1752 Py_DECREF(prod);
1753 if (sum == NULL)
1754 return NULL;
1755
1756 if (fracpart == 0.0)
1757 return sum;
1758 /* So far we've lost no information. Dealing with the
1759 * fractional part requires float arithmetic, and may
1760 * lose a little info.
1761 */
1762 assert(PyInt_Check(factor) || PyLong_Check(factor));
1763 if (PyInt_Check(factor))
1764 dnum = (double)PyInt_AsLong(factor);
1765 else
1766 dnum = PyLong_AsDouble(factor);
1767
1768 dnum *= fracpart;
1769 fracpart = modf(dnum, &intpart);
1770 x = PyLong_FromDouble(intpart);
1771 if (x == NULL) {
1772 Py_DECREF(sum);
1773 return NULL;
1774 }
1775
1776 y = PyNumber_Add(sum, x);
1777 Py_DECREF(sum);
1778 Py_DECREF(x);
1779 *leftover += fracpart;
1780 return y;
1781 }
1782
1783 PyErr_Format(PyExc_TypeError,
1784 "unsupported type for timedelta %s component: %s",
1785 tag, num->ob_type->tp_name);
1786 return NULL;
1787}
1788
1789static PyObject *
1790delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1791{
1792 PyObject *self = NULL;
1793
1794 /* Argument objects. */
1795 PyObject *day = NULL;
1796 PyObject *second = NULL;
1797 PyObject *us = NULL;
1798 PyObject *ms = NULL;
1799 PyObject *minute = NULL;
1800 PyObject *hour = NULL;
1801 PyObject *week = NULL;
1802
1803 PyObject *x = NULL; /* running sum of microseconds */
1804 PyObject *y = NULL; /* temp sum of microseconds */
1805 double leftover_us = 0.0;
1806
1807 static char *keywords[] = {
1808 "days", "seconds", "microseconds", "milliseconds",
1809 "minutes", "hours", "weeks", NULL
1810 };
1811
1812 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1813 keywords,
1814 &day, &second, &us,
1815 &ms, &minute, &hour, &week) == 0)
1816 goto Done;
1817
1818 x = PyInt_FromLong(0);
1819 if (x == NULL)
1820 goto Done;
1821
1822#define CLEANUP \
1823 Py_DECREF(x); \
1824 x = y; \
1825 if (x == NULL) \
1826 goto Done
1827
1828 if (us) {
1829 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1830 CLEANUP;
1831 }
1832 if (ms) {
1833 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1834 CLEANUP;
1835 }
1836 if (second) {
1837 y = accum("seconds", x, second, us_per_second, &leftover_us);
1838 CLEANUP;
1839 }
1840 if (minute) {
1841 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1842 CLEANUP;
1843 }
1844 if (hour) {
1845 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1846 CLEANUP;
1847 }
1848 if (day) {
1849 y = accum("days", x, day, us_per_day, &leftover_us);
1850 CLEANUP;
1851 }
1852 if (week) {
1853 y = accum("weeks", x, week, us_per_week, &leftover_us);
1854 CLEANUP;
1855 }
1856 if (leftover_us) {
1857 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001858 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001859 if (temp == NULL) {
1860 Py_DECREF(x);
1861 goto Done;
1862 }
1863 y = PyNumber_Add(x, temp);
1864 Py_DECREF(temp);
1865 CLEANUP;
1866 }
1867
1868 self = microseconds_to_delta(x);
1869 Py_DECREF(x);
1870Done:
1871 return self;
1872
1873#undef CLEANUP
1874}
1875
1876static int
1877delta_nonzero(PyDateTime_Delta *self)
1878{
1879 return (GET_TD_DAYS(self) != 0
1880 || GET_TD_SECONDS(self) != 0
1881 || GET_TD_MICROSECONDS(self) != 0);
1882}
1883
1884static PyObject *
1885delta_repr(PyDateTime_Delta *self)
1886{
1887 if (GET_TD_MICROSECONDS(self) != 0)
1888 return PyString_FromFormat("%s(%d, %d, %d)",
1889 self->ob_type->tp_name,
1890 GET_TD_DAYS(self),
1891 GET_TD_SECONDS(self),
1892 GET_TD_MICROSECONDS(self));
1893 if (GET_TD_SECONDS(self) != 0)
1894 return PyString_FromFormat("%s(%d, %d)",
1895 self->ob_type->tp_name,
1896 GET_TD_DAYS(self),
1897 GET_TD_SECONDS(self));
1898
1899 return PyString_FromFormat("%s(%d)",
1900 self->ob_type->tp_name,
1901 GET_TD_DAYS(self));
1902}
1903
1904static PyObject *
1905delta_str(PyDateTime_Delta *self)
1906{
1907 int days = GET_TD_DAYS(self);
1908 int seconds = GET_TD_SECONDS(self);
1909 int us = GET_TD_MICROSECONDS(self);
1910 int hours;
1911 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001912 char buf[100];
1913 char *pbuf = buf;
1914 size_t buflen = sizeof(buf);
1915 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001916
1917 minutes = divmod(seconds, 60, &seconds);
1918 hours = divmod(minutes, 60, &minutes);
1919
1920 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00001921 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
1922 (days == 1 || days == -1) ? "" : "s");
1923 if (n < 0 || (size_t)n >= buflen)
1924 goto Fail;
1925 pbuf += n;
1926 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001927 }
1928
Tim Petersba873472002-12-18 20:19:21 +00001929 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
1930 hours, minutes, seconds);
1931 if (n < 0 || (size_t)n >= buflen)
1932 goto Fail;
1933 pbuf += n;
1934 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001935
1936 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00001937 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
1938 if (n < 0 || (size_t)n >= buflen)
1939 goto Fail;
1940 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001941 }
1942
Tim Petersba873472002-12-18 20:19:21 +00001943 return PyString_FromStringAndSize(buf, pbuf - buf);
1944
1945 Fail:
1946 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
1947 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001948}
1949
1950/* Pickle support. Quite a maze! While __getstate__/__setstate__ sufficed
1951 * in the Python implementation, the C implementation also requires
1952 * __reduce__, and a __safe_for_unpickling__ attr in the type object.
1953 */
1954static PyObject *
1955delta_getstate(PyDateTime_Delta *self)
1956{
1957 return Py_BuildValue("iii", GET_TD_DAYS(self),
1958 GET_TD_SECONDS(self),
1959 GET_TD_MICROSECONDS(self));
1960}
1961
1962static PyObject *
1963delta_setstate(PyDateTime_Delta *self, PyObject *state)
1964{
1965 int day;
1966 int second;
1967 int us;
1968
1969 if (!PyArg_ParseTuple(state, "iii:__setstate__", &day, &second, &us))
1970 return NULL;
1971
1972 self->hashcode = -1;
1973 SET_TD_DAYS(self, day);
1974 SET_TD_SECONDS(self, second);
1975 SET_TD_MICROSECONDS(self, us);
1976
1977 Py_INCREF(Py_None);
1978 return Py_None;
1979}
1980
1981static PyObject *
1982delta_reduce(PyDateTime_Delta* self)
1983{
1984 PyObject* result = NULL;
1985 PyObject* state = delta_getstate(self);
1986
1987 if (state != NULL) {
1988 /* The funky "()" in the format string creates an empty
1989 * tuple as the 2nd component of the result 3-tuple.
1990 */
1991 result = Py_BuildValue("O()O", self->ob_type, state);
1992 Py_DECREF(state);
1993 }
1994 return result;
1995}
1996
1997#define OFFSET(field) offsetof(PyDateTime_Delta, field)
1998
1999static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002000
Neal Norwitzdfb80862002-12-19 02:30:56 +00002001 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002002 PyDoc_STR("Number of days.")},
2003
Neal Norwitzdfb80862002-12-19 02:30:56 +00002004 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002005 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2006
Neal Norwitzdfb80862002-12-19 02:30:56 +00002007 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002008 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2009 {NULL}
2010};
2011
2012static PyMethodDef delta_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00002013
Guido van Rossum177e41a2003-01-30 22:06:23 +00002014 {"__setstate__", (PyCFunction)delta_setstate, METH_O,
Tim Peters2a799bf2002-12-16 20:18:38 +00002015 PyDoc_STR("__setstate__(state)")},
2016
2017 {"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS,
2018 PyDoc_STR("__getstate__() -> state")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00002019
2020 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2021 PyDoc_STR("__reduce__() -> (cls, state)")},
2022
Tim Peters2a799bf2002-12-16 20:18:38 +00002023 {NULL, NULL},
2024};
2025
2026static char delta_doc[] =
2027PyDoc_STR("Difference between two datetime values.");
2028
2029static PyNumberMethods delta_as_number = {
2030 delta_add, /* nb_add */
2031 delta_subtract, /* nb_subtract */
2032 delta_multiply, /* nb_multiply */
2033 delta_divide, /* nb_divide */
2034 0, /* nb_remainder */
2035 0, /* nb_divmod */
2036 0, /* nb_power */
2037 (unaryfunc)delta_negative, /* nb_negative */
2038 (unaryfunc)delta_positive, /* nb_positive */
2039 (unaryfunc)delta_abs, /* nb_absolute */
2040 (inquiry)delta_nonzero, /* nb_nonzero */
2041 0, /*nb_invert*/
2042 0, /*nb_lshift*/
2043 0, /*nb_rshift*/
2044 0, /*nb_and*/
2045 0, /*nb_xor*/
2046 0, /*nb_or*/
2047 0, /*nb_coerce*/
2048 0, /*nb_int*/
2049 0, /*nb_long*/
2050 0, /*nb_float*/
2051 0, /*nb_oct*/
2052 0, /*nb_hex*/
2053 0, /*nb_inplace_add*/
2054 0, /*nb_inplace_subtract*/
2055 0, /*nb_inplace_multiply*/
2056 0, /*nb_inplace_divide*/
2057 0, /*nb_inplace_remainder*/
2058 0, /*nb_inplace_power*/
2059 0, /*nb_inplace_lshift*/
2060 0, /*nb_inplace_rshift*/
2061 0, /*nb_inplace_and*/
2062 0, /*nb_inplace_xor*/
2063 0, /*nb_inplace_or*/
2064 delta_divide, /* nb_floor_divide */
2065 0, /* nb_true_divide */
2066 0, /* nb_inplace_floor_divide */
2067 0, /* nb_inplace_true_divide */
2068};
2069
2070static PyTypeObject PyDateTime_DeltaType = {
2071 PyObject_HEAD_INIT(NULL)
2072 0, /* ob_size */
2073 "datetime.timedelta", /* tp_name */
2074 sizeof(PyDateTime_Delta), /* tp_basicsize */
2075 0, /* tp_itemsize */
2076 0, /* tp_dealloc */
2077 0, /* tp_print */
2078 0, /* tp_getattr */
2079 0, /* tp_setattr */
2080 0, /* tp_compare */
2081 (reprfunc)delta_repr, /* tp_repr */
2082 &delta_as_number, /* tp_as_number */
2083 0, /* tp_as_sequence */
2084 0, /* tp_as_mapping */
2085 (hashfunc)delta_hash, /* tp_hash */
2086 0, /* tp_call */
2087 (reprfunc)delta_str, /* tp_str */
2088 PyObject_GenericGetAttr, /* tp_getattro */
2089 0, /* tp_setattro */
2090 0, /* tp_as_buffer */
2091 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
2092 delta_doc, /* tp_doc */
2093 0, /* tp_traverse */
2094 0, /* tp_clear */
2095 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2096 0, /* tp_weaklistoffset */
2097 0, /* tp_iter */
2098 0, /* tp_iternext */
2099 delta_methods, /* tp_methods */
2100 delta_members, /* tp_members */
2101 0, /* tp_getset */
2102 0, /* tp_base */
2103 0, /* tp_dict */
2104 0, /* tp_descr_get */
2105 0, /* tp_descr_set */
2106 0, /* tp_dictoffset */
2107 0, /* tp_init */
2108 0, /* tp_alloc */
2109 delta_new, /* tp_new */
2110 _PyObject_Del, /* tp_free */
2111};
2112
2113/*
2114 * PyDateTime_Date implementation.
2115 */
2116
2117/* Accessor properties. */
2118
2119static PyObject *
2120date_year(PyDateTime_Date *self, void *unused)
2121{
2122 return PyInt_FromLong(GET_YEAR(self));
2123}
2124
2125static PyObject *
2126date_month(PyDateTime_Date *self, void *unused)
2127{
2128 return PyInt_FromLong(GET_MONTH(self));
2129}
2130
2131static PyObject *
2132date_day(PyDateTime_Date *self, void *unused)
2133{
2134 return PyInt_FromLong(GET_DAY(self));
2135}
2136
2137static PyGetSetDef date_getset[] = {
2138 {"year", (getter)date_year},
2139 {"month", (getter)date_month},
2140 {"day", (getter)date_day},
2141 {NULL}
2142};
2143
2144/* Constructors. */
2145
Tim Peters12bf3392002-12-24 05:41:27 +00002146static char *date_kws[] = {"year", "month", "day", NULL};
2147
Guido van Rossum177e41a2003-01-30 22:06:23 +00002148static PyObject *date_setstate(PyDateTime_Date *self, PyObject *arg);
2149
Tim Peters2a799bf2002-12-16 20:18:38 +00002150static PyObject *
2151date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2152{
2153 PyObject *self = NULL;
2154 int year;
2155 int month;
2156 int day;
2157
Guido van Rossum177e41a2003-01-30 22:06:23 +00002158 /* Check for invocation from pickle with __getstate__ state */
2159 if (PyTuple_GET_SIZE(args) == 1 &&
2160 PyString_Check(PyTuple_GET_ITEM(args, 0)))
2161 {
2162 self = new_date(1, 1, 1);
2163 if (self != NULL) {
2164 PyObject *res = date_setstate(
2165 (PyDateTime_Date *)self, args);
2166 if (res == Py_None)
2167 Py_DECREF(res);
2168 else {
2169 Py_DECREF(self);
2170 self = NULL;
2171 }
2172 }
2173 return self;
2174 }
2175
Tim Peters12bf3392002-12-24 05:41:27 +00002176 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002177 &year, &month, &day)) {
2178 if (check_date_args(year, month, day) < 0)
2179 return NULL;
2180 self = new_date(year, month, day);
2181 }
2182 return self;
2183}
2184
2185/* Return new date from localtime(t). */
2186static PyObject *
2187date_local_from_time_t(PyObject *cls, time_t t)
2188{
2189 struct tm *tm;
2190 PyObject *result = NULL;
2191
2192 tm = localtime(&t);
2193 if (tm)
2194 result = PyObject_CallFunction(cls, "iii",
2195 tm->tm_year + 1900,
2196 tm->tm_mon + 1,
2197 tm->tm_mday);
2198 else
2199 PyErr_SetString(PyExc_ValueError,
2200 "timestamp out of range for "
2201 "platform localtime() function");
2202 return result;
2203}
2204
2205/* Return new date from current time.
2206 * We say this is equivalent to fromtimestamp(time.time()), and the
2207 * only way to be sure of that is to *call* time.time(). That's not
2208 * generally the same as calling C's time.
2209 */
2210static PyObject *
2211date_today(PyObject *cls, PyObject *dummy)
2212{
2213 PyObject *time;
2214 PyObject *result;
2215
2216 time = time_time();
2217 if (time == NULL)
2218 return NULL;
2219
2220 /* Note well: today() is a class method, so this may not call
2221 * date.fromtimestamp. For example, it may call
2222 * datetime.fromtimestamp. That's why we need all the accuracy
2223 * time.time() delivers; if someone were gonzo about optimization,
2224 * date.today() could get away with plain C time().
2225 */
2226 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2227 Py_DECREF(time);
2228 return result;
2229}
2230
2231/* Return new date from given timestamp (Python timestamp -- a double). */
2232static PyObject *
2233date_fromtimestamp(PyObject *cls, PyObject *args)
2234{
2235 double timestamp;
2236 PyObject *result = NULL;
2237
2238 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2239 result = date_local_from_time_t(cls, (time_t)timestamp);
2240 return result;
2241}
2242
2243/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2244 * the ordinal is out of range.
2245 */
2246static PyObject *
2247date_fromordinal(PyObject *cls, PyObject *args)
2248{
2249 PyObject *result = NULL;
2250 int ordinal;
2251
2252 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2253 int year;
2254 int month;
2255 int day;
2256
2257 if (ordinal < 1)
2258 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2259 ">= 1");
2260 else {
2261 ord_to_ymd(ordinal, &year, &month, &day);
2262 result = PyObject_CallFunction(cls, "iii",
2263 year, month, day);
2264 }
2265 }
2266 return result;
2267}
2268
2269/*
2270 * Date arithmetic.
2271 */
2272
2273/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2274 * instead.
2275 */
2276static PyObject *
2277add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2278{
2279 PyObject *result = NULL;
2280 int year = GET_YEAR(date);
2281 int month = GET_MONTH(date);
2282 int deltadays = GET_TD_DAYS(delta);
2283 /* C-level overflow is impossible because |deltadays| < 1e9. */
2284 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2285
2286 if (normalize_date(&year, &month, &day) >= 0)
2287 result = new_date(year, month, day);
2288 return result;
2289}
2290
2291static PyObject *
2292date_add(PyObject *left, PyObject *right)
2293{
2294 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2295 Py_INCREF(Py_NotImplemented);
2296 return Py_NotImplemented;
2297 }
2298 if (PyDate_CheckExact(left)) {
2299 /* date + ??? */
2300 if (PyDelta_Check(right))
2301 /* date + delta */
2302 return add_date_timedelta((PyDateTime_Date *) left,
2303 (PyDateTime_Delta *) right,
2304 0);
2305 }
2306 else {
2307 /* ??? + date
2308 * 'right' must be one of us, or we wouldn't have been called
2309 */
2310 if (PyDelta_Check(left))
2311 /* delta + date */
2312 return add_date_timedelta((PyDateTime_Date *) right,
2313 (PyDateTime_Delta *) left,
2314 0);
2315 }
2316 Py_INCREF(Py_NotImplemented);
2317 return Py_NotImplemented;
2318}
2319
2320static PyObject *
2321date_subtract(PyObject *left, PyObject *right)
2322{
2323 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2324 Py_INCREF(Py_NotImplemented);
2325 return Py_NotImplemented;
2326 }
2327 if (PyDate_CheckExact(left)) {
2328 if (PyDate_CheckExact(right)) {
2329 /* date - date */
2330 int left_ord = ymd_to_ord(GET_YEAR(left),
2331 GET_MONTH(left),
2332 GET_DAY(left));
2333 int right_ord = ymd_to_ord(GET_YEAR(right),
2334 GET_MONTH(right),
2335 GET_DAY(right));
2336 return new_delta(left_ord - right_ord, 0, 0, 0);
2337 }
2338 if (PyDelta_Check(right)) {
2339 /* date - delta */
2340 return add_date_timedelta((PyDateTime_Date *) left,
2341 (PyDateTime_Delta *) right,
2342 1);
2343 }
2344 }
2345 Py_INCREF(Py_NotImplemented);
2346 return Py_NotImplemented;
2347}
2348
2349
2350/* Various ways to turn a date into a string. */
2351
2352static PyObject *
2353date_repr(PyDateTime_Date *self)
2354{
2355 char buffer[1028];
2356 char *typename;
2357
2358 typename = self->ob_type->tp_name;
2359 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2360 typename,
2361 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2362
2363 return PyString_FromString(buffer);
2364}
2365
2366static PyObject *
2367date_isoformat(PyDateTime_Date *self)
2368{
2369 char buffer[128];
2370
2371 isoformat_date(self, buffer, sizeof(buffer));
2372 return PyString_FromString(buffer);
2373}
2374
2375/* str() calls the appropriate isofomat() method. */
2376static PyObject *
2377date_str(PyDateTime_Date *self)
2378{
2379 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2380}
2381
2382
2383static PyObject *
2384date_ctime(PyDateTime_Date *self)
2385{
2386 return format_ctime(self, 0, 0, 0);
2387}
2388
2389static PyObject *
2390date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2391{
2392 /* This method can be inherited, and needs to call the
2393 * timetuple() method appropriate to self's class.
2394 */
2395 PyObject *result;
2396 PyObject *format;
2397 PyObject *tuple;
2398 static char *keywords[] = {"format", NULL};
2399
2400 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2401 &PyString_Type, &format))
2402 return NULL;
2403
2404 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2405 if (tuple == NULL)
2406 return NULL;
Tim Petersbad8ff02002-12-30 20:52:32 +00002407 result = wrap_strftime((PyObject *)self, format, tuple,
2408 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002409 Py_DECREF(tuple);
2410 return result;
2411}
2412
2413/* ISO methods. */
2414
2415static PyObject *
2416date_isoweekday(PyDateTime_Date *self)
2417{
2418 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2419
2420 return PyInt_FromLong(dow + 1);
2421}
2422
2423static PyObject *
2424date_isocalendar(PyDateTime_Date *self)
2425{
2426 int year = GET_YEAR(self);
2427 int week1_monday = iso_week1_monday(year);
2428 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2429 int week;
2430 int day;
2431
2432 week = divmod(today - week1_monday, 7, &day);
2433 if (week < 0) {
2434 --year;
2435 week1_monday = iso_week1_monday(year);
2436 week = divmod(today - week1_monday, 7, &day);
2437 }
2438 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2439 ++year;
2440 week = 0;
2441 }
2442 return Py_BuildValue("iii", year, week + 1, day + 1);
2443}
2444
2445/* Miscellaneous methods. */
2446
2447/* This is more natural as a tp_compare, but doesn't work then: for whatever
2448 * reason, Python's try_3way_compare ignores tp_compare unless
2449 * PyInstance_Check returns true, but these aren't old-style classes.
2450 */
2451static PyObject *
2452date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2453{
2454 int diff;
2455
2456 if (! PyDate_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00002457 if (PyObject_HasAttrString(other, "timetuple")) {
2458 /* A hook for other kinds of date objects. */
2459 Py_INCREF(Py_NotImplemented);
2460 return Py_NotImplemented;
2461 }
2462 /* Stop this from falling back to address comparison. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002463 PyErr_Format(PyExc_TypeError,
Tim Peters8d81a012003-01-24 22:36:34 +00002464 "can't compare '%s' to '%s'",
2465 self->ob_type->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002466 other->ob_type->tp_name);
2467 return NULL;
2468 }
2469 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2470 _PyDateTime_DATE_DATASIZE);
2471 return diff_to_bool(diff, op);
2472}
2473
2474static PyObject *
2475date_timetuple(PyDateTime_Date *self)
2476{
2477 return build_struct_time(GET_YEAR(self),
2478 GET_MONTH(self),
2479 GET_DAY(self),
2480 0, 0, 0, -1);
2481}
2482
Tim Peters12bf3392002-12-24 05:41:27 +00002483static PyObject *
2484date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2485{
2486 PyObject *clone;
2487 PyObject *tuple;
2488 int year = GET_YEAR(self);
2489 int month = GET_MONTH(self);
2490 int day = GET_DAY(self);
2491
2492 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2493 &year, &month, &day))
2494 return NULL;
2495 tuple = Py_BuildValue("iii", year, month, day);
2496 if (tuple == NULL)
2497 return NULL;
2498 clone = date_new(self->ob_type, tuple, NULL);
2499 Py_DECREF(tuple);
2500 return clone;
2501}
2502
Tim Peters2a799bf2002-12-16 20:18:38 +00002503static PyObject *date_getstate(PyDateTime_Date *self);
2504
2505static long
2506date_hash(PyDateTime_Date *self)
2507{
2508 if (self->hashcode == -1) {
2509 PyObject *temp = date_getstate(self);
2510 if (temp != NULL) {
2511 self->hashcode = PyObject_Hash(temp);
2512 Py_DECREF(temp);
2513 }
2514 }
2515 return self->hashcode;
2516}
2517
2518static PyObject *
2519date_toordinal(PyDateTime_Date *self)
2520{
2521 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2522 GET_DAY(self)));
2523}
2524
2525static PyObject *
2526date_weekday(PyDateTime_Date *self)
2527{
2528 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2529
2530 return PyInt_FromLong(dow);
2531}
2532
2533/* Pickle support. Quite a maze! */
2534
2535static PyObject *
2536date_getstate(PyDateTime_Date *self)
2537{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002538 return Py_BuildValue(
2539 "(N)",
2540 PyString_FromStringAndSize((char *)self->data,
2541 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002542}
2543
2544static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002545date_setstate(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002546{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002547 PyObject *state;
2548 int len;
2549 unsigned char *pdata;
Tim Peters2a799bf2002-12-16 20:18:38 +00002550
Guido van Rossum177e41a2003-01-30 22:06:23 +00002551 if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1) {
2552 error:
Tim Peters2a799bf2002-12-16 20:18:38 +00002553 PyErr_SetString(PyExc_TypeError,
2554 "bad argument to date.__setstate__");
2555 return NULL;
2556 }
Guido van Rossum177e41a2003-01-30 22:06:23 +00002557 state = PyTuple_GET_ITEM(arg, 0);
2558 if (!PyString_Check(state))
2559 goto error;
2560
2561 len = PyString_Size(state);
2562 if (len != _PyDateTime_DATE_DATASIZE)
2563 goto error;
2564
2565 pdata = (unsigned char*)PyString_AsString(state);
Tim Peters2a799bf2002-12-16 20:18:38 +00002566 memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE);
2567 self->hashcode = -1;
2568
2569 Py_INCREF(Py_None);
2570 return Py_None;
2571}
2572
Tim Peters2a799bf2002-12-16 20:18:38 +00002573static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002574date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002575{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002576 return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002577}
2578
2579static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002580
Tim Peters2a799bf2002-12-16 20:18:38 +00002581 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002582
Tim Peters2a799bf2002-12-16 20:18:38 +00002583 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2584 METH_CLASS,
2585 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2586 "time.time()).")},
2587
2588 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2589 METH_CLASS,
2590 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2591 "ordinal.")},
2592
2593 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2594 PyDoc_STR("Current date or datetime: same as "
2595 "self.__class__.fromtimestamp(time.time()).")},
2596
2597 /* Instance methods: */
2598
2599 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2600 PyDoc_STR("Return ctime() style string.")},
2601
2602 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2603 PyDoc_STR("format -> strftime() style string.")},
2604
2605 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2606 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2607
2608 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2609 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2610 "weekday.")},
2611
2612 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2613 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2614
2615 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2616 PyDoc_STR("Return the day of the week represented by the date.\n"
2617 "Monday == 1 ... Sunday == 7")},
2618
2619 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2620 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2621 "1 is day 1.")},
2622
2623 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2624 PyDoc_STR("Return the day of the week represented by the date.\n"
2625 "Monday == 0 ... Sunday == 6")},
2626
Tim Peters12bf3392002-12-24 05:41:27 +00002627 {"replace", (PyCFunction)date_replace, METH_KEYWORDS,
2628 PyDoc_STR("Return date with new specified fields.")},
2629
Tim Peters2a799bf2002-12-16 20:18:38 +00002630 {"__setstate__", (PyCFunction)date_setstate, METH_O,
2631 PyDoc_STR("__setstate__(state)")},
2632
2633 {"__getstate__", (PyCFunction)date_getstate, METH_NOARGS,
2634 PyDoc_STR("__getstate__() -> state")},
2635
Guido van Rossum177e41a2003-01-30 22:06:23 +00002636 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2637 PyDoc_STR("__reduce__() -> (cls, state)")},
2638
Tim Peters2a799bf2002-12-16 20:18:38 +00002639 {NULL, NULL}
2640};
2641
2642static char date_doc[] =
2643PyDoc_STR("Basic date type.");
2644
2645static PyNumberMethods date_as_number = {
2646 date_add, /* nb_add */
2647 date_subtract, /* nb_subtract */
2648 0, /* nb_multiply */
2649 0, /* nb_divide */
2650 0, /* nb_remainder */
2651 0, /* nb_divmod */
2652 0, /* nb_power */
2653 0, /* nb_negative */
2654 0, /* nb_positive */
2655 0, /* nb_absolute */
2656 0, /* nb_nonzero */
2657};
2658
2659static PyTypeObject PyDateTime_DateType = {
2660 PyObject_HEAD_INIT(NULL)
2661 0, /* ob_size */
2662 "datetime.date", /* tp_name */
2663 sizeof(PyDateTime_Date), /* tp_basicsize */
2664 0, /* tp_itemsize */
2665 (destructor)PyObject_Del, /* tp_dealloc */
2666 0, /* tp_print */
2667 0, /* tp_getattr */
2668 0, /* tp_setattr */
2669 0, /* tp_compare */
2670 (reprfunc)date_repr, /* tp_repr */
2671 &date_as_number, /* tp_as_number */
2672 0, /* tp_as_sequence */
2673 0, /* tp_as_mapping */
2674 (hashfunc)date_hash, /* tp_hash */
2675 0, /* tp_call */
2676 (reprfunc)date_str, /* tp_str */
2677 PyObject_GenericGetAttr, /* tp_getattro */
2678 0, /* tp_setattro */
2679 0, /* tp_as_buffer */
2680 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2681 Py_TPFLAGS_BASETYPE, /* tp_flags */
2682 date_doc, /* tp_doc */
2683 0, /* tp_traverse */
2684 0, /* tp_clear */
2685 (richcmpfunc)date_richcompare, /* tp_richcompare */
2686 0, /* tp_weaklistoffset */
2687 0, /* tp_iter */
2688 0, /* tp_iternext */
2689 date_methods, /* tp_methods */
2690 0, /* tp_members */
2691 date_getset, /* tp_getset */
2692 0, /* tp_base */
2693 0, /* tp_dict */
2694 0, /* tp_descr_get */
2695 0, /* tp_descr_set */
2696 0, /* tp_dictoffset */
2697 0, /* tp_init */
2698 0, /* tp_alloc */
2699 date_new, /* tp_new */
2700 _PyObject_Del, /* tp_free */
2701};
2702
2703/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002704 * PyDateTime_TZInfo implementation.
2705 */
2706
2707/* This is a pure abstract base class, so doesn't do anything beyond
2708 * raising NotImplemented exceptions. Real tzinfo classes need
2709 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002710 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002711 * be subclasses of this tzinfo class, which is easy and quick to check).
2712 *
2713 * Note: For reasons having to do with pickling of subclasses, we have
2714 * to allow tzinfo objects to be instantiated. This wasn't an issue
2715 * in the Python implementation (__init__() could raise NotImplementedError
2716 * there without ill effect), but doing so in the C implementation hit a
2717 * brick wall.
2718 */
2719
2720static PyObject *
2721tzinfo_nogo(const char* methodname)
2722{
2723 PyErr_Format(PyExc_NotImplementedError,
2724 "a tzinfo subclass must implement %s()",
2725 methodname);
2726 return NULL;
2727}
2728
2729/* Methods. A subclass must implement these. */
2730
Tim Peters52dcce22003-01-23 16:36:11 +00002731static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002732tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2733{
2734 return tzinfo_nogo("tzname");
2735}
2736
Tim Peters52dcce22003-01-23 16:36:11 +00002737static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002738tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2739{
2740 return tzinfo_nogo("utcoffset");
2741}
2742
Tim Peters52dcce22003-01-23 16:36:11 +00002743static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002744tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2745{
2746 return tzinfo_nogo("dst");
2747}
2748
Tim Peters52dcce22003-01-23 16:36:11 +00002749static PyObject *
2750tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2751{
2752 int y, m, d, hh, mm, ss, us;
2753
2754 PyObject *result;
2755 int off, dst;
2756 int none;
2757 int delta;
2758
2759 if (! PyDateTime_Check(dt)) {
2760 PyErr_SetString(PyExc_TypeError,
2761 "fromutc: argument must be a datetime");
2762 return NULL;
2763 }
2764 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2765 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2766 "is not self");
2767 return NULL;
2768 }
2769
2770 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2771 if (off == -1 && PyErr_Occurred())
2772 return NULL;
2773 if (none) {
2774 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2775 "utcoffset() result required");
2776 return NULL;
2777 }
2778
2779 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2780 if (dst == -1 && PyErr_Occurred())
2781 return NULL;
2782 if (none) {
2783 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2784 "dst() result required");
2785 return NULL;
2786 }
2787
2788 y = GET_YEAR(dt);
2789 m = GET_MONTH(dt);
2790 d = GET_DAY(dt);
2791 hh = DATE_GET_HOUR(dt);
2792 mm = DATE_GET_MINUTE(dt);
2793 ss = DATE_GET_SECOND(dt);
2794 us = DATE_GET_MICROSECOND(dt);
2795
2796 delta = off - dst;
2797 mm += delta;
2798 if ((mm < 0 || mm >= 60) &&
2799 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002800 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002801 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2802 if (result == NULL)
2803 return result;
2804
2805 dst = call_dst(dt->tzinfo, result, &none);
2806 if (dst == -1 && PyErr_Occurred())
2807 goto Fail;
2808 if (none)
2809 goto Inconsistent;
2810 if (dst == 0)
2811 return result;
2812
2813 mm += dst;
2814 if ((mm < 0 || mm >= 60) &&
2815 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2816 goto Fail;
2817 Py_DECREF(result);
2818 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2819 return result;
2820
2821Inconsistent:
2822 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2823 "inconsistent results; cannot convert");
2824
2825 /* fall thru to failure */
2826Fail:
2827 Py_DECREF(result);
2828 return NULL;
2829}
2830
Tim Peters2a799bf2002-12-16 20:18:38 +00002831/*
2832 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002833 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002834 */
2835
Guido van Rossum177e41a2003-01-30 22:06:23 +00002836static PyObject *
2837tzinfo_reduce(PyObject *self)
2838{
2839 PyObject *args, *state, *tmp;
2840 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002841
Guido van Rossum177e41a2003-01-30 22:06:23 +00002842 tmp = PyTuple_New(0);
2843 if (tmp == NULL)
2844 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002845
Guido van Rossum177e41a2003-01-30 22:06:23 +00002846 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2847 if (getinitargs != NULL) {
2848 args = PyObject_CallObject(getinitargs, tmp);
2849 Py_DECREF(getinitargs);
2850 if (args == NULL) {
2851 Py_DECREF(tmp);
2852 return NULL;
2853 }
2854 }
2855 else {
2856 PyErr_Clear();
2857 args = tmp;
2858 Py_INCREF(args);
2859 }
2860
2861 getstate = PyObject_GetAttrString(self, "__getstate__");
2862 if (getstate != NULL) {
2863 state = PyObject_CallObject(getstate, tmp);
2864 Py_DECREF(getstate);
2865 if (state == NULL) {
2866 Py_DECREF(args);
2867 Py_DECREF(tmp);
2868 return NULL;
2869 }
2870 }
2871 else {
2872 PyObject **dictptr;
2873 PyErr_Clear();
2874 state = Py_None;
2875 dictptr = _PyObject_GetDictPtr(self);
2876 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2877 state = *dictptr;
2878 Py_INCREF(state);
2879 }
2880
2881 Py_DECREF(tmp);
2882
2883 if (state == Py_None) {
2884 Py_DECREF(state);
2885 return Py_BuildValue("(ON)", self->ob_type, args);
2886 }
2887 else
2888 return Py_BuildValue("(ONN)", self->ob_type, args, state);
2889}
Tim Peters2a799bf2002-12-16 20:18:38 +00002890
2891static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002892
Tim Peters2a799bf2002-12-16 20:18:38 +00002893 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2894 PyDoc_STR("datetime -> string name of time zone.")},
2895
2896 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2897 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2898 "west of UTC).")},
2899
2900 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2901 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2902
Tim Peters52dcce22003-01-23 16:36:11 +00002903 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2904 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2905
Guido van Rossum177e41a2003-01-30 22:06:23 +00002906 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2907 PyDoc_STR("-> (cls, state)")},
2908
Tim Peters2a799bf2002-12-16 20:18:38 +00002909 {NULL, NULL}
2910};
2911
2912static char tzinfo_doc[] =
2913PyDoc_STR("Abstract base class for time zone info objects.");
2914
2915 statichere PyTypeObject PyDateTime_TZInfoType = {
2916 PyObject_HEAD_INIT(NULL)
2917 0, /* ob_size */
2918 "datetime.tzinfo", /* tp_name */
2919 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2920 0, /* tp_itemsize */
2921 0, /* tp_dealloc */
2922 0, /* tp_print */
2923 0, /* tp_getattr */
2924 0, /* tp_setattr */
2925 0, /* tp_compare */
2926 0, /* tp_repr */
2927 0, /* tp_as_number */
2928 0, /* tp_as_sequence */
2929 0, /* tp_as_mapping */
2930 0, /* tp_hash */
2931 0, /* tp_call */
2932 0, /* tp_str */
2933 PyObject_GenericGetAttr, /* tp_getattro */
2934 0, /* tp_setattro */
2935 0, /* tp_as_buffer */
2936 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2937 Py_TPFLAGS_BASETYPE, /* tp_flags */
2938 tzinfo_doc, /* tp_doc */
2939 0, /* tp_traverse */
2940 0, /* tp_clear */
2941 0, /* tp_richcompare */
2942 0, /* tp_weaklistoffset */
2943 0, /* tp_iter */
2944 0, /* tp_iternext */
2945 tzinfo_methods, /* tp_methods */
2946 0, /* tp_members */
2947 0, /* tp_getset */
2948 0, /* tp_base */
2949 0, /* tp_dict */
2950 0, /* tp_descr_get */
2951 0, /* tp_descr_set */
2952 0, /* tp_dictoffset */
2953 0, /* tp_init */
2954 0, /* tp_alloc */
2955 PyType_GenericNew, /* tp_new */
2956 0, /* tp_free */
2957};
2958
2959/*
Tim Peters37f39822003-01-10 03:49:02 +00002960 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00002961 */
2962
Tim Peters37f39822003-01-10 03:49:02 +00002963/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00002964 */
2965
2966static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002967time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00002968{
Tim Peters37f39822003-01-10 03:49:02 +00002969 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002970}
2971
Tim Peters37f39822003-01-10 03:49:02 +00002972static PyObject *
2973time_minute(PyDateTime_Time *self, void *unused)
2974{
2975 return PyInt_FromLong(TIME_GET_MINUTE(self));
2976}
2977
2978/* The name time_second conflicted with some platform header file. */
2979static PyObject *
2980py_time_second(PyDateTime_Time *self, void *unused)
2981{
2982 return PyInt_FromLong(TIME_GET_SECOND(self));
2983}
2984
2985static PyObject *
2986time_microsecond(PyDateTime_Time *self, void *unused)
2987{
2988 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
2989}
2990
2991static PyObject *
2992time_tzinfo(PyDateTime_Time *self, void *unused)
2993{
Tim Petersa032d2e2003-01-11 00:15:54 +00002994 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00002995 Py_INCREF(result);
2996 return result;
2997}
2998
2999static PyGetSetDef time_getset[] = {
3000 {"hour", (getter)time_hour},
3001 {"minute", (getter)time_minute},
3002 {"second", (getter)py_time_second},
3003 {"microsecond", (getter)time_microsecond},
3004 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003005 {NULL}
3006};
3007
3008/*
3009 * Constructors.
3010 */
3011
Tim Peters37f39822003-01-10 03:49:02 +00003012static char *time_kws[] = {"hour", "minute", "second", "microsecond",
3013 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003014
Guido van Rossum177e41a2003-01-30 22:06:23 +00003015static PyObject *time_setstate(PyDateTime_Time *self, PyObject *state);
3016
Tim Peters2a799bf2002-12-16 20:18:38 +00003017static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003018time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003019{
3020 PyObject *self = NULL;
3021 int hour = 0;
3022 int minute = 0;
3023 int second = 0;
3024 int usecond = 0;
3025 PyObject *tzinfo = Py_None;
3026
Guido van Rossum177e41a2003-01-30 22:06:23 +00003027 /* Check for invocation from pickle with __getstate__ state */
3028 if (PyTuple_GET_SIZE(args) >= 1 &&
3029 PyTuple_GET_SIZE(args) <= 2 &&
3030 PyString_Check(PyTuple_GET_ITEM(args, 0)))
3031 {
3032 if (PyTuple_GET_SIZE(args) == 2)
3033 tzinfo = PyTuple_GET_ITEM(args, 1);
3034 self = new_time(0, 0, 0, 0, tzinfo);
3035 if (self != NULL) {
3036 PyObject *res = time_setstate(
3037 (PyDateTime_Time *)self, args);
3038 if (res == Py_None)
3039 Py_DECREF(res);
3040 else {
3041 Py_DECREF(self);
3042 self = NULL;
3043 }
3044 }
3045 return self;
3046 }
3047
Tim Peters37f39822003-01-10 03:49:02 +00003048 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003049 &hour, &minute, &second, &usecond,
3050 &tzinfo)) {
3051 if (check_time_args(hour, minute, second, usecond) < 0)
3052 return NULL;
3053 if (check_tzinfo_subclass(tzinfo) < 0)
3054 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003055 self = new_time(hour, minute, second, usecond, tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003056 }
3057 return self;
3058}
3059
3060/*
3061 * Destructor.
3062 */
3063
3064static void
Tim Peters37f39822003-01-10 03:49:02 +00003065time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003066{
Tim Petersa032d2e2003-01-11 00:15:54 +00003067 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003068 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003069 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003070 self->ob_type->tp_free((PyObject *)self);
3071}
3072
3073/*
Tim Peters855fe882002-12-22 03:43:39 +00003074 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003075 */
3076
Tim Peters2a799bf2002-12-16 20:18:38 +00003077/* These are all METH_NOARGS, so don't need to check the arglist. */
3078static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003079time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003080 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003081 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003082}
3083
3084static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003085time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003086 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003087 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003088}
3089
3090static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003091time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003092 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003093 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003094}
3095
3096/*
Tim Peters37f39822003-01-10 03:49:02 +00003097 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003098 */
3099
3100static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003101time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003102{
Tim Peters37f39822003-01-10 03:49:02 +00003103 char buffer[100];
3104 char *typename = self->ob_type->tp_name;
3105 int h = TIME_GET_HOUR(self);
3106 int m = TIME_GET_MINUTE(self);
3107 int s = TIME_GET_SECOND(self);
3108 int us = TIME_GET_MICROSECOND(self);
3109 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003110
Tim Peters37f39822003-01-10 03:49:02 +00003111 if (us)
3112 PyOS_snprintf(buffer, sizeof(buffer),
3113 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3114 else if (s)
3115 PyOS_snprintf(buffer, sizeof(buffer),
3116 "%s(%d, %d, %d)", typename, h, m, s);
3117 else
3118 PyOS_snprintf(buffer, sizeof(buffer),
3119 "%s(%d, %d)", typename, h, m);
3120 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003121 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003122 result = append_keyword_tzinfo(result, self->tzinfo);
3123 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003124}
3125
Tim Peters37f39822003-01-10 03:49:02 +00003126static PyObject *
3127time_str(PyDateTime_Time *self)
3128{
3129 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3130}
Tim Peters2a799bf2002-12-16 20:18:38 +00003131
3132static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003133time_isoformat(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003134{
3135 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003136 PyObject *result;
3137 /* Reuse the time format code from the datetime type. */
3138 PyDateTime_DateTime datetime;
3139 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003140
Tim Peters37f39822003-01-10 03:49:02 +00003141 /* Copy over just the time bytes. */
3142 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3143 self->data,
3144 _PyDateTime_TIME_DATASIZE);
3145
3146 isoformat_time(pdatetime, buf, sizeof(buf));
3147 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003148 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003149 return result;
3150
3151 /* We need to append the UTC offset. */
3152 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003153 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003154 Py_DECREF(result);
3155 return NULL;
3156 }
3157 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3158 return result;
3159}
3160
Tim Peters37f39822003-01-10 03:49:02 +00003161static PyObject *
3162time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3163{
3164 PyObject *result;
3165 PyObject *format;
3166 PyObject *tuple;
3167 static char *keywords[] = {"format", NULL};
3168
3169 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3170 &PyString_Type, &format))
3171 return NULL;
3172
3173 /* Python's strftime does insane things with the year part of the
3174 * timetuple. The year is forced to (the otherwise nonsensical)
3175 * 1900 to worm around that.
3176 */
3177 tuple = Py_BuildValue("iiiiiiiii",
3178 1900, 0, 0, /* year, month, day */
3179 TIME_GET_HOUR(self),
3180 TIME_GET_MINUTE(self),
3181 TIME_GET_SECOND(self),
3182 0, 0, -1); /* weekday, daynum, dst */
3183 if (tuple == NULL)
3184 return NULL;
3185 assert(PyTuple_Size(tuple) == 9);
3186 result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
3187 Py_DECREF(tuple);
3188 return result;
3189}
Tim Peters2a799bf2002-12-16 20:18:38 +00003190
3191/*
3192 * Miscellaneous methods.
3193 */
3194
Tim Peters37f39822003-01-10 03:49:02 +00003195/* This is more natural as a tp_compare, but doesn't work then: for whatever
3196 * reason, Python's try_3way_compare ignores tp_compare unless
3197 * PyInstance_Check returns true, but these aren't old-style classes.
3198 */
3199static PyObject *
3200time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3201{
3202 int diff;
3203 naivety n1, n2;
3204 int offset1, offset2;
3205
3206 if (! PyTime_Check(other)) {
3207 /* Stop this from falling back to address comparison. */
3208 PyErr_Format(PyExc_TypeError,
3209 "can't compare '%s' to '%s'",
3210 self->ob_type->tp_name,
3211 other->ob_type->tp_name);
3212 return NULL;
3213 }
3214 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3215 other, &offset2, &n2, Py_None) < 0)
3216 return NULL;
3217 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3218 /* If they're both naive, or both aware and have the same offsets,
3219 * we get off cheap. Note that if they're both naive, offset1 ==
3220 * offset2 == 0 at this point.
3221 */
3222 if (n1 == n2 && offset1 == offset2) {
3223 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3224 _PyDateTime_TIME_DATASIZE);
3225 return diff_to_bool(diff, op);
3226 }
3227
3228 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3229 assert(offset1 != offset2); /* else last "if" handled it */
3230 /* Convert everything except microseconds to seconds. These
3231 * can't overflow (no more than the # of seconds in 2 days).
3232 */
3233 offset1 = TIME_GET_HOUR(self) * 3600 +
3234 (TIME_GET_MINUTE(self) - offset1) * 60 +
3235 TIME_GET_SECOND(self);
3236 offset2 = TIME_GET_HOUR(other) * 3600 +
3237 (TIME_GET_MINUTE(other) - offset2) * 60 +
3238 TIME_GET_SECOND(other);
3239 diff = offset1 - offset2;
3240 if (diff == 0)
3241 diff = TIME_GET_MICROSECOND(self) -
3242 TIME_GET_MICROSECOND(other);
3243 return diff_to_bool(diff, op);
3244 }
3245
3246 assert(n1 != n2);
3247 PyErr_SetString(PyExc_TypeError,
3248 "can't compare offset-naive and "
3249 "offset-aware times");
3250 return NULL;
3251}
3252
3253static long
3254time_hash(PyDateTime_Time *self)
3255{
3256 if (self->hashcode == -1) {
3257 naivety n;
3258 int offset;
3259 PyObject *temp;
3260
3261 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3262 assert(n != OFFSET_UNKNOWN);
3263 if (n == OFFSET_ERROR)
3264 return -1;
3265
3266 /* Reduce this to a hash of another object. */
3267 if (offset == 0)
3268 temp = PyString_FromStringAndSize((char *)self->data,
3269 _PyDateTime_TIME_DATASIZE);
3270 else {
3271 int hour;
3272 int minute;
3273
3274 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003275 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003276 hour = divmod(TIME_GET_HOUR(self) * 60 +
3277 TIME_GET_MINUTE(self) - offset,
3278 60,
3279 &minute);
3280 if (0 <= hour && hour < 24)
3281 temp = new_time(hour, minute,
3282 TIME_GET_SECOND(self),
3283 TIME_GET_MICROSECOND(self),
3284 Py_None);
3285 else
3286 temp = Py_BuildValue("iiii",
3287 hour, minute,
3288 TIME_GET_SECOND(self),
3289 TIME_GET_MICROSECOND(self));
3290 }
3291 if (temp != NULL) {
3292 self->hashcode = PyObject_Hash(temp);
3293 Py_DECREF(temp);
3294 }
3295 }
3296 return self->hashcode;
3297}
Tim Peters2a799bf2002-12-16 20:18:38 +00003298
Tim Peters12bf3392002-12-24 05:41:27 +00003299static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003300time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003301{
3302 PyObject *clone;
3303 PyObject *tuple;
3304 int hh = TIME_GET_HOUR(self);
3305 int mm = TIME_GET_MINUTE(self);
3306 int ss = TIME_GET_SECOND(self);
3307 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003308 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003309
3310 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003311 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003312 &hh, &mm, &ss, &us, &tzinfo))
3313 return NULL;
3314 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3315 if (tuple == NULL)
3316 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003317 clone = time_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003318 Py_DECREF(tuple);
3319 return clone;
3320}
3321
Tim Peters2a799bf2002-12-16 20:18:38 +00003322static int
Tim Peters37f39822003-01-10 03:49:02 +00003323time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003324{
3325 int offset;
3326 int none;
3327
3328 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3329 /* Since utcoffset is in whole minutes, nothing can
3330 * alter the conclusion that this is nonzero.
3331 */
3332 return 1;
3333 }
3334 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003335 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003336 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003337 if (offset == -1 && PyErr_Occurred())
3338 return -1;
3339 }
3340 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3341}
3342
3343/*
3344 * Pickle support. Quite a maze!
3345 */
3346
Tim Peters33e0f382003-01-10 02:05:14 +00003347/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003348 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3349 * So it's a tuple in any (non-error) case.
3350 */
3351static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003352time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003353{
3354 PyObject *basestate;
3355 PyObject *result = NULL;
3356
Tim Peters33e0f382003-01-10 02:05:14 +00003357 basestate = PyString_FromStringAndSize((char *)self->data,
3358 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003359 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003360 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003361 result = Py_BuildValue("(O)", basestate);
3362 else
3363 result = Py_BuildValue("OO", basestate, self->tzinfo);
3364 Py_DECREF(basestate);
3365 }
3366 return result;
3367}
3368
3369static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003370time_setstate(PyDateTime_Time *self, PyObject *state)
Tim Peters2a799bf2002-12-16 20:18:38 +00003371{
Tim Peters2a799bf2002-12-16 20:18:38 +00003372 PyObject *basestate;
3373 PyObject *tzinfo = Py_None;
3374
3375 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
3376 &PyString_Type, &basestate,
3377 &tzinfo))
3378 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00003379 if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE ||
3380 check_tzinfo_subclass(tzinfo) < 0) {
3381 PyErr_SetString(PyExc_TypeError,
3382 "bad argument to time.__setstate__");
Tim Peters2a799bf2002-12-16 20:18:38 +00003383 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00003384 }
Tim Petersa032d2e2003-01-11 00:15:54 +00003385 if (tzinfo != Py_None && ! HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003386 PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't "
3387 "add a non-None tzinfo to a time object that "
3388 "doesn't have one already");
3389 return NULL;
3390 }
Tim Peters33e0f382003-01-10 02:05:14 +00003391 memcpy((char *)self->data,
3392 PyString_AsString(basestate),
3393 _PyDateTime_TIME_DATASIZE);
3394 self->hashcode = -1;
Tim Petersa032d2e2003-01-11 00:15:54 +00003395 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003396 Py_INCREF(tzinfo);
3397 Py_XDECREF(self->tzinfo);
3398 self->tzinfo = tzinfo;
3399 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003400 Py_INCREF(Py_None);
3401 return Py_None;
3402}
3403
3404static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003405time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003406{
Guido van Rossum177e41a2003-01-30 22:06:23 +00003407 return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003408}
3409
Tim Peters37f39822003-01-10 03:49:02 +00003410static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003411
Tim Peters37f39822003-01-10 03:49:02 +00003412 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003413 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3414 "[+HH:MM].")},
3415
Tim Peters37f39822003-01-10 03:49:02 +00003416 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3417 PyDoc_STR("format -> strftime() style string.")},
3418
3419 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003420 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3421
Tim Peters37f39822003-01-10 03:49:02 +00003422 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003423 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3424
Tim Peters37f39822003-01-10 03:49:02 +00003425 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003426 PyDoc_STR("Return self.tzinfo.dst(self).")},
3427
Tim Peters37f39822003-01-10 03:49:02 +00003428 {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
3429 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003430
Tim Peters37f39822003-01-10 03:49:02 +00003431 {"__setstate__", (PyCFunction)time_setstate, METH_O,
Tim Peters2a799bf2002-12-16 20:18:38 +00003432 PyDoc_STR("__setstate__(state)")},
3433
Tim Peters37f39822003-01-10 03:49:02 +00003434 {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003435 PyDoc_STR("__getstate__() -> state")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00003436
3437 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3438 PyDoc_STR("__reduce__() -> (cls, state)")},
3439
Tim Peters2a799bf2002-12-16 20:18:38 +00003440 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003441};
3442
Tim Peters37f39822003-01-10 03:49:02 +00003443static char time_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003444PyDoc_STR("Time type.");
3445
Tim Peters37f39822003-01-10 03:49:02 +00003446static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003447 0, /* nb_add */
3448 0, /* nb_subtract */
3449 0, /* nb_multiply */
3450 0, /* nb_divide */
3451 0, /* nb_remainder */
3452 0, /* nb_divmod */
3453 0, /* nb_power */
3454 0, /* nb_negative */
3455 0, /* nb_positive */
3456 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003457 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003458};
3459
Tim Peters37f39822003-01-10 03:49:02 +00003460statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003461 PyObject_HEAD_INIT(NULL)
3462 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003463 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003464 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003465 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003466 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003467 0, /* tp_print */
3468 0, /* tp_getattr */
3469 0, /* tp_setattr */
3470 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003471 (reprfunc)time_repr, /* tp_repr */
3472 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003473 0, /* tp_as_sequence */
3474 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003475 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003476 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003477 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003478 PyObject_GenericGetAttr, /* tp_getattro */
3479 0, /* tp_setattro */
3480 0, /* tp_as_buffer */
3481 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3482 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003483 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003484 0, /* tp_traverse */
3485 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003486 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003487 0, /* tp_weaklistoffset */
3488 0, /* tp_iter */
3489 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003490 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003491 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003492 time_getset, /* tp_getset */
3493 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003494 0, /* tp_dict */
3495 0, /* tp_descr_get */
3496 0, /* tp_descr_set */
3497 0, /* tp_dictoffset */
3498 0, /* tp_init */
3499 0, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003500 time_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00003501 _PyObject_Del, /* tp_free */
3502};
3503
3504/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003505 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003506 */
3507
Tim Petersa9bc1682003-01-11 03:39:11 +00003508/* Accessor properties. Properties for day, month, and year are inherited
3509 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003510 */
3511
3512static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003513datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003514{
Tim Petersa9bc1682003-01-11 03:39:11 +00003515 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003516}
3517
Tim Petersa9bc1682003-01-11 03:39:11 +00003518static PyObject *
3519datetime_minute(PyDateTime_DateTime *self, void *unused)
3520{
3521 return PyInt_FromLong(DATE_GET_MINUTE(self));
3522}
3523
3524static PyObject *
3525datetime_second(PyDateTime_DateTime *self, void *unused)
3526{
3527 return PyInt_FromLong(DATE_GET_SECOND(self));
3528}
3529
3530static PyObject *
3531datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3532{
3533 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3534}
3535
3536static PyObject *
3537datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3538{
3539 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3540 Py_INCREF(result);
3541 return result;
3542}
3543
3544static PyGetSetDef datetime_getset[] = {
3545 {"hour", (getter)datetime_hour},
3546 {"minute", (getter)datetime_minute},
3547 {"second", (getter)datetime_second},
3548 {"microsecond", (getter)datetime_microsecond},
3549 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003550 {NULL}
3551};
3552
3553/*
3554 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003555 */
3556
Tim Petersa9bc1682003-01-11 03:39:11 +00003557static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003558 "year", "month", "day", "hour", "minute", "second",
3559 "microsecond", "tzinfo", NULL
3560};
3561
Guido van Rossum177e41a2003-01-30 22:06:23 +00003562static PyObject *datetime_setstate(PyDateTime_DateTime *self, PyObject *state);
3563
Tim Peters2a799bf2002-12-16 20:18:38 +00003564static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003565datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003566{
3567 PyObject *self = NULL;
3568 int year;
3569 int month;
3570 int day;
3571 int hour = 0;
3572 int minute = 0;
3573 int second = 0;
3574 int usecond = 0;
3575 PyObject *tzinfo = Py_None;
3576
Guido van Rossum177e41a2003-01-30 22:06:23 +00003577 /* Check for invocation from pickle with __getstate__ state */
3578 if (PyTuple_GET_SIZE(args) >= 1 &&
3579 PyTuple_GET_SIZE(args) <= 2 &&
3580 PyString_Check(PyTuple_GET_ITEM(args, 0)))
3581 {
3582 if (PyTuple_GET_SIZE(args) == 2)
3583 tzinfo = PyTuple_GET_ITEM(args, 1);
3584 self = new_datetime(1, 1, 1, 0, 0, 0, 0, tzinfo);
3585 if (self != NULL) {
3586 PyObject *res = datetime_setstate(
3587 (PyDateTime_DateTime *)self, args);
3588 if (res == Py_None)
3589 Py_DECREF(res);
3590 else {
3591 Py_DECREF(self);
3592 self = NULL;
3593 }
3594 }
3595 return self;
3596 }
3597
Tim Petersa9bc1682003-01-11 03:39:11 +00003598 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003599 &year, &month, &day, &hour, &minute,
3600 &second, &usecond, &tzinfo)) {
3601 if (check_date_args(year, month, day) < 0)
3602 return NULL;
3603 if (check_time_args(hour, minute, second, usecond) < 0)
3604 return NULL;
3605 if (check_tzinfo_subclass(tzinfo) < 0)
3606 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003607 self = new_datetime(year, month, day,
3608 hour, minute, second, usecond,
3609 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003610 }
3611 return self;
3612}
3613
Tim Petersa9bc1682003-01-11 03:39:11 +00003614/* TM_FUNC is the shared type of localtime() and gmtime(). */
3615typedef struct tm *(*TM_FUNC)(const time_t *timer);
3616
3617/* Internal helper.
3618 * Build datetime from a time_t and a distinct count of microseconds.
3619 * Pass localtime or gmtime for f, to control the interpretation of timet.
3620 */
3621static PyObject *
3622datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3623 PyObject *tzinfo)
3624{
3625 struct tm *tm;
3626 PyObject *result = NULL;
3627
3628 tm = f(&timet);
3629 if (tm) {
3630 /* The platform localtime/gmtime may insert leap seconds,
3631 * indicated by tm->tm_sec > 59. We don't care about them,
3632 * except to the extent that passing them on to the datetime
3633 * constructor would raise ValueError for a reason that
3634 * made no sense to the user.
3635 */
3636 if (tm->tm_sec > 59)
3637 tm->tm_sec = 59;
3638 result = PyObject_CallFunction(cls, "iiiiiiiO",
3639 tm->tm_year + 1900,
3640 tm->tm_mon + 1,
3641 tm->tm_mday,
3642 tm->tm_hour,
3643 tm->tm_min,
3644 tm->tm_sec,
3645 us,
3646 tzinfo);
3647 }
3648 else
3649 PyErr_SetString(PyExc_ValueError,
3650 "timestamp out of range for "
3651 "platform localtime()/gmtime() function");
3652 return result;
3653}
3654
3655/* Internal helper.
3656 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3657 * to control the interpretation of the timestamp. Since a double doesn't
3658 * have enough bits to cover a datetime's full range of precision, it's
3659 * better to call datetime_from_timet_and_us provided you have a way
3660 * to get that much precision (e.g., C time() isn't good enough).
3661 */
3662static PyObject *
3663datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3664 PyObject *tzinfo)
3665{
3666 time_t timet = (time_t)timestamp;
3667 double fraction = timestamp - (double)timet;
3668 int us = (int)round_to_long(fraction * 1e6);
3669
3670 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3671}
3672
3673/* Internal helper.
3674 * Build most accurate possible datetime for current time. Pass localtime or
3675 * gmtime for f as appropriate.
3676 */
3677static PyObject *
3678datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3679{
3680#ifdef HAVE_GETTIMEOFDAY
3681 struct timeval t;
3682
3683#ifdef GETTIMEOFDAY_NO_TZ
3684 gettimeofday(&t);
3685#else
3686 gettimeofday(&t, (struct timezone *)NULL);
3687#endif
3688 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3689 tzinfo);
3690
3691#else /* ! HAVE_GETTIMEOFDAY */
3692 /* No flavor of gettimeofday exists on this platform. Python's
3693 * time.time() does a lot of other platform tricks to get the
3694 * best time it can on the platform, and we're not going to do
3695 * better than that (if we could, the better code would belong
3696 * in time.time()!) We're limited by the precision of a double,
3697 * though.
3698 */
3699 PyObject *time;
3700 double dtime;
3701
3702 time = time_time();
3703 if (time == NULL)
3704 return NULL;
3705 dtime = PyFloat_AsDouble(time);
3706 Py_DECREF(time);
3707 if (dtime == -1.0 && PyErr_Occurred())
3708 return NULL;
3709 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3710#endif /* ! HAVE_GETTIMEOFDAY */
3711}
3712
Tim Peters2a799bf2002-12-16 20:18:38 +00003713/* Return best possible local time -- this isn't constrained by the
3714 * precision of a timestamp.
3715 */
3716static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003717datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003718{
Tim Peters10cadce2003-01-23 19:58:02 +00003719 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003720 PyObject *tzinfo = Py_None;
Tim Peters10cadce2003-01-23 19:58:02 +00003721 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003722
Tim Peters10cadce2003-01-23 19:58:02 +00003723 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3724 &tzinfo))
3725 return NULL;
3726 if (check_tzinfo_subclass(tzinfo) < 0)
3727 return NULL;
3728
3729 self = datetime_best_possible(cls,
3730 tzinfo == Py_None ? localtime : gmtime,
3731 tzinfo);
3732 if (self != NULL && tzinfo != Py_None) {
3733 /* Convert UTC to tzinfo's zone. */
3734 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003735 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003736 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003737 }
3738 return self;
3739}
3740
Tim Petersa9bc1682003-01-11 03:39:11 +00003741/* Return best possible UTC time -- this isn't constrained by the
3742 * precision of a timestamp.
3743 */
3744static PyObject *
3745datetime_utcnow(PyObject *cls, PyObject *dummy)
3746{
3747 return datetime_best_possible(cls, gmtime, Py_None);
3748}
3749
Tim Peters2a799bf2002-12-16 20:18:38 +00003750/* Return new local datetime from timestamp (Python timestamp -- a double). */
3751static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003752datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003753{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003754 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003755 double timestamp;
3756 PyObject *tzinfo = Py_None;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003757 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003758
Tim Peters2a44a8d2003-01-23 20:53:10 +00003759 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3760 keywords, &timestamp, &tzinfo))
3761 return NULL;
3762 if (check_tzinfo_subclass(tzinfo) < 0)
3763 return NULL;
3764
3765 self = datetime_from_timestamp(cls,
3766 tzinfo == Py_None ? localtime : gmtime,
3767 timestamp,
3768 tzinfo);
3769 if (self != NULL && tzinfo != Py_None) {
3770 /* Convert UTC to tzinfo's zone. */
3771 PyObject *temp = self;
3772 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3773 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003774 }
3775 return self;
3776}
3777
Tim Petersa9bc1682003-01-11 03:39:11 +00003778/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3779static PyObject *
3780datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3781{
3782 double timestamp;
3783 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003784
Tim Petersa9bc1682003-01-11 03:39:11 +00003785 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3786 result = datetime_from_timestamp(cls, gmtime, timestamp,
3787 Py_None);
3788 return result;
3789}
3790
3791/* Return new datetime from date/datetime and time arguments. */
3792static PyObject *
3793datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3794{
3795 static char *keywords[] = {"date", "time", NULL};
3796 PyObject *date;
3797 PyObject *time;
3798 PyObject *result = NULL;
3799
3800 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3801 &PyDateTime_DateType, &date,
3802 &PyDateTime_TimeType, &time)) {
3803 PyObject *tzinfo = Py_None;
3804
3805 if (HASTZINFO(time))
3806 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3807 result = PyObject_CallFunction(cls, "iiiiiiiO",
3808 GET_YEAR(date),
3809 GET_MONTH(date),
3810 GET_DAY(date),
3811 TIME_GET_HOUR(time),
3812 TIME_GET_MINUTE(time),
3813 TIME_GET_SECOND(time),
3814 TIME_GET_MICROSECOND(time),
3815 tzinfo);
3816 }
3817 return result;
3818}
Tim Peters2a799bf2002-12-16 20:18:38 +00003819
3820/*
3821 * Destructor.
3822 */
3823
3824static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003825datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003826{
Tim Petersa9bc1682003-01-11 03:39:11 +00003827 if (HASTZINFO(self)) {
3828 Py_XDECREF(self->tzinfo);
3829 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003830 self->ob_type->tp_free((PyObject *)self);
3831}
3832
3833/*
3834 * Indirect access to tzinfo methods.
3835 */
3836
Tim Peters2a799bf2002-12-16 20:18:38 +00003837/* These are all METH_NOARGS, so don't need to check the arglist. */
3838static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003839datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3840 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3841 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003842}
3843
3844static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003845datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3846 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3847 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003848}
3849
3850static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003851datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3852 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3853 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003854}
3855
3856/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003857 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003858 */
3859
Tim Petersa9bc1682003-01-11 03:39:11 +00003860/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3861 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003862 */
3863static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003864add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3865 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003866{
Tim Petersa9bc1682003-01-11 03:39:11 +00003867 /* Note that the C-level additions can't overflow, because of
3868 * invariant bounds on the member values.
3869 */
3870 int year = GET_YEAR(date);
3871 int month = GET_MONTH(date);
3872 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3873 int hour = DATE_GET_HOUR(date);
3874 int minute = DATE_GET_MINUTE(date);
3875 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3876 int microsecond = DATE_GET_MICROSECOND(date) +
3877 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003878
Tim Petersa9bc1682003-01-11 03:39:11 +00003879 assert(factor == 1 || factor == -1);
3880 if (normalize_datetime(&year, &month, &day,
3881 &hour, &minute, &second, &microsecond) < 0)
3882 return NULL;
3883 else
3884 return new_datetime(year, month, day,
3885 hour, minute, second, microsecond,
3886 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003887}
3888
3889static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003890datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003891{
Tim Petersa9bc1682003-01-11 03:39:11 +00003892 if (PyDateTime_Check(left)) {
3893 /* datetime + ??? */
3894 if (PyDelta_Check(right))
3895 /* datetime + delta */
3896 return add_datetime_timedelta(
3897 (PyDateTime_DateTime *)left,
3898 (PyDateTime_Delta *)right,
3899 1);
3900 }
3901 else if (PyDelta_Check(left)) {
3902 /* delta + datetime */
3903 return add_datetime_timedelta((PyDateTime_DateTime *) right,
3904 (PyDateTime_Delta *) left,
3905 1);
3906 }
3907 Py_INCREF(Py_NotImplemented);
3908 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00003909}
3910
3911static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003912datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003913{
3914 PyObject *result = Py_NotImplemented;
3915
3916 if (PyDateTime_Check(left)) {
3917 /* datetime - ??? */
3918 if (PyDateTime_Check(right)) {
3919 /* datetime - datetime */
3920 naivety n1, n2;
3921 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00003922 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00003923
Tim Peterse39a80c2002-12-30 21:28:52 +00003924 if (classify_two_utcoffsets(left, &offset1, &n1, left,
3925 right, &offset2, &n2,
3926 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00003927 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00003928 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00003929 if (n1 != n2) {
3930 PyErr_SetString(PyExc_TypeError,
3931 "can't subtract offset-naive and "
3932 "offset-aware datetimes");
3933 return NULL;
3934 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003935 delta_d = ymd_to_ord(GET_YEAR(left),
3936 GET_MONTH(left),
3937 GET_DAY(left)) -
3938 ymd_to_ord(GET_YEAR(right),
3939 GET_MONTH(right),
3940 GET_DAY(right));
3941 /* These can't overflow, since the values are
3942 * normalized. At most this gives the number of
3943 * seconds in one day.
3944 */
3945 delta_s = (DATE_GET_HOUR(left) -
3946 DATE_GET_HOUR(right)) * 3600 +
3947 (DATE_GET_MINUTE(left) -
3948 DATE_GET_MINUTE(right)) * 60 +
3949 (DATE_GET_SECOND(left) -
3950 DATE_GET_SECOND(right));
3951 delta_us = DATE_GET_MICROSECOND(left) -
3952 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00003953 /* (left - offset1) - (right - offset2) =
3954 * (left - right) + (offset2 - offset1)
3955 */
Tim Petersa9bc1682003-01-11 03:39:11 +00003956 delta_s += (offset2 - offset1) * 60;
3957 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003958 }
3959 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00003960 /* datetime - delta */
3961 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00003962 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00003963 (PyDateTime_Delta *)right,
3964 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003965 }
3966 }
3967
3968 if (result == Py_NotImplemented)
3969 Py_INCREF(result);
3970 return result;
3971}
3972
3973/* Various ways to turn a datetime into a string. */
3974
3975static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003976datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003977{
Tim Petersa9bc1682003-01-11 03:39:11 +00003978 char buffer[1000];
3979 char *typename = self->ob_type->tp_name;
3980 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003981
Tim Petersa9bc1682003-01-11 03:39:11 +00003982 if (DATE_GET_MICROSECOND(self)) {
3983 PyOS_snprintf(buffer, sizeof(buffer),
3984 "%s(%d, %d, %d, %d, %d, %d, %d)",
3985 typename,
3986 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3987 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3988 DATE_GET_SECOND(self),
3989 DATE_GET_MICROSECOND(self));
3990 }
3991 else if (DATE_GET_SECOND(self)) {
3992 PyOS_snprintf(buffer, sizeof(buffer),
3993 "%s(%d, %d, %d, %d, %d, %d)",
3994 typename,
3995 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3996 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3997 DATE_GET_SECOND(self));
3998 }
3999 else {
4000 PyOS_snprintf(buffer, sizeof(buffer),
4001 "%s(%d, %d, %d, %d, %d)",
4002 typename,
4003 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4004 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4005 }
4006 baserepr = PyString_FromString(buffer);
4007 if (baserepr == NULL || ! HASTZINFO(self))
4008 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004009 return append_keyword_tzinfo(baserepr, self->tzinfo);
4010}
4011
Tim Petersa9bc1682003-01-11 03:39:11 +00004012static PyObject *
4013datetime_str(PyDateTime_DateTime *self)
4014{
4015 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4016}
Tim Peters2a799bf2002-12-16 20:18:38 +00004017
4018static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004019datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004020{
Tim Petersa9bc1682003-01-11 03:39:11 +00004021 char sep = 'T';
4022 static char *keywords[] = {"sep", NULL};
4023 char buffer[100];
4024 char *cp;
4025 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004026
Tim Petersa9bc1682003-01-11 03:39:11 +00004027 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4028 &sep))
4029 return NULL;
4030 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4031 assert(cp != NULL);
4032 *cp++ = sep;
4033 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4034 result = PyString_FromString(buffer);
4035 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00004036 return result;
4037
4038 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00004039 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00004040 (PyObject *)self) < 0) {
4041 Py_DECREF(result);
4042 return NULL;
4043 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004044 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00004045 return result;
4046}
4047
Tim Petersa9bc1682003-01-11 03:39:11 +00004048static PyObject *
4049datetime_ctime(PyDateTime_DateTime *self)
4050{
4051 return format_ctime((PyDateTime_Date *)self,
4052 DATE_GET_HOUR(self),
4053 DATE_GET_MINUTE(self),
4054 DATE_GET_SECOND(self));
4055}
4056
Tim Peters2a799bf2002-12-16 20:18:38 +00004057/* Miscellaneous methods. */
4058
Tim Petersa9bc1682003-01-11 03:39:11 +00004059/* This is more natural as a tp_compare, but doesn't work then: for whatever
4060 * reason, Python's try_3way_compare ignores tp_compare unless
4061 * PyInstance_Check returns true, but these aren't old-style classes.
4062 */
4063static PyObject *
4064datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4065{
4066 int diff;
4067 naivety n1, n2;
4068 int offset1, offset2;
4069
4070 if (! PyDateTime_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004071 if (PyObject_HasAttrString(other, "timetuple")) {
4072 /* A hook for other kinds of datetime objects. */
4073 Py_INCREF(Py_NotImplemented);
4074 return Py_NotImplemented;
4075 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004076 /* Stop this from falling back to address comparison. */
4077 PyErr_Format(PyExc_TypeError,
4078 "can't compare '%s' to '%s'",
4079 self->ob_type->tp_name,
4080 other->ob_type->tp_name);
4081 return NULL;
4082 }
4083
4084 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4085 (PyObject *)self,
4086 other, &offset2, &n2,
4087 other) < 0)
4088 return NULL;
4089 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4090 /* If they're both naive, or both aware and have the same offsets,
4091 * we get off cheap. Note that if they're both naive, offset1 ==
4092 * offset2 == 0 at this point.
4093 */
4094 if (n1 == n2 && offset1 == offset2) {
4095 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4096 _PyDateTime_DATETIME_DATASIZE);
4097 return diff_to_bool(diff, op);
4098 }
4099
4100 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4101 PyDateTime_Delta *delta;
4102
4103 assert(offset1 != offset2); /* else last "if" handled it */
4104 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4105 other);
4106 if (delta == NULL)
4107 return NULL;
4108 diff = GET_TD_DAYS(delta);
4109 if (diff == 0)
4110 diff = GET_TD_SECONDS(delta) |
4111 GET_TD_MICROSECONDS(delta);
4112 Py_DECREF(delta);
4113 return diff_to_bool(diff, op);
4114 }
4115
4116 assert(n1 != n2);
4117 PyErr_SetString(PyExc_TypeError,
4118 "can't compare offset-naive and "
4119 "offset-aware datetimes");
4120 return NULL;
4121}
4122
4123static long
4124datetime_hash(PyDateTime_DateTime *self)
4125{
4126 if (self->hashcode == -1) {
4127 naivety n;
4128 int offset;
4129 PyObject *temp;
4130
4131 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4132 &offset);
4133 assert(n != OFFSET_UNKNOWN);
4134 if (n == OFFSET_ERROR)
4135 return -1;
4136
4137 /* Reduce this to a hash of another object. */
4138 if (n == OFFSET_NAIVE)
4139 temp = PyString_FromStringAndSize(
4140 (char *)self->data,
4141 _PyDateTime_DATETIME_DATASIZE);
4142 else {
4143 int days;
4144 int seconds;
4145
4146 assert(n == OFFSET_AWARE);
4147 assert(HASTZINFO(self));
4148 days = ymd_to_ord(GET_YEAR(self),
4149 GET_MONTH(self),
4150 GET_DAY(self));
4151 seconds = DATE_GET_HOUR(self) * 3600 +
4152 (DATE_GET_MINUTE(self) - offset) * 60 +
4153 DATE_GET_SECOND(self);
4154 temp = new_delta(days,
4155 seconds,
4156 DATE_GET_MICROSECOND(self),
4157 1);
4158 }
4159 if (temp != NULL) {
4160 self->hashcode = PyObject_Hash(temp);
4161 Py_DECREF(temp);
4162 }
4163 }
4164 return self->hashcode;
4165}
Tim Peters2a799bf2002-12-16 20:18:38 +00004166
4167static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004168datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004169{
4170 PyObject *clone;
4171 PyObject *tuple;
4172 int y = GET_YEAR(self);
4173 int m = GET_MONTH(self);
4174 int d = GET_DAY(self);
4175 int hh = DATE_GET_HOUR(self);
4176 int mm = DATE_GET_MINUTE(self);
4177 int ss = DATE_GET_SECOND(self);
4178 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004179 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004180
4181 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004182 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004183 &y, &m, &d, &hh, &mm, &ss, &us,
4184 &tzinfo))
4185 return NULL;
4186 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4187 if (tuple == NULL)
4188 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004189 clone = datetime_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004190 Py_DECREF(tuple);
4191 return clone;
4192}
4193
4194static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004195datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004196{
Tim Peters52dcce22003-01-23 16:36:11 +00004197 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004198 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004199 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004200
Tim Peters80475bb2002-12-25 07:40:55 +00004201 PyObject *tzinfo;
4202 static char *keywords[] = {"tz", NULL};
4203
Tim Peters52dcce22003-01-23 16:36:11 +00004204 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4205 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004206 return NULL;
4207
Tim Peters52dcce22003-01-23 16:36:11 +00004208 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4209 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004210
Tim Peters52dcce22003-01-23 16:36:11 +00004211 /* Conversion to self's own time zone is a NOP. */
4212 if (self->tzinfo == tzinfo) {
4213 Py_INCREF(self);
4214 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004215 }
Tim Peters521fc152002-12-31 17:36:56 +00004216
Tim Peters52dcce22003-01-23 16:36:11 +00004217 /* Convert self to UTC. */
4218 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4219 if (offset == -1 && PyErr_Occurred())
4220 return NULL;
4221 if (none)
4222 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004223
Tim Peters52dcce22003-01-23 16:36:11 +00004224 y = GET_YEAR(self);
4225 m = GET_MONTH(self);
4226 d = GET_DAY(self);
4227 hh = DATE_GET_HOUR(self);
4228 mm = DATE_GET_MINUTE(self);
4229 ss = DATE_GET_SECOND(self);
4230 us = DATE_GET_MICROSECOND(self);
4231
4232 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004233 if ((mm < 0 || mm >= 60) &&
4234 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004235 return NULL;
4236
4237 /* Attach new tzinfo and let fromutc() do the rest. */
4238 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4239 if (result != NULL) {
4240 PyObject *temp = result;
4241
4242 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4243 Py_DECREF(temp);
4244 }
Tim Petersadf64202003-01-04 06:03:15 +00004245 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004246
Tim Peters52dcce22003-01-23 16:36:11 +00004247NeedAware:
4248 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4249 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004250 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004251}
4252
4253static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004254datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004255{
4256 int dstflag = -1;
4257
Tim Petersa9bc1682003-01-11 03:39:11 +00004258 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004259 int none;
4260
4261 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4262 if (dstflag == -1 && PyErr_Occurred())
4263 return NULL;
4264
4265 if (none)
4266 dstflag = -1;
4267 else if (dstflag != 0)
4268 dstflag = 1;
4269
4270 }
4271 return build_struct_time(GET_YEAR(self),
4272 GET_MONTH(self),
4273 GET_DAY(self),
4274 DATE_GET_HOUR(self),
4275 DATE_GET_MINUTE(self),
4276 DATE_GET_SECOND(self),
4277 dstflag);
4278}
4279
4280static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004281datetime_getdate(PyDateTime_DateTime *self)
4282{
4283 return new_date(GET_YEAR(self),
4284 GET_MONTH(self),
4285 GET_DAY(self));
4286}
4287
4288static PyObject *
4289datetime_gettime(PyDateTime_DateTime *self)
4290{
4291 return new_time(DATE_GET_HOUR(self),
4292 DATE_GET_MINUTE(self),
4293 DATE_GET_SECOND(self),
4294 DATE_GET_MICROSECOND(self),
4295 Py_None);
4296}
4297
4298static PyObject *
4299datetime_gettimetz(PyDateTime_DateTime *self)
4300{
4301 return new_time(DATE_GET_HOUR(self),
4302 DATE_GET_MINUTE(self),
4303 DATE_GET_SECOND(self),
4304 DATE_GET_MICROSECOND(self),
4305 HASTZINFO(self) ? self->tzinfo : Py_None);
4306}
4307
4308static PyObject *
4309datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004310{
4311 int y = GET_YEAR(self);
4312 int m = GET_MONTH(self);
4313 int d = GET_DAY(self);
4314 int hh = DATE_GET_HOUR(self);
4315 int mm = DATE_GET_MINUTE(self);
4316 int ss = DATE_GET_SECOND(self);
4317 int us = 0; /* microseconds are ignored in a timetuple */
4318 int offset = 0;
4319
Tim Petersa9bc1682003-01-11 03:39:11 +00004320 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004321 int none;
4322
4323 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4324 if (offset == -1 && PyErr_Occurred())
4325 return NULL;
4326 }
4327 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4328 * 0 in a UTC timetuple regardless of what dst() says.
4329 */
4330 if (offset) {
4331 /* Subtract offset minutes & normalize. */
4332 int stat;
4333
4334 mm -= offset;
4335 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4336 if (stat < 0) {
4337 /* At the edges, it's possible we overflowed
4338 * beyond MINYEAR or MAXYEAR.
4339 */
4340 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4341 PyErr_Clear();
4342 else
4343 return NULL;
4344 }
4345 }
4346 return build_struct_time(y, m, d, hh, mm, ss, 0);
4347}
4348
Tim Peters33e0f382003-01-10 02:05:14 +00004349/* Pickle support. Quite a maze! */
4350
Tim Petersa9bc1682003-01-11 03:39:11 +00004351/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004352 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4353 * So it's a tuple in any (non-error) case.
4354 */
4355static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004356datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004357{
4358 PyObject *basestate;
4359 PyObject *result = NULL;
4360
Tim Peters33e0f382003-01-10 02:05:14 +00004361 basestate = PyString_FromStringAndSize((char *)self->data,
4362 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004363 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004364 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00004365 result = Py_BuildValue("(O)", basestate);
4366 else
4367 result = Py_BuildValue("OO", basestate, self->tzinfo);
4368 Py_DECREF(basestate);
4369 }
4370 return result;
4371}
4372
4373static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004374datetime_setstate(PyDateTime_DateTime *self, PyObject *state)
Tim Peters2a799bf2002-12-16 20:18:38 +00004375{
Tim Peters2a799bf2002-12-16 20:18:38 +00004376 PyObject *basestate;
4377 PyObject *tzinfo = Py_None;
4378
4379 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
4380 &PyString_Type, &basestate,
4381 &tzinfo))
4382 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00004383 if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE ||
4384 check_tzinfo_subclass(tzinfo) < 0) {
4385 PyErr_SetString(PyExc_TypeError,
4386 "bad argument to datetime.__setstate__");
Tim Peters2a799bf2002-12-16 20:18:38 +00004387 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00004388 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004389 if (tzinfo != Py_None && ! HASTZINFO(self)) {
4390 PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ "
4391 "can't add a non-None tzinfo to a datetime "
4392 "object that doesn't have one already");
4393 return NULL;
4394 }
Tim Peters33e0f382003-01-10 02:05:14 +00004395 memcpy((char *)self->data,
4396 PyString_AsString(basestate),
4397 _PyDateTime_DATETIME_DATASIZE);
4398 self->hashcode = -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004399 if (HASTZINFO(self)) {
4400 Py_INCREF(tzinfo);
4401 Py_XDECREF(self->tzinfo);
4402 self->tzinfo = tzinfo;
4403 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004404 Py_INCREF(Py_None);
4405 return Py_None;
4406}
4407
4408static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004409datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004410{
Guido van Rossum177e41a2003-01-30 22:06:23 +00004411 return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004412}
4413
Tim Petersa9bc1682003-01-11 03:39:11 +00004414static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004415
Tim Peters2a799bf2002-12-16 20:18:38 +00004416 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004417
Tim Petersa9bc1682003-01-11 03:39:11 +00004418 {"now", (PyCFunction)datetime_now,
Tim Peters2a799bf2002-12-16 20:18:38 +00004419 METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004420 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004421
Tim Petersa9bc1682003-01-11 03:39:11 +00004422 {"utcnow", (PyCFunction)datetime_utcnow,
4423 METH_NOARGS | METH_CLASS,
4424 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4425
4426 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Tim Peters2a799bf2002-12-16 20:18:38 +00004427 METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004428 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004429
Tim Petersa9bc1682003-01-11 03:39:11 +00004430 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4431 METH_VARARGS | METH_CLASS,
4432 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4433 "(like time.time()).")},
4434
4435 {"combine", (PyCFunction)datetime_combine,
4436 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4437 PyDoc_STR("date, time -> datetime with same date and time fields")},
4438
Tim Peters2a799bf2002-12-16 20:18:38 +00004439 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004440
Tim Petersa9bc1682003-01-11 03:39:11 +00004441 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4442 PyDoc_STR("Return date object with same year, month and day.")},
4443
4444 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4445 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4446
4447 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4448 PyDoc_STR("Return time object with same time and tzinfo.")},
4449
4450 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4451 PyDoc_STR("Return ctime() style string.")},
4452
4453 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004454 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4455
Tim Petersa9bc1682003-01-11 03:39:11 +00004456 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004457 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4458
Tim Petersa9bc1682003-01-11 03:39:11 +00004459 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004460 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4461 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4462 "sep is used to separate the year from the time, and "
4463 "defaults to 'T'.")},
4464
Tim Petersa9bc1682003-01-11 03:39:11 +00004465 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004466 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4467
Tim Petersa9bc1682003-01-11 03:39:11 +00004468 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004469 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4470
Tim Petersa9bc1682003-01-11 03:39:11 +00004471 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004472 PyDoc_STR("Return self.tzinfo.dst(self).")},
4473
Tim Petersa9bc1682003-01-11 03:39:11 +00004474 {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
4475 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004476
Tim Petersa9bc1682003-01-11 03:39:11 +00004477 {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004478 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4479
Tim Petersa9bc1682003-01-11 03:39:11 +00004480 {"__setstate__", (PyCFunction)datetime_setstate, METH_O,
Tim Peters2a799bf2002-12-16 20:18:38 +00004481 PyDoc_STR("__setstate__(state)")},
4482
Tim Petersa9bc1682003-01-11 03:39:11 +00004483 {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004484 PyDoc_STR("__getstate__() -> state")},
Guido van Rossum177e41a2003-01-30 22:06:23 +00004485
4486 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4487 PyDoc_STR("__reduce__() -> (cls, state)")},
4488
Tim Peters2a799bf2002-12-16 20:18:38 +00004489 {NULL, NULL}
4490};
4491
Tim Petersa9bc1682003-01-11 03:39:11 +00004492static char datetime_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00004493PyDoc_STR("date/time type.");
4494
Tim Petersa9bc1682003-01-11 03:39:11 +00004495static PyNumberMethods datetime_as_number = {
4496 datetime_add, /* nb_add */
4497 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004498 0, /* nb_multiply */
4499 0, /* nb_divide */
4500 0, /* nb_remainder */
4501 0, /* nb_divmod */
4502 0, /* nb_power */
4503 0, /* nb_negative */
4504 0, /* nb_positive */
4505 0, /* nb_absolute */
4506 0, /* nb_nonzero */
4507};
4508
Tim Petersa9bc1682003-01-11 03:39:11 +00004509statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004510 PyObject_HEAD_INIT(NULL)
4511 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004512 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004513 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004514 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004515 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004516 0, /* tp_print */
4517 0, /* tp_getattr */
4518 0, /* tp_setattr */
4519 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004520 (reprfunc)datetime_repr, /* tp_repr */
4521 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004522 0, /* tp_as_sequence */
4523 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004524 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004525 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004526 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004527 PyObject_GenericGetAttr, /* tp_getattro */
4528 0, /* tp_setattro */
4529 0, /* tp_as_buffer */
4530 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4531 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004532 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004533 0, /* tp_traverse */
4534 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004535 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004536 0, /* tp_weaklistoffset */
4537 0, /* tp_iter */
4538 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004539 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004540 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004541 datetime_getset, /* tp_getset */
4542 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004543 0, /* tp_dict */
4544 0, /* tp_descr_get */
4545 0, /* tp_descr_set */
4546 0, /* tp_dictoffset */
4547 0, /* tp_init */
4548 0, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004549 datetime_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00004550 _PyObject_Del, /* tp_free */
4551};
4552
4553/* ---------------------------------------------------------------------------
4554 * Module methods and initialization.
4555 */
4556
4557static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004558 {NULL, NULL}
4559};
4560
4561PyMODINIT_FUNC
4562initdatetime(void)
4563{
4564 PyObject *m; /* a module object */
4565 PyObject *d; /* its dict */
4566 PyObject *x;
4567
4568 /* Types that use __reduce__ for pickling need to set the following
4569 * magical attr in the type dict, with a true value.
4570 */
4571 PyObject *safepickle = PyString_FromString("__safe_for_unpickling__");
4572 if (safepickle == NULL)
4573 return;
4574
4575 m = Py_InitModule3("datetime", module_methods,
4576 "Fast implementation of the datetime type.");
4577
4578 if (PyType_Ready(&PyDateTime_DateType) < 0)
4579 return;
4580 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4581 return;
4582 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4583 return;
4584 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4585 return;
4586 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4587 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004588
Guido van Rossum177e41a2003-01-30 22:06:23 +00004589 /* Make __getnewargs__ a true alias for __getstate__ */
Tim Peters2a799bf2002-12-16 20:18:38 +00004590 {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004591 PyObject *d, *f;
Tim Peters2a799bf2002-12-16 20:18:38 +00004592
Guido van Rossum177e41a2003-01-30 22:06:23 +00004593 d = PyDateTime_DateType.tp_dict;
4594 f = PyDict_GetItemString(d, "__getstate__");
4595 if (f != NULL) {
4596 if (PyDict_SetItemString(d, "__getnewargs__", f) < 0)
4597 return;
4598 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004599
Guido van Rossum177e41a2003-01-30 22:06:23 +00004600 d = PyDateTime_DateTimeType.tp_dict;
4601 f = PyDict_GetItemString(d, "__getstate__");
4602 if (f != NULL) {
4603 if (PyDict_SetItemString(d, "__getnewargs__", f) < 0)
4604 return;
4605 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004606
Guido van Rossum177e41a2003-01-30 22:06:23 +00004607 d = PyDateTime_DeltaType.tp_dict;
4608 f = PyDict_GetItemString(d, "__getstate__");
4609 if (f != NULL) {
4610 if (PyDict_SetItemString(d, "__getnewargs__", f) < 0)
4611 return;
4612 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004613
Guido van Rossum177e41a2003-01-30 22:06:23 +00004614 d = PyDateTime_TimeType.tp_dict;
4615 f = PyDict_GetItemString(d, "__getstate__");
4616 if (f != NULL) {
4617 if (PyDict_SetItemString(d, "__getnewargs__", f) < 0)
4618 return;
4619 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004620
Guido van Rossum177e41a2003-01-30 22:06:23 +00004621 d = PyDateTime_TZInfoType.tp_dict;
4622 f = PyDict_GetItemString(d, "__getstate__");
4623 if (f != NULL) {
4624 if (PyDict_SetItemString(d, "__getnewargs__", f) < 0)
4625 return;
4626 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004627 }
4628
Guido van Rossum177e41a2003-01-30 22:06:23 +00004629 /* tzinfo values */
4630 d = PyDateTime_TZInfoType.tp_dict;
4631
4632 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
4633 return;
4634
Tim Peters2a799bf2002-12-16 20:18:38 +00004635 /* timedelta values */
4636 d = PyDateTime_DeltaType.tp_dict;
4637
4638 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
4639 return;
4640
4641 x = new_delta(0, 0, 1, 0);
4642 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4643 return;
4644 Py_DECREF(x);
4645
4646 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4647 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4648 return;
4649 Py_DECREF(x);
4650
4651 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4652 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4653 return;
4654 Py_DECREF(x);
4655
4656 /* date values */
4657 d = PyDateTime_DateType.tp_dict;
4658
Guido van Rossum177e41a2003-01-30 22:06:23 +00004659 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
4660 return;
4661
Tim Peters2a799bf2002-12-16 20:18:38 +00004662 x = new_date(1, 1, 1);
4663 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4664 return;
4665 Py_DECREF(x);
4666
4667 x = new_date(MAXYEAR, 12, 31);
4668 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4669 return;
4670 Py_DECREF(x);
4671
4672 x = new_delta(1, 0, 0, 0);
4673 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4674 return;
4675 Py_DECREF(x);
4676
Tim Peters37f39822003-01-10 03:49:02 +00004677 /* time values */
4678 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004679
Guido van Rossum177e41a2003-01-30 22:06:23 +00004680 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
4681 return;
4682
Tim Peters37f39822003-01-10 03:49:02 +00004683 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004684 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4685 return;
4686 Py_DECREF(x);
4687
Tim Peters37f39822003-01-10 03:49:02 +00004688 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004689 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4690 return;
4691 Py_DECREF(x);
4692
4693 x = new_delta(0, 0, 1, 0);
4694 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4695 return;
4696 Py_DECREF(x);
4697
Tim Petersa9bc1682003-01-11 03:39:11 +00004698 /* datetime values */
4699 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004700
Guido van Rossum177e41a2003-01-30 22:06:23 +00004701 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
4702 return;
4703
Tim Petersa9bc1682003-01-11 03:39:11 +00004704 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004705 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4706 return;
4707 Py_DECREF(x);
4708
Tim Petersa9bc1682003-01-11 03:39:11 +00004709 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004710 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4711 return;
4712 Py_DECREF(x);
4713
4714 x = new_delta(0, 0, 1, 0);
4715 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4716 return;
4717 Py_DECREF(x);
4718
4719 Py_DECREF(safepickle);
4720
4721 /* module initialization */
4722 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4723 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4724
4725 Py_INCREF(&PyDateTime_DateType);
4726 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4727
Tim Petersa9bc1682003-01-11 03:39:11 +00004728 Py_INCREF(&PyDateTime_DateTimeType);
4729 PyModule_AddObject(m, "datetime",
4730 (PyObject *)&PyDateTime_DateTimeType);
4731
4732 Py_INCREF(&PyDateTime_TimeType);
4733 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4734
Tim Peters2a799bf2002-12-16 20:18:38 +00004735 Py_INCREF(&PyDateTime_DeltaType);
4736 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4737
Tim Peters2a799bf2002-12-16 20:18:38 +00004738 Py_INCREF(&PyDateTime_TZInfoType);
4739 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4740
Tim Peters2a799bf2002-12-16 20:18:38 +00004741 /* A 4-year cycle has an extra leap day over what we'd get from
4742 * pasting together 4 single years.
4743 */
4744 assert(DI4Y == 4 * 365 + 1);
4745 assert(DI4Y == days_before_year(4+1));
4746
4747 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4748 * get from pasting together 4 100-year cycles.
4749 */
4750 assert(DI400Y == 4 * DI100Y + 1);
4751 assert(DI400Y == days_before_year(400+1));
4752
4753 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4754 * pasting together 25 4-year cycles.
4755 */
4756 assert(DI100Y == 25 * DI4Y - 1);
4757 assert(DI100Y == days_before_year(100+1));
4758
4759 us_per_us = PyInt_FromLong(1);
4760 us_per_ms = PyInt_FromLong(1000);
4761 us_per_second = PyInt_FromLong(1000000);
4762 us_per_minute = PyInt_FromLong(60000000);
4763 seconds_per_day = PyInt_FromLong(24 * 3600);
4764 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4765 us_per_minute == NULL || seconds_per_day == NULL)
4766 return;
4767
4768 /* The rest are too big for 32-bit ints, but even
4769 * us_per_week fits in 40 bits, so doubles should be exact.
4770 */
4771 us_per_hour = PyLong_FromDouble(3600000000.0);
4772 us_per_day = PyLong_FromDouble(86400000000.0);
4773 us_per_week = PyLong_FromDouble(604800000000.0);
4774 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4775 return;
4776}
Tim Petersf3615152003-01-01 21:51:37 +00004777
4778/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004779Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004780 x.n = x stripped of its timezone -- its naive time.
4781 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4782 return None
4783 x.d = x.dst(), and assuming that doesn't raise an exception or
4784 return None
4785 x.s = x's standard offset, x.o - x.d
4786
4787Now some derived rules, where k is a duration (timedelta).
4788
47891. x.o = x.s + x.d
4790 This follows from the definition of x.s.
4791
Tim Petersc5dc4da2003-01-02 17:55:03 +000047922. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004793 This is actually a requirement, an assumption we need to make about
4794 sane tzinfo classes.
4795
47963. The naive UTC time corresponding to x is x.n - x.o.
4797 This is again a requirement for a sane tzinfo class.
4798
47994. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004800 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004801
Tim Petersc5dc4da2003-01-02 17:55:03 +000048025. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004803 Again follows from how arithmetic is defined.
4804
Tim Peters8bb5ad22003-01-24 02:44:45 +00004805Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004806(meaning that the various tzinfo methods exist, and don't blow up or return
4807None when called).
4808
Tim Petersa9bc1682003-01-11 03:39:11 +00004809The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004810x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004811
4812By #3, we want
4813
Tim Peters8bb5ad22003-01-24 02:44:45 +00004814 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004815
4816The algorithm starts by attaching tz to x.n, and calling that y. So
4817x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4818becomes true; in effect, we want to solve [2] for k:
4819
Tim Peters8bb5ad22003-01-24 02:44:45 +00004820 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004821
4822By #1, this is the same as
4823
Tim Peters8bb5ad22003-01-24 02:44:45 +00004824 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004825
4826By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4827Substituting that into [3],
4828
Tim Peters8bb5ad22003-01-24 02:44:45 +00004829 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4830 k - (y+k).s - (y+k).d = 0; rearranging,
4831 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4832 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004833
Tim Peters8bb5ad22003-01-24 02:44:45 +00004834On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4835approximate k by ignoring the (y+k).d term at first. Note that k can't be
4836very large, since all offset-returning methods return a duration of magnitude
4837less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4838be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004839
4840In any case, the new value is
4841
Tim Peters8bb5ad22003-01-24 02:44:45 +00004842 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004843
Tim Peters8bb5ad22003-01-24 02:44:45 +00004844It's helpful to step back at look at [4] from a higher level: it's simply
4845mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004846
4847At this point, if
4848
Tim Peters8bb5ad22003-01-24 02:44:45 +00004849 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004850
4851we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004852at the start of daylight time. Picture US Eastern for concreteness. The wall
4853time 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 +00004854sense then. The docs ask that an Eastern tzinfo class consider such a time to
4855be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4856on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004857the only spelling that makes sense on the local wall clock.
4858
Tim Petersc5dc4da2003-01-02 17:55:03 +00004859In fact, if [5] holds at this point, we do have the standard-time spelling,
4860but that takes a bit of proof. We first prove a stronger result. What's the
4861difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004862
Tim Peters8bb5ad22003-01-24 02:44:45 +00004863 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004864
Tim Petersc5dc4da2003-01-02 17:55:03 +00004865Now
4866 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004867 (y + y.s).n = by #5
4868 y.n + y.s = since y.n = x.n
4869 x.n + y.s = since z and y are have the same tzinfo member,
4870 y.s = z.s by #2
4871 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004872
Tim Petersc5dc4da2003-01-02 17:55:03 +00004873Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004874
Tim Petersc5dc4da2003-01-02 17:55:03 +00004875 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004876 x.n - ((x.n + z.s) - z.o) = expanding
4877 x.n - x.n - z.s + z.o = cancelling
4878 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004879 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004880
Tim Petersc5dc4da2003-01-02 17:55:03 +00004881So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004882
Tim Petersc5dc4da2003-01-02 17:55:03 +00004883If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004884spelling we wanted in the endcase described above. We're done. Contrarily,
4885if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004886
Tim Petersc5dc4da2003-01-02 17:55:03 +00004887If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4888add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00004889local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004890
Tim Petersc5dc4da2003-01-02 17:55:03 +00004891Let
Tim Petersf3615152003-01-01 21:51:37 +00004892
Tim Peters4fede1a2003-01-04 00:26:59 +00004893 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004894
Tim Peters4fede1a2003-01-04 00:26:59 +00004895and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004896
Tim Peters8bb5ad22003-01-24 02:44:45 +00004897 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004898
Tim Peters8bb5ad22003-01-24 02:44:45 +00004899If so, we're done. If not, the tzinfo class is insane, according to the
4900assumptions we've made. This also requires a bit of proof. As before, let's
4901compute the difference between the LHS and RHS of [8] (and skipping some of
4902the justifications for the kinds of substitutions we've done several times
4903already):
Tim Peters4fede1a2003-01-04 00:26:59 +00004904
Tim Peters8bb5ad22003-01-24 02:44:45 +00004905 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
4906 x.n - (z.n + diff - z'.o) = replacing diff via [6]
4907 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
4908 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
4909 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00004910 - z.o + z'.o = #1 twice
4911 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4912 z'.d - z.d
4913
4914So 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 +00004915we've found the UTC-equivalent so are done. In fact, we stop with [7] and
4916return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00004917
Tim Peters8bb5ad22003-01-24 02:44:45 +00004918How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
4919a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
4920would have to change the result dst() returns: we start in DST, and moving
4921a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00004922
Tim Peters8bb5ad22003-01-24 02:44:45 +00004923There isn't a sane case where this can happen. The closest it gets is at
4924the end of DST, where there's an hour in UTC with no spelling in a hybrid
4925tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
4926that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
4927UTC) because the docs insist on that, but 0:MM is taken as being in daylight
4928time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
4929clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
4930standard time. Since that's what the local clock *does*, we want to map both
4931UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00004932in local time, but so it goes -- it's the way the local clock works.
4933
Tim Peters8bb5ad22003-01-24 02:44:45 +00004934When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4935so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4936z' = 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 +00004937(correctly) concludes that z' is not UTC-equivalent to x.
4938
4939Because we know z.d said z was in daylight time (else [5] would have held and
4940we would have stopped then), and we know z.d != z'.d (else [8] would have held
4941and we we have stopped then), and there are only 2 possible values dst() can
4942return in Eastern, it follows that z'.d must be 0 (which it is in the example,
4943but the reasoning doesn't depend on the example -- it depends on there being
4944two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00004945z' must be in standard time, and is the spelling we want in this case.
4946
4947Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
4948concerned (because it takes z' as being in standard time rather than the
4949daylight time we intend here), but returning it gives the real-life "local
4950clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
4951tz.
4952
4953When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
4954the 1:MM standard time spelling we want.
4955
4956So how can this break? One of the assumptions must be violated. Two
4957possibilities:
4958
49591) [2] effectively says that y.s is invariant across all y belong to a given
4960 time zone. This isn't true if, for political reasons or continental drift,
4961 a region decides to change its base offset from UTC.
4962
49632) There may be versions of "double daylight" time where the tail end of
4964 the analysis gives up a step too early. I haven't thought about that
4965 enough to say.
4966
4967In any case, it's clear that the default fromutc() is strong enough to handle
4968"almost all" time zones: so long as the standard offset is invariant, it
4969doesn't matter if daylight time transition points change from year to year, or
4970if daylight time is skipped in some years; it doesn't matter how large or
4971small dst() may get within its bounds; and it doesn't even matter if some
4972perverse time zone returns a negative dst()). So a breaking case must be
4973pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00004974--------------------------------------------------------------------------- */