blob: e514a5427f43c9c006a0136bd17528b0f4473388 [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
Tim Peters07534a62003-02-07 22:50:28 +00001227/* Raises a "can't compare" TypeError and returns NULL. */
1228static PyObject *
1229cmperror(PyObject *a, PyObject *b)
1230{
1231 PyErr_Format(PyExc_TypeError,
1232 "can't compare %s to %s",
1233 a->ob_type->tp_name, b->ob_type->tp_name);
1234 return NULL;
1235}
1236
Tim Peters2a799bf2002-12-16 20:18:38 +00001237/* ---------------------------------------------------------------------------
Tim Peters70533e22003-02-01 04:40:04 +00001238 * Basic object allocation. These allocate Python objects of the right
1239 * size and type, and do the Python object-initialization bit. If there's
1240 * not enough memory, they return NULL after setting MemoryError. All
1241 * data members remain uninitialized trash.
1242 */
1243static PyDateTime_Time *
1244alloc_time(int aware)
1245{
1246 PyDateTime_Time *self;
1247
1248 self = (PyDateTime_Time *)
1249 PyObject_MALLOC(aware ?
1250 sizeof(PyDateTime_Time) :
1251 sizeof(_PyDateTime_BaseTime));
1252 if (self == NULL)
1253 return (PyDateTime_Time *)PyErr_NoMemory();
1254 PyObject_INIT(self, &PyDateTime_TimeType);
1255 return self;
1256}
1257
1258static PyDateTime_DateTime *
1259alloc_datetime(int aware)
1260{
1261 PyDateTime_DateTime *self;
1262
1263 self = (PyDateTime_DateTime *)
1264 PyObject_MALLOC(aware ?
1265 sizeof(PyDateTime_DateTime) :
1266 sizeof(_PyDateTime_BaseDateTime));
1267 if (self == NULL)
1268 return (PyDateTime_DateTime *)PyErr_NoMemory();
1269 PyObject_INIT(self, &PyDateTime_DateTimeType);
1270 return self;
1271}
1272
1273/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001274 * Helpers for setting object fields. These work on pointers to the
1275 * appropriate base class.
1276 */
1277
Tim Petersa9bc1682003-01-11 03:39:11 +00001278/* For date and datetime. */
Tim Peters2a799bf2002-12-16 20:18:38 +00001279static void
1280set_date_fields(PyDateTime_Date *self, int y, int m, int d)
1281{
1282 self->hashcode = -1;
1283 SET_YEAR(self, y);
1284 SET_MONTH(self, m);
1285 SET_DAY(self, d);
1286}
1287
Tim Peters2a799bf2002-12-16 20:18:38 +00001288/* ---------------------------------------------------------------------------
1289 * Create various objects, mostly without range checking.
1290 */
1291
1292/* Create a date instance with no range checking. */
1293static PyObject *
1294new_date(int year, int month, int day)
1295{
1296 PyDateTime_Date *self;
1297
1298 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
1299 if (self != NULL)
1300 set_date_fields(self, year, month, day);
1301 return (PyObject *) self;
1302}
1303
1304/* Create a datetime instance with no range checking. */
1305static PyObject *
1306new_datetime(int year, int month, int day, int hour, int minute,
Tim Petersa9bc1682003-01-11 03:39:11 +00001307 int second, int usecond, PyObject *tzinfo)
Tim Peters2a799bf2002-12-16 20:18:38 +00001308{
1309 PyDateTime_DateTime *self;
Tim Petersa9bc1682003-01-11 03:39:11 +00001310 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001311
Tim Peters70533e22003-02-01 04:40:04 +00001312 self = alloc_datetime(aware);
1313 if (self != NULL) {
1314 self->hastzinfo = aware;
1315 set_date_fields((PyDateTime_Date *)self, year, month, day);
1316 DATE_SET_HOUR(self, hour);
1317 DATE_SET_MINUTE(self, minute);
1318 DATE_SET_SECOND(self, second);
1319 DATE_SET_MICROSECOND(self, usecond);
1320 if (aware) {
1321 Py_INCREF(tzinfo);
1322 self->tzinfo = tzinfo;
1323 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001324 }
Tim Peters70533e22003-02-01 04:40:04 +00001325 return (PyObject *)self;
Tim Peters2a799bf2002-12-16 20:18:38 +00001326}
1327
1328/* Create a time instance with no range checking. */
1329static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00001330new_time(int hour, int minute, int second, int usecond, PyObject *tzinfo)
Tim Peters2a799bf2002-12-16 20:18:38 +00001331{
1332 PyDateTime_Time *self;
Tim Peters37f39822003-01-10 03:49:02 +00001333 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001334
Tim Peters70533e22003-02-01 04:40:04 +00001335 self = alloc_time(aware);
1336 if (self != NULL) {
1337 self->hastzinfo = aware;
1338 self->hashcode = -1;
1339 TIME_SET_HOUR(self, hour);
1340 TIME_SET_MINUTE(self, minute);
1341 TIME_SET_SECOND(self, second);
1342 TIME_SET_MICROSECOND(self, usecond);
1343 if (aware) {
1344 Py_INCREF(tzinfo);
1345 self->tzinfo = tzinfo;
1346 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001347 }
Tim Peters70533e22003-02-01 04:40:04 +00001348 return (PyObject *)self;
Tim Peters2a799bf2002-12-16 20:18:38 +00001349}
1350
1351/* Create a timedelta instance. Normalize the members iff normalize is
1352 * true. Passing false is a speed optimization, if you know for sure
1353 * that seconds and microseconds are already in their proper ranges. In any
1354 * case, raises OverflowError and returns NULL if the normalized days is out
1355 * of range).
1356 */
1357static PyObject *
1358new_delta(int days, int seconds, int microseconds, int normalize)
1359{
1360 PyDateTime_Delta *self;
1361
1362 if (normalize)
1363 normalize_d_s_us(&days, &seconds, &microseconds);
1364 assert(0 <= seconds && seconds < 24*3600);
1365 assert(0 <= microseconds && microseconds < 1000000);
1366
1367 if (check_delta_day_range(days) < 0)
1368 return NULL;
1369
1370 self = PyObject_New(PyDateTime_Delta, &PyDateTime_DeltaType);
1371 if (self != NULL) {
1372 self->hashcode = -1;
1373 SET_TD_DAYS(self, days);
1374 SET_TD_SECONDS(self, seconds);
1375 SET_TD_MICROSECONDS(self, microseconds);
1376 }
1377 return (PyObject *) self;
1378}
1379
1380
1381/* ---------------------------------------------------------------------------
1382 * Cached Python objects; these are set by the module init function.
1383 */
1384
1385/* Conversion factors. */
1386static PyObject *us_per_us = NULL; /* 1 */
1387static PyObject *us_per_ms = NULL; /* 1000 */
1388static PyObject *us_per_second = NULL; /* 1000000 */
1389static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1390static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1391static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1392static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1393static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1394
Tim Peters2a799bf2002-12-16 20:18:38 +00001395/* ---------------------------------------------------------------------------
1396 * Class implementations.
1397 */
1398
1399/*
1400 * PyDateTime_Delta implementation.
1401 */
1402
1403/* Convert a timedelta to a number of us,
1404 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1405 * as a Python int or long.
1406 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1407 * due to ubiquitous overflow possibilities.
1408 */
1409static PyObject *
1410delta_to_microseconds(PyDateTime_Delta *self)
1411{
1412 PyObject *x1 = NULL;
1413 PyObject *x2 = NULL;
1414 PyObject *x3 = NULL;
1415 PyObject *result = NULL;
1416
1417 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1418 if (x1 == NULL)
1419 goto Done;
1420 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1421 if (x2 == NULL)
1422 goto Done;
1423 Py_DECREF(x1);
1424 x1 = NULL;
1425
1426 /* x2 has days in seconds */
1427 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1428 if (x1 == NULL)
1429 goto Done;
1430 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1431 if (x3 == NULL)
1432 goto Done;
1433 Py_DECREF(x1);
1434 Py_DECREF(x2);
1435 x1 = x2 = NULL;
1436
1437 /* x3 has days+seconds in seconds */
1438 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1439 if (x1 == NULL)
1440 goto Done;
1441 Py_DECREF(x3);
1442 x3 = NULL;
1443
1444 /* x1 has days+seconds in us */
1445 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1446 if (x2 == NULL)
1447 goto Done;
1448 result = PyNumber_Add(x1, x2);
1449
1450Done:
1451 Py_XDECREF(x1);
1452 Py_XDECREF(x2);
1453 Py_XDECREF(x3);
1454 return result;
1455}
1456
1457/* Convert a number of us (as a Python int or long) to a timedelta.
1458 */
1459static PyObject *
1460microseconds_to_delta(PyObject *pyus)
1461{
1462 int us;
1463 int s;
1464 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001465 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001466
1467 PyObject *tuple = NULL;
1468 PyObject *num = NULL;
1469 PyObject *result = NULL;
1470
1471 tuple = PyNumber_Divmod(pyus, us_per_second);
1472 if (tuple == NULL)
1473 goto Done;
1474
1475 num = PyTuple_GetItem(tuple, 1); /* us */
1476 if (num == NULL)
1477 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001478 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001479 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001480 if (temp == -1 && PyErr_Occurred())
1481 goto Done;
1482 assert(0 <= temp && temp < 1000000);
1483 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001484 if (us < 0) {
1485 /* The divisor was positive, so this must be an error. */
1486 assert(PyErr_Occurred());
1487 goto Done;
1488 }
1489
1490 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1491 if (num == NULL)
1492 goto Done;
1493 Py_INCREF(num);
1494 Py_DECREF(tuple);
1495
1496 tuple = PyNumber_Divmod(num, seconds_per_day);
1497 if (tuple == NULL)
1498 goto Done;
1499 Py_DECREF(num);
1500
1501 num = PyTuple_GetItem(tuple, 1); /* seconds */
1502 if (num == NULL)
1503 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001504 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001505 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001506 if (temp == -1 && PyErr_Occurred())
1507 goto Done;
1508 assert(0 <= temp && temp < 24*3600);
1509 s = (int)temp;
1510
Tim Peters2a799bf2002-12-16 20:18:38 +00001511 if (s < 0) {
1512 /* The divisor was positive, so this must be an error. */
1513 assert(PyErr_Occurred());
1514 goto Done;
1515 }
1516
1517 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1518 if (num == NULL)
1519 goto Done;
1520 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001521 temp = PyLong_AsLong(num);
1522 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001523 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001524 d = (int)temp;
1525 if ((long)d != temp) {
1526 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1527 "large to fit in a C int");
1528 goto Done;
1529 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001530 result = new_delta(d, s, us, 0);
1531
1532Done:
1533 Py_XDECREF(tuple);
1534 Py_XDECREF(num);
1535 return result;
1536}
1537
1538static PyObject *
1539multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1540{
1541 PyObject *pyus_in;
1542 PyObject *pyus_out;
1543 PyObject *result;
1544
1545 pyus_in = delta_to_microseconds(delta);
1546 if (pyus_in == NULL)
1547 return NULL;
1548
1549 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1550 Py_DECREF(pyus_in);
1551 if (pyus_out == NULL)
1552 return NULL;
1553
1554 result = microseconds_to_delta(pyus_out);
1555 Py_DECREF(pyus_out);
1556 return result;
1557}
1558
1559static PyObject *
1560divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1561{
1562 PyObject *pyus_in;
1563 PyObject *pyus_out;
1564 PyObject *result;
1565
1566 pyus_in = delta_to_microseconds(delta);
1567 if (pyus_in == NULL)
1568 return NULL;
1569
1570 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1571 Py_DECREF(pyus_in);
1572 if (pyus_out == NULL)
1573 return NULL;
1574
1575 result = microseconds_to_delta(pyus_out);
1576 Py_DECREF(pyus_out);
1577 return result;
1578}
1579
1580static PyObject *
1581delta_add(PyObject *left, PyObject *right)
1582{
1583 PyObject *result = Py_NotImplemented;
1584
1585 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1586 /* delta + delta */
1587 /* The C-level additions can't overflow because of the
1588 * invariant bounds.
1589 */
1590 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1591 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1592 int microseconds = GET_TD_MICROSECONDS(left) +
1593 GET_TD_MICROSECONDS(right);
1594 result = new_delta(days, seconds, microseconds, 1);
1595 }
1596
1597 if (result == Py_NotImplemented)
1598 Py_INCREF(result);
1599 return result;
1600}
1601
1602static PyObject *
1603delta_negative(PyDateTime_Delta *self)
1604{
1605 return new_delta(-GET_TD_DAYS(self),
1606 -GET_TD_SECONDS(self),
1607 -GET_TD_MICROSECONDS(self),
1608 1);
1609}
1610
1611static PyObject *
1612delta_positive(PyDateTime_Delta *self)
1613{
1614 /* Could optimize this (by returning self) if this isn't a
1615 * subclass -- but who uses unary + ? Approximately nobody.
1616 */
1617 return new_delta(GET_TD_DAYS(self),
1618 GET_TD_SECONDS(self),
1619 GET_TD_MICROSECONDS(self),
1620 0);
1621}
1622
1623static PyObject *
1624delta_abs(PyDateTime_Delta *self)
1625{
1626 PyObject *result;
1627
1628 assert(GET_TD_MICROSECONDS(self) >= 0);
1629 assert(GET_TD_SECONDS(self) >= 0);
1630
1631 if (GET_TD_DAYS(self) < 0)
1632 result = delta_negative(self);
1633 else
1634 result = delta_positive(self);
1635
1636 return result;
1637}
1638
1639static PyObject *
1640delta_subtract(PyObject *left, PyObject *right)
1641{
1642 PyObject *result = Py_NotImplemented;
1643
1644 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1645 /* delta - delta */
1646 PyObject *minus_right = PyNumber_Negative(right);
1647 if (minus_right) {
1648 result = delta_add(left, minus_right);
1649 Py_DECREF(minus_right);
1650 }
1651 else
1652 result = NULL;
1653 }
1654
1655 if (result == Py_NotImplemented)
1656 Py_INCREF(result);
1657 return result;
1658}
1659
1660/* This is more natural as a tp_compare, but doesn't work then: for whatever
1661 * reason, Python's try_3way_compare ignores tp_compare unless
1662 * PyInstance_Check returns true, but these aren't old-style classes.
1663 */
1664static PyObject *
1665delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1666{
Tim Peters07534a62003-02-07 22:50:28 +00001667 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001668
Tim Petersaa7d8492003-02-08 03:28:59 +00001669 if (PyDelta_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00001670 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1671 if (diff == 0) {
1672 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1673 if (diff == 0)
1674 diff = GET_TD_MICROSECONDS(self) -
1675 GET_TD_MICROSECONDS(other);
1676 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001677 }
Tim Peters07534a62003-02-07 22:50:28 +00001678 else if (op == Py_EQ || op == Py_NE)
1679 diff = 1; /* any non-zero value will do */
1680
1681 else /* stop this from falling back to address comparison */
1682 return cmperror((PyObject *)self, other);
1683
Tim Peters2a799bf2002-12-16 20:18:38 +00001684 return diff_to_bool(diff, op);
1685}
1686
1687static PyObject *delta_getstate(PyDateTime_Delta *self);
1688
1689static long
1690delta_hash(PyDateTime_Delta *self)
1691{
1692 if (self->hashcode == -1) {
1693 PyObject *temp = delta_getstate(self);
1694 if (temp != NULL) {
1695 self->hashcode = PyObject_Hash(temp);
1696 Py_DECREF(temp);
1697 }
1698 }
1699 return self->hashcode;
1700}
1701
1702static PyObject *
1703delta_multiply(PyObject *left, PyObject *right)
1704{
1705 PyObject *result = Py_NotImplemented;
1706
1707 if (PyDelta_Check(left)) {
1708 /* delta * ??? */
1709 if (PyInt_Check(right) || PyLong_Check(right))
1710 result = multiply_int_timedelta(right,
1711 (PyDateTime_Delta *) left);
1712 }
1713 else if (PyInt_Check(left) || PyLong_Check(left))
1714 result = multiply_int_timedelta(left,
1715 (PyDateTime_Delta *) right);
1716
1717 if (result == Py_NotImplemented)
1718 Py_INCREF(result);
1719 return result;
1720}
1721
1722static PyObject *
1723delta_divide(PyObject *left, PyObject *right)
1724{
1725 PyObject *result = Py_NotImplemented;
1726
1727 if (PyDelta_Check(left)) {
1728 /* delta * ??? */
1729 if (PyInt_Check(right) || PyLong_Check(right))
1730 result = divide_timedelta_int(
1731 (PyDateTime_Delta *)left,
1732 right);
1733 }
1734
1735 if (result == Py_NotImplemented)
1736 Py_INCREF(result);
1737 return result;
1738}
1739
1740/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1741 * timedelta constructor. sofar is the # of microseconds accounted for
1742 * so far, and there are factor microseconds per current unit, the number
1743 * of which is given by num. num * factor is added to sofar in a
1744 * numerically careful way, and that's the result. Any fractional
1745 * microseconds left over (this can happen if num is a float type) are
1746 * added into *leftover.
1747 * Note that there are many ways this can give an error (NULL) return.
1748 */
1749static PyObject *
1750accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1751 double *leftover)
1752{
1753 PyObject *prod;
1754 PyObject *sum;
1755
1756 assert(num != NULL);
1757
1758 if (PyInt_Check(num) || PyLong_Check(num)) {
1759 prod = PyNumber_Multiply(num, factor);
1760 if (prod == NULL)
1761 return NULL;
1762 sum = PyNumber_Add(sofar, prod);
1763 Py_DECREF(prod);
1764 return sum;
1765 }
1766
1767 if (PyFloat_Check(num)) {
1768 double dnum;
1769 double fracpart;
1770 double intpart;
1771 PyObject *x;
1772 PyObject *y;
1773
1774 /* The Plan: decompose num into an integer part and a
1775 * fractional part, num = intpart + fracpart.
1776 * Then num * factor ==
1777 * intpart * factor + fracpart * factor
1778 * and the LHS can be computed exactly in long arithmetic.
1779 * The RHS is again broken into an int part and frac part.
1780 * and the frac part is added into *leftover.
1781 */
1782 dnum = PyFloat_AsDouble(num);
1783 if (dnum == -1.0 && PyErr_Occurred())
1784 return NULL;
1785 fracpart = modf(dnum, &intpart);
1786 x = PyLong_FromDouble(intpart);
1787 if (x == NULL)
1788 return NULL;
1789
1790 prod = PyNumber_Multiply(x, factor);
1791 Py_DECREF(x);
1792 if (prod == NULL)
1793 return NULL;
1794
1795 sum = PyNumber_Add(sofar, prod);
1796 Py_DECREF(prod);
1797 if (sum == NULL)
1798 return NULL;
1799
1800 if (fracpart == 0.0)
1801 return sum;
1802 /* So far we've lost no information. Dealing with the
1803 * fractional part requires float arithmetic, and may
1804 * lose a little info.
1805 */
1806 assert(PyInt_Check(factor) || PyLong_Check(factor));
1807 if (PyInt_Check(factor))
1808 dnum = (double)PyInt_AsLong(factor);
1809 else
1810 dnum = PyLong_AsDouble(factor);
1811
1812 dnum *= fracpart;
1813 fracpart = modf(dnum, &intpart);
1814 x = PyLong_FromDouble(intpart);
1815 if (x == NULL) {
1816 Py_DECREF(sum);
1817 return NULL;
1818 }
1819
1820 y = PyNumber_Add(sum, x);
1821 Py_DECREF(sum);
1822 Py_DECREF(x);
1823 *leftover += fracpart;
1824 return y;
1825 }
1826
1827 PyErr_Format(PyExc_TypeError,
1828 "unsupported type for timedelta %s component: %s",
1829 tag, num->ob_type->tp_name);
1830 return NULL;
1831}
1832
1833static PyObject *
1834delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1835{
1836 PyObject *self = NULL;
1837
1838 /* Argument objects. */
1839 PyObject *day = NULL;
1840 PyObject *second = NULL;
1841 PyObject *us = NULL;
1842 PyObject *ms = NULL;
1843 PyObject *minute = NULL;
1844 PyObject *hour = NULL;
1845 PyObject *week = NULL;
1846
1847 PyObject *x = NULL; /* running sum of microseconds */
1848 PyObject *y = NULL; /* temp sum of microseconds */
1849 double leftover_us = 0.0;
1850
1851 static char *keywords[] = {
1852 "days", "seconds", "microseconds", "milliseconds",
1853 "minutes", "hours", "weeks", NULL
1854 };
1855
1856 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1857 keywords,
1858 &day, &second, &us,
1859 &ms, &minute, &hour, &week) == 0)
1860 goto Done;
1861
1862 x = PyInt_FromLong(0);
1863 if (x == NULL)
1864 goto Done;
1865
1866#define CLEANUP \
1867 Py_DECREF(x); \
1868 x = y; \
1869 if (x == NULL) \
1870 goto Done
1871
1872 if (us) {
1873 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1874 CLEANUP;
1875 }
1876 if (ms) {
1877 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1878 CLEANUP;
1879 }
1880 if (second) {
1881 y = accum("seconds", x, second, us_per_second, &leftover_us);
1882 CLEANUP;
1883 }
1884 if (minute) {
1885 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1886 CLEANUP;
1887 }
1888 if (hour) {
1889 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1890 CLEANUP;
1891 }
1892 if (day) {
1893 y = accum("days", x, day, us_per_day, &leftover_us);
1894 CLEANUP;
1895 }
1896 if (week) {
1897 y = accum("weeks", x, week, us_per_week, &leftover_us);
1898 CLEANUP;
1899 }
1900 if (leftover_us) {
1901 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001902 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001903 if (temp == NULL) {
1904 Py_DECREF(x);
1905 goto Done;
1906 }
1907 y = PyNumber_Add(x, temp);
1908 Py_DECREF(temp);
1909 CLEANUP;
1910 }
1911
1912 self = microseconds_to_delta(x);
1913 Py_DECREF(x);
1914Done:
1915 return self;
1916
1917#undef CLEANUP
1918}
1919
1920static int
1921delta_nonzero(PyDateTime_Delta *self)
1922{
1923 return (GET_TD_DAYS(self) != 0
1924 || GET_TD_SECONDS(self) != 0
1925 || GET_TD_MICROSECONDS(self) != 0);
1926}
1927
1928static PyObject *
1929delta_repr(PyDateTime_Delta *self)
1930{
1931 if (GET_TD_MICROSECONDS(self) != 0)
1932 return PyString_FromFormat("%s(%d, %d, %d)",
1933 self->ob_type->tp_name,
1934 GET_TD_DAYS(self),
1935 GET_TD_SECONDS(self),
1936 GET_TD_MICROSECONDS(self));
1937 if (GET_TD_SECONDS(self) != 0)
1938 return PyString_FromFormat("%s(%d, %d)",
1939 self->ob_type->tp_name,
1940 GET_TD_DAYS(self),
1941 GET_TD_SECONDS(self));
1942
1943 return PyString_FromFormat("%s(%d)",
1944 self->ob_type->tp_name,
1945 GET_TD_DAYS(self));
1946}
1947
1948static PyObject *
1949delta_str(PyDateTime_Delta *self)
1950{
1951 int days = GET_TD_DAYS(self);
1952 int seconds = GET_TD_SECONDS(self);
1953 int us = GET_TD_MICROSECONDS(self);
1954 int hours;
1955 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001956 char buf[100];
1957 char *pbuf = buf;
1958 size_t buflen = sizeof(buf);
1959 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001960
1961 minutes = divmod(seconds, 60, &seconds);
1962 hours = divmod(minutes, 60, &minutes);
1963
1964 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00001965 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
1966 (days == 1 || days == -1) ? "" : "s");
1967 if (n < 0 || (size_t)n >= buflen)
1968 goto Fail;
1969 pbuf += n;
1970 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001971 }
1972
Tim Petersba873472002-12-18 20:19:21 +00001973 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
1974 hours, minutes, seconds);
1975 if (n < 0 || (size_t)n >= buflen)
1976 goto Fail;
1977 pbuf += n;
1978 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001979
1980 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00001981 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
1982 if (n < 0 || (size_t)n >= buflen)
1983 goto Fail;
1984 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001985 }
1986
Tim Petersba873472002-12-18 20:19:21 +00001987 return PyString_FromStringAndSize(buf, pbuf - buf);
1988
1989 Fail:
1990 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
1991 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001992}
1993
Tim Peters371935f2003-02-01 01:52:50 +00001994/* Pickle support, a simple use of __reduce__. */
1995
Tim Petersb57f8f02003-02-01 02:54:15 +00001996/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00001997static PyObject *
1998delta_getstate(PyDateTime_Delta *self)
1999{
2000 return Py_BuildValue("iii", GET_TD_DAYS(self),
2001 GET_TD_SECONDS(self),
2002 GET_TD_MICROSECONDS(self));
2003}
2004
Tim Peters2a799bf2002-12-16 20:18:38 +00002005static PyObject *
2006delta_reduce(PyDateTime_Delta* self)
2007{
Tim Peters8a60c222003-02-01 01:47:29 +00002008 return Py_BuildValue("ON", self->ob_type, delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002009}
2010
2011#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2012
2013static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002014
Neal Norwitzdfb80862002-12-19 02:30:56 +00002015 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002016 PyDoc_STR("Number of days.")},
2017
Neal Norwitzdfb80862002-12-19 02:30:56 +00002018 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002019 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2020
Neal Norwitzdfb80862002-12-19 02:30:56 +00002021 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002022 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2023 {NULL}
2024};
2025
2026static PyMethodDef delta_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002027 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2028 PyDoc_STR("__reduce__() -> (cls, state)")},
2029
Tim Peters2a799bf2002-12-16 20:18:38 +00002030 {NULL, NULL},
2031};
2032
2033static char delta_doc[] =
2034PyDoc_STR("Difference between two datetime values.");
2035
2036static PyNumberMethods delta_as_number = {
2037 delta_add, /* nb_add */
2038 delta_subtract, /* nb_subtract */
2039 delta_multiply, /* nb_multiply */
2040 delta_divide, /* nb_divide */
2041 0, /* nb_remainder */
2042 0, /* nb_divmod */
2043 0, /* nb_power */
2044 (unaryfunc)delta_negative, /* nb_negative */
2045 (unaryfunc)delta_positive, /* nb_positive */
2046 (unaryfunc)delta_abs, /* nb_absolute */
2047 (inquiry)delta_nonzero, /* nb_nonzero */
2048 0, /*nb_invert*/
2049 0, /*nb_lshift*/
2050 0, /*nb_rshift*/
2051 0, /*nb_and*/
2052 0, /*nb_xor*/
2053 0, /*nb_or*/
2054 0, /*nb_coerce*/
2055 0, /*nb_int*/
2056 0, /*nb_long*/
2057 0, /*nb_float*/
2058 0, /*nb_oct*/
2059 0, /*nb_hex*/
2060 0, /*nb_inplace_add*/
2061 0, /*nb_inplace_subtract*/
2062 0, /*nb_inplace_multiply*/
2063 0, /*nb_inplace_divide*/
2064 0, /*nb_inplace_remainder*/
2065 0, /*nb_inplace_power*/
2066 0, /*nb_inplace_lshift*/
2067 0, /*nb_inplace_rshift*/
2068 0, /*nb_inplace_and*/
2069 0, /*nb_inplace_xor*/
2070 0, /*nb_inplace_or*/
2071 delta_divide, /* nb_floor_divide */
2072 0, /* nb_true_divide */
2073 0, /* nb_inplace_floor_divide */
2074 0, /* nb_inplace_true_divide */
2075};
2076
2077static PyTypeObject PyDateTime_DeltaType = {
2078 PyObject_HEAD_INIT(NULL)
2079 0, /* ob_size */
2080 "datetime.timedelta", /* tp_name */
2081 sizeof(PyDateTime_Delta), /* tp_basicsize */
2082 0, /* tp_itemsize */
2083 0, /* tp_dealloc */
2084 0, /* tp_print */
2085 0, /* tp_getattr */
2086 0, /* tp_setattr */
2087 0, /* tp_compare */
2088 (reprfunc)delta_repr, /* tp_repr */
2089 &delta_as_number, /* tp_as_number */
2090 0, /* tp_as_sequence */
2091 0, /* tp_as_mapping */
2092 (hashfunc)delta_hash, /* tp_hash */
2093 0, /* tp_call */
2094 (reprfunc)delta_str, /* tp_str */
2095 PyObject_GenericGetAttr, /* tp_getattro */
2096 0, /* tp_setattro */
2097 0, /* tp_as_buffer */
2098 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
2099 delta_doc, /* tp_doc */
2100 0, /* tp_traverse */
2101 0, /* tp_clear */
2102 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2103 0, /* tp_weaklistoffset */
2104 0, /* tp_iter */
2105 0, /* tp_iternext */
2106 delta_methods, /* tp_methods */
2107 delta_members, /* tp_members */
2108 0, /* tp_getset */
2109 0, /* tp_base */
2110 0, /* tp_dict */
2111 0, /* tp_descr_get */
2112 0, /* tp_descr_set */
2113 0, /* tp_dictoffset */
2114 0, /* tp_init */
2115 0, /* tp_alloc */
2116 delta_new, /* tp_new */
2117 _PyObject_Del, /* tp_free */
2118};
2119
2120/*
2121 * PyDateTime_Date implementation.
2122 */
2123
2124/* Accessor properties. */
2125
2126static PyObject *
2127date_year(PyDateTime_Date *self, void *unused)
2128{
2129 return PyInt_FromLong(GET_YEAR(self));
2130}
2131
2132static PyObject *
2133date_month(PyDateTime_Date *self, void *unused)
2134{
2135 return PyInt_FromLong(GET_MONTH(self));
2136}
2137
2138static PyObject *
2139date_day(PyDateTime_Date *self, void *unused)
2140{
2141 return PyInt_FromLong(GET_DAY(self));
2142}
2143
2144static PyGetSetDef date_getset[] = {
2145 {"year", (getter)date_year},
2146 {"month", (getter)date_month},
2147 {"day", (getter)date_day},
2148 {NULL}
2149};
2150
2151/* Constructors. */
2152
Tim Peters12bf3392002-12-24 05:41:27 +00002153static char *date_kws[] = {"year", "month", "day", NULL};
2154
Tim Peters2a799bf2002-12-16 20:18:38 +00002155static PyObject *
2156date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2157{
2158 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002159 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002160 int year;
2161 int month;
2162 int day;
2163
Guido van Rossum177e41a2003-01-30 22:06:23 +00002164 /* Check for invocation from pickle with __getstate__ state */
2165 if (PyTuple_GET_SIZE(args) == 1 &&
Tim Peters70533e22003-02-01 04:40:04 +00002166 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2167 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00002168 {
Tim Peters70533e22003-02-01 04:40:04 +00002169 PyDateTime_Date *me;
2170
2171 me = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
2172 if (me != NULL) {
2173 char *pdata = PyString_AS_STRING(state);
2174 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2175 me->hashcode = -1;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002176 }
Tim Peters70533e22003-02-01 04:40:04 +00002177 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002178 }
2179
Tim Peters12bf3392002-12-24 05:41:27 +00002180 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002181 &year, &month, &day)) {
2182 if (check_date_args(year, month, day) < 0)
2183 return NULL;
2184 self = new_date(year, month, day);
2185 }
2186 return self;
2187}
2188
2189/* Return new date from localtime(t). */
2190static PyObject *
2191date_local_from_time_t(PyObject *cls, time_t t)
2192{
2193 struct tm *tm;
2194 PyObject *result = NULL;
2195
2196 tm = localtime(&t);
2197 if (tm)
2198 result = PyObject_CallFunction(cls, "iii",
2199 tm->tm_year + 1900,
2200 tm->tm_mon + 1,
2201 tm->tm_mday);
2202 else
2203 PyErr_SetString(PyExc_ValueError,
2204 "timestamp out of range for "
2205 "platform localtime() function");
2206 return result;
2207}
2208
2209/* Return new date from current time.
2210 * We say this is equivalent to fromtimestamp(time.time()), and the
2211 * only way to be sure of that is to *call* time.time(). That's not
2212 * generally the same as calling C's time.
2213 */
2214static PyObject *
2215date_today(PyObject *cls, PyObject *dummy)
2216{
2217 PyObject *time;
2218 PyObject *result;
2219
2220 time = time_time();
2221 if (time == NULL)
2222 return NULL;
2223
2224 /* Note well: today() is a class method, so this may not call
2225 * date.fromtimestamp. For example, it may call
2226 * datetime.fromtimestamp. That's why we need all the accuracy
2227 * time.time() delivers; if someone were gonzo about optimization,
2228 * date.today() could get away with plain C time().
2229 */
2230 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2231 Py_DECREF(time);
2232 return result;
2233}
2234
2235/* Return new date from given timestamp (Python timestamp -- a double). */
2236static PyObject *
2237date_fromtimestamp(PyObject *cls, PyObject *args)
2238{
2239 double timestamp;
2240 PyObject *result = NULL;
2241
2242 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2243 result = date_local_from_time_t(cls, (time_t)timestamp);
2244 return result;
2245}
2246
2247/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2248 * the ordinal is out of range.
2249 */
2250static PyObject *
2251date_fromordinal(PyObject *cls, PyObject *args)
2252{
2253 PyObject *result = NULL;
2254 int ordinal;
2255
2256 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2257 int year;
2258 int month;
2259 int day;
2260
2261 if (ordinal < 1)
2262 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2263 ">= 1");
2264 else {
2265 ord_to_ymd(ordinal, &year, &month, &day);
2266 result = PyObject_CallFunction(cls, "iii",
2267 year, month, day);
2268 }
2269 }
2270 return result;
2271}
2272
2273/*
2274 * Date arithmetic.
2275 */
2276
2277/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2278 * instead.
2279 */
2280static PyObject *
2281add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2282{
2283 PyObject *result = NULL;
2284 int year = GET_YEAR(date);
2285 int month = GET_MONTH(date);
2286 int deltadays = GET_TD_DAYS(delta);
2287 /* C-level overflow is impossible because |deltadays| < 1e9. */
2288 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2289
2290 if (normalize_date(&year, &month, &day) >= 0)
2291 result = new_date(year, month, day);
2292 return result;
2293}
2294
2295static PyObject *
2296date_add(PyObject *left, PyObject *right)
2297{
2298 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2299 Py_INCREF(Py_NotImplemented);
2300 return Py_NotImplemented;
2301 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002302 if (PyDate_Check(left)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002303 /* date + ??? */
2304 if (PyDelta_Check(right))
2305 /* date + delta */
2306 return add_date_timedelta((PyDateTime_Date *) left,
2307 (PyDateTime_Delta *) right,
2308 0);
2309 }
2310 else {
2311 /* ??? + date
2312 * 'right' must be one of us, or we wouldn't have been called
2313 */
2314 if (PyDelta_Check(left))
2315 /* delta + date */
2316 return add_date_timedelta((PyDateTime_Date *) right,
2317 (PyDateTime_Delta *) left,
2318 0);
2319 }
2320 Py_INCREF(Py_NotImplemented);
2321 return Py_NotImplemented;
2322}
2323
2324static PyObject *
2325date_subtract(PyObject *left, PyObject *right)
2326{
2327 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2328 Py_INCREF(Py_NotImplemented);
2329 return Py_NotImplemented;
2330 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002331 if (PyDate_Check(left)) {
2332 if (PyDate_Check(right)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002333 /* date - date */
2334 int left_ord = ymd_to_ord(GET_YEAR(left),
2335 GET_MONTH(left),
2336 GET_DAY(left));
2337 int right_ord = ymd_to_ord(GET_YEAR(right),
2338 GET_MONTH(right),
2339 GET_DAY(right));
2340 return new_delta(left_ord - right_ord, 0, 0, 0);
2341 }
2342 if (PyDelta_Check(right)) {
2343 /* date - delta */
2344 return add_date_timedelta((PyDateTime_Date *) left,
2345 (PyDateTime_Delta *) right,
2346 1);
2347 }
2348 }
2349 Py_INCREF(Py_NotImplemented);
2350 return Py_NotImplemented;
2351}
2352
2353
2354/* Various ways to turn a date into a string. */
2355
2356static PyObject *
2357date_repr(PyDateTime_Date *self)
2358{
2359 char buffer[1028];
2360 char *typename;
2361
2362 typename = self->ob_type->tp_name;
2363 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2364 typename,
2365 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2366
2367 return PyString_FromString(buffer);
2368}
2369
2370static PyObject *
2371date_isoformat(PyDateTime_Date *self)
2372{
2373 char buffer[128];
2374
2375 isoformat_date(self, buffer, sizeof(buffer));
2376 return PyString_FromString(buffer);
2377}
2378
2379/* str() calls the appropriate isofomat() method. */
2380static PyObject *
2381date_str(PyDateTime_Date *self)
2382{
2383 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2384}
2385
2386
2387static PyObject *
2388date_ctime(PyDateTime_Date *self)
2389{
2390 return format_ctime(self, 0, 0, 0);
2391}
2392
2393static PyObject *
2394date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2395{
2396 /* This method can be inherited, and needs to call the
2397 * timetuple() method appropriate to self's class.
2398 */
2399 PyObject *result;
2400 PyObject *format;
2401 PyObject *tuple;
2402 static char *keywords[] = {"format", NULL};
2403
2404 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2405 &PyString_Type, &format))
2406 return NULL;
2407
2408 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2409 if (tuple == NULL)
2410 return NULL;
Tim Petersbad8ff02002-12-30 20:52:32 +00002411 result = wrap_strftime((PyObject *)self, format, tuple,
2412 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002413 Py_DECREF(tuple);
2414 return result;
2415}
2416
2417/* ISO methods. */
2418
2419static PyObject *
2420date_isoweekday(PyDateTime_Date *self)
2421{
2422 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2423
2424 return PyInt_FromLong(dow + 1);
2425}
2426
2427static PyObject *
2428date_isocalendar(PyDateTime_Date *self)
2429{
2430 int year = GET_YEAR(self);
2431 int week1_monday = iso_week1_monday(year);
2432 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2433 int week;
2434 int day;
2435
2436 week = divmod(today - week1_monday, 7, &day);
2437 if (week < 0) {
2438 --year;
2439 week1_monday = iso_week1_monday(year);
2440 week = divmod(today - week1_monday, 7, &day);
2441 }
2442 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2443 ++year;
2444 week = 0;
2445 }
2446 return Py_BuildValue("iii", year, week + 1, day + 1);
2447}
2448
2449/* Miscellaneous methods. */
2450
2451/* This is more natural as a tp_compare, but doesn't work then: for whatever
2452 * reason, Python's try_3way_compare ignores tp_compare unless
2453 * PyInstance_Check returns true, but these aren't old-style classes.
2454 */
2455static PyObject *
2456date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2457{
Tim Peters07534a62003-02-07 22:50:28 +00002458 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002459
Tim Peters07534a62003-02-07 22:50:28 +00002460 if (PyDate_Check(other))
2461 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2462 _PyDateTime_DATE_DATASIZE);
2463
2464 else if (PyObject_HasAttrString(other, "timetuple")) {
2465 /* A hook for other kinds of date objects. */
2466 Py_INCREF(Py_NotImplemented);
2467 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002468 }
Tim Peters07534a62003-02-07 22:50:28 +00002469 else if (op == Py_EQ || op == Py_NE)
2470 diff = 1; /* any non-zero value will do */
2471
2472 else /* stop this from falling back to address comparison */
2473 return cmperror((PyObject *)self, other);
2474
Tim Peters2a799bf2002-12-16 20:18:38 +00002475 return diff_to_bool(diff, op);
2476}
2477
2478static PyObject *
2479date_timetuple(PyDateTime_Date *self)
2480{
2481 return build_struct_time(GET_YEAR(self),
2482 GET_MONTH(self),
2483 GET_DAY(self),
2484 0, 0, 0, -1);
2485}
2486
Tim Peters12bf3392002-12-24 05:41:27 +00002487static PyObject *
2488date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2489{
2490 PyObject *clone;
2491 PyObject *tuple;
2492 int year = GET_YEAR(self);
2493 int month = GET_MONTH(self);
2494 int day = GET_DAY(self);
2495
2496 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2497 &year, &month, &day))
2498 return NULL;
2499 tuple = Py_BuildValue("iii", year, month, day);
2500 if (tuple == NULL)
2501 return NULL;
2502 clone = date_new(self->ob_type, tuple, NULL);
2503 Py_DECREF(tuple);
2504 return clone;
2505}
2506
Tim Peters2a799bf2002-12-16 20:18:38 +00002507static PyObject *date_getstate(PyDateTime_Date *self);
2508
2509static long
2510date_hash(PyDateTime_Date *self)
2511{
2512 if (self->hashcode == -1) {
2513 PyObject *temp = date_getstate(self);
2514 if (temp != NULL) {
2515 self->hashcode = PyObject_Hash(temp);
2516 Py_DECREF(temp);
2517 }
2518 }
2519 return self->hashcode;
2520}
2521
2522static PyObject *
2523date_toordinal(PyDateTime_Date *self)
2524{
2525 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2526 GET_DAY(self)));
2527}
2528
2529static PyObject *
2530date_weekday(PyDateTime_Date *self)
2531{
2532 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2533
2534 return PyInt_FromLong(dow);
2535}
2536
Tim Peters371935f2003-02-01 01:52:50 +00002537/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002538
Tim Petersb57f8f02003-02-01 02:54:15 +00002539/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002540static PyObject *
2541date_getstate(PyDateTime_Date *self)
2542{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002543 return Py_BuildValue(
2544 "(N)",
2545 PyString_FromStringAndSize((char *)self->data,
2546 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002547}
2548
2549static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002550date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002551{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002552 return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002553}
2554
2555static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002556
Tim Peters2a799bf2002-12-16 20:18:38 +00002557 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002558
Tim Peters2a799bf2002-12-16 20:18:38 +00002559 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2560 METH_CLASS,
2561 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2562 "time.time()).")},
2563
2564 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2565 METH_CLASS,
2566 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2567 "ordinal.")},
2568
2569 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2570 PyDoc_STR("Current date or datetime: same as "
2571 "self.__class__.fromtimestamp(time.time()).")},
2572
2573 /* Instance methods: */
2574
2575 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2576 PyDoc_STR("Return ctime() style string.")},
2577
2578 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2579 PyDoc_STR("format -> strftime() style string.")},
2580
2581 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2582 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2583
2584 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2585 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2586 "weekday.")},
2587
2588 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2589 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2590
2591 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2592 PyDoc_STR("Return the day of the week represented by the date.\n"
2593 "Monday == 1 ... Sunday == 7")},
2594
2595 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2596 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2597 "1 is day 1.")},
2598
2599 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2600 PyDoc_STR("Return the day of the week represented by the date.\n"
2601 "Monday == 0 ... Sunday == 6")},
2602
Tim Peters12bf3392002-12-24 05:41:27 +00002603 {"replace", (PyCFunction)date_replace, METH_KEYWORDS,
2604 PyDoc_STR("Return date with new specified fields.")},
2605
Guido van Rossum177e41a2003-01-30 22:06:23 +00002606 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2607 PyDoc_STR("__reduce__() -> (cls, state)")},
2608
Tim Peters2a799bf2002-12-16 20:18:38 +00002609 {NULL, NULL}
2610};
2611
2612static char date_doc[] =
2613PyDoc_STR("Basic date type.");
2614
2615static PyNumberMethods date_as_number = {
2616 date_add, /* nb_add */
2617 date_subtract, /* nb_subtract */
2618 0, /* nb_multiply */
2619 0, /* nb_divide */
2620 0, /* nb_remainder */
2621 0, /* nb_divmod */
2622 0, /* nb_power */
2623 0, /* nb_negative */
2624 0, /* nb_positive */
2625 0, /* nb_absolute */
2626 0, /* nb_nonzero */
2627};
2628
2629static PyTypeObject PyDateTime_DateType = {
2630 PyObject_HEAD_INIT(NULL)
2631 0, /* ob_size */
2632 "datetime.date", /* tp_name */
2633 sizeof(PyDateTime_Date), /* tp_basicsize */
2634 0, /* tp_itemsize */
2635 (destructor)PyObject_Del, /* tp_dealloc */
2636 0, /* tp_print */
2637 0, /* tp_getattr */
2638 0, /* tp_setattr */
2639 0, /* tp_compare */
2640 (reprfunc)date_repr, /* tp_repr */
2641 &date_as_number, /* tp_as_number */
2642 0, /* tp_as_sequence */
2643 0, /* tp_as_mapping */
2644 (hashfunc)date_hash, /* tp_hash */
2645 0, /* tp_call */
2646 (reprfunc)date_str, /* tp_str */
2647 PyObject_GenericGetAttr, /* tp_getattro */
2648 0, /* tp_setattro */
2649 0, /* tp_as_buffer */
2650 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2651 Py_TPFLAGS_BASETYPE, /* tp_flags */
2652 date_doc, /* tp_doc */
2653 0, /* tp_traverse */
2654 0, /* tp_clear */
2655 (richcmpfunc)date_richcompare, /* tp_richcompare */
2656 0, /* tp_weaklistoffset */
2657 0, /* tp_iter */
2658 0, /* tp_iternext */
2659 date_methods, /* tp_methods */
2660 0, /* tp_members */
2661 date_getset, /* tp_getset */
2662 0, /* tp_base */
2663 0, /* tp_dict */
2664 0, /* tp_descr_get */
2665 0, /* tp_descr_set */
2666 0, /* tp_dictoffset */
2667 0, /* tp_init */
2668 0, /* tp_alloc */
2669 date_new, /* tp_new */
2670 _PyObject_Del, /* tp_free */
2671};
2672
2673/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002674 * PyDateTime_TZInfo implementation.
2675 */
2676
2677/* This is a pure abstract base class, so doesn't do anything beyond
2678 * raising NotImplemented exceptions. Real tzinfo classes need
2679 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002680 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002681 * be subclasses of this tzinfo class, which is easy and quick to check).
2682 *
2683 * Note: For reasons having to do with pickling of subclasses, we have
2684 * to allow tzinfo objects to be instantiated. This wasn't an issue
2685 * in the Python implementation (__init__() could raise NotImplementedError
2686 * there without ill effect), but doing so in the C implementation hit a
2687 * brick wall.
2688 */
2689
2690static PyObject *
2691tzinfo_nogo(const char* methodname)
2692{
2693 PyErr_Format(PyExc_NotImplementedError,
2694 "a tzinfo subclass must implement %s()",
2695 methodname);
2696 return NULL;
2697}
2698
2699/* Methods. A subclass must implement these. */
2700
Tim Peters52dcce22003-01-23 16:36:11 +00002701static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002702tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2703{
2704 return tzinfo_nogo("tzname");
2705}
2706
Tim Peters52dcce22003-01-23 16:36:11 +00002707static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002708tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2709{
2710 return tzinfo_nogo("utcoffset");
2711}
2712
Tim Peters52dcce22003-01-23 16:36:11 +00002713static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002714tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2715{
2716 return tzinfo_nogo("dst");
2717}
2718
Tim Peters52dcce22003-01-23 16:36:11 +00002719static PyObject *
2720tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2721{
2722 int y, m, d, hh, mm, ss, us;
2723
2724 PyObject *result;
2725 int off, dst;
2726 int none;
2727 int delta;
2728
2729 if (! PyDateTime_Check(dt)) {
2730 PyErr_SetString(PyExc_TypeError,
2731 "fromutc: argument must be a datetime");
2732 return NULL;
2733 }
2734 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2735 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2736 "is not self");
2737 return NULL;
2738 }
2739
2740 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2741 if (off == -1 && PyErr_Occurred())
2742 return NULL;
2743 if (none) {
2744 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2745 "utcoffset() result required");
2746 return NULL;
2747 }
2748
2749 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2750 if (dst == -1 && PyErr_Occurred())
2751 return NULL;
2752 if (none) {
2753 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2754 "dst() result required");
2755 return NULL;
2756 }
2757
2758 y = GET_YEAR(dt);
2759 m = GET_MONTH(dt);
2760 d = GET_DAY(dt);
2761 hh = DATE_GET_HOUR(dt);
2762 mm = DATE_GET_MINUTE(dt);
2763 ss = DATE_GET_SECOND(dt);
2764 us = DATE_GET_MICROSECOND(dt);
2765
2766 delta = off - dst;
2767 mm += delta;
2768 if ((mm < 0 || mm >= 60) &&
2769 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002770 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002771 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2772 if (result == NULL)
2773 return result;
2774
2775 dst = call_dst(dt->tzinfo, result, &none);
2776 if (dst == -1 && PyErr_Occurred())
2777 goto Fail;
2778 if (none)
2779 goto Inconsistent;
2780 if (dst == 0)
2781 return result;
2782
2783 mm += dst;
2784 if ((mm < 0 || mm >= 60) &&
2785 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2786 goto Fail;
2787 Py_DECREF(result);
2788 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2789 return result;
2790
2791Inconsistent:
2792 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2793 "inconsistent results; cannot convert");
2794
2795 /* fall thru to failure */
2796Fail:
2797 Py_DECREF(result);
2798 return NULL;
2799}
2800
Tim Peters2a799bf2002-12-16 20:18:38 +00002801/*
2802 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002803 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002804 */
2805
Guido van Rossum177e41a2003-01-30 22:06:23 +00002806static PyObject *
2807tzinfo_reduce(PyObject *self)
2808{
2809 PyObject *args, *state, *tmp;
2810 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002811
Guido van Rossum177e41a2003-01-30 22:06:23 +00002812 tmp = PyTuple_New(0);
2813 if (tmp == NULL)
2814 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002815
Guido van Rossum177e41a2003-01-30 22:06:23 +00002816 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2817 if (getinitargs != NULL) {
2818 args = PyObject_CallObject(getinitargs, tmp);
2819 Py_DECREF(getinitargs);
2820 if (args == NULL) {
2821 Py_DECREF(tmp);
2822 return NULL;
2823 }
2824 }
2825 else {
2826 PyErr_Clear();
2827 args = tmp;
2828 Py_INCREF(args);
2829 }
2830
2831 getstate = PyObject_GetAttrString(self, "__getstate__");
2832 if (getstate != NULL) {
2833 state = PyObject_CallObject(getstate, tmp);
2834 Py_DECREF(getstate);
2835 if (state == NULL) {
2836 Py_DECREF(args);
2837 Py_DECREF(tmp);
2838 return NULL;
2839 }
2840 }
2841 else {
2842 PyObject **dictptr;
2843 PyErr_Clear();
2844 state = Py_None;
2845 dictptr = _PyObject_GetDictPtr(self);
2846 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2847 state = *dictptr;
2848 Py_INCREF(state);
2849 }
2850
2851 Py_DECREF(tmp);
2852
2853 if (state == Py_None) {
2854 Py_DECREF(state);
2855 return Py_BuildValue("(ON)", self->ob_type, args);
2856 }
2857 else
2858 return Py_BuildValue("(ONN)", self->ob_type, args, state);
2859}
Tim Peters2a799bf2002-12-16 20:18:38 +00002860
2861static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002862
Tim Peters2a799bf2002-12-16 20:18:38 +00002863 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2864 PyDoc_STR("datetime -> string name of time zone.")},
2865
2866 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2867 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2868 "west of UTC).")},
2869
2870 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2871 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2872
Tim Peters52dcce22003-01-23 16:36:11 +00002873 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2874 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2875
Guido van Rossum177e41a2003-01-30 22:06:23 +00002876 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2877 PyDoc_STR("-> (cls, state)")},
2878
Tim Peters2a799bf2002-12-16 20:18:38 +00002879 {NULL, NULL}
2880};
2881
2882static char tzinfo_doc[] =
2883PyDoc_STR("Abstract base class for time zone info objects.");
2884
Neal Norwitzce3d34d2003-02-04 20:45:17 +00002885statichere PyTypeObject PyDateTime_TZInfoType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00002886 PyObject_HEAD_INIT(NULL)
2887 0, /* ob_size */
2888 "datetime.tzinfo", /* tp_name */
2889 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2890 0, /* tp_itemsize */
2891 0, /* tp_dealloc */
2892 0, /* tp_print */
2893 0, /* tp_getattr */
2894 0, /* tp_setattr */
2895 0, /* tp_compare */
2896 0, /* tp_repr */
2897 0, /* tp_as_number */
2898 0, /* tp_as_sequence */
2899 0, /* tp_as_mapping */
2900 0, /* tp_hash */
2901 0, /* tp_call */
2902 0, /* tp_str */
2903 PyObject_GenericGetAttr, /* tp_getattro */
2904 0, /* tp_setattro */
2905 0, /* tp_as_buffer */
2906 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2907 Py_TPFLAGS_BASETYPE, /* tp_flags */
2908 tzinfo_doc, /* tp_doc */
2909 0, /* tp_traverse */
2910 0, /* tp_clear */
2911 0, /* tp_richcompare */
2912 0, /* tp_weaklistoffset */
2913 0, /* tp_iter */
2914 0, /* tp_iternext */
2915 tzinfo_methods, /* tp_methods */
2916 0, /* tp_members */
2917 0, /* tp_getset */
2918 0, /* tp_base */
2919 0, /* tp_dict */
2920 0, /* tp_descr_get */
2921 0, /* tp_descr_set */
2922 0, /* tp_dictoffset */
2923 0, /* tp_init */
2924 0, /* tp_alloc */
2925 PyType_GenericNew, /* tp_new */
2926 0, /* tp_free */
2927};
2928
2929/*
Tim Peters37f39822003-01-10 03:49:02 +00002930 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00002931 */
2932
Tim Peters37f39822003-01-10 03:49:02 +00002933/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00002934 */
2935
2936static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002937time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00002938{
Tim Peters37f39822003-01-10 03:49:02 +00002939 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002940}
2941
Tim Peters37f39822003-01-10 03:49:02 +00002942static PyObject *
2943time_minute(PyDateTime_Time *self, void *unused)
2944{
2945 return PyInt_FromLong(TIME_GET_MINUTE(self));
2946}
2947
2948/* The name time_second conflicted with some platform header file. */
2949static PyObject *
2950py_time_second(PyDateTime_Time *self, void *unused)
2951{
2952 return PyInt_FromLong(TIME_GET_SECOND(self));
2953}
2954
2955static PyObject *
2956time_microsecond(PyDateTime_Time *self, void *unused)
2957{
2958 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
2959}
2960
2961static PyObject *
2962time_tzinfo(PyDateTime_Time *self, void *unused)
2963{
Tim Petersa032d2e2003-01-11 00:15:54 +00002964 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00002965 Py_INCREF(result);
2966 return result;
2967}
2968
2969static PyGetSetDef time_getset[] = {
2970 {"hour", (getter)time_hour},
2971 {"minute", (getter)time_minute},
2972 {"second", (getter)py_time_second},
2973 {"microsecond", (getter)time_microsecond},
2974 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00002975 {NULL}
2976};
2977
2978/*
2979 * Constructors.
2980 */
2981
Tim Peters37f39822003-01-10 03:49:02 +00002982static char *time_kws[] = {"hour", "minute", "second", "microsecond",
2983 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002984
Tim Peters2a799bf2002-12-16 20:18:38 +00002985static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002986time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00002987{
2988 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002989 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002990 int hour = 0;
2991 int minute = 0;
2992 int second = 0;
2993 int usecond = 0;
2994 PyObject *tzinfo = Py_None;
2995
Guido van Rossum177e41a2003-01-30 22:06:23 +00002996 /* Check for invocation from pickle with __getstate__ state */
2997 if (PyTuple_GET_SIZE(args) >= 1 &&
2998 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00002999 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3000 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003001 {
Tim Peters70533e22003-02-01 04:40:04 +00003002 PyDateTime_Time *me;
3003 char aware;
3004
3005 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003006 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003007 if (check_tzinfo_subclass(tzinfo) < 0) {
3008 PyErr_SetString(PyExc_TypeError, "bad "
3009 "tzinfo state arg");
3010 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003011 }
3012 }
Tim Peters70533e22003-02-01 04:40:04 +00003013 aware = (char)(tzinfo != Py_None);
3014 me = alloc_time(aware);
3015 if (me != NULL) {
3016 char *pdata = PyString_AS_STRING(state);
3017
3018 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3019 me->hashcode = -1;
3020 me->hastzinfo = aware;
3021 if (aware) {
3022 Py_INCREF(tzinfo);
3023 me->tzinfo = tzinfo;
3024 }
3025 }
3026 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003027 }
3028
Tim Peters37f39822003-01-10 03:49:02 +00003029 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003030 &hour, &minute, &second, &usecond,
3031 &tzinfo)) {
3032 if (check_time_args(hour, minute, second, usecond) < 0)
3033 return NULL;
3034 if (check_tzinfo_subclass(tzinfo) < 0)
3035 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003036 self = new_time(hour, minute, second, usecond, tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003037 }
3038 return self;
3039}
3040
3041/*
3042 * Destructor.
3043 */
3044
3045static void
Tim Peters37f39822003-01-10 03:49:02 +00003046time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003047{
Tim Petersa032d2e2003-01-11 00:15:54 +00003048 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003049 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003050 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003051 self->ob_type->tp_free((PyObject *)self);
3052}
3053
3054/*
Tim Peters855fe882002-12-22 03:43:39 +00003055 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003056 */
3057
Tim Peters2a799bf2002-12-16 20:18:38 +00003058/* These are all METH_NOARGS, so don't need to check the arglist. */
3059static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003060time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003061 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003062 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003063}
3064
3065static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003066time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003067 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003068 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003069}
3070
3071static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003072time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003073 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003074 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003075}
3076
3077/*
Tim Peters37f39822003-01-10 03:49:02 +00003078 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003079 */
3080
3081static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003082time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003083{
Tim Peters37f39822003-01-10 03:49:02 +00003084 char buffer[100];
3085 char *typename = self->ob_type->tp_name;
3086 int h = TIME_GET_HOUR(self);
3087 int m = TIME_GET_MINUTE(self);
3088 int s = TIME_GET_SECOND(self);
3089 int us = TIME_GET_MICROSECOND(self);
3090 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003091
Tim Peters37f39822003-01-10 03:49:02 +00003092 if (us)
3093 PyOS_snprintf(buffer, sizeof(buffer),
3094 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3095 else if (s)
3096 PyOS_snprintf(buffer, sizeof(buffer),
3097 "%s(%d, %d, %d)", typename, h, m, s);
3098 else
3099 PyOS_snprintf(buffer, sizeof(buffer),
3100 "%s(%d, %d)", typename, h, m);
3101 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003102 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003103 result = append_keyword_tzinfo(result, self->tzinfo);
3104 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003105}
3106
Tim Peters37f39822003-01-10 03:49:02 +00003107static PyObject *
3108time_str(PyDateTime_Time *self)
3109{
3110 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3111}
Tim Peters2a799bf2002-12-16 20:18:38 +00003112
3113static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003114time_isoformat(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003115{
3116 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003117 PyObject *result;
3118 /* Reuse the time format code from the datetime type. */
3119 PyDateTime_DateTime datetime;
3120 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003121
Tim Peters37f39822003-01-10 03:49:02 +00003122 /* Copy over just the time bytes. */
3123 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3124 self->data,
3125 _PyDateTime_TIME_DATASIZE);
3126
3127 isoformat_time(pdatetime, buf, sizeof(buf));
3128 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003129 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003130 return result;
3131
3132 /* We need to append the UTC offset. */
3133 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003134 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003135 Py_DECREF(result);
3136 return NULL;
3137 }
3138 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3139 return result;
3140}
3141
Tim Peters37f39822003-01-10 03:49:02 +00003142static PyObject *
3143time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3144{
3145 PyObject *result;
3146 PyObject *format;
3147 PyObject *tuple;
3148 static char *keywords[] = {"format", NULL};
3149
3150 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3151 &PyString_Type, &format))
3152 return NULL;
3153
3154 /* Python's strftime does insane things with the year part of the
3155 * timetuple. The year is forced to (the otherwise nonsensical)
3156 * 1900 to worm around that.
3157 */
3158 tuple = Py_BuildValue("iiiiiiiii",
3159 1900, 0, 0, /* year, month, day */
3160 TIME_GET_HOUR(self),
3161 TIME_GET_MINUTE(self),
3162 TIME_GET_SECOND(self),
3163 0, 0, -1); /* weekday, daynum, dst */
3164 if (tuple == NULL)
3165 return NULL;
3166 assert(PyTuple_Size(tuple) == 9);
3167 result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
3168 Py_DECREF(tuple);
3169 return result;
3170}
Tim Peters2a799bf2002-12-16 20:18:38 +00003171
3172/*
3173 * Miscellaneous methods.
3174 */
3175
Tim Peters37f39822003-01-10 03:49:02 +00003176/* This is more natural as a tp_compare, but doesn't work then: for whatever
3177 * reason, Python's try_3way_compare ignores tp_compare unless
3178 * PyInstance_Check returns true, but these aren't old-style classes.
3179 */
3180static PyObject *
3181time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3182{
3183 int diff;
3184 naivety n1, n2;
3185 int offset1, offset2;
3186
3187 if (! PyTime_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00003188 if (op == Py_EQ || op == Py_NE) {
3189 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3190 Py_INCREF(result);
3191 return result;
3192 }
Tim Peters37f39822003-01-10 03:49:02 +00003193 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00003194 return cmperror((PyObject *)self, other);
Tim Peters37f39822003-01-10 03:49:02 +00003195 }
3196 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3197 other, &offset2, &n2, Py_None) < 0)
3198 return NULL;
3199 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3200 /* If they're both naive, or both aware and have the same offsets,
3201 * we get off cheap. Note that if they're both naive, offset1 ==
3202 * offset2 == 0 at this point.
3203 */
3204 if (n1 == n2 && offset1 == offset2) {
3205 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3206 _PyDateTime_TIME_DATASIZE);
3207 return diff_to_bool(diff, op);
3208 }
3209
3210 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3211 assert(offset1 != offset2); /* else last "if" handled it */
3212 /* Convert everything except microseconds to seconds. These
3213 * can't overflow (no more than the # of seconds in 2 days).
3214 */
3215 offset1 = TIME_GET_HOUR(self) * 3600 +
3216 (TIME_GET_MINUTE(self) - offset1) * 60 +
3217 TIME_GET_SECOND(self);
3218 offset2 = TIME_GET_HOUR(other) * 3600 +
3219 (TIME_GET_MINUTE(other) - offset2) * 60 +
3220 TIME_GET_SECOND(other);
3221 diff = offset1 - offset2;
3222 if (diff == 0)
3223 diff = TIME_GET_MICROSECOND(self) -
3224 TIME_GET_MICROSECOND(other);
3225 return diff_to_bool(diff, op);
3226 }
3227
3228 assert(n1 != n2);
3229 PyErr_SetString(PyExc_TypeError,
3230 "can't compare offset-naive and "
3231 "offset-aware times");
3232 return NULL;
3233}
3234
3235static long
3236time_hash(PyDateTime_Time *self)
3237{
3238 if (self->hashcode == -1) {
3239 naivety n;
3240 int offset;
3241 PyObject *temp;
3242
3243 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3244 assert(n != OFFSET_UNKNOWN);
3245 if (n == OFFSET_ERROR)
3246 return -1;
3247
3248 /* Reduce this to a hash of another object. */
3249 if (offset == 0)
3250 temp = PyString_FromStringAndSize((char *)self->data,
3251 _PyDateTime_TIME_DATASIZE);
3252 else {
3253 int hour;
3254 int minute;
3255
3256 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003257 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003258 hour = divmod(TIME_GET_HOUR(self) * 60 +
3259 TIME_GET_MINUTE(self) - offset,
3260 60,
3261 &minute);
3262 if (0 <= hour && hour < 24)
3263 temp = new_time(hour, minute,
3264 TIME_GET_SECOND(self),
3265 TIME_GET_MICROSECOND(self),
3266 Py_None);
3267 else
3268 temp = Py_BuildValue("iiii",
3269 hour, minute,
3270 TIME_GET_SECOND(self),
3271 TIME_GET_MICROSECOND(self));
3272 }
3273 if (temp != NULL) {
3274 self->hashcode = PyObject_Hash(temp);
3275 Py_DECREF(temp);
3276 }
3277 }
3278 return self->hashcode;
3279}
Tim Peters2a799bf2002-12-16 20:18:38 +00003280
Tim Peters12bf3392002-12-24 05:41:27 +00003281static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003282time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003283{
3284 PyObject *clone;
3285 PyObject *tuple;
3286 int hh = TIME_GET_HOUR(self);
3287 int mm = TIME_GET_MINUTE(self);
3288 int ss = TIME_GET_SECOND(self);
3289 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003290 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003291
3292 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003293 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003294 &hh, &mm, &ss, &us, &tzinfo))
3295 return NULL;
3296 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3297 if (tuple == NULL)
3298 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003299 clone = time_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003300 Py_DECREF(tuple);
3301 return clone;
3302}
3303
Tim Peters2a799bf2002-12-16 20:18:38 +00003304static int
Tim Peters37f39822003-01-10 03:49:02 +00003305time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003306{
3307 int offset;
3308 int none;
3309
3310 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3311 /* Since utcoffset is in whole minutes, nothing can
3312 * alter the conclusion that this is nonzero.
3313 */
3314 return 1;
3315 }
3316 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003317 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003318 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003319 if (offset == -1 && PyErr_Occurred())
3320 return -1;
3321 }
3322 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3323}
3324
Tim Peters371935f2003-02-01 01:52:50 +00003325/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003326
Tim Peters33e0f382003-01-10 02:05:14 +00003327/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003328 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3329 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003330 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003331 */
3332static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003333time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003334{
3335 PyObject *basestate;
3336 PyObject *result = NULL;
3337
Tim Peters33e0f382003-01-10 02:05:14 +00003338 basestate = PyString_FromStringAndSize((char *)self->data,
3339 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003340 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003341 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003342 result = Py_BuildValue("(O)", basestate);
3343 else
3344 result = Py_BuildValue("OO", basestate, self->tzinfo);
3345 Py_DECREF(basestate);
3346 }
3347 return result;
3348}
3349
3350static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003351time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003352{
Guido van Rossum177e41a2003-01-30 22:06:23 +00003353 return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003354}
3355
Tim Peters37f39822003-01-10 03:49:02 +00003356static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003357
Tim Peters37f39822003-01-10 03:49:02 +00003358 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003359 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3360 "[+HH:MM].")},
3361
Tim Peters37f39822003-01-10 03:49:02 +00003362 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3363 PyDoc_STR("format -> strftime() style string.")},
3364
3365 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003366 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3367
Tim Peters37f39822003-01-10 03:49:02 +00003368 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003369 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3370
Tim Peters37f39822003-01-10 03:49:02 +00003371 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003372 PyDoc_STR("Return self.tzinfo.dst(self).")},
3373
Tim Peters37f39822003-01-10 03:49:02 +00003374 {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
3375 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003376
Guido van Rossum177e41a2003-01-30 22:06:23 +00003377 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3378 PyDoc_STR("__reduce__() -> (cls, state)")},
3379
Tim Peters2a799bf2002-12-16 20:18:38 +00003380 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003381};
3382
Tim Peters37f39822003-01-10 03:49:02 +00003383static char time_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003384PyDoc_STR("Time type.");
3385
Tim Peters37f39822003-01-10 03:49:02 +00003386static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003387 0, /* nb_add */
3388 0, /* nb_subtract */
3389 0, /* nb_multiply */
3390 0, /* nb_divide */
3391 0, /* nb_remainder */
3392 0, /* nb_divmod */
3393 0, /* nb_power */
3394 0, /* nb_negative */
3395 0, /* nb_positive */
3396 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003397 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003398};
3399
Tim Peters37f39822003-01-10 03:49:02 +00003400statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003401 PyObject_HEAD_INIT(NULL)
3402 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003403 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003404 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003405 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003406 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003407 0, /* tp_print */
3408 0, /* tp_getattr */
3409 0, /* tp_setattr */
3410 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003411 (reprfunc)time_repr, /* tp_repr */
3412 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003413 0, /* tp_as_sequence */
3414 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003415 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003416 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003417 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003418 PyObject_GenericGetAttr, /* tp_getattro */
3419 0, /* tp_setattro */
3420 0, /* tp_as_buffer */
3421 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3422 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003423 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003424 0, /* tp_traverse */
3425 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003426 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003427 0, /* tp_weaklistoffset */
3428 0, /* tp_iter */
3429 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003430 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003431 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003432 time_getset, /* tp_getset */
3433 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003434 0, /* tp_dict */
3435 0, /* tp_descr_get */
3436 0, /* tp_descr_set */
3437 0, /* tp_dictoffset */
3438 0, /* tp_init */
3439 0, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003440 time_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00003441 _PyObject_Del, /* tp_free */
3442};
3443
3444/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003445 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003446 */
3447
Tim Petersa9bc1682003-01-11 03:39:11 +00003448/* Accessor properties. Properties for day, month, and year are inherited
3449 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003450 */
3451
3452static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003453datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003454{
Tim Petersa9bc1682003-01-11 03:39:11 +00003455 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003456}
3457
Tim Petersa9bc1682003-01-11 03:39:11 +00003458static PyObject *
3459datetime_minute(PyDateTime_DateTime *self, void *unused)
3460{
3461 return PyInt_FromLong(DATE_GET_MINUTE(self));
3462}
3463
3464static PyObject *
3465datetime_second(PyDateTime_DateTime *self, void *unused)
3466{
3467 return PyInt_FromLong(DATE_GET_SECOND(self));
3468}
3469
3470static PyObject *
3471datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3472{
3473 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3474}
3475
3476static PyObject *
3477datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3478{
3479 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3480 Py_INCREF(result);
3481 return result;
3482}
3483
3484static PyGetSetDef datetime_getset[] = {
3485 {"hour", (getter)datetime_hour},
3486 {"minute", (getter)datetime_minute},
3487 {"second", (getter)datetime_second},
3488 {"microsecond", (getter)datetime_microsecond},
3489 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003490 {NULL}
3491};
3492
3493/*
3494 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003495 */
3496
Tim Petersa9bc1682003-01-11 03:39:11 +00003497static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003498 "year", "month", "day", "hour", "minute", "second",
3499 "microsecond", "tzinfo", NULL
3500};
3501
Tim Peters2a799bf2002-12-16 20:18:38 +00003502static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003503datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003504{
3505 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003506 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003507 int year;
3508 int month;
3509 int day;
3510 int hour = 0;
3511 int minute = 0;
3512 int second = 0;
3513 int usecond = 0;
3514 PyObject *tzinfo = Py_None;
3515
Guido van Rossum177e41a2003-01-30 22:06:23 +00003516 /* Check for invocation from pickle with __getstate__ state */
3517 if (PyTuple_GET_SIZE(args) >= 1 &&
3518 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00003519 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3520 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003521 {
Tim Peters70533e22003-02-01 04:40:04 +00003522 PyDateTime_DateTime *me;
3523 char aware;
3524
3525 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003526 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003527 if (check_tzinfo_subclass(tzinfo) < 0) {
3528 PyErr_SetString(PyExc_TypeError, "bad "
3529 "tzinfo state arg");
3530 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003531 }
3532 }
Tim Peters70533e22003-02-01 04:40:04 +00003533 aware = (char)(tzinfo != Py_None);
3534 me = alloc_datetime(aware);
3535 if (me != NULL) {
3536 char *pdata = PyString_AS_STRING(state);
3537
3538 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3539 me->hashcode = -1;
3540 me->hastzinfo = aware;
3541 if (aware) {
3542 Py_INCREF(tzinfo);
3543 me->tzinfo = tzinfo;
3544 }
3545 }
3546 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003547 }
3548
Tim Petersa9bc1682003-01-11 03:39:11 +00003549 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003550 &year, &month, &day, &hour, &minute,
3551 &second, &usecond, &tzinfo)) {
3552 if (check_date_args(year, month, day) < 0)
3553 return NULL;
3554 if (check_time_args(hour, minute, second, usecond) < 0)
3555 return NULL;
3556 if (check_tzinfo_subclass(tzinfo) < 0)
3557 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003558 self = new_datetime(year, month, day,
3559 hour, minute, second, usecond,
3560 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003561 }
3562 return self;
3563}
3564
Tim Petersa9bc1682003-01-11 03:39:11 +00003565/* TM_FUNC is the shared type of localtime() and gmtime(). */
3566typedef struct tm *(*TM_FUNC)(const time_t *timer);
3567
3568/* Internal helper.
3569 * Build datetime from a time_t and a distinct count of microseconds.
3570 * Pass localtime or gmtime for f, to control the interpretation of timet.
3571 */
3572static PyObject *
3573datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3574 PyObject *tzinfo)
3575{
3576 struct tm *tm;
3577 PyObject *result = NULL;
3578
3579 tm = f(&timet);
3580 if (tm) {
3581 /* The platform localtime/gmtime may insert leap seconds,
3582 * indicated by tm->tm_sec > 59. We don't care about them,
3583 * except to the extent that passing them on to the datetime
3584 * constructor would raise ValueError for a reason that
3585 * made no sense to the user.
3586 */
3587 if (tm->tm_sec > 59)
3588 tm->tm_sec = 59;
3589 result = PyObject_CallFunction(cls, "iiiiiiiO",
3590 tm->tm_year + 1900,
3591 tm->tm_mon + 1,
3592 tm->tm_mday,
3593 tm->tm_hour,
3594 tm->tm_min,
3595 tm->tm_sec,
3596 us,
3597 tzinfo);
3598 }
3599 else
3600 PyErr_SetString(PyExc_ValueError,
3601 "timestamp out of range for "
3602 "platform localtime()/gmtime() function");
3603 return result;
3604}
3605
3606/* Internal helper.
3607 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3608 * to control the interpretation of the timestamp. Since a double doesn't
3609 * have enough bits to cover a datetime's full range of precision, it's
3610 * better to call datetime_from_timet_and_us provided you have a way
3611 * to get that much precision (e.g., C time() isn't good enough).
3612 */
3613static PyObject *
3614datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3615 PyObject *tzinfo)
3616{
3617 time_t timet = (time_t)timestamp;
3618 double fraction = timestamp - (double)timet;
3619 int us = (int)round_to_long(fraction * 1e6);
3620
3621 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3622}
3623
3624/* Internal helper.
3625 * Build most accurate possible datetime for current time. Pass localtime or
3626 * gmtime for f as appropriate.
3627 */
3628static PyObject *
3629datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3630{
3631#ifdef HAVE_GETTIMEOFDAY
3632 struct timeval t;
3633
3634#ifdef GETTIMEOFDAY_NO_TZ
3635 gettimeofday(&t);
3636#else
3637 gettimeofday(&t, (struct timezone *)NULL);
3638#endif
3639 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3640 tzinfo);
3641
3642#else /* ! HAVE_GETTIMEOFDAY */
3643 /* No flavor of gettimeofday exists on this platform. Python's
3644 * time.time() does a lot of other platform tricks to get the
3645 * best time it can on the platform, and we're not going to do
3646 * better than that (if we could, the better code would belong
3647 * in time.time()!) We're limited by the precision of a double,
3648 * though.
3649 */
3650 PyObject *time;
3651 double dtime;
3652
3653 time = time_time();
3654 if (time == NULL)
3655 return NULL;
3656 dtime = PyFloat_AsDouble(time);
3657 Py_DECREF(time);
3658 if (dtime == -1.0 && PyErr_Occurred())
3659 return NULL;
3660 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3661#endif /* ! HAVE_GETTIMEOFDAY */
3662}
3663
Tim Peters2a799bf2002-12-16 20:18:38 +00003664/* Return best possible local time -- this isn't constrained by the
3665 * precision of a timestamp.
3666 */
3667static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003668datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003669{
Tim Peters10cadce2003-01-23 19:58:02 +00003670 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003671 PyObject *tzinfo = Py_None;
Tim Peters10cadce2003-01-23 19:58:02 +00003672 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003673
Tim Peters10cadce2003-01-23 19:58:02 +00003674 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3675 &tzinfo))
3676 return NULL;
3677 if (check_tzinfo_subclass(tzinfo) < 0)
3678 return NULL;
3679
3680 self = datetime_best_possible(cls,
3681 tzinfo == Py_None ? localtime : gmtime,
3682 tzinfo);
3683 if (self != NULL && tzinfo != Py_None) {
3684 /* Convert UTC to tzinfo's zone. */
3685 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003686 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003687 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003688 }
3689 return self;
3690}
3691
Tim Petersa9bc1682003-01-11 03:39:11 +00003692/* Return best possible UTC time -- this isn't constrained by the
3693 * precision of a timestamp.
3694 */
3695static PyObject *
3696datetime_utcnow(PyObject *cls, PyObject *dummy)
3697{
3698 return datetime_best_possible(cls, gmtime, Py_None);
3699}
3700
Tim Peters2a799bf2002-12-16 20:18:38 +00003701/* Return new local datetime from timestamp (Python timestamp -- a double). */
3702static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003703datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003704{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003705 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003706 double timestamp;
3707 PyObject *tzinfo = Py_None;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003708 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003709
Tim Peters2a44a8d2003-01-23 20:53:10 +00003710 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3711 keywords, &timestamp, &tzinfo))
3712 return NULL;
3713 if (check_tzinfo_subclass(tzinfo) < 0)
3714 return NULL;
3715
3716 self = datetime_from_timestamp(cls,
3717 tzinfo == Py_None ? localtime : gmtime,
3718 timestamp,
3719 tzinfo);
3720 if (self != NULL && tzinfo != Py_None) {
3721 /* Convert UTC to tzinfo's zone. */
3722 PyObject *temp = self;
3723 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3724 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003725 }
3726 return self;
3727}
3728
Tim Petersa9bc1682003-01-11 03:39:11 +00003729/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3730static PyObject *
3731datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3732{
3733 double timestamp;
3734 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003735
Tim Petersa9bc1682003-01-11 03:39:11 +00003736 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3737 result = datetime_from_timestamp(cls, gmtime, timestamp,
3738 Py_None);
3739 return result;
3740}
3741
3742/* Return new datetime from date/datetime and time arguments. */
3743static PyObject *
3744datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3745{
3746 static char *keywords[] = {"date", "time", NULL};
3747 PyObject *date;
3748 PyObject *time;
3749 PyObject *result = NULL;
3750
3751 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3752 &PyDateTime_DateType, &date,
3753 &PyDateTime_TimeType, &time)) {
3754 PyObject *tzinfo = Py_None;
3755
3756 if (HASTZINFO(time))
3757 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3758 result = PyObject_CallFunction(cls, "iiiiiiiO",
3759 GET_YEAR(date),
3760 GET_MONTH(date),
3761 GET_DAY(date),
3762 TIME_GET_HOUR(time),
3763 TIME_GET_MINUTE(time),
3764 TIME_GET_SECOND(time),
3765 TIME_GET_MICROSECOND(time),
3766 tzinfo);
3767 }
3768 return result;
3769}
Tim Peters2a799bf2002-12-16 20:18:38 +00003770
3771/*
3772 * Destructor.
3773 */
3774
3775static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003776datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003777{
Tim Petersa9bc1682003-01-11 03:39:11 +00003778 if (HASTZINFO(self)) {
3779 Py_XDECREF(self->tzinfo);
3780 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003781 self->ob_type->tp_free((PyObject *)self);
3782}
3783
3784/*
3785 * Indirect access to tzinfo methods.
3786 */
3787
Tim Peters2a799bf2002-12-16 20:18:38 +00003788/* These are all METH_NOARGS, so don't need to check the arglist. */
3789static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003790datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3791 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3792 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003793}
3794
3795static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003796datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3797 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3798 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003799}
3800
3801static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003802datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3803 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3804 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003805}
3806
3807/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003808 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003809 */
3810
Tim Petersa9bc1682003-01-11 03:39:11 +00003811/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3812 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003813 */
3814static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003815add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3816 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003817{
Tim Petersa9bc1682003-01-11 03:39:11 +00003818 /* Note that the C-level additions can't overflow, because of
3819 * invariant bounds on the member values.
3820 */
3821 int year = GET_YEAR(date);
3822 int month = GET_MONTH(date);
3823 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3824 int hour = DATE_GET_HOUR(date);
3825 int minute = DATE_GET_MINUTE(date);
3826 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3827 int microsecond = DATE_GET_MICROSECOND(date) +
3828 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003829
Tim Petersa9bc1682003-01-11 03:39:11 +00003830 assert(factor == 1 || factor == -1);
3831 if (normalize_datetime(&year, &month, &day,
3832 &hour, &minute, &second, &microsecond) < 0)
3833 return NULL;
3834 else
3835 return new_datetime(year, month, day,
3836 hour, minute, second, microsecond,
3837 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003838}
3839
3840static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003841datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003842{
Tim Petersa9bc1682003-01-11 03:39:11 +00003843 if (PyDateTime_Check(left)) {
3844 /* datetime + ??? */
3845 if (PyDelta_Check(right))
3846 /* datetime + delta */
3847 return add_datetime_timedelta(
3848 (PyDateTime_DateTime *)left,
3849 (PyDateTime_Delta *)right,
3850 1);
3851 }
3852 else if (PyDelta_Check(left)) {
3853 /* delta + datetime */
3854 return add_datetime_timedelta((PyDateTime_DateTime *) right,
3855 (PyDateTime_Delta *) left,
3856 1);
3857 }
3858 Py_INCREF(Py_NotImplemented);
3859 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00003860}
3861
3862static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003863datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003864{
3865 PyObject *result = Py_NotImplemented;
3866
3867 if (PyDateTime_Check(left)) {
3868 /* datetime - ??? */
3869 if (PyDateTime_Check(right)) {
3870 /* datetime - datetime */
3871 naivety n1, n2;
3872 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00003873 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00003874
Tim Peterse39a80c2002-12-30 21:28:52 +00003875 if (classify_two_utcoffsets(left, &offset1, &n1, left,
3876 right, &offset2, &n2,
3877 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00003878 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00003879 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00003880 if (n1 != n2) {
3881 PyErr_SetString(PyExc_TypeError,
3882 "can't subtract offset-naive and "
3883 "offset-aware datetimes");
3884 return NULL;
3885 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003886 delta_d = ymd_to_ord(GET_YEAR(left),
3887 GET_MONTH(left),
3888 GET_DAY(left)) -
3889 ymd_to_ord(GET_YEAR(right),
3890 GET_MONTH(right),
3891 GET_DAY(right));
3892 /* These can't overflow, since the values are
3893 * normalized. At most this gives the number of
3894 * seconds in one day.
3895 */
3896 delta_s = (DATE_GET_HOUR(left) -
3897 DATE_GET_HOUR(right)) * 3600 +
3898 (DATE_GET_MINUTE(left) -
3899 DATE_GET_MINUTE(right)) * 60 +
3900 (DATE_GET_SECOND(left) -
3901 DATE_GET_SECOND(right));
3902 delta_us = DATE_GET_MICROSECOND(left) -
3903 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00003904 /* (left - offset1) - (right - offset2) =
3905 * (left - right) + (offset2 - offset1)
3906 */
Tim Petersa9bc1682003-01-11 03:39:11 +00003907 delta_s += (offset2 - offset1) * 60;
3908 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003909 }
3910 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00003911 /* datetime - delta */
3912 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00003913 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00003914 (PyDateTime_Delta *)right,
3915 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003916 }
3917 }
3918
3919 if (result == Py_NotImplemented)
3920 Py_INCREF(result);
3921 return result;
3922}
3923
3924/* Various ways to turn a datetime into a string. */
3925
3926static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003927datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003928{
Tim Petersa9bc1682003-01-11 03:39:11 +00003929 char buffer[1000];
3930 char *typename = self->ob_type->tp_name;
3931 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003932
Tim Petersa9bc1682003-01-11 03:39:11 +00003933 if (DATE_GET_MICROSECOND(self)) {
3934 PyOS_snprintf(buffer, sizeof(buffer),
3935 "%s(%d, %d, %d, %d, %d, %d, %d)",
3936 typename,
3937 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3938 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3939 DATE_GET_SECOND(self),
3940 DATE_GET_MICROSECOND(self));
3941 }
3942 else if (DATE_GET_SECOND(self)) {
3943 PyOS_snprintf(buffer, sizeof(buffer),
3944 "%s(%d, %d, %d, %d, %d, %d)",
3945 typename,
3946 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3947 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3948 DATE_GET_SECOND(self));
3949 }
3950 else {
3951 PyOS_snprintf(buffer, sizeof(buffer),
3952 "%s(%d, %d, %d, %d, %d)",
3953 typename,
3954 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3955 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
3956 }
3957 baserepr = PyString_FromString(buffer);
3958 if (baserepr == NULL || ! HASTZINFO(self))
3959 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003960 return append_keyword_tzinfo(baserepr, self->tzinfo);
3961}
3962
Tim Petersa9bc1682003-01-11 03:39:11 +00003963static PyObject *
3964datetime_str(PyDateTime_DateTime *self)
3965{
3966 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
3967}
Tim Peters2a799bf2002-12-16 20:18:38 +00003968
3969static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003970datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003971{
Tim Petersa9bc1682003-01-11 03:39:11 +00003972 char sep = 'T';
3973 static char *keywords[] = {"sep", NULL};
3974 char buffer[100];
3975 char *cp;
3976 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003977
Tim Petersa9bc1682003-01-11 03:39:11 +00003978 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
3979 &sep))
3980 return NULL;
3981 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
3982 assert(cp != NULL);
3983 *cp++ = sep;
3984 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
3985 result = PyString_FromString(buffer);
3986 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00003987 return result;
3988
3989 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00003990 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00003991 (PyObject *)self) < 0) {
3992 Py_DECREF(result);
3993 return NULL;
3994 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003995 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00003996 return result;
3997}
3998
Tim Petersa9bc1682003-01-11 03:39:11 +00003999static PyObject *
4000datetime_ctime(PyDateTime_DateTime *self)
4001{
4002 return format_ctime((PyDateTime_Date *)self,
4003 DATE_GET_HOUR(self),
4004 DATE_GET_MINUTE(self),
4005 DATE_GET_SECOND(self));
4006}
4007
Tim Peters2a799bf2002-12-16 20:18:38 +00004008/* Miscellaneous methods. */
4009
Tim Petersa9bc1682003-01-11 03:39:11 +00004010/* This is more natural as a tp_compare, but doesn't work then: for whatever
4011 * reason, Python's try_3way_compare ignores tp_compare unless
4012 * PyInstance_Check returns true, but these aren't old-style classes.
4013 */
4014static PyObject *
4015datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4016{
4017 int diff;
4018 naivety n1, n2;
4019 int offset1, offset2;
4020
4021 if (! PyDateTime_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004022 if (PyObject_HasAttrString(other, "timetuple")) {
4023 /* A hook for other kinds of datetime objects. */
4024 Py_INCREF(Py_NotImplemented);
4025 return Py_NotImplemented;
4026 }
Tim Peters07534a62003-02-07 22:50:28 +00004027 if (op == Py_EQ || op == Py_NE) {
4028 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4029 Py_INCREF(result);
4030 return result;
4031 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004032 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00004033 return cmperror((PyObject *)self, other);
Tim Petersa9bc1682003-01-11 03:39:11 +00004034 }
4035
4036 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4037 (PyObject *)self,
4038 other, &offset2, &n2,
4039 other) < 0)
4040 return NULL;
4041 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4042 /* If they're both naive, or both aware and have the same offsets,
4043 * we get off cheap. Note that if they're both naive, offset1 ==
4044 * offset2 == 0 at this point.
4045 */
4046 if (n1 == n2 && offset1 == offset2) {
4047 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4048 _PyDateTime_DATETIME_DATASIZE);
4049 return diff_to_bool(diff, op);
4050 }
4051
4052 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4053 PyDateTime_Delta *delta;
4054
4055 assert(offset1 != offset2); /* else last "if" handled it */
4056 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4057 other);
4058 if (delta == NULL)
4059 return NULL;
4060 diff = GET_TD_DAYS(delta);
4061 if (diff == 0)
4062 diff = GET_TD_SECONDS(delta) |
4063 GET_TD_MICROSECONDS(delta);
4064 Py_DECREF(delta);
4065 return diff_to_bool(diff, op);
4066 }
4067
4068 assert(n1 != n2);
4069 PyErr_SetString(PyExc_TypeError,
4070 "can't compare offset-naive and "
4071 "offset-aware datetimes");
4072 return NULL;
4073}
4074
4075static long
4076datetime_hash(PyDateTime_DateTime *self)
4077{
4078 if (self->hashcode == -1) {
4079 naivety n;
4080 int offset;
4081 PyObject *temp;
4082
4083 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4084 &offset);
4085 assert(n != OFFSET_UNKNOWN);
4086 if (n == OFFSET_ERROR)
4087 return -1;
4088
4089 /* Reduce this to a hash of another object. */
4090 if (n == OFFSET_NAIVE)
4091 temp = PyString_FromStringAndSize(
4092 (char *)self->data,
4093 _PyDateTime_DATETIME_DATASIZE);
4094 else {
4095 int days;
4096 int seconds;
4097
4098 assert(n == OFFSET_AWARE);
4099 assert(HASTZINFO(self));
4100 days = ymd_to_ord(GET_YEAR(self),
4101 GET_MONTH(self),
4102 GET_DAY(self));
4103 seconds = DATE_GET_HOUR(self) * 3600 +
4104 (DATE_GET_MINUTE(self) - offset) * 60 +
4105 DATE_GET_SECOND(self);
4106 temp = new_delta(days,
4107 seconds,
4108 DATE_GET_MICROSECOND(self),
4109 1);
4110 }
4111 if (temp != NULL) {
4112 self->hashcode = PyObject_Hash(temp);
4113 Py_DECREF(temp);
4114 }
4115 }
4116 return self->hashcode;
4117}
Tim Peters2a799bf2002-12-16 20:18:38 +00004118
4119static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004120datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004121{
4122 PyObject *clone;
4123 PyObject *tuple;
4124 int y = GET_YEAR(self);
4125 int m = GET_MONTH(self);
4126 int d = GET_DAY(self);
4127 int hh = DATE_GET_HOUR(self);
4128 int mm = DATE_GET_MINUTE(self);
4129 int ss = DATE_GET_SECOND(self);
4130 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004131 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004132
4133 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004134 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004135 &y, &m, &d, &hh, &mm, &ss, &us,
4136 &tzinfo))
4137 return NULL;
4138 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4139 if (tuple == NULL)
4140 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004141 clone = datetime_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004142 Py_DECREF(tuple);
4143 return clone;
4144}
4145
4146static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004147datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004148{
Tim Peters52dcce22003-01-23 16:36:11 +00004149 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004150 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004151 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004152
Tim Peters80475bb2002-12-25 07:40:55 +00004153 PyObject *tzinfo;
4154 static char *keywords[] = {"tz", NULL};
4155
Tim Peters52dcce22003-01-23 16:36:11 +00004156 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4157 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004158 return NULL;
4159
Tim Peters52dcce22003-01-23 16:36:11 +00004160 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4161 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004162
Tim Peters52dcce22003-01-23 16:36:11 +00004163 /* Conversion to self's own time zone is a NOP. */
4164 if (self->tzinfo == tzinfo) {
4165 Py_INCREF(self);
4166 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004167 }
Tim Peters521fc152002-12-31 17:36:56 +00004168
Tim Peters52dcce22003-01-23 16:36:11 +00004169 /* Convert self to UTC. */
4170 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4171 if (offset == -1 && PyErr_Occurred())
4172 return NULL;
4173 if (none)
4174 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004175
Tim Peters52dcce22003-01-23 16:36:11 +00004176 y = GET_YEAR(self);
4177 m = GET_MONTH(self);
4178 d = GET_DAY(self);
4179 hh = DATE_GET_HOUR(self);
4180 mm = DATE_GET_MINUTE(self);
4181 ss = DATE_GET_SECOND(self);
4182 us = DATE_GET_MICROSECOND(self);
4183
4184 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004185 if ((mm < 0 || mm >= 60) &&
4186 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004187 return NULL;
4188
4189 /* Attach new tzinfo and let fromutc() do the rest. */
4190 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4191 if (result != NULL) {
4192 PyObject *temp = result;
4193
4194 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4195 Py_DECREF(temp);
4196 }
Tim Petersadf64202003-01-04 06:03:15 +00004197 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004198
Tim Peters52dcce22003-01-23 16:36:11 +00004199NeedAware:
4200 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4201 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004202 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004203}
4204
4205static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004206datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004207{
4208 int dstflag = -1;
4209
Tim Petersa9bc1682003-01-11 03:39:11 +00004210 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004211 int none;
4212
4213 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4214 if (dstflag == -1 && PyErr_Occurred())
4215 return NULL;
4216
4217 if (none)
4218 dstflag = -1;
4219 else if (dstflag != 0)
4220 dstflag = 1;
4221
4222 }
4223 return build_struct_time(GET_YEAR(self),
4224 GET_MONTH(self),
4225 GET_DAY(self),
4226 DATE_GET_HOUR(self),
4227 DATE_GET_MINUTE(self),
4228 DATE_GET_SECOND(self),
4229 dstflag);
4230}
4231
4232static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004233datetime_getdate(PyDateTime_DateTime *self)
4234{
4235 return new_date(GET_YEAR(self),
4236 GET_MONTH(self),
4237 GET_DAY(self));
4238}
4239
4240static PyObject *
4241datetime_gettime(PyDateTime_DateTime *self)
4242{
4243 return new_time(DATE_GET_HOUR(self),
4244 DATE_GET_MINUTE(self),
4245 DATE_GET_SECOND(self),
4246 DATE_GET_MICROSECOND(self),
4247 Py_None);
4248}
4249
4250static PyObject *
4251datetime_gettimetz(PyDateTime_DateTime *self)
4252{
4253 return new_time(DATE_GET_HOUR(self),
4254 DATE_GET_MINUTE(self),
4255 DATE_GET_SECOND(self),
4256 DATE_GET_MICROSECOND(self),
4257 HASTZINFO(self) ? self->tzinfo : Py_None);
4258}
4259
4260static PyObject *
4261datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004262{
4263 int y = GET_YEAR(self);
4264 int m = GET_MONTH(self);
4265 int d = GET_DAY(self);
4266 int hh = DATE_GET_HOUR(self);
4267 int mm = DATE_GET_MINUTE(self);
4268 int ss = DATE_GET_SECOND(self);
4269 int us = 0; /* microseconds are ignored in a timetuple */
4270 int offset = 0;
4271
Tim Petersa9bc1682003-01-11 03:39:11 +00004272 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004273 int none;
4274
4275 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4276 if (offset == -1 && PyErr_Occurred())
4277 return NULL;
4278 }
4279 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4280 * 0 in a UTC timetuple regardless of what dst() says.
4281 */
4282 if (offset) {
4283 /* Subtract offset minutes & normalize. */
4284 int stat;
4285
4286 mm -= offset;
4287 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4288 if (stat < 0) {
4289 /* At the edges, it's possible we overflowed
4290 * beyond MINYEAR or MAXYEAR.
4291 */
4292 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4293 PyErr_Clear();
4294 else
4295 return NULL;
4296 }
4297 }
4298 return build_struct_time(y, m, d, hh, mm, ss, 0);
4299}
4300
Tim Peters371935f2003-02-01 01:52:50 +00004301/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004302
Tim Petersa9bc1682003-01-11 03:39:11 +00004303/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004304 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4305 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004306 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004307 */
4308static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004309datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004310{
4311 PyObject *basestate;
4312 PyObject *result = NULL;
4313
Tim Peters33e0f382003-01-10 02:05:14 +00004314 basestate = PyString_FromStringAndSize((char *)self->data,
4315 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004316 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004317 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00004318 result = Py_BuildValue("(O)", basestate);
4319 else
4320 result = Py_BuildValue("OO", basestate, self->tzinfo);
4321 Py_DECREF(basestate);
4322 }
4323 return result;
4324}
4325
4326static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004327datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004328{
Guido van Rossum177e41a2003-01-30 22:06:23 +00004329 return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004330}
4331
Tim Petersa9bc1682003-01-11 03:39:11 +00004332static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004333
Tim Peters2a799bf2002-12-16 20:18:38 +00004334 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004335
Tim Petersa9bc1682003-01-11 03:39:11 +00004336 {"now", (PyCFunction)datetime_now,
Tim Peters2a799bf2002-12-16 20:18:38 +00004337 METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004338 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004339
Tim Petersa9bc1682003-01-11 03:39:11 +00004340 {"utcnow", (PyCFunction)datetime_utcnow,
4341 METH_NOARGS | METH_CLASS,
4342 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4343
4344 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Tim Peters2a799bf2002-12-16 20:18:38 +00004345 METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004346 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004347
Tim Petersa9bc1682003-01-11 03:39:11 +00004348 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4349 METH_VARARGS | METH_CLASS,
4350 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4351 "(like time.time()).")},
4352
4353 {"combine", (PyCFunction)datetime_combine,
4354 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4355 PyDoc_STR("date, time -> datetime with same date and time fields")},
4356
Tim Peters2a799bf2002-12-16 20:18:38 +00004357 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004358
Tim Petersa9bc1682003-01-11 03:39:11 +00004359 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4360 PyDoc_STR("Return date object with same year, month and day.")},
4361
4362 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4363 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4364
4365 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4366 PyDoc_STR("Return time object with same time and tzinfo.")},
4367
4368 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4369 PyDoc_STR("Return ctime() style string.")},
4370
4371 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004372 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4373
Tim Petersa9bc1682003-01-11 03:39:11 +00004374 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004375 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4376
Tim Petersa9bc1682003-01-11 03:39:11 +00004377 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004378 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4379 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4380 "sep is used to separate the year from the time, and "
4381 "defaults to 'T'.")},
4382
Tim Petersa9bc1682003-01-11 03:39:11 +00004383 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004384 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4385
Tim Petersa9bc1682003-01-11 03:39:11 +00004386 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004387 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4388
Tim Petersa9bc1682003-01-11 03:39:11 +00004389 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004390 PyDoc_STR("Return self.tzinfo.dst(self).")},
4391
Tim Petersa9bc1682003-01-11 03:39:11 +00004392 {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
4393 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004394
Tim Petersa9bc1682003-01-11 03:39:11 +00004395 {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004396 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4397
Guido van Rossum177e41a2003-01-30 22:06:23 +00004398 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4399 PyDoc_STR("__reduce__() -> (cls, state)")},
4400
Tim Peters2a799bf2002-12-16 20:18:38 +00004401 {NULL, NULL}
4402};
4403
Tim Petersa9bc1682003-01-11 03:39:11 +00004404static char datetime_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00004405PyDoc_STR("date/time type.");
4406
Tim Petersa9bc1682003-01-11 03:39:11 +00004407static PyNumberMethods datetime_as_number = {
4408 datetime_add, /* nb_add */
4409 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004410 0, /* nb_multiply */
4411 0, /* nb_divide */
4412 0, /* nb_remainder */
4413 0, /* nb_divmod */
4414 0, /* nb_power */
4415 0, /* nb_negative */
4416 0, /* nb_positive */
4417 0, /* nb_absolute */
4418 0, /* nb_nonzero */
4419};
4420
Tim Petersa9bc1682003-01-11 03:39:11 +00004421statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004422 PyObject_HEAD_INIT(NULL)
4423 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004424 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004425 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004426 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004427 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004428 0, /* tp_print */
4429 0, /* tp_getattr */
4430 0, /* tp_setattr */
4431 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004432 (reprfunc)datetime_repr, /* tp_repr */
4433 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004434 0, /* tp_as_sequence */
4435 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004436 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004437 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004438 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004439 PyObject_GenericGetAttr, /* tp_getattro */
4440 0, /* tp_setattro */
4441 0, /* tp_as_buffer */
4442 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4443 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004444 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004445 0, /* tp_traverse */
4446 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004447 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004448 0, /* tp_weaklistoffset */
4449 0, /* tp_iter */
4450 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004451 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004452 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004453 datetime_getset, /* tp_getset */
4454 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004455 0, /* tp_dict */
4456 0, /* tp_descr_get */
4457 0, /* tp_descr_set */
4458 0, /* tp_dictoffset */
4459 0, /* tp_init */
4460 0, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004461 datetime_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00004462 _PyObject_Del, /* tp_free */
4463};
4464
4465/* ---------------------------------------------------------------------------
4466 * Module methods and initialization.
4467 */
4468
4469static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004470 {NULL, NULL}
4471};
4472
4473PyMODINIT_FUNC
4474initdatetime(void)
4475{
4476 PyObject *m; /* a module object */
4477 PyObject *d; /* its dict */
4478 PyObject *x;
4479
Tim Peters2a799bf2002-12-16 20:18:38 +00004480 m = Py_InitModule3("datetime", module_methods,
4481 "Fast implementation of the datetime type.");
4482
4483 if (PyType_Ready(&PyDateTime_DateType) < 0)
4484 return;
4485 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4486 return;
4487 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4488 return;
4489 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4490 return;
4491 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4492 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004493
Tim Peters2a799bf2002-12-16 20:18:38 +00004494 /* timedelta values */
4495 d = PyDateTime_DeltaType.tp_dict;
4496
Tim Peters2a799bf2002-12-16 20:18:38 +00004497 x = new_delta(0, 0, 1, 0);
4498 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4499 return;
4500 Py_DECREF(x);
4501
4502 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4503 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4504 return;
4505 Py_DECREF(x);
4506
4507 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4508 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4509 return;
4510 Py_DECREF(x);
4511
4512 /* date values */
4513 d = PyDateTime_DateType.tp_dict;
4514
4515 x = new_date(1, 1, 1);
4516 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4517 return;
4518 Py_DECREF(x);
4519
4520 x = new_date(MAXYEAR, 12, 31);
4521 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4522 return;
4523 Py_DECREF(x);
4524
4525 x = new_delta(1, 0, 0, 0);
4526 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4527 return;
4528 Py_DECREF(x);
4529
Tim Peters37f39822003-01-10 03:49:02 +00004530 /* time values */
4531 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004532
Tim Peters37f39822003-01-10 03:49:02 +00004533 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004534 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4535 return;
4536 Py_DECREF(x);
4537
Tim Peters37f39822003-01-10 03:49:02 +00004538 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004539 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4540 return;
4541 Py_DECREF(x);
4542
4543 x = new_delta(0, 0, 1, 0);
4544 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4545 return;
4546 Py_DECREF(x);
4547
Tim Petersa9bc1682003-01-11 03:39:11 +00004548 /* datetime values */
4549 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004550
Tim Petersa9bc1682003-01-11 03:39:11 +00004551 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004552 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4553 return;
4554 Py_DECREF(x);
4555
Tim Petersa9bc1682003-01-11 03:39:11 +00004556 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004557 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4558 return;
4559 Py_DECREF(x);
4560
4561 x = new_delta(0, 0, 1, 0);
4562 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4563 return;
4564 Py_DECREF(x);
4565
Tim Peters2a799bf2002-12-16 20:18:38 +00004566 /* module initialization */
4567 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4568 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4569
4570 Py_INCREF(&PyDateTime_DateType);
4571 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4572
Tim Petersa9bc1682003-01-11 03:39:11 +00004573 Py_INCREF(&PyDateTime_DateTimeType);
4574 PyModule_AddObject(m, "datetime",
4575 (PyObject *)&PyDateTime_DateTimeType);
4576
4577 Py_INCREF(&PyDateTime_TimeType);
4578 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4579
Tim Peters2a799bf2002-12-16 20:18:38 +00004580 Py_INCREF(&PyDateTime_DeltaType);
4581 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4582
Tim Peters2a799bf2002-12-16 20:18:38 +00004583 Py_INCREF(&PyDateTime_TZInfoType);
4584 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4585
Tim Peters2a799bf2002-12-16 20:18:38 +00004586 /* A 4-year cycle has an extra leap day over what we'd get from
4587 * pasting together 4 single years.
4588 */
4589 assert(DI4Y == 4 * 365 + 1);
4590 assert(DI4Y == days_before_year(4+1));
4591
4592 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4593 * get from pasting together 4 100-year cycles.
4594 */
4595 assert(DI400Y == 4 * DI100Y + 1);
4596 assert(DI400Y == days_before_year(400+1));
4597
4598 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4599 * pasting together 25 4-year cycles.
4600 */
4601 assert(DI100Y == 25 * DI4Y - 1);
4602 assert(DI100Y == days_before_year(100+1));
4603
4604 us_per_us = PyInt_FromLong(1);
4605 us_per_ms = PyInt_FromLong(1000);
4606 us_per_second = PyInt_FromLong(1000000);
4607 us_per_minute = PyInt_FromLong(60000000);
4608 seconds_per_day = PyInt_FromLong(24 * 3600);
4609 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4610 us_per_minute == NULL || seconds_per_day == NULL)
4611 return;
4612
4613 /* The rest are too big for 32-bit ints, but even
4614 * us_per_week fits in 40 bits, so doubles should be exact.
4615 */
4616 us_per_hour = PyLong_FromDouble(3600000000.0);
4617 us_per_day = PyLong_FromDouble(86400000000.0);
4618 us_per_week = PyLong_FromDouble(604800000000.0);
4619 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4620 return;
4621}
Tim Petersf3615152003-01-01 21:51:37 +00004622
4623/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004624Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004625 x.n = x stripped of its timezone -- its naive time.
4626 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4627 return None
4628 x.d = x.dst(), and assuming that doesn't raise an exception or
4629 return None
4630 x.s = x's standard offset, x.o - x.d
4631
4632Now some derived rules, where k is a duration (timedelta).
4633
46341. x.o = x.s + x.d
4635 This follows from the definition of x.s.
4636
Tim Petersc5dc4da2003-01-02 17:55:03 +000046372. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004638 This is actually a requirement, an assumption we need to make about
4639 sane tzinfo classes.
4640
46413. The naive UTC time corresponding to x is x.n - x.o.
4642 This is again a requirement for a sane tzinfo class.
4643
46444. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004645 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004646
Tim Petersc5dc4da2003-01-02 17:55:03 +000046475. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004648 Again follows from how arithmetic is defined.
4649
Tim Peters8bb5ad22003-01-24 02:44:45 +00004650Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004651(meaning that the various tzinfo methods exist, and don't blow up or return
4652None when called).
4653
Tim Petersa9bc1682003-01-11 03:39:11 +00004654The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004655x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004656
4657By #3, we want
4658
Tim Peters8bb5ad22003-01-24 02:44:45 +00004659 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004660
4661The algorithm starts by attaching tz to x.n, and calling that y. So
4662x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4663becomes true; in effect, we want to solve [2] for k:
4664
Tim Peters8bb5ad22003-01-24 02:44:45 +00004665 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004666
4667By #1, this is the same as
4668
Tim Peters8bb5ad22003-01-24 02:44:45 +00004669 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004670
4671By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4672Substituting that into [3],
4673
Tim Peters8bb5ad22003-01-24 02:44:45 +00004674 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4675 k - (y+k).s - (y+k).d = 0; rearranging,
4676 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4677 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004678
Tim Peters8bb5ad22003-01-24 02:44:45 +00004679On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4680approximate k by ignoring the (y+k).d term at first. Note that k can't be
4681very large, since all offset-returning methods return a duration of magnitude
4682less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4683be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004684
4685In any case, the new value is
4686
Tim Peters8bb5ad22003-01-24 02:44:45 +00004687 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004688
Tim Peters8bb5ad22003-01-24 02:44:45 +00004689It's helpful to step back at look at [4] from a higher level: it's simply
4690mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004691
4692At this point, if
4693
Tim Peters8bb5ad22003-01-24 02:44:45 +00004694 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004695
4696we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004697at the start of daylight time. Picture US Eastern for concreteness. The wall
4698time 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 +00004699sense then. The docs ask that an Eastern tzinfo class consider such a time to
4700be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4701on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004702the only spelling that makes sense on the local wall clock.
4703
Tim Petersc5dc4da2003-01-02 17:55:03 +00004704In fact, if [5] holds at this point, we do have the standard-time spelling,
4705but that takes a bit of proof. We first prove a stronger result. What's the
4706difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004707
Tim Peters8bb5ad22003-01-24 02:44:45 +00004708 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004709
Tim Petersc5dc4da2003-01-02 17:55:03 +00004710Now
4711 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004712 (y + y.s).n = by #5
4713 y.n + y.s = since y.n = x.n
4714 x.n + y.s = since z and y are have the same tzinfo member,
4715 y.s = z.s by #2
4716 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004717
Tim Petersc5dc4da2003-01-02 17:55:03 +00004718Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004719
Tim Petersc5dc4da2003-01-02 17:55:03 +00004720 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004721 x.n - ((x.n + z.s) - z.o) = expanding
4722 x.n - x.n - z.s + z.o = cancelling
4723 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004724 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004725
Tim Petersc5dc4da2003-01-02 17:55:03 +00004726So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004727
Tim Petersc5dc4da2003-01-02 17:55:03 +00004728If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004729spelling we wanted in the endcase described above. We're done. Contrarily,
4730if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004731
Tim Petersc5dc4da2003-01-02 17:55:03 +00004732If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4733add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00004734local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004735
Tim Petersc5dc4da2003-01-02 17:55:03 +00004736Let
Tim Petersf3615152003-01-01 21:51:37 +00004737
Tim Peters4fede1a2003-01-04 00:26:59 +00004738 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004739
Tim Peters4fede1a2003-01-04 00:26:59 +00004740and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004741
Tim Peters8bb5ad22003-01-24 02:44:45 +00004742 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004743
Tim Peters8bb5ad22003-01-24 02:44:45 +00004744If so, we're done. If not, the tzinfo class is insane, according to the
4745assumptions we've made. This also requires a bit of proof. As before, let's
4746compute the difference between the LHS and RHS of [8] (and skipping some of
4747the justifications for the kinds of substitutions we've done several times
4748already):
Tim Peters4fede1a2003-01-04 00:26:59 +00004749
Tim Peters8bb5ad22003-01-24 02:44:45 +00004750 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
4751 x.n - (z.n + diff - z'.o) = replacing diff via [6]
4752 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
4753 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
4754 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00004755 - z.o + z'.o = #1 twice
4756 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4757 z'.d - z.d
4758
4759So 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 +00004760we've found the UTC-equivalent so are done. In fact, we stop with [7] and
4761return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00004762
Tim Peters8bb5ad22003-01-24 02:44:45 +00004763How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
4764a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
4765would have to change the result dst() returns: we start in DST, and moving
4766a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00004767
Tim Peters8bb5ad22003-01-24 02:44:45 +00004768There isn't a sane case where this can happen. The closest it gets is at
4769the end of DST, where there's an hour in UTC with no spelling in a hybrid
4770tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
4771that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
4772UTC) because the docs insist on that, but 0:MM is taken as being in daylight
4773time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
4774clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
4775standard time. Since that's what the local clock *does*, we want to map both
4776UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00004777in local time, but so it goes -- it's the way the local clock works.
4778
Tim Peters8bb5ad22003-01-24 02:44:45 +00004779When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4780so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4781z' = 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 +00004782(correctly) concludes that z' is not UTC-equivalent to x.
4783
4784Because we know z.d said z was in daylight time (else [5] would have held and
4785we would have stopped then), and we know z.d != z'.d (else [8] would have held
4786and we we have stopped then), and there are only 2 possible values dst() can
4787return in Eastern, it follows that z'.d must be 0 (which it is in the example,
4788but the reasoning doesn't depend on the example -- it depends on there being
4789two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00004790z' must be in standard time, and is the spelling we want in this case.
4791
4792Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
4793concerned (because it takes z' as being in standard time rather than the
4794daylight time we intend here), but returning it gives the real-life "local
4795clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
4796tz.
4797
4798When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
4799the 1:MM standard time spelling we want.
4800
4801So how can this break? One of the assumptions must be violated. Two
4802possibilities:
4803
48041) [2] effectively says that y.s is invariant across all y belong to a given
4805 time zone. This isn't true if, for political reasons or continental drift,
4806 a region decides to change its base offset from UTC.
4807
48082) There may be versions of "double daylight" time where the tail end of
4809 the analysis gives up a step too early. I haven't thought about that
4810 enough to say.
4811
4812In any case, it's clear that the default fromutc() is strong enough to handle
4813"almost all" time zones: so long as the standard offset is invariant, it
4814doesn't matter if daylight time transition points change from year to year, or
4815if daylight time is skipped in some years; it doesn't matter how large or
4816small dst() may get within its bounds; and it doesn't even matter if some
4817perverse time zone returns a negative dst()). So a breaking case must be
4818pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00004819--------------------------------------------------------------------------- */