blob: fa9e3a15a8ddf119873b0901535a5823ccb3def5 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
6#include "modsupport.h"
7#include "structmember.h"
8
9#include <time.h>
10
11#include "datetime.h"
12
13/* We require that C int be at least 32 bits, and use int virtually
14 * everywhere. In just a few cases we use a temp long, where a Python
15 * API returns a C long. In such cases, we have to ensure that the
16 * final result fits in a C int (this can be an issue on 64-bit boxes).
17 */
18#if SIZEOF_INT < 4
19# error "datetime.c requires that C int have at least 32 bits"
20#endif
21
22#define MINYEAR 1
23#define MAXYEAR 9999
24
25/* Nine decimal digits is easy to communicate, and leaves enough room
26 * so that two delta days can be added w/o fear of overflowing a signed
27 * 32-bit int, and with plenty of room left over to absorb any possible
28 * carries from adding seconds.
29 */
30#define MAX_DELTA_DAYS 999999999
31
32/* Rename the long macros in datetime.h to more reasonable short names. */
33#define GET_YEAR PyDateTime_GET_YEAR
34#define GET_MONTH PyDateTime_GET_MONTH
35#define GET_DAY PyDateTime_GET_DAY
36#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
37#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
38#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
39#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
40
41/* Date accessors for date and datetime. */
42#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
43 ((o)->data[1] = ((v) & 0x00ff)))
44#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
45#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
46
47/* Date/Time accessors for datetime. */
48#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
49#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
50#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
51#define DATE_SET_MICROSECOND(o, v) \
52 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
53 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
54 ((o)->data[9] = ((v) & 0x0000ff)))
55
56/* Time accessors for time. */
57#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
58#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
59#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
60#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
61#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
62#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
63#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
64#define TIME_SET_MICROSECOND(o, v) \
65 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
66 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
67 ((o)->data[5] = ((v) & 0x0000ff)))
68
69/* Delta accessors for timedelta. */
70#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
71#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
72#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
73
74#define SET_TD_DAYS(o, v) ((o)->days = (v))
75#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
76#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
77
Tim Petersa032d2e2003-01-11 00:15:54 +000078/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
79 * p->hastzinfo.
80 */
81#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
82
Tim Peters2a799bf2002-12-16 20:18:38 +000083/* Forward declarations. */
84static PyTypeObject PyDateTime_DateType;
85static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +000086static PyTypeObject PyDateTime_DeltaType;
87static PyTypeObject PyDateTime_TimeType;
88static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +000089
90/* ---------------------------------------------------------------------------
91 * Math utilities.
92 */
93
94/* k = i+j overflows iff k differs in sign from both inputs,
95 * iff k^i has sign bit set and k^j has sign bit set,
96 * iff (k^i)&(k^j) has sign bit set.
97 */
98#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
99 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
100
101/* Compute Python divmod(x, y), returning the quotient and storing the
102 * remainder into *r. The quotient is the floor of x/y, and that's
103 * the real point of this. C will probably truncate instead (C99
104 * requires truncation; C89 left it implementation-defined).
105 * Simplification: we *require* that y > 0 here. That's appropriate
106 * for all the uses made of it. This simplifies the code and makes
107 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
108 * overflow case).
109 */
110static int
111divmod(int x, int y, int *r)
112{
113 int quo;
114
115 assert(y > 0);
116 quo = x / y;
117 *r = x - quo * y;
118 if (*r < 0) {
119 --quo;
120 *r += y;
121 }
122 assert(0 <= *r && *r < y);
123 return quo;
124}
125
Tim Peters5d644dd2003-01-02 16:32:54 +0000126/* Round a double to the nearest long. |x| must be small enough to fit
127 * in a C long; this is not checked.
128 */
129static long
130round_to_long(double x)
131{
132 if (x >= 0.0)
133 x = floor(x + 0.5);
134 else
135 x = ceil(x - 0.5);
136 return (long)x;
137}
138
Tim Peters2a799bf2002-12-16 20:18:38 +0000139/* ---------------------------------------------------------------------------
140 * General calendrical helper functions
141 */
142
143/* For each month ordinal in 1..12, the number of days in that month,
144 * and the number of days before that month in the same year. These
145 * are correct for non-leap years only.
146 */
147static int _days_in_month[] = {
148 0, /* unused; this vector uses 1-based indexing */
149 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
150};
151
152static int _days_before_month[] = {
153 0, /* unused; this vector uses 1-based indexing */
154 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
155};
156
157/* year -> 1 if leap year, else 0. */
158static int
159is_leap(int year)
160{
161 /* Cast year to unsigned. The result is the same either way, but
162 * C can generate faster code for unsigned mod than for signed
163 * mod (especially for % 4 -- a good compiler should just grab
164 * the last 2 bits when the LHS is unsigned).
165 */
166 const unsigned int ayear = (unsigned int)year;
167 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
168}
169
170/* year, month -> number of days in that month in that year */
171static int
172days_in_month(int year, int month)
173{
174 assert(month >= 1);
175 assert(month <= 12);
176 if (month == 2 && is_leap(year))
177 return 29;
178 else
179 return _days_in_month[month];
180}
181
182/* year, month -> number of days in year preceeding first day of month */
183static int
184days_before_month(int year, int month)
185{
186 int days;
187
188 assert(month >= 1);
189 assert(month <= 12);
190 days = _days_before_month[month];
191 if (month > 2 && is_leap(year))
192 ++days;
193 return days;
194}
195
196/* year -> number of days before January 1st of year. Remember that we
197 * start with year 1, so days_before_year(1) == 0.
198 */
199static int
200days_before_year(int year)
201{
202 int y = year - 1;
203 /* This is incorrect if year <= 0; we really want the floor
204 * here. But so long as MINYEAR is 1, the smallest year this
205 * can see is 0 (this can happen in some normalization endcases),
206 * so we'll just special-case that.
207 */
208 assert (year >= 0);
209 if (y >= 0)
210 return y*365 + y/4 - y/100 + y/400;
211 else {
212 assert(y == -1);
213 return -366;
214 }
215}
216
217/* Number of days in 4, 100, and 400 year cycles. That these have
218 * the correct values is asserted in the module init function.
219 */
220#define DI4Y 1461 /* days_before_year(5); days in 4 years */
221#define DI100Y 36524 /* days_before_year(101); days in 100 years */
222#define DI400Y 146097 /* days_before_year(401); days in 400 years */
223
224/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
225static void
226ord_to_ymd(int ordinal, int *year, int *month, int *day)
227{
228 int n, n1, n4, n100, n400, leapyear, preceding;
229
230 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
231 * leap years repeats exactly every 400 years. The basic strategy is
232 * to find the closest 400-year boundary at or before ordinal, then
233 * work with the offset from that boundary to ordinal. Life is much
234 * clearer if we subtract 1 from ordinal first -- then the values
235 * of ordinal at 400-year boundaries are exactly those divisible
236 * by DI400Y:
237 *
238 * D M Y n n-1
239 * -- --- ---- ---------- ----------------
240 * 31 Dec -400 -DI400Y -DI400Y -1
241 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
242 * ...
243 * 30 Dec 000 -1 -2
244 * 31 Dec 000 0 -1
245 * 1 Jan 001 1 0 400-year boundary
246 * 2 Jan 001 2 1
247 * 3 Jan 001 3 2
248 * ...
249 * 31 Dec 400 DI400Y DI400Y -1
250 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
251 */
252 assert(ordinal >= 1);
253 --ordinal;
254 n400 = ordinal / DI400Y;
255 n = ordinal % DI400Y;
256 *year = n400 * 400 + 1;
257
258 /* Now n is the (non-negative) offset, in days, from January 1 of
259 * year, to the desired date. Now compute how many 100-year cycles
260 * precede n.
261 * Note that it's possible for n100 to equal 4! In that case 4 full
262 * 100-year cycles precede the desired day, which implies the
263 * desired day is December 31 at the end of a 400-year cycle.
264 */
265 n100 = n / DI100Y;
266 n = n % DI100Y;
267
268 /* Now compute how many 4-year cycles precede it. */
269 n4 = n / DI4Y;
270 n = n % DI4Y;
271
272 /* And now how many single years. Again n1 can be 4, and again
273 * meaning that the desired day is December 31 at the end of the
274 * 4-year cycle.
275 */
276 n1 = n / 365;
277 n = n % 365;
278
279 *year += n100 * 100 + n4 * 4 + n1;
280 if (n1 == 4 || n100 == 4) {
281 assert(n == 0);
282 *year -= 1;
283 *month = 12;
284 *day = 31;
285 return;
286 }
287
288 /* Now the year is correct, and n is the offset from January 1. We
289 * find the month via an estimate that's either exact or one too
290 * large.
291 */
292 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
293 assert(leapyear == is_leap(*year));
294 *month = (n + 50) >> 5;
295 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
296 if (preceding > n) {
297 /* estimate is too large */
298 *month -= 1;
299 preceding -= days_in_month(*year, *month);
300 }
301 n -= preceding;
302 assert(0 <= n);
303 assert(n < days_in_month(*year, *month));
304
305 *day = n + 1;
306}
307
308/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
309static int
310ymd_to_ord(int year, int month, int day)
311{
312 return days_before_year(year) + days_before_month(year, month) + day;
313}
314
315/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
316static int
317weekday(int year, int month, int day)
318{
319 return (ymd_to_ord(year, month, day) + 6) % 7;
320}
321
322/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
323 * first calendar week containing a Thursday.
324 */
325static int
326iso_week1_monday(int year)
327{
328 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
329 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
330 int first_weekday = (first_day + 6) % 7;
331 /* ordinal of closest Monday at or before 1/1 */
332 int week1_monday = first_day - first_weekday;
333
334 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
335 week1_monday += 7;
336 return week1_monday;
337}
338
339/* ---------------------------------------------------------------------------
340 * Range checkers.
341 */
342
343/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
344 * If not, raise OverflowError and return -1.
345 */
346static int
347check_delta_day_range(int days)
348{
349 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
350 return 0;
351 PyErr_Format(PyExc_OverflowError,
352 "days=%d; must have magnitude <= %d",
Guido van Rossumbd43e912002-12-16 20:34:55 +0000353 days, MAX_DELTA_DAYS);
Tim Peters2a799bf2002-12-16 20:18:38 +0000354 return -1;
355}
356
357/* Check that date arguments are in range. Return 0 if they are. If they
358 * aren't, raise ValueError and return -1.
359 */
360static int
361check_date_args(int year, int month, int day)
362{
363
364 if (year < MINYEAR || year > MAXYEAR) {
365 PyErr_SetString(PyExc_ValueError,
366 "year is out of range");
367 return -1;
368 }
369 if (month < 1 || month > 12) {
370 PyErr_SetString(PyExc_ValueError,
371 "month must be in 1..12");
372 return -1;
373 }
374 if (day < 1 || day > days_in_month(year, month)) {
375 PyErr_SetString(PyExc_ValueError,
376 "day is out of range for month");
377 return -1;
378 }
379 return 0;
380}
381
382/* Check that time arguments are in range. Return 0 if they are. If they
383 * aren't, raise ValueError and return -1.
384 */
385static int
386check_time_args(int h, int m, int s, int us)
387{
388 if (h < 0 || h > 23) {
389 PyErr_SetString(PyExc_ValueError,
390 "hour must be in 0..23");
391 return -1;
392 }
393 if (m < 0 || m > 59) {
394 PyErr_SetString(PyExc_ValueError,
395 "minute must be in 0..59");
396 return -1;
397 }
398 if (s < 0 || s > 59) {
399 PyErr_SetString(PyExc_ValueError,
400 "second must be in 0..59");
401 return -1;
402 }
403 if (us < 0 || us > 999999) {
404 PyErr_SetString(PyExc_ValueError,
405 "microsecond must be in 0..999999");
406 return -1;
407 }
408 return 0;
409}
410
411/* ---------------------------------------------------------------------------
412 * Normalization utilities.
413 */
414
415/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
416 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
417 * at least factor, enough of *lo is converted into "hi" units so that
418 * 0 <= *lo < factor. The input values must be such that int overflow
419 * is impossible.
420 */
421static void
422normalize_pair(int *hi, int *lo, int factor)
423{
424 assert(factor > 0);
425 assert(lo != hi);
426 if (*lo < 0 || *lo >= factor) {
427 const int num_hi = divmod(*lo, factor, lo);
428 const int new_hi = *hi + num_hi;
429 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
430 *hi = new_hi;
431 }
432 assert(0 <= *lo && *lo < factor);
433}
434
435/* Fiddle days (d), seconds (s), and microseconds (us) so that
436 * 0 <= *s < 24*3600
437 * 0 <= *us < 1000000
438 * The input values must be such that the internals don't overflow.
439 * The way this routine is used, we don't get close.
440 */
441static void
442normalize_d_s_us(int *d, int *s, int *us)
443{
444 if (*us < 0 || *us >= 1000000) {
445 normalize_pair(s, us, 1000000);
446 /* |s| can't be bigger than about
447 * |original s| + |original us|/1000000 now.
448 */
449
450 }
451 if (*s < 0 || *s >= 24*3600) {
452 normalize_pair(d, s, 24*3600);
453 /* |d| can't be bigger than about
454 * |original d| +
455 * (|original s| + |original us|/1000000) / (24*3600) now.
456 */
457 }
458 assert(0 <= *s && *s < 24*3600);
459 assert(0 <= *us && *us < 1000000);
460}
461
462/* Fiddle years (y), months (m), and days (d) so that
463 * 1 <= *m <= 12
464 * 1 <= *d <= days_in_month(*y, *m)
465 * The input values must be such that the internals don't overflow.
466 * The way this routine is used, we don't get close.
467 */
468static void
469normalize_y_m_d(int *y, int *m, int *d)
470{
471 int dim; /* # of days in month */
472
473 /* This gets muddy: the proper range for day can't be determined
474 * without knowing the correct month and year, but if day is, e.g.,
475 * plus or minus a million, the current month and year values make
476 * no sense (and may also be out of bounds themselves).
477 * Saying 12 months == 1 year should be non-controversial.
478 */
479 if (*m < 1 || *m > 12) {
480 --*m;
481 normalize_pair(y, m, 12);
482 ++*m;
483 /* |y| can't be bigger than about
484 * |original y| + |original m|/12 now.
485 */
486 }
487 assert(1 <= *m && *m <= 12);
488
489 /* Now only day can be out of bounds (year may also be out of bounds
490 * for a datetime object, but we don't care about that here).
491 * If day is out of bounds, what to do is arguable, but at least the
492 * method here is principled and explainable.
493 */
494 dim = days_in_month(*y, *m);
495 if (*d < 1 || *d > dim) {
496 /* Move day-1 days from the first of the month. First try to
497 * get off cheap if we're only one day out of range
498 * (adjustments for timezone alone can't be worse than that).
499 */
500 if (*d == 0) {
501 --*m;
502 if (*m > 0)
503 *d = days_in_month(*y, *m);
504 else {
505 --*y;
506 *m = 12;
507 *d = 31;
508 }
509 }
510 else if (*d == dim + 1) {
511 /* move forward a day */
512 ++*m;
513 *d = 1;
514 if (*m > 12) {
515 *m = 1;
516 ++*y;
517 }
518 }
519 else {
520 int ordinal = ymd_to_ord(*y, *m, 1) +
521 *d - 1;
522 ord_to_ymd(ordinal, y, m, d);
523 }
524 }
525 assert(*m > 0);
526 assert(*d > 0);
527}
528
529/* Fiddle out-of-bounds months and days so that the result makes some kind
530 * of sense. The parameters are both inputs and outputs. Returns < 0 on
531 * failure, where failure means the adjusted year is out of bounds.
532 */
533static int
534normalize_date(int *year, int *month, int *day)
535{
536 int result;
537
538 normalize_y_m_d(year, month, day);
539 if (MINYEAR <= *year && *year <= MAXYEAR)
540 result = 0;
541 else {
542 PyErr_SetString(PyExc_OverflowError,
543 "date value out of range");
544 result = -1;
545 }
546 return result;
547}
548
549/* Force all the datetime fields into range. The parameters are both
550 * inputs and outputs. Returns < 0 on error.
551 */
552static int
553normalize_datetime(int *year, int *month, int *day,
554 int *hour, int *minute, int *second,
555 int *microsecond)
556{
557 normalize_pair(second, microsecond, 1000000);
558 normalize_pair(minute, second, 60);
559 normalize_pair(hour, minute, 60);
560 normalize_pair(day, hour, 24);
561 return normalize_date(year, month, day);
562}
563
564/* ---------------------------------------------------------------------------
565 * tzinfo helpers.
566 */
567
Tim Peters855fe882002-12-22 03:43:39 +0000568/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
569 * raise TypeError and return -1.
570 */
571static int
572check_tzinfo_subclass(PyObject *p)
573{
574 if (p == Py_None || PyTZInfo_Check(p))
575 return 0;
576 PyErr_Format(PyExc_TypeError,
577 "tzinfo argument must be None or of a tzinfo subclass, "
578 "not type '%s'",
579 p->ob_type->tp_name);
580 return -1;
581}
582
Tim Petersbad8ff02002-12-30 20:52:32 +0000583/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000584 * If tzinfo is None, returns None.
585 */
586static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000587call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000588{
589 PyObject *result;
590
Tim Petersbad8ff02002-12-30 20:52:32 +0000591 assert(tzinfo && methname && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000592 assert(check_tzinfo_subclass(tzinfo) >= 0);
593 if (tzinfo == Py_None) {
594 result = Py_None;
595 Py_INCREF(result);
596 }
597 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000598 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000599 return result;
600}
601
Tim Peters2a799bf2002-12-16 20:18:38 +0000602/* If self has a tzinfo member, return a BORROWED reference to it. Else
603 * return NULL, which is NOT AN ERROR. There are no error returns here,
604 * and the caller must not decref the result.
605 */
606static PyObject *
607get_tzinfo_member(PyObject *self)
608{
609 PyObject *tzinfo = NULL;
610
Tim Petersa9bc1682003-01-11 03:39:11 +0000611 if (PyDateTime_Check(self) && HASTZINFO(self))
612 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
Tim Petersa032d2e2003-01-11 00:15:54 +0000613 else if (PyTime_Check(self) && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +0000614 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000615
616 return tzinfo;
617}
618
Tim Petersbad8ff02002-12-30 20:52:32 +0000619/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000620 * result. tzinfo must be an instance of the tzinfo class. If the method
621 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000622 * return None or timedelta, TypeError is raised and this returns -1. If it
623 * returnsa timedelta and the value is out of range or isn't a whole number
624 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000625 * Else *none is set to 0 and the integer method result is returned.
626 */
627static int
628call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
629 int *none)
630{
631 PyObject *u;
Tim Peters397301e2003-01-02 21:28:08 +0000632 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000633
634 assert(tzinfo != NULL);
635 assert(PyTZInfo_Check(tzinfo));
636 assert(tzinfoarg != NULL);
637
638 *none = 0;
Tim Petersbad8ff02002-12-30 20:52:32 +0000639 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000640 if (u == NULL)
641 return -1;
642
Tim Peters27362852002-12-23 16:17:39 +0000643 else if (u == Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +0000644 result = 0;
645 *none = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000646 }
Tim Peters855fe882002-12-22 03:43:39 +0000647 else if (PyDelta_Check(u)) {
648 const int days = GET_TD_DAYS(u);
649 if (days < -1 || days > 0)
650 result = 24*60; /* trigger ValueError below */
651 else {
652 /* next line can't overflow because we know days
653 * is -1 or 0 now
654 */
655 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
656 result = divmod(ss, 60, &ss);
657 if (ss || GET_TD_MICROSECONDS(u)) {
658 PyErr_Format(PyExc_ValueError,
659 "tzinfo.%s() must return a "
660 "whole number of minutes",
661 name);
662 result = -1;
Tim Peters855fe882002-12-22 03:43:39 +0000663 }
664 }
665 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000666 else {
667 PyErr_Format(PyExc_TypeError,
Tim Peters397301e2003-01-02 21:28:08 +0000668 "tzinfo.%s() must return None or "
Tim Peters855fe882002-12-22 03:43:39 +0000669 "timedelta, not '%s'",
670 name, u->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000671 }
672
Tim Peters2a799bf2002-12-16 20:18:38 +0000673 Py_DECREF(u);
674 if (result < -1439 || result > 1439) {
675 PyErr_Format(PyExc_ValueError,
Neal Norwitz506a2242003-01-04 01:02:25 +0000676 "tzinfo.%s() returned %d; must be in "
Tim Peters2a799bf2002-12-16 20:18:38 +0000677 "-1439 .. 1439",
678 name, result);
679 result = -1;
680 }
Tim Peters397301e2003-01-02 21:28:08 +0000681 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000682}
683
684/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
685 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
686 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000687 * doesn't return None or timedelta, TypeError is raised and this returns -1.
688 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
689 * # of minutes), ValueError is raised and this returns -1. Else *none is
690 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000691 */
692static int
693call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
694{
695 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
696}
697
Tim Peters855fe882002-12-22 03:43:39 +0000698static PyObject *new_delta(int d, int sec, int usec, int normalize);
699
Tim Petersbad8ff02002-12-30 20:52:32 +0000700/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
701 */
Tim Peters855fe882002-12-22 03:43:39 +0000702static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000703offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Tim Peters855fe882002-12-22 03:43:39 +0000704 PyObject *result;
705
Tim Petersbad8ff02002-12-30 20:52:32 +0000706 assert(tzinfo && name && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000707 if (tzinfo == Py_None) {
708 result = Py_None;
709 Py_INCREF(result);
710 }
711 else {
712 int none;
Tim Petersbad8ff02002-12-30 20:52:32 +0000713 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
714 &none);
Tim Peters855fe882002-12-22 03:43:39 +0000715 if (offset < 0 && PyErr_Occurred())
716 return NULL;
717 if (none) {
718 result = Py_None;
719 Py_INCREF(result);
720 }
721 else
722 result = new_delta(0, offset * 60, 0, 1);
723 }
724 return result;
725}
726
Tim Peters2a799bf2002-12-16 20:18:38 +0000727/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
728 * result. tzinfo must be an instance of the tzinfo class. If dst()
729 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000730 & doesn't return None or timedelta, TypeError is raised and this
731 * returns -1. If dst() returns an invalid timedelta for for a UTC offset,
732 * ValueError is raised and this returns -1. Else *none is set to 0 and
733 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000734 */
735static int
736call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
737{
738 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
739}
740
Tim Petersbad8ff02002-12-30 20:52:32 +0000741/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000742 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000743 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000744 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000745 */
746static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000747call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000748{
749 PyObject *result;
750
751 assert(tzinfo != NULL);
Tim Peters855fe882002-12-22 03:43:39 +0000752 assert(check_tzinfo_subclass(tzinfo) >= 0);
Tim Petersbad8ff02002-12-30 20:52:32 +0000753 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000754
Tim Peters855fe882002-12-22 03:43:39 +0000755 if (tzinfo == Py_None) {
756 result = Py_None;
757 Py_INCREF(result);
758 }
759 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000760 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000761
762 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
763 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
Tim Peters2a799bf2002-12-16 20:18:38 +0000764 "return None or a string, not '%s'",
765 result->ob_type->tp_name);
766 Py_DECREF(result);
767 result = NULL;
768 }
769 return result;
770}
771
772typedef enum {
773 /* an exception has been set; the caller should pass it on */
774 OFFSET_ERROR,
775
Tim Petersa9bc1682003-01-11 03:39:11 +0000776 /* type isn't date, datetime, or time subclass */
Tim Peters2a799bf2002-12-16 20:18:38 +0000777 OFFSET_UNKNOWN,
778
779 /* date,
Tim Petersa9bc1682003-01-11 03:39:11 +0000780 * datetime with !hastzinfo
781 * datetime with None tzinfo,
782 * datetime where utcoffset() returns None
Tim Peters37f39822003-01-10 03:49:02 +0000783 * time with !hastzinfo
784 * time with None tzinfo,
785 * time where utcoffset() returns None
Tim Peters2a799bf2002-12-16 20:18:38 +0000786 */
787 OFFSET_NAIVE,
788
Tim Petersa9bc1682003-01-11 03:39:11 +0000789 /* time or datetime where utcoffset() doesn't return None */
Tim Peters2a799bf2002-12-16 20:18:38 +0000790 OFFSET_AWARE,
791} naivety;
792
Tim Peters14b69412002-12-22 18:10:22 +0000793/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000794 * the "naivety" typedef for details. If the type is aware, *offset is set
795 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000796 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000797 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000798 */
799static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000800classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000801{
802 int none;
803 PyObject *tzinfo;
804
Tim Peterse39a80c2002-12-30 21:28:52 +0000805 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000806 *offset = 0;
Tim Peters14b69412002-12-22 18:10:22 +0000807 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
Tim Peters2a799bf2002-12-16 20:18:38 +0000808 if (tzinfo == Py_None)
809 return OFFSET_NAIVE;
Tim Peters14b69412002-12-22 18:10:22 +0000810 if (tzinfo == NULL) {
811 /* note that a datetime passes the PyDate_Check test */
812 return (PyTime_Check(op) || PyDate_Check(op)) ?
813 OFFSET_NAIVE : OFFSET_UNKNOWN;
814 }
Tim Peterse39a80c2002-12-30 21:28:52 +0000815 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000816 if (*offset == -1 && PyErr_Occurred())
817 return OFFSET_ERROR;
818 return none ? OFFSET_NAIVE : OFFSET_AWARE;
819}
820
Tim Peters00237032002-12-27 02:21:51 +0000821/* Classify two objects as to whether they're naive or offset-aware.
822 * This isn't quite the same as calling classify_utcoffset() twice: for
823 * binary operations (comparison and subtraction), we generally want to
824 * ignore the tzinfo members if they're identical. This is by design,
825 * so that results match "naive" expectations when mixing objects from a
826 * single timezone. So in that case, this sets both offsets to 0 and
827 * both naiveties to OFFSET_NAIVE.
828 * The function returns 0 if everything's OK, and -1 on error.
829 */
830static int
831classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Tim Peterse39a80c2002-12-30 21:28:52 +0000832 PyObject *tzinfoarg1,
833 PyObject *o2, int *offset2, naivety *n2,
834 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +0000835{
836 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
837 *offset1 = *offset2 = 0;
838 *n1 = *n2 = OFFSET_NAIVE;
839 }
840 else {
Tim Peterse39a80c2002-12-30 21:28:52 +0000841 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
Tim Peters00237032002-12-27 02:21:51 +0000842 if (*n1 == OFFSET_ERROR)
843 return -1;
Tim Peterse39a80c2002-12-30 21:28:52 +0000844 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
Tim Peters00237032002-12-27 02:21:51 +0000845 if (*n2 == OFFSET_ERROR)
846 return -1;
847 }
848 return 0;
849}
850
Tim Peters2a799bf2002-12-16 20:18:38 +0000851/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
852 * stuff
853 * ", tzinfo=" + repr(tzinfo)
854 * before the closing ")".
855 */
856static PyObject *
857append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
858{
859 PyObject *temp;
860
861 assert(PyString_Check(repr));
862 assert(tzinfo);
863 if (tzinfo == Py_None)
864 return repr;
865 /* Get rid of the trailing ')'. */
866 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
867 temp = PyString_FromStringAndSize(PyString_AsString(repr),
868 PyString_Size(repr) - 1);
869 Py_DECREF(repr);
870 if (temp == NULL)
871 return NULL;
872 repr = temp;
873
874 /* Append ", tzinfo=". */
875 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
876
877 /* Append repr(tzinfo). */
878 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
879
880 /* Add a closing paren. */
881 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
882 return repr;
883}
884
885/* ---------------------------------------------------------------------------
886 * String format helpers.
887 */
888
889static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +0000890format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000891{
892 static char *DayNames[] = {
893 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
894 };
895 static char *MonthNames[] = {
896 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
897 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
898 };
899
900 char buffer[128];
901 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
902
903 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
904 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
905 GET_DAY(date), hours, minutes, seconds,
906 GET_YEAR(date));
907 return PyString_FromString(buffer);
908}
909
910/* Add an hours & minutes UTC offset string to buf. buf has no more than
911 * buflen bytes remaining. The UTC offset is gotten by calling
912 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
913 * *buf, and that's all. Else the returned value is checked for sanity (an
914 * integer in range), and if that's OK it's converted to an hours & minutes
915 * string of the form
916 * sign HH sep MM
917 * Returns 0 if everything is OK. If the return value from utcoffset() is
918 * bogus, an appropriate exception is set and -1 is returned.
919 */
920static int
Tim Peters328fff72002-12-20 01:31:27 +0000921format_utcoffset(char *buf, size_t buflen, const char *sep,
Tim Peters2a799bf2002-12-16 20:18:38 +0000922 PyObject *tzinfo, PyObject *tzinfoarg)
923{
924 int offset;
925 int hours;
926 int minutes;
927 char sign;
928 int none;
929
930 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
931 if (offset == -1 && PyErr_Occurred())
932 return -1;
933 if (none) {
934 *buf = '\0';
935 return 0;
936 }
937 sign = '+';
938 if (offset < 0) {
939 sign = '-';
940 offset = - offset;
941 }
942 hours = divmod(offset, 60, &minutes);
943 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
944 return 0;
945}
946
947/* I sure don't want to reproduce the strftime code from the time module,
948 * so this imports the module and calls it. All the hair is due to
949 * giving special meanings to the %z and %Z format codes via a preprocessing
950 * step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +0000951 * tzinfoarg is the argument to pass to the object's tzinfo method, if
952 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +0000953 */
954static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000955wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
956 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000957{
958 PyObject *result = NULL; /* guilty until proved innocent */
959
960 PyObject *zreplacement = NULL; /* py string, replacement for %z */
961 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
962
963 char *pin; /* pointer to next char in input format */
964 char ch; /* next char in input format */
965
966 PyObject *newfmt = NULL; /* py string, the output format */
967 char *pnew; /* pointer to available byte in output format */
968 char totalnew; /* number bytes total in output format buffer,
969 exclusive of trailing \0 */
970 char usednew; /* number bytes used so far in output format buffer */
971
972 char *ptoappend; /* pointer to string to append to output buffer */
973 int ntoappend; /* # of bytes to append to output buffer */
974
Tim Peters2a799bf2002-12-16 20:18:38 +0000975 assert(object && format && timetuple);
976 assert(PyString_Check(format));
977
Tim Petersd6844152002-12-22 20:58:42 +0000978 /* Give up if the year is before 1900.
979 * Python strftime() plays games with the year, and different
980 * games depending on whether envar PYTHON2K is set. This makes
981 * years before 1900 a nightmare, even if the platform strftime
982 * supports them (and not all do).
983 * We could get a lot farther here by avoiding Python's strftime
984 * wrapper and calling the C strftime() directly, but that isn't
985 * an option in the Python implementation of this module.
986 */
987 {
988 long year;
989 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
990 if (pyyear == NULL) return NULL;
991 assert(PyInt_Check(pyyear));
992 year = PyInt_AsLong(pyyear);
993 Py_DECREF(pyyear);
994 if (year < 1900) {
995 PyErr_Format(PyExc_ValueError, "year=%ld is before "
996 "1900; the datetime strftime() "
997 "methods require year >= 1900",
998 year);
999 return NULL;
1000 }
1001 }
1002
Tim Peters2a799bf2002-12-16 20:18:38 +00001003 /* Scan the input format, looking for %z and %Z escapes, building
Tim Peters328fff72002-12-20 01:31:27 +00001004 * a new format. Since computing the replacements for those codes
1005 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +00001006 */
1007 totalnew = PyString_Size(format); /* realistic if no %z/%Z */
1008 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1009 if (newfmt == NULL) goto Done;
1010 pnew = PyString_AsString(newfmt);
1011 usednew = 0;
1012
1013 pin = PyString_AsString(format);
1014 while ((ch = *pin++) != '\0') {
1015 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +00001016 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001017 ntoappend = 1;
1018 }
1019 else if ((ch = *pin++) == '\0') {
1020 /* There's a lone trailing %; doesn't make sense. */
1021 PyErr_SetString(PyExc_ValueError, "strftime format "
1022 "ends with raw %");
1023 goto Done;
1024 }
1025 /* A % has been seen and ch is the character after it. */
1026 else if (ch == 'z') {
1027 if (zreplacement == NULL) {
1028 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +00001029 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +00001030 PyObject *tzinfo = get_tzinfo_member(object);
1031 zreplacement = PyString_FromString("");
1032 if (zreplacement == NULL) goto Done;
1033 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001034 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001035 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001036 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001037 "",
1038 tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00001039 tzinfoarg) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001040 goto Done;
1041 Py_DECREF(zreplacement);
1042 zreplacement = PyString_FromString(buf);
1043 if (zreplacement == NULL) goto Done;
1044 }
1045 }
1046 assert(zreplacement != NULL);
1047 ptoappend = PyString_AsString(zreplacement);
1048 ntoappend = PyString_Size(zreplacement);
1049 }
1050 else if (ch == 'Z') {
1051 /* format tzname */
1052 if (Zreplacement == NULL) {
1053 PyObject *tzinfo = get_tzinfo_member(object);
1054 Zreplacement = PyString_FromString("");
1055 if (Zreplacement == NULL) goto Done;
1056 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001057 PyObject *temp;
1058 assert(tzinfoarg != NULL);
1059 temp = call_tzname(tzinfo, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001060 if (temp == NULL) goto Done;
1061 if (temp != Py_None) {
1062 assert(PyString_Check(temp));
1063 /* Since the tzname is getting
1064 * stuffed into the format, we
1065 * have to double any % signs
1066 * so that strftime doesn't
1067 * treat them as format codes.
1068 */
1069 Py_DECREF(Zreplacement);
1070 Zreplacement = PyObject_CallMethod(
1071 temp, "replace",
1072 "ss", "%", "%%");
1073 Py_DECREF(temp);
1074 if (Zreplacement == NULL)
1075 goto Done;
1076 }
1077 else
1078 Py_DECREF(temp);
1079 }
1080 }
1081 assert(Zreplacement != NULL);
1082 ptoappend = PyString_AsString(Zreplacement);
1083 ntoappend = PyString_Size(Zreplacement);
1084 }
1085 else {
Tim Peters328fff72002-12-20 01:31:27 +00001086 /* percent followed by neither z nor Z */
1087 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001088 ntoappend = 2;
1089 }
1090
1091 /* Append the ntoappend chars starting at ptoappend to
1092 * the new format.
1093 */
1094 assert(ntoappend >= 0);
1095 if (ntoappend == 0)
1096 continue;
1097 while (usednew + ntoappend > totalnew) {
1098 int bigger = totalnew << 1;
1099 if ((bigger >> 1) != totalnew) { /* overflow */
1100 PyErr_NoMemory();
1101 goto Done;
1102 }
1103 if (_PyString_Resize(&newfmt, bigger) < 0)
1104 goto Done;
1105 totalnew = bigger;
1106 pnew = PyString_AsString(newfmt) + usednew;
1107 }
1108 memcpy(pnew, ptoappend, ntoappend);
1109 pnew += ntoappend;
1110 usednew += ntoappend;
1111 assert(usednew <= totalnew);
1112 } /* end while() */
1113
1114 if (_PyString_Resize(&newfmt, usednew) < 0)
1115 goto Done;
1116 {
1117 PyObject *time = PyImport_ImportModule("time");
1118 if (time == NULL)
1119 goto Done;
1120 result = PyObject_CallMethod(time, "strftime", "OO",
1121 newfmt, timetuple);
1122 Py_DECREF(time);
1123 }
1124 Done:
1125 Py_XDECREF(zreplacement);
1126 Py_XDECREF(Zreplacement);
1127 Py_XDECREF(newfmt);
1128 return result;
1129}
1130
1131static char *
1132isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1133{
1134 int x;
1135 x = PyOS_snprintf(buffer, bufflen,
1136 "%04d-%02d-%02d",
1137 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1138 return buffer + x;
1139}
1140
1141static void
1142isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1143{
1144 int us = DATE_GET_MICROSECOND(dt);
1145
1146 PyOS_snprintf(buffer, bufflen,
1147 "%02d:%02d:%02d", /* 8 characters */
1148 DATE_GET_HOUR(dt),
1149 DATE_GET_MINUTE(dt),
1150 DATE_GET_SECOND(dt));
1151 if (us)
1152 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1153}
1154
1155/* ---------------------------------------------------------------------------
1156 * Wrap functions from the time module. These aren't directly available
1157 * from C. Perhaps they should be.
1158 */
1159
1160/* Call time.time() and return its result (a Python float). */
1161static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001162time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001163{
1164 PyObject *result = NULL;
1165 PyObject *time = PyImport_ImportModule("time");
1166
1167 if (time != NULL) {
1168 result = PyObject_CallMethod(time, "time", "()");
1169 Py_DECREF(time);
1170 }
1171 return result;
1172}
1173
1174/* Build a time.struct_time. The weekday and day number are automatically
1175 * computed from the y,m,d args.
1176 */
1177static PyObject *
1178build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1179{
1180 PyObject *time;
1181 PyObject *result = NULL;
1182
1183 time = PyImport_ImportModule("time");
1184 if (time != NULL) {
1185 result = PyObject_CallMethod(time, "struct_time",
1186 "((iiiiiiiii))",
1187 y, m, d,
1188 hh, mm, ss,
1189 weekday(y, m, d),
1190 days_before_month(y, m) + d,
1191 dstflag);
1192 Py_DECREF(time);
1193 }
1194 return result;
1195}
1196
1197/* ---------------------------------------------------------------------------
1198 * Miscellaneous helpers.
1199 */
1200
1201/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1202 * The comparisons here all most naturally compute a cmp()-like result.
1203 * This little helper turns that into a bool result for rich comparisons.
1204 */
1205static PyObject *
1206diff_to_bool(int diff, int op)
1207{
1208 PyObject *result;
1209 int istrue;
1210
1211 switch (op) {
1212 case Py_EQ: istrue = diff == 0; break;
1213 case Py_NE: istrue = diff != 0; break;
1214 case Py_LE: istrue = diff <= 0; break;
1215 case Py_GE: istrue = diff >= 0; break;
1216 case Py_LT: istrue = diff < 0; break;
1217 case Py_GT: istrue = diff > 0; break;
1218 default:
1219 assert(! "op unknown");
1220 istrue = 0; /* To shut up compiler */
1221 }
1222 result = istrue ? Py_True : Py_False;
1223 Py_INCREF(result);
1224 return result;
1225}
1226
1227/* ---------------------------------------------------------------------------
Tim Peters70533e22003-02-01 04:40:04 +00001228 * Basic object allocation. These allocate Python objects of the right
1229 * size and type, and do the Python object-initialization bit. If there's
1230 * not enough memory, they return NULL after setting MemoryError. All
1231 * data members remain uninitialized trash.
1232 */
1233static PyDateTime_Time *
1234alloc_time(int aware)
1235{
1236 PyDateTime_Time *self;
1237
1238 self = (PyDateTime_Time *)
1239 PyObject_MALLOC(aware ?
1240 sizeof(PyDateTime_Time) :
1241 sizeof(_PyDateTime_BaseTime));
1242 if (self == NULL)
1243 return (PyDateTime_Time *)PyErr_NoMemory();
1244 PyObject_INIT(self, &PyDateTime_TimeType);
1245 return self;
1246}
1247
1248static PyDateTime_DateTime *
1249alloc_datetime(int aware)
1250{
1251 PyDateTime_DateTime *self;
1252
1253 self = (PyDateTime_DateTime *)
1254 PyObject_MALLOC(aware ?
1255 sizeof(PyDateTime_DateTime) :
1256 sizeof(_PyDateTime_BaseDateTime));
1257 if (self == NULL)
1258 return (PyDateTime_DateTime *)PyErr_NoMemory();
1259 PyObject_INIT(self, &PyDateTime_DateTimeType);
1260 return self;
1261}
1262
1263/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001264 * Helpers for setting object fields. These work on pointers to the
1265 * appropriate base class.
1266 */
1267
Tim Petersa9bc1682003-01-11 03:39:11 +00001268/* For date and datetime. */
Tim Peters2a799bf2002-12-16 20:18:38 +00001269static void
1270set_date_fields(PyDateTime_Date *self, int y, int m, int d)
1271{
1272 self->hashcode = -1;
1273 SET_YEAR(self, y);
1274 SET_MONTH(self, m);
1275 SET_DAY(self, d);
1276}
1277
Tim Peters2a799bf2002-12-16 20:18:38 +00001278/* ---------------------------------------------------------------------------
1279 * Create various objects, mostly without range checking.
1280 */
1281
1282/* Create a date instance with no range checking. */
1283static PyObject *
1284new_date(int year, int month, int day)
1285{
1286 PyDateTime_Date *self;
1287
1288 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
1289 if (self != NULL)
1290 set_date_fields(self, year, month, day);
1291 return (PyObject *) self;
1292}
1293
1294/* Create a datetime instance with no range checking. */
1295static PyObject *
1296new_datetime(int year, int month, int day, int hour, int minute,
Tim Petersa9bc1682003-01-11 03:39:11 +00001297 int second, int usecond, PyObject *tzinfo)
Tim Peters2a799bf2002-12-16 20:18:38 +00001298{
1299 PyDateTime_DateTime *self;
Tim Petersa9bc1682003-01-11 03:39:11 +00001300 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001301
Tim Peters70533e22003-02-01 04:40:04 +00001302 self = alloc_datetime(aware);
1303 if (self != NULL) {
1304 self->hastzinfo = aware;
1305 set_date_fields((PyDateTime_Date *)self, year, month, day);
1306 DATE_SET_HOUR(self, hour);
1307 DATE_SET_MINUTE(self, minute);
1308 DATE_SET_SECOND(self, second);
1309 DATE_SET_MICROSECOND(self, usecond);
1310 if (aware) {
1311 Py_INCREF(tzinfo);
1312 self->tzinfo = tzinfo;
1313 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001314 }
Tim Peters70533e22003-02-01 04:40:04 +00001315 return (PyObject *)self;
Tim Peters2a799bf2002-12-16 20:18:38 +00001316}
1317
1318/* Create a time instance with no range checking. */
1319static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00001320new_time(int hour, int minute, int second, int usecond, PyObject *tzinfo)
Tim Peters2a799bf2002-12-16 20:18:38 +00001321{
1322 PyDateTime_Time *self;
Tim Peters37f39822003-01-10 03:49:02 +00001323 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001324
Tim Peters70533e22003-02-01 04:40:04 +00001325 self = alloc_time(aware);
1326 if (self != NULL) {
1327 self->hastzinfo = aware;
1328 self->hashcode = -1;
1329 TIME_SET_HOUR(self, hour);
1330 TIME_SET_MINUTE(self, minute);
1331 TIME_SET_SECOND(self, second);
1332 TIME_SET_MICROSECOND(self, usecond);
1333 if (aware) {
1334 Py_INCREF(tzinfo);
1335 self->tzinfo = tzinfo;
1336 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001337 }
Tim Peters70533e22003-02-01 04:40:04 +00001338 return (PyObject *)self;
Tim Peters2a799bf2002-12-16 20:18:38 +00001339}
1340
1341/* Create a timedelta instance. Normalize the members iff normalize is
1342 * true. Passing false is a speed optimization, if you know for sure
1343 * that seconds and microseconds are already in their proper ranges. In any
1344 * case, raises OverflowError and returns NULL if the normalized days is out
1345 * of range).
1346 */
1347static PyObject *
1348new_delta(int days, int seconds, int microseconds, int normalize)
1349{
1350 PyDateTime_Delta *self;
1351
1352 if (normalize)
1353 normalize_d_s_us(&days, &seconds, &microseconds);
1354 assert(0 <= seconds && seconds < 24*3600);
1355 assert(0 <= microseconds && microseconds < 1000000);
1356
1357 if (check_delta_day_range(days) < 0)
1358 return NULL;
1359
1360 self = PyObject_New(PyDateTime_Delta, &PyDateTime_DeltaType);
1361 if (self != NULL) {
1362 self->hashcode = -1;
1363 SET_TD_DAYS(self, days);
1364 SET_TD_SECONDS(self, seconds);
1365 SET_TD_MICROSECONDS(self, microseconds);
1366 }
1367 return (PyObject *) self;
1368}
1369
1370
1371/* ---------------------------------------------------------------------------
1372 * Cached Python objects; these are set by the module init function.
1373 */
1374
1375/* Conversion factors. */
1376static PyObject *us_per_us = NULL; /* 1 */
1377static PyObject *us_per_ms = NULL; /* 1000 */
1378static PyObject *us_per_second = NULL; /* 1000000 */
1379static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1380static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1381static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1382static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1383static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1384
Tim Peters2a799bf2002-12-16 20:18:38 +00001385/* ---------------------------------------------------------------------------
1386 * Class implementations.
1387 */
1388
1389/*
1390 * PyDateTime_Delta implementation.
1391 */
1392
1393/* Convert a timedelta to a number of us,
1394 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1395 * as a Python int or long.
1396 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1397 * due to ubiquitous overflow possibilities.
1398 */
1399static PyObject *
1400delta_to_microseconds(PyDateTime_Delta *self)
1401{
1402 PyObject *x1 = NULL;
1403 PyObject *x2 = NULL;
1404 PyObject *x3 = NULL;
1405 PyObject *result = NULL;
1406
1407 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1408 if (x1 == NULL)
1409 goto Done;
1410 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1411 if (x2 == NULL)
1412 goto Done;
1413 Py_DECREF(x1);
1414 x1 = NULL;
1415
1416 /* x2 has days in seconds */
1417 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1418 if (x1 == NULL)
1419 goto Done;
1420 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1421 if (x3 == NULL)
1422 goto Done;
1423 Py_DECREF(x1);
1424 Py_DECREF(x2);
1425 x1 = x2 = NULL;
1426
1427 /* x3 has days+seconds in seconds */
1428 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1429 if (x1 == NULL)
1430 goto Done;
1431 Py_DECREF(x3);
1432 x3 = NULL;
1433
1434 /* x1 has days+seconds in us */
1435 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1436 if (x2 == NULL)
1437 goto Done;
1438 result = PyNumber_Add(x1, x2);
1439
1440Done:
1441 Py_XDECREF(x1);
1442 Py_XDECREF(x2);
1443 Py_XDECREF(x3);
1444 return result;
1445}
1446
1447/* Convert a number of us (as a Python int or long) to a timedelta.
1448 */
1449static PyObject *
1450microseconds_to_delta(PyObject *pyus)
1451{
1452 int us;
1453 int s;
1454 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001455 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001456
1457 PyObject *tuple = NULL;
1458 PyObject *num = NULL;
1459 PyObject *result = NULL;
1460
1461 tuple = PyNumber_Divmod(pyus, us_per_second);
1462 if (tuple == NULL)
1463 goto Done;
1464
1465 num = PyTuple_GetItem(tuple, 1); /* us */
1466 if (num == NULL)
1467 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001468 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001469 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001470 if (temp == -1 && PyErr_Occurred())
1471 goto Done;
1472 assert(0 <= temp && temp < 1000000);
1473 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001474 if (us < 0) {
1475 /* The divisor was positive, so this must be an error. */
1476 assert(PyErr_Occurred());
1477 goto Done;
1478 }
1479
1480 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1481 if (num == NULL)
1482 goto Done;
1483 Py_INCREF(num);
1484 Py_DECREF(tuple);
1485
1486 tuple = PyNumber_Divmod(num, seconds_per_day);
1487 if (tuple == NULL)
1488 goto Done;
1489 Py_DECREF(num);
1490
1491 num = PyTuple_GetItem(tuple, 1); /* seconds */
1492 if (num == NULL)
1493 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001494 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001495 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001496 if (temp == -1 && PyErr_Occurred())
1497 goto Done;
1498 assert(0 <= temp && temp < 24*3600);
1499 s = (int)temp;
1500
Tim Peters2a799bf2002-12-16 20:18:38 +00001501 if (s < 0) {
1502 /* The divisor was positive, so this must be an error. */
1503 assert(PyErr_Occurred());
1504 goto Done;
1505 }
1506
1507 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1508 if (num == NULL)
1509 goto Done;
1510 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001511 temp = PyLong_AsLong(num);
1512 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001513 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001514 d = (int)temp;
1515 if ((long)d != temp) {
1516 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1517 "large to fit in a C int");
1518 goto Done;
1519 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001520 result = new_delta(d, s, us, 0);
1521
1522Done:
1523 Py_XDECREF(tuple);
1524 Py_XDECREF(num);
1525 return result;
1526}
1527
1528static PyObject *
1529multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1530{
1531 PyObject *pyus_in;
1532 PyObject *pyus_out;
1533 PyObject *result;
1534
1535 pyus_in = delta_to_microseconds(delta);
1536 if (pyus_in == NULL)
1537 return NULL;
1538
1539 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1540 Py_DECREF(pyus_in);
1541 if (pyus_out == NULL)
1542 return NULL;
1543
1544 result = microseconds_to_delta(pyus_out);
1545 Py_DECREF(pyus_out);
1546 return result;
1547}
1548
1549static PyObject *
1550divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1551{
1552 PyObject *pyus_in;
1553 PyObject *pyus_out;
1554 PyObject *result;
1555
1556 pyus_in = delta_to_microseconds(delta);
1557 if (pyus_in == NULL)
1558 return NULL;
1559
1560 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1561 Py_DECREF(pyus_in);
1562 if (pyus_out == NULL)
1563 return NULL;
1564
1565 result = microseconds_to_delta(pyus_out);
1566 Py_DECREF(pyus_out);
1567 return result;
1568}
1569
1570static PyObject *
1571delta_add(PyObject *left, PyObject *right)
1572{
1573 PyObject *result = Py_NotImplemented;
1574
1575 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1576 /* delta + delta */
1577 /* The C-level additions can't overflow because of the
1578 * invariant bounds.
1579 */
1580 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1581 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1582 int microseconds = GET_TD_MICROSECONDS(left) +
1583 GET_TD_MICROSECONDS(right);
1584 result = new_delta(days, seconds, microseconds, 1);
1585 }
1586
1587 if (result == Py_NotImplemented)
1588 Py_INCREF(result);
1589 return result;
1590}
1591
1592static PyObject *
1593delta_negative(PyDateTime_Delta *self)
1594{
1595 return new_delta(-GET_TD_DAYS(self),
1596 -GET_TD_SECONDS(self),
1597 -GET_TD_MICROSECONDS(self),
1598 1);
1599}
1600
1601static PyObject *
1602delta_positive(PyDateTime_Delta *self)
1603{
1604 /* Could optimize this (by returning self) if this isn't a
1605 * subclass -- but who uses unary + ? Approximately nobody.
1606 */
1607 return new_delta(GET_TD_DAYS(self),
1608 GET_TD_SECONDS(self),
1609 GET_TD_MICROSECONDS(self),
1610 0);
1611}
1612
1613static PyObject *
1614delta_abs(PyDateTime_Delta *self)
1615{
1616 PyObject *result;
1617
1618 assert(GET_TD_MICROSECONDS(self) >= 0);
1619 assert(GET_TD_SECONDS(self) >= 0);
1620
1621 if (GET_TD_DAYS(self) < 0)
1622 result = delta_negative(self);
1623 else
1624 result = delta_positive(self);
1625
1626 return result;
1627}
1628
1629static PyObject *
1630delta_subtract(PyObject *left, PyObject *right)
1631{
1632 PyObject *result = Py_NotImplemented;
1633
1634 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1635 /* delta - delta */
1636 PyObject *minus_right = PyNumber_Negative(right);
1637 if (minus_right) {
1638 result = delta_add(left, minus_right);
1639 Py_DECREF(minus_right);
1640 }
1641 else
1642 result = NULL;
1643 }
1644
1645 if (result == Py_NotImplemented)
1646 Py_INCREF(result);
1647 return result;
1648}
1649
1650/* This is more natural as a tp_compare, but doesn't work then: for whatever
1651 * reason, Python's try_3way_compare ignores tp_compare unless
1652 * PyInstance_Check returns true, but these aren't old-style classes.
1653 */
1654static PyObject *
1655delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1656{
1657 int diff;
1658
1659 if (! PyDelta_CheckExact(other)) {
1660 PyErr_Format(PyExc_TypeError,
1661 "can't compare %s to %s instance",
1662 self->ob_type->tp_name, other->ob_type->tp_name);
1663 return NULL;
1664 }
1665 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1666 if (diff == 0) {
1667 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1668 if (diff == 0)
1669 diff = GET_TD_MICROSECONDS(self) -
1670 GET_TD_MICROSECONDS(other);
1671 }
1672 return diff_to_bool(diff, op);
1673}
1674
1675static PyObject *delta_getstate(PyDateTime_Delta *self);
1676
1677static long
1678delta_hash(PyDateTime_Delta *self)
1679{
1680 if (self->hashcode == -1) {
1681 PyObject *temp = delta_getstate(self);
1682 if (temp != NULL) {
1683 self->hashcode = PyObject_Hash(temp);
1684 Py_DECREF(temp);
1685 }
1686 }
1687 return self->hashcode;
1688}
1689
1690static PyObject *
1691delta_multiply(PyObject *left, PyObject *right)
1692{
1693 PyObject *result = Py_NotImplemented;
1694
1695 if (PyDelta_Check(left)) {
1696 /* delta * ??? */
1697 if (PyInt_Check(right) || PyLong_Check(right))
1698 result = multiply_int_timedelta(right,
1699 (PyDateTime_Delta *) left);
1700 }
1701 else if (PyInt_Check(left) || PyLong_Check(left))
1702 result = multiply_int_timedelta(left,
1703 (PyDateTime_Delta *) right);
1704
1705 if (result == Py_NotImplemented)
1706 Py_INCREF(result);
1707 return result;
1708}
1709
1710static PyObject *
1711delta_divide(PyObject *left, PyObject *right)
1712{
1713 PyObject *result = Py_NotImplemented;
1714
1715 if (PyDelta_Check(left)) {
1716 /* delta * ??? */
1717 if (PyInt_Check(right) || PyLong_Check(right))
1718 result = divide_timedelta_int(
1719 (PyDateTime_Delta *)left,
1720 right);
1721 }
1722
1723 if (result == Py_NotImplemented)
1724 Py_INCREF(result);
1725 return result;
1726}
1727
1728/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1729 * timedelta constructor. sofar is the # of microseconds accounted for
1730 * so far, and there are factor microseconds per current unit, the number
1731 * of which is given by num. num * factor is added to sofar in a
1732 * numerically careful way, and that's the result. Any fractional
1733 * microseconds left over (this can happen if num is a float type) are
1734 * added into *leftover.
1735 * Note that there are many ways this can give an error (NULL) return.
1736 */
1737static PyObject *
1738accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1739 double *leftover)
1740{
1741 PyObject *prod;
1742 PyObject *sum;
1743
1744 assert(num != NULL);
1745
1746 if (PyInt_Check(num) || PyLong_Check(num)) {
1747 prod = PyNumber_Multiply(num, factor);
1748 if (prod == NULL)
1749 return NULL;
1750 sum = PyNumber_Add(sofar, prod);
1751 Py_DECREF(prod);
1752 return sum;
1753 }
1754
1755 if (PyFloat_Check(num)) {
1756 double dnum;
1757 double fracpart;
1758 double intpart;
1759 PyObject *x;
1760 PyObject *y;
1761
1762 /* The Plan: decompose num into an integer part and a
1763 * fractional part, num = intpart + fracpart.
1764 * Then num * factor ==
1765 * intpart * factor + fracpart * factor
1766 * and the LHS can be computed exactly in long arithmetic.
1767 * The RHS is again broken into an int part and frac part.
1768 * and the frac part is added into *leftover.
1769 */
1770 dnum = PyFloat_AsDouble(num);
1771 if (dnum == -1.0 && PyErr_Occurred())
1772 return NULL;
1773 fracpart = modf(dnum, &intpart);
1774 x = PyLong_FromDouble(intpart);
1775 if (x == NULL)
1776 return NULL;
1777
1778 prod = PyNumber_Multiply(x, factor);
1779 Py_DECREF(x);
1780 if (prod == NULL)
1781 return NULL;
1782
1783 sum = PyNumber_Add(sofar, prod);
1784 Py_DECREF(prod);
1785 if (sum == NULL)
1786 return NULL;
1787
1788 if (fracpart == 0.0)
1789 return sum;
1790 /* So far we've lost no information. Dealing with the
1791 * fractional part requires float arithmetic, and may
1792 * lose a little info.
1793 */
1794 assert(PyInt_Check(factor) || PyLong_Check(factor));
1795 if (PyInt_Check(factor))
1796 dnum = (double)PyInt_AsLong(factor);
1797 else
1798 dnum = PyLong_AsDouble(factor);
1799
1800 dnum *= fracpart;
1801 fracpart = modf(dnum, &intpart);
1802 x = PyLong_FromDouble(intpart);
1803 if (x == NULL) {
1804 Py_DECREF(sum);
1805 return NULL;
1806 }
1807
1808 y = PyNumber_Add(sum, x);
1809 Py_DECREF(sum);
1810 Py_DECREF(x);
1811 *leftover += fracpart;
1812 return y;
1813 }
1814
1815 PyErr_Format(PyExc_TypeError,
1816 "unsupported type for timedelta %s component: %s",
1817 tag, num->ob_type->tp_name);
1818 return NULL;
1819}
1820
1821static PyObject *
1822delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1823{
1824 PyObject *self = NULL;
1825
1826 /* Argument objects. */
1827 PyObject *day = NULL;
1828 PyObject *second = NULL;
1829 PyObject *us = NULL;
1830 PyObject *ms = NULL;
1831 PyObject *minute = NULL;
1832 PyObject *hour = NULL;
1833 PyObject *week = NULL;
1834
1835 PyObject *x = NULL; /* running sum of microseconds */
1836 PyObject *y = NULL; /* temp sum of microseconds */
1837 double leftover_us = 0.0;
1838
1839 static char *keywords[] = {
1840 "days", "seconds", "microseconds", "milliseconds",
1841 "minutes", "hours", "weeks", NULL
1842 };
1843
1844 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1845 keywords,
1846 &day, &second, &us,
1847 &ms, &minute, &hour, &week) == 0)
1848 goto Done;
1849
1850 x = PyInt_FromLong(0);
1851 if (x == NULL)
1852 goto Done;
1853
1854#define CLEANUP \
1855 Py_DECREF(x); \
1856 x = y; \
1857 if (x == NULL) \
1858 goto Done
1859
1860 if (us) {
1861 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1862 CLEANUP;
1863 }
1864 if (ms) {
1865 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1866 CLEANUP;
1867 }
1868 if (second) {
1869 y = accum("seconds", x, second, us_per_second, &leftover_us);
1870 CLEANUP;
1871 }
1872 if (minute) {
1873 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1874 CLEANUP;
1875 }
1876 if (hour) {
1877 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1878 CLEANUP;
1879 }
1880 if (day) {
1881 y = accum("days", x, day, us_per_day, &leftover_us);
1882 CLEANUP;
1883 }
1884 if (week) {
1885 y = accum("weeks", x, week, us_per_week, &leftover_us);
1886 CLEANUP;
1887 }
1888 if (leftover_us) {
1889 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001890 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001891 if (temp == NULL) {
1892 Py_DECREF(x);
1893 goto Done;
1894 }
1895 y = PyNumber_Add(x, temp);
1896 Py_DECREF(temp);
1897 CLEANUP;
1898 }
1899
1900 self = microseconds_to_delta(x);
1901 Py_DECREF(x);
1902Done:
1903 return self;
1904
1905#undef CLEANUP
1906}
1907
1908static int
1909delta_nonzero(PyDateTime_Delta *self)
1910{
1911 return (GET_TD_DAYS(self) != 0
1912 || GET_TD_SECONDS(self) != 0
1913 || GET_TD_MICROSECONDS(self) != 0);
1914}
1915
1916static PyObject *
1917delta_repr(PyDateTime_Delta *self)
1918{
1919 if (GET_TD_MICROSECONDS(self) != 0)
1920 return PyString_FromFormat("%s(%d, %d, %d)",
1921 self->ob_type->tp_name,
1922 GET_TD_DAYS(self),
1923 GET_TD_SECONDS(self),
1924 GET_TD_MICROSECONDS(self));
1925 if (GET_TD_SECONDS(self) != 0)
1926 return PyString_FromFormat("%s(%d, %d)",
1927 self->ob_type->tp_name,
1928 GET_TD_DAYS(self),
1929 GET_TD_SECONDS(self));
1930
1931 return PyString_FromFormat("%s(%d)",
1932 self->ob_type->tp_name,
1933 GET_TD_DAYS(self));
1934}
1935
1936static PyObject *
1937delta_str(PyDateTime_Delta *self)
1938{
1939 int days = GET_TD_DAYS(self);
1940 int seconds = GET_TD_SECONDS(self);
1941 int us = GET_TD_MICROSECONDS(self);
1942 int hours;
1943 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001944 char buf[100];
1945 char *pbuf = buf;
1946 size_t buflen = sizeof(buf);
1947 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001948
1949 minutes = divmod(seconds, 60, &seconds);
1950 hours = divmod(minutes, 60, &minutes);
1951
1952 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00001953 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
1954 (days == 1 || days == -1) ? "" : "s");
1955 if (n < 0 || (size_t)n >= buflen)
1956 goto Fail;
1957 pbuf += n;
1958 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001959 }
1960
Tim Petersba873472002-12-18 20:19:21 +00001961 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
1962 hours, minutes, seconds);
1963 if (n < 0 || (size_t)n >= buflen)
1964 goto Fail;
1965 pbuf += n;
1966 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001967
1968 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00001969 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
1970 if (n < 0 || (size_t)n >= buflen)
1971 goto Fail;
1972 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001973 }
1974
Tim Petersba873472002-12-18 20:19:21 +00001975 return PyString_FromStringAndSize(buf, pbuf - buf);
1976
1977 Fail:
1978 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
1979 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001980}
1981
Tim Peters371935f2003-02-01 01:52:50 +00001982/* Pickle support, a simple use of __reduce__. */
1983
Tim Petersb57f8f02003-02-01 02:54:15 +00001984/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00001985static PyObject *
1986delta_getstate(PyDateTime_Delta *self)
1987{
1988 return Py_BuildValue("iii", GET_TD_DAYS(self),
1989 GET_TD_SECONDS(self),
1990 GET_TD_MICROSECONDS(self));
1991}
1992
Tim Peters2a799bf2002-12-16 20:18:38 +00001993static PyObject *
1994delta_reduce(PyDateTime_Delta* self)
1995{
Tim Peters8a60c222003-02-01 01:47:29 +00001996 return Py_BuildValue("ON", self->ob_type, delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00001997}
1998
1999#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2000
2001static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002002
Neal Norwitzdfb80862002-12-19 02:30:56 +00002003 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002004 PyDoc_STR("Number of days.")},
2005
Neal Norwitzdfb80862002-12-19 02:30:56 +00002006 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002007 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2008
Neal Norwitzdfb80862002-12-19 02:30:56 +00002009 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002010 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2011 {NULL}
2012};
2013
2014static PyMethodDef delta_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002015 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2016 PyDoc_STR("__reduce__() -> (cls, state)")},
2017
Tim Peters2a799bf2002-12-16 20:18:38 +00002018 {NULL, NULL},
2019};
2020
2021static char delta_doc[] =
2022PyDoc_STR("Difference between two datetime values.");
2023
2024static PyNumberMethods delta_as_number = {
2025 delta_add, /* nb_add */
2026 delta_subtract, /* nb_subtract */
2027 delta_multiply, /* nb_multiply */
2028 delta_divide, /* nb_divide */
2029 0, /* nb_remainder */
2030 0, /* nb_divmod */
2031 0, /* nb_power */
2032 (unaryfunc)delta_negative, /* nb_negative */
2033 (unaryfunc)delta_positive, /* nb_positive */
2034 (unaryfunc)delta_abs, /* nb_absolute */
2035 (inquiry)delta_nonzero, /* nb_nonzero */
2036 0, /*nb_invert*/
2037 0, /*nb_lshift*/
2038 0, /*nb_rshift*/
2039 0, /*nb_and*/
2040 0, /*nb_xor*/
2041 0, /*nb_or*/
2042 0, /*nb_coerce*/
2043 0, /*nb_int*/
2044 0, /*nb_long*/
2045 0, /*nb_float*/
2046 0, /*nb_oct*/
2047 0, /*nb_hex*/
2048 0, /*nb_inplace_add*/
2049 0, /*nb_inplace_subtract*/
2050 0, /*nb_inplace_multiply*/
2051 0, /*nb_inplace_divide*/
2052 0, /*nb_inplace_remainder*/
2053 0, /*nb_inplace_power*/
2054 0, /*nb_inplace_lshift*/
2055 0, /*nb_inplace_rshift*/
2056 0, /*nb_inplace_and*/
2057 0, /*nb_inplace_xor*/
2058 0, /*nb_inplace_or*/
2059 delta_divide, /* nb_floor_divide */
2060 0, /* nb_true_divide */
2061 0, /* nb_inplace_floor_divide */
2062 0, /* nb_inplace_true_divide */
2063};
2064
2065static PyTypeObject PyDateTime_DeltaType = {
2066 PyObject_HEAD_INIT(NULL)
2067 0, /* ob_size */
2068 "datetime.timedelta", /* tp_name */
2069 sizeof(PyDateTime_Delta), /* tp_basicsize */
2070 0, /* tp_itemsize */
2071 0, /* tp_dealloc */
2072 0, /* tp_print */
2073 0, /* tp_getattr */
2074 0, /* tp_setattr */
2075 0, /* tp_compare */
2076 (reprfunc)delta_repr, /* tp_repr */
2077 &delta_as_number, /* tp_as_number */
2078 0, /* tp_as_sequence */
2079 0, /* tp_as_mapping */
2080 (hashfunc)delta_hash, /* tp_hash */
2081 0, /* tp_call */
2082 (reprfunc)delta_str, /* tp_str */
2083 PyObject_GenericGetAttr, /* tp_getattro */
2084 0, /* tp_setattro */
2085 0, /* tp_as_buffer */
2086 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
2087 delta_doc, /* tp_doc */
2088 0, /* tp_traverse */
2089 0, /* tp_clear */
2090 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2091 0, /* tp_weaklistoffset */
2092 0, /* tp_iter */
2093 0, /* tp_iternext */
2094 delta_methods, /* tp_methods */
2095 delta_members, /* tp_members */
2096 0, /* tp_getset */
2097 0, /* tp_base */
2098 0, /* tp_dict */
2099 0, /* tp_descr_get */
2100 0, /* tp_descr_set */
2101 0, /* tp_dictoffset */
2102 0, /* tp_init */
2103 0, /* tp_alloc */
2104 delta_new, /* tp_new */
2105 _PyObject_Del, /* tp_free */
2106};
2107
2108/*
2109 * PyDateTime_Date implementation.
2110 */
2111
2112/* Accessor properties. */
2113
2114static PyObject *
2115date_year(PyDateTime_Date *self, void *unused)
2116{
2117 return PyInt_FromLong(GET_YEAR(self));
2118}
2119
2120static PyObject *
2121date_month(PyDateTime_Date *self, void *unused)
2122{
2123 return PyInt_FromLong(GET_MONTH(self));
2124}
2125
2126static PyObject *
2127date_day(PyDateTime_Date *self, void *unused)
2128{
2129 return PyInt_FromLong(GET_DAY(self));
2130}
2131
2132static PyGetSetDef date_getset[] = {
2133 {"year", (getter)date_year},
2134 {"month", (getter)date_month},
2135 {"day", (getter)date_day},
2136 {NULL}
2137};
2138
2139/* Constructors. */
2140
Tim Peters12bf3392002-12-24 05:41:27 +00002141static char *date_kws[] = {"year", "month", "day", NULL};
2142
Tim Peters2a799bf2002-12-16 20:18:38 +00002143static PyObject *
2144date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2145{
2146 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002147 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002148 int year;
2149 int month;
2150 int day;
2151
Guido van Rossum177e41a2003-01-30 22:06:23 +00002152 /* Check for invocation from pickle with __getstate__ state */
2153 if (PyTuple_GET_SIZE(args) == 1 &&
Tim Peters70533e22003-02-01 04:40:04 +00002154 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2155 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00002156 {
Tim Peters70533e22003-02-01 04:40:04 +00002157 PyDateTime_Date *me;
2158
2159 me = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
2160 if (me != NULL) {
2161 char *pdata = PyString_AS_STRING(state);
2162 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2163 me->hashcode = -1;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002164 }
Tim Peters70533e22003-02-01 04:40:04 +00002165 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002166 }
2167
Tim Peters12bf3392002-12-24 05:41:27 +00002168 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002169 &year, &month, &day)) {
2170 if (check_date_args(year, month, day) < 0)
2171 return NULL;
2172 self = new_date(year, month, day);
2173 }
2174 return self;
2175}
2176
2177/* Return new date from localtime(t). */
2178static PyObject *
2179date_local_from_time_t(PyObject *cls, time_t t)
2180{
2181 struct tm *tm;
2182 PyObject *result = NULL;
2183
2184 tm = localtime(&t);
2185 if (tm)
2186 result = PyObject_CallFunction(cls, "iii",
2187 tm->tm_year + 1900,
2188 tm->tm_mon + 1,
2189 tm->tm_mday);
2190 else
2191 PyErr_SetString(PyExc_ValueError,
2192 "timestamp out of range for "
2193 "platform localtime() function");
2194 return result;
2195}
2196
2197/* Return new date from current time.
2198 * We say this is equivalent to fromtimestamp(time.time()), and the
2199 * only way to be sure of that is to *call* time.time(). That's not
2200 * generally the same as calling C's time.
2201 */
2202static PyObject *
2203date_today(PyObject *cls, PyObject *dummy)
2204{
2205 PyObject *time;
2206 PyObject *result;
2207
2208 time = time_time();
2209 if (time == NULL)
2210 return NULL;
2211
2212 /* Note well: today() is a class method, so this may not call
2213 * date.fromtimestamp. For example, it may call
2214 * datetime.fromtimestamp. That's why we need all the accuracy
2215 * time.time() delivers; if someone were gonzo about optimization,
2216 * date.today() could get away with plain C time().
2217 */
2218 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2219 Py_DECREF(time);
2220 return result;
2221}
2222
2223/* Return new date from given timestamp (Python timestamp -- a double). */
2224static PyObject *
2225date_fromtimestamp(PyObject *cls, PyObject *args)
2226{
2227 double timestamp;
2228 PyObject *result = NULL;
2229
2230 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2231 result = date_local_from_time_t(cls, (time_t)timestamp);
2232 return result;
2233}
2234
2235/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2236 * the ordinal is out of range.
2237 */
2238static PyObject *
2239date_fromordinal(PyObject *cls, PyObject *args)
2240{
2241 PyObject *result = NULL;
2242 int ordinal;
2243
2244 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2245 int year;
2246 int month;
2247 int day;
2248
2249 if (ordinal < 1)
2250 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2251 ">= 1");
2252 else {
2253 ord_to_ymd(ordinal, &year, &month, &day);
2254 result = PyObject_CallFunction(cls, "iii",
2255 year, month, day);
2256 }
2257 }
2258 return result;
2259}
2260
2261/*
2262 * Date arithmetic.
2263 */
2264
2265/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2266 * instead.
2267 */
2268static PyObject *
2269add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2270{
2271 PyObject *result = NULL;
2272 int year = GET_YEAR(date);
2273 int month = GET_MONTH(date);
2274 int deltadays = GET_TD_DAYS(delta);
2275 /* C-level overflow is impossible because |deltadays| < 1e9. */
2276 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2277
2278 if (normalize_date(&year, &month, &day) >= 0)
2279 result = new_date(year, month, day);
2280 return result;
2281}
2282
2283static PyObject *
2284date_add(PyObject *left, PyObject *right)
2285{
2286 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2287 Py_INCREF(Py_NotImplemented);
2288 return Py_NotImplemented;
2289 }
2290 if (PyDate_CheckExact(left)) {
2291 /* date + ??? */
2292 if (PyDelta_Check(right))
2293 /* date + delta */
2294 return add_date_timedelta((PyDateTime_Date *) left,
2295 (PyDateTime_Delta *) right,
2296 0);
2297 }
2298 else {
2299 /* ??? + date
2300 * 'right' must be one of us, or we wouldn't have been called
2301 */
2302 if (PyDelta_Check(left))
2303 /* delta + date */
2304 return add_date_timedelta((PyDateTime_Date *) right,
2305 (PyDateTime_Delta *) left,
2306 0);
2307 }
2308 Py_INCREF(Py_NotImplemented);
2309 return Py_NotImplemented;
2310}
2311
2312static PyObject *
2313date_subtract(PyObject *left, PyObject *right)
2314{
2315 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2316 Py_INCREF(Py_NotImplemented);
2317 return Py_NotImplemented;
2318 }
2319 if (PyDate_CheckExact(left)) {
2320 if (PyDate_CheckExact(right)) {
2321 /* date - date */
2322 int left_ord = ymd_to_ord(GET_YEAR(left),
2323 GET_MONTH(left),
2324 GET_DAY(left));
2325 int right_ord = ymd_to_ord(GET_YEAR(right),
2326 GET_MONTH(right),
2327 GET_DAY(right));
2328 return new_delta(left_ord - right_ord, 0, 0, 0);
2329 }
2330 if (PyDelta_Check(right)) {
2331 /* date - delta */
2332 return add_date_timedelta((PyDateTime_Date *) left,
2333 (PyDateTime_Delta *) right,
2334 1);
2335 }
2336 }
2337 Py_INCREF(Py_NotImplemented);
2338 return Py_NotImplemented;
2339}
2340
2341
2342/* Various ways to turn a date into a string. */
2343
2344static PyObject *
2345date_repr(PyDateTime_Date *self)
2346{
2347 char buffer[1028];
2348 char *typename;
2349
2350 typename = self->ob_type->tp_name;
2351 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2352 typename,
2353 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2354
2355 return PyString_FromString(buffer);
2356}
2357
2358static PyObject *
2359date_isoformat(PyDateTime_Date *self)
2360{
2361 char buffer[128];
2362
2363 isoformat_date(self, buffer, sizeof(buffer));
2364 return PyString_FromString(buffer);
2365}
2366
2367/* str() calls the appropriate isofomat() method. */
2368static PyObject *
2369date_str(PyDateTime_Date *self)
2370{
2371 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2372}
2373
2374
2375static PyObject *
2376date_ctime(PyDateTime_Date *self)
2377{
2378 return format_ctime(self, 0, 0, 0);
2379}
2380
2381static PyObject *
2382date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2383{
2384 /* This method can be inherited, and needs to call the
2385 * timetuple() method appropriate to self's class.
2386 */
2387 PyObject *result;
2388 PyObject *format;
2389 PyObject *tuple;
2390 static char *keywords[] = {"format", NULL};
2391
2392 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2393 &PyString_Type, &format))
2394 return NULL;
2395
2396 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2397 if (tuple == NULL)
2398 return NULL;
Tim Petersbad8ff02002-12-30 20:52:32 +00002399 result = wrap_strftime((PyObject *)self, format, tuple,
2400 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002401 Py_DECREF(tuple);
2402 return result;
2403}
2404
2405/* ISO methods. */
2406
2407static PyObject *
2408date_isoweekday(PyDateTime_Date *self)
2409{
2410 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2411
2412 return PyInt_FromLong(dow + 1);
2413}
2414
2415static PyObject *
2416date_isocalendar(PyDateTime_Date *self)
2417{
2418 int year = GET_YEAR(self);
2419 int week1_monday = iso_week1_monday(year);
2420 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2421 int week;
2422 int day;
2423
2424 week = divmod(today - week1_monday, 7, &day);
2425 if (week < 0) {
2426 --year;
2427 week1_monday = iso_week1_monday(year);
2428 week = divmod(today - week1_monday, 7, &day);
2429 }
2430 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2431 ++year;
2432 week = 0;
2433 }
2434 return Py_BuildValue("iii", year, week + 1, day + 1);
2435}
2436
2437/* Miscellaneous methods. */
2438
2439/* This is more natural as a tp_compare, but doesn't work then: for whatever
2440 * reason, Python's try_3way_compare ignores tp_compare unless
2441 * PyInstance_Check returns true, but these aren't old-style classes.
2442 */
2443static PyObject *
2444date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2445{
2446 int diff;
2447
2448 if (! PyDate_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00002449 if (PyObject_HasAttrString(other, "timetuple")) {
2450 /* A hook for other kinds of date objects. */
2451 Py_INCREF(Py_NotImplemented);
2452 return Py_NotImplemented;
2453 }
2454 /* Stop this from falling back to address comparison. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002455 PyErr_Format(PyExc_TypeError,
Tim Peters8d81a012003-01-24 22:36:34 +00002456 "can't compare '%s' to '%s'",
2457 self->ob_type->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002458 other->ob_type->tp_name);
2459 return NULL;
2460 }
2461 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2462 _PyDateTime_DATE_DATASIZE);
2463 return diff_to_bool(diff, op);
2464}
2465
2466static PyObject *
2467date_timetuple(PyDateTime_Date *self)
2468{
2469 return build_struct_time(GET_YEAR(self),
2470 GET_MONTH(self),
2471 GET_DAY(self),
2472 0, 0, 0, -1);
2473}
2474
Tim Peters12bf3392002-12-24 05:41:27 +00002475static PyObject *
2476date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2477{
2478 PyObject *clone;
2479 PyObject *tuple;
2480 int year = GET_YEAR(self);
2481 int month = GET_MONTH(self);
2482 int day = GET_DAY(self);
2483
2484 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2485 &year, &month, &day))
2486 return NULL;
2487 tuple = Py_BuildValue("iii", year, month, day);
2488 if (tuple == NULL)
2489 return NULL;
2490 clone = date_new(self->ob_type, tuple, NULL);
2491 Py_DECREF(tuple);
2492 return clone;
2493}
2494
Tim Peters2a799bf2002-12-16 20:18:38 +00002495static PyObject *date_getstate(PyDateTime_Date *self);
2496
2497static long
2498date_hash(PyDateTime_Date *self)
2499{
2500 if (self->hashcode == -1) {
2501 PyObject *temp = date_getstate(self);
2502 if (temp != NULL) {
2503 self->hashcode = PyObject_Hash(temp);
2504 Py_DECREF(temp);
2505 }
2506 }
2507 return self->hashcode;
2508}
2509
2510static PyObject *
2511date_toordinal(PyDateTime_Date *self)
2512{
2513 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2514 GET_DAY(self)));
2515}
2516
2517static PyObject *
2518date_weekday(PyDateTime_Date *self)
2519{
2520 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2521
2522 return PyInt_FromLong(dow);
2523}
2524
Tim Peters371935f2003-02-01 01:52:50 +00002525/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002526
Tim Petersb57f8f02003-02-01 02:54:15 +00002527/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002528static PyObject *
2529date_getstate(PyDateTime_Date *self)
2530{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002531 return Py_BuildValue(
2532 "(N)",
2533 PyString_FromStringAndSize((char *)self->data,
2534 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002535}
2536
2537static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002538date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002539{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002540 return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002541}
2542
2543static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002544
Tim Peters2a799bf2002-12-16 20:18:38 +00002545 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002546
Tim Peters2a799bf2002-12-16 20:18:38 +00002547 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2548 METH_CLASS,
2549 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2550 "time.time()).")},
2551
2552 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2553 METH_CLASS,
2554 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2555 "ordinal.")},
2556
2557 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2558 PyDoc_STR("Current date or datetime: same as "
2559 "self.__class__.fromtimestamp(time.time()).")},
2560
2561 /* Instance methods: */
2562
2563 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2564 PyDoc_STR("Return ctime() style string.")},
2565
2566 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2567 PyDoc_STR("format -> strftime() style string.")},
2568
2569 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2570 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2571
2572 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2573 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2574 "weekday.")},
2575
2576 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2577 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2578
2579 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2580 PyDoc_STR("Return the day of the week represented by the date.\n"
2581 "Monday == 1 ... Sunday == 7")},
2582
2583 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2584 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2585 "1 is day 1.")},
2586
2587 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2588 PyDoc_STR("Return the day of the week represented by the date.\n"
2589 "Monday == 0 ... Sunday == 6")},
2590
Tim Peters12bf3392002-12-24 05:41:27 +00002591 {"replace", (PyCFunction)date_replace, METH_KEYWORDS,
2592 PyDoc_STR("Return date with new specified fields.")},
2593
Guido van Rossum177e41a2003-01-30 22:06:23 +00002594 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2595 PyDoc_STR("__reduce__() -> (cls, state)")},
2596
Tim Peters2a799bf2002-12-16 20:18:38 +00002597 {NULL, NULL}
2598};
2599
2600static char date_doc[] =
2601PyDoc_STR("Basic date type.");
2602
2603static PyNumberMethods date_as_number = {
2604 date_add, /* nb_add */
2605 date_subtract, /* nb_subtract */
2606 0, /* nb_multiply */
2607 0, /* nb_divide */
2608 0, /* nb_remainder */
2609 0, /* nb_divmod */
2610 0, /* nb_power */
2611 0, /* nb_negative */
2612 0, /* nb_positive */
2613 0, /* nb_absolute */
2614 0, /* nb_nonzero */
2615};
2616
2617static PyTypeObject PyDateTime_DateType = {
2618 PyObject_HEAD_INIT(NULL)
2619 0, /* ob_size */
2620 "datetime.date", /* tp_name */
2621 sizeof(PyDateTime_Date), /* tp_basicsize */
2622 0, /* tp_itemsize */
2623 (destructor)PyObject_Del, /* tp_dealloc */
2624 0, /* tp_print */
2625 0, /* tp_getattr */
2626 0, /* tp_setattr */
2627 0, /* tp_compare */
2628 (reprfunc)date_repr, /* tp_repr */
2629 &date_as_number, /* tp_as_number */
2630 0, /* tp_as_sequence */
2631 0, /* tp_as_mapping */
2632 (hashfunc)date_hash, /* tp_hash */
2633 0, /* tp_call */
2634 (reprfunc)date_str, /* tp_str */
2635 PyObject_GenericGetAttr, /* tp_getattro */
2636 0, /* tp_setattro */
2637 0, /* tp_as_buffer */
2638 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2639 Py_TPFLAGS_BASETYPE, /* tp_flags */
2640 date_doc, /* tp_doc */
2641 0, /* tp_traverse */
2642 0, /* tp_clear */
2643 (richcmpfunc)date_richcompare, /* tp_richcompare */
2644 0, /* tp_weaklistoffset */
2645 0, /* tp_iter */
2646 0, /* tp_iternext */
2647 date_methods, /* tp_methods */
2648 0, /* tp_members */
2649 date_getset, /* tp_getset */
2650 0, /* tp_base */
2651 0, /* tp_dict */
2652 0, /* tp_descr_get */
2653 0, /* tp_descr_set */
2654 0, /* tp_dictoffset */
2655 0, /* tp_init */
2656 0, /* tp_alloc */
2657 date_new, /* tp_new */
2658 _PyObject_Del, /* tp_free */
2659};
2660
2661/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002662 * PyDateTime_TZInfo implementation.
2663 */
2664
2665/* This is a pure abstract base class, so doesn't do anything beyond
2666 * raising NotImplemented exceptions. Real tzinfo classes need
2667 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002668 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002669 * be subclasses of this tzinfo class, which is easy and quick to check).
2670 *
2671 * Note: For reasons having to do with pickling of subclasses, we have
2672 * to allow tzinfo objects to be instantiated. This wasn't an issue
2673 * in the Python implementation (__init__() could raise NotImplementedError
2674 * there without ill effect), but doing so in the C implementation hit a
2675 * brick wall.
2676 */
2677
2678static PyObject *
2679tzinfo_nogo(const char* methodname)
2680{
2681 PyErr_Format(PyExc_NotImplementedError,
2682 "a tzinfo subclass must implement %s()",
2683 methodname);
2684 return NULL;
2685}
2686
2687/* Methods. A subclass must implement these. */
2688
Tim Peters52dcce22003-01-23 16:36:11 +00002689static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002690tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2691{
2692 return tzinfo_nogo("tzname");
2693}
2694
Tim Peters52dcce22003-01-23 16:36:11 +00002695static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002696tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2697{
2698 return tzinfo_nogo("utcoffset");
2699}
2700
Tim Peters52dcce22003-01-23 16:36:11 +00002701static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002702tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2703{
2704 return tzinfo_nogo("dst");
2705}
2706
Tim Peters52dcce22003-01-23 16:36:11 +00002707static PyObject *
2708tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2709{
2710 int y, m, d, hh, mm, ss, us;
2711
2712 PyObject *result;
2713 int off, dst;
2714 int none;
2715 int delta;
2716
2717 if (! PyDateTime_Check(dt)) {
2718 PyErr_SetString(PyExc_TypeError,
2719 "fromutc: argument must be a datetime");
2720 return NULL;
2721 }
2722 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2723 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2724 "is not self");
2725 return NULL;
2726 }
2727
2728 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2729 if (off == -1 && PyErr_Occurred())
2730 return NULL;
2731 if (none) {
2732 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2733 "utcoffset() result required");
2734 return NULL;
2735 }
2736
2737 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2738 if (dst == -1 && PyErr_Occurred())
2739 return NULL;
2740 if (none) {
2741 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2742 "dst() result required");
2743 return NULL;
2744 }
2745
2746 y = GET_YEAR(dt);
2747 m = GET_MONTH(dt);
2748 d = GET_DAY(dt);
2749 hh = DATE_GET_HOUR(dt);
2750 mm = DATE_GET_MINUTE(dt);
2751 ss = DATE_GET_SECOND(dt);
2752 us = DATE_GET_MICROSECOND(dt);
2753
2754 delta = off - dst;
2755 mm += delta;
2756 if ((mm < 0 || mm >= 60) &&
2757 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002758 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002759 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2760 if (result == NULL)
2761 return result;
2762
2763 dst = call_dst(dt->tzinfo, result, &none);
2764 if (dst == -1 && PyErr_Occurred())
2765 goto Fail;
2766 if (none)
2767 goto Inconsistent;
2768 if (dst == 0)
2769 return result;
2770
2771 mm += dst;
2772 if ((mm < 0 || mm >= 60) &&
2773 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2774 goto Fail;
2775 Py_DECREF(result);
2776 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2777 return result;
2778
2779Inconsistent:
2780 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2781 "inconsistent results; cannot convert");
2782
2783 /* fall thru to failure */
2784Fail:
2785 Py_DECREF(result);
2786 return NULL;
2787}
2788
Tim Peters2a799bf2002-12-16 20:18:38 +00002789/*
2790 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002791 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002792 */
2793
Guido van Rossum177e41a2003-01-30 22:06:23 +00002794static PyObject *
2795tzinfo_reduce(PyObject *self)
2796{
2797 PyObject *args, *state, *tmp;
2798 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002799
Guido van Rossum177e41a2003-01-30 22:06:23 +00002800 tmp = PyTuple_New(0);
2801 if (tmp == NULL)
2802 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002803
Guido van Rossum177e41a2003-01-30 22:06:23 +00002804 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2805 if (getinitargs != NULL) {
2806 args = PyObject_CallObject(getinitargs, tmp);
2807 Py_DECREF(getinitargs);
2808 if (args == NULL) {
2809 Py_DECREF(tmp);
2810 return NULL;
2811 }
2812 }
2813 else {
2814 PyErr_Clear();
2815 args = tmp;
2816 Py_INCREF(args);
2817 }
2818
2819 getstate = PyObject_GetAttrString(self, "__getstate__");
2820 if (getstate != NULL) {
2821 state = PyObject_CallObject(getstate, tmp);
2822 Py_DECREF(getstate);
2823 if (state == NULL) {
2824 Py_DECREF(args);
2825 Py_DECREF(tmp);
2826 return NULL;
2827 }
2828 }
2829 else {
2830 PyObject **dictptr;
2831 PyErr_Clear();
2832 state = Py_None;
2833 dictptr = _PyObject_GetDictPtr(self);
2834 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2835 state = *dictptr;
2836 Py_INCREF(state);
2837 }
2838
2839 Py_DECREF(tmp);
2840
2841 if (state == Py_None) {
2842 Py_DECREF(state);
2843 return Py_BuildValue("(ON)", self->ob_type, args);
2844 }
2845 else
2846 return Py_BuildValue("(ONN)", self->ob_type, args, state);
2847}
Tim Peters2a799bf2002-12-16 20:18:38 +00002848
2849static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002850
Tim Peters2a799bf2002-12-16 20:18:38 +00002851 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2852 PyDoc_STR("datetime -> string name of time zone.")},
2853
2854 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2855 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2856 "west of UTC).")},
2857
2858 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2859 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2860
Tim Peters52dcce22003-01-23 16:36:11 +00002861 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2862 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2863
Guido van Rossum177e41a2003-01-30 22:06:23 +00002864 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2865 PyDoc_STR("-> (cls, state)")},
2866
Tim Peters2a799bf2002-12-16 20:18:38 +00002867 {NULL, NULL}
2868};
2869
2870static char tzinfo_doc[] =
2871PyDoc_STR("Abstract base class for time zone info objects.");
2872
Neal Norwitzce3d34d2003-02-04 20:45:17 +00002873statichere PyTypeObject PyDateTime_TZInfoType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00002874 PyObject_HEAD_INIT(NULL)
2875 0, /* ob_size */
2876 "datetime.tzinfo", /* tp_name */
2877 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2878 0, /* tp_itemsize */
2879 0, /* tp_dealloc */
2880 0, /* tp_print */
2881 0, /* tp_getattr */
2882 0, /* tp_setattr */
2883 0, /* tp_compare */
2884 0, /* tp_repr */
2885 0, /* tp_as_number */
2886 0, /* tp_as_sequence */
2887 0, /* tp_as_mapping */
2888 0, /* tp_hash */
2889 0, /* tp_call */
2890 0, /* tp_str */
2891 PyObject_GenericGetAttr, /* tp_getattro */
2892 0, /* tp_setattro */
2893 0, /* tp_as_buffer */
2894 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2895 Py_TPFLAGS_BASETYPE, /* tp_flags */
2896 tzinfo_doc, /* tp_doc */
2897 0, /* tp_traverse */
2898 0, /* tp_clear */
2899 0, /* tp_richcompare */
2900 0, /* tp_weaklistoffset */
2901 0, /* tp_iter */
2902 0, /* tp_iternext */
2903 tzinfo_methods, /* tp_methods */
2904 0, /* tp_members */
2905 0, /* tp_getset */
2906 0, /* tp_base */
2907 0, /* tp_dict */
2908 0, /* tp_descr_get */
2909 0, /* tp_descr_set */
2910 0, /* tp_dictoffset */
2911 0, /* tp_init */
2912 0, /* tp_alloc */
2913 PyType_GenericNew, /* tp_new */
2914 0, /* tp_free */
2915};
2916
2917/*
Tim Peters37f39822003-01-10 03:49:02 +00002918 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00002919 */
2920
Tim Peters37f39822003-01-10 03:49:02 +00002921/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00002922 */
2923
2924static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002925time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00002926{
Tim Peters37f39822003-01-10 03:49:02 +00002927 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002928}
2929
Tim Peters37f39822003-01-10 03:49:02 +00002930static PyObject *
2931time_minute(PyDateTime_Time *self, void *unused)
2932{
2933 return PyInt_FromLong(TIME_GET_MINUTE(self));
2934}
2935
2936/* The name time_second conflicted with some platform header file. */
2937static PyObject *
2938py_time_second(PyDateTime_Time *self, void *unused)
2939{
2940 return PyInt_FromLong(TIME_GET_SECOND(self));
2941}
2942
2943static PyObject *
2944time_microsecond(PyDateTime_Time *self, void *unused)
2945{
2946 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
2947}
2948
2949static PyObject *
2950time_tzinfo(PyDateTime_Time *self, void *unused)
2951{
Tim Petersa032d2e2003-01-11 00:15:54 +00002952 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00002953 Py_INCREF(result);
2954 return result;
2955}
2956
2957static PyGetSetDef time_getset[] = {
2958 {"hour", (getter)time_hour},
2959 {"minute", (getter)time_minute},
2960 {"second", (getter)py_time_second},
2961 {"microsecond", (getter)time_microsecond},
2962 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00002963 {NULL}
2964};
2965
2966/*
2967 * Constructors.
2968 */
2969
Tim Peters37f39822003-01-10 03:49:02 +00002970static char *time_kws[] = {"hour", "minute", "second", "microsecond",
2971 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002972
Tim Peters2a799bf2002-12-16 20:18:38 +00002973static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002974time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00002975{
2976 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002977 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002978 int hour = 0;
2979 int minute = 0;
2980 int second = 0;
2981 int usecond = 0;
2982 PyObject *tzinfo = Py_None;
2983
Guido van Rossum177e41a2003-01-30 22:06:23 +00002984 /* Check for invocation from pickle with __getstate__ state */
2985 if (PyTuple_GET_SIZE(args) >= 1 &&
2986 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00002987 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2988 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00002989 {
Tim Peters70533e22003-02-01 04:40:04 +00002990 PyDateTime_Time *me;
2991 char aware;
2992
2993 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002994 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00002995 if (check_tzinfo_subclass(tzinfo) < 0) {
2996 PyErr_SetString(PyExc_TypeError, "bad "
2997 "tzinfo state arg");
2998 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002999 }
3000 }
Tim Peters70533e22003-02-01 04:40:04 +00003001 aware = (char)(tzinfo != Py_None);
3002 me = alloc_time(aware);
3003 if (me != NULL) {
3004 char *pdata = PyString_AS_STRING(state);
3005
3006 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3007 me->hashcode = -1;
3008 me->hastzinfo = aware;
3009 if (aware) {
3010 Py_INCREF(tzinfo);
3011 me->tzinfo = tzinfo;
3012 }
3013 }
3014 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003015 }
3016
Tim Peters37f39822003-01-10 03:49:02 +00003017 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003018 &hour, &minute, &second, &usecond,
3019 &tzinfo)) {
3020 if (check_time_args(hour, minute, second, usecond) < 0)
3021 return NULL;
3022 if (check_tzinfo_subclass(tzinfo) < 0)
3023 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003024 self = new_time(hour, minute, second, usecond, tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003025 }
3026 return self;
3027}
3028
3029/*
3030 * Destructor.
3031 */
3032
3033static void
Tim Peters37f39822003-01-10 03:49:02 +00003034time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003035{
Tim Petersa032d2e2003-01-11 00:15:54 +00003036 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003037 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003038 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003039 self->ob_type->tp_free((PyObject *)self);
3040}
3041
3042/*
Tim Peters855fe882002-12-22 03:43:39 +00003043 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003044 */
3045
Tim Peters2a799bf2002-12-16 20:18:38 +00003046/* These are all METH_NOARGS, so don't need to check the arglist. */
3047static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003048time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003049 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003050 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003051}
3052
3053static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003054time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003055 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003056 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003057}
3058
3059static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003060time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003061 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003062 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003063}
3064
3065/*
Tim Peters37f39822003-01-10 03:49:02 +00003066 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003067 */
3068
3069static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003070time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003071{
Tim Peters37f39822003-01-10 03:49:02 +00003072 char buffer[100];
3073 char *typename = self->ob_type->tp_name;
3074 int h = TIME_GET_HOUR(self);
3075 int m = TIME_GET_MINUTE(self);
3076 int s = TIME_GET_SECOND(self);
3077 int us = TIME_GET_MICROSECOND(self);
3078 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003079
Tim Peters37f39822003-01-10 03:49:02 +00003080 if (us)
3081 PyOS_snprintf(buffer, sizeof(buffer),
3082 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3083 else if (s)
3084 PyOS_snprintf(buffer, sizeof(buffer),
3085 "%s(%d, %d, %d)", typename, h, m, s);
3086 else
3087 PyOS_snprintf(buffer, sizeof(buffer),
3088 "%s(%d, %d)", typename, h, m);
3089 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003090 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003091 result = append_keyword_tzinfo(result, self->tzinfo);
3092 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003093}
3094
Tim Peters37f39822003-01-10 03:49:02 +00003095static PyObject *
3096time_str(PyDateTime_Time *self)
3097{
3098 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3099}
Tim Peters2a799bf2002-12-16 20:18:38 +00003100
3101static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003102time_isoformat(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003103{
3104 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003105 PyObject *result;
3106 /* Reuse the time format code from the datetime type. */
3107 PyDateTime_DateTime datetime;
3108 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003109
Tim Peters37f39822003-01-10 03:49:02 +00003110 /* Copy over just the time bytes. */
3111 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3112 self->data,
3113 _PyDateTime_TIME_DATASIZE);
3114
3115 isoformat_time(pdatetime, buf, sizeof(buf));
3116 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003117 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003118 return result;
3119
3120 /* We need to append the UTC offset. */
3121 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003122 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003123 Py_DECREF(result);
3124 return NULL;
3125 }
3126 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3127 return result;
3128}
3129
Tim Peters37f39822003-01-10 03:49:02 +00003130static PyObject *
3131time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3132{
3133 PyObject *result;
3134 PyObject *format;
3135 PyObject *tuple;
3136 static char *keywords[] = {"format", NULL};
3137
3138 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3139 &PyString_Type, &format))
3140 return NULL;
3141
3142 /* Python's strftime does insane things with the year part of the
3143 * timetuple. The year is forced to (the otherwise nonsensical)
3144 * 1900 to worm around that.
3145 */
3146 tuple = Py_BuildValue("iiiiiiiii",
3147 1900, 0, 0, /* year, month, day */
3148 TIME_GET_HOUR(self),
3149 TIME_GET_MINUTE(self),
3150 TIME_GET_SECOND(self),
3151 0, 0, -1); /* weekday, daynum, dst */
3152 if (tuple == NULL)
3153 return NULL;
3154 assert(PyTuple_Size(tuple) == 9);
3155 result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
3156 Py_DECREF(tuple);
3157 return result;
3158}
Tim Peters2a799bf2002-12-16 20:18:38 +00003159
3160/*
3161 * Miscellaneous methods.
3162 */
3163
Tim Peters37f39822003-01-10 03:49:02 +00003164/* This is more natural as a tp_compare, but doesn't work then: for whatever
3165 * reason, Python's try_3way_compare ignores tp_compare unless
3166 * PyInstance_Check returns true, but these aren't old-style classes.
3167 */
3168static PyObject *
3169time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3170{
3171 int diff;
3172 naivety n1, n2;
3173 int offset1, offset2;
3174
3175 if (! PyTime_Check(other)) {
3176 /* Stop this from falling back to address comparison. */
3177 PyErr_Format(PyExc_TypeError,
3178 "can't compare '%s' to '%s'",
3179 self->ob_type->tp_name,
3180 other->ob_type->tp_name);
3181 return NULL;
3182 }
3183 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3184 other, &offset2, &n2, Py_None) < 0)
3185 return NULL;
3186 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3187 /* If they're both naive, or both aware and have the same offsets,
3188 * we get off cheap. Note that if they're both naive, offset1 ==
3189 * offset2 == 0 at this point.
3190 */
3191 if (n1 == n2 && offset1 == offset2) {
3192 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3193 _PyDateTime_TIME_DATASIZE);
3194 return diff_to_bool(diff, op);
3195 }
3196
3197 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3198 assert(offset1 != offset2); /* else last "if" handled it */
3199 /* Convert everything except microseconds to seconds. These
3200 * can't overflow (no more than the # of seconds in 2 days).
3201 */
3202 offset1 = TIME_GET_HOUR(self) * 3600 +
3203 (TIME_GET_MINUTE(self) - offset1) * 60 +
3204 TIME_GET_SECOND(self);
3205 offset2 = TIME_GET_HOUR(other) * 3600 +
3206 (TIME_GET_MINUTE(other) - offset2) * 60 +
3207 TIME_GET_SECOND(other);
3208 diff = offset1 - offset2;
3209 if (diff == 0)
3210 diff = TIME_GET_MICROSECOND(self) -
3211 TIME_GET_MICROSECOND(other);
3212 return diff_to_bool(diff, op);
3213 }
3214
3215 assert(n1 != n2);
3216 PyErr_SetString(PyExc_TypeError,
3217 "can't compare offset-naive and "
3218 "offset-aware times");
3219 return NULL;
3220}
3221
3222static long
3223time_hash(PyDateTime_Time *self)
3224{
3225 if (self->hashcode == -1) {
3226 naivety n;
3227 int offset;
3228 PyObject *temp;
3229
3230 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3231 assert(n != OFFSET_UNKNOWN);
3232 if (n == OFFSET_ERROR)
3233 return -1;
3234
3235 /* Reduce this to a hash of another object. */
3236 if (offset == 0)
3237 temp = PyString_FromStringAndSize((char *)self->data,
3238 _PyDateTime_TIME_DATASIZE);
3239 else {
3240 int hour;
3241 int minute;
3242
3243 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003244 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003245 hour = divmod(TIME_GET_HOUR(self) * 60 +
3246 TIME_GET_MINUTE(self) - offset,
3247 60,
3248 &minute);
3249 if (0 <= hour && hour < 24)
3250 temp = new_time(hour, minute,
3251 TIME_GET_SECOND(self),
3252 TIME_GET_MICROSECOND(self),
3253 Py_None);
3254 else
3255 temp = Py_BuildValue("iiii",
3256 hour, minute,
3257 TIME_GET_SECOND(self),
3258 TIME_GET_MICROSECOND(self));
3259 }
3260 if (temp != NULL) {
3261 self->hashcode = PyObject_Hash(temp);
3262 Py_DECREF(temp);
3263 }
3264 }
3265 return self->hashcode;
3266}
Tim Peters2a799bf2002-12-16 20:18:38 +00003267
Tim Peters12bf3392002-12-24 05:41:27 +00003268static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003269time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003270{
3271 PyObject *clone;
3272 PyObject *tuple;
3273 int hh = TIME_GET_HOUR(self);
3274 int mm = TIME_GET_MINUTE(self);
3275 int ss = TIME_GET_SECOND(self);
3276 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003277 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003278
3279 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003280 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003281 &hh, &mm, &ss, &us, &tzinfo))
3282 return NULL;
3283 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3284 if (tuple == NULL)
3285 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003286 clone = time_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003287 Py_DECREF(tuple);
3288 return clone;
3289}
3290
Tim Peters2a799bf2002-12-16 20:18:38 +00003291static int
Tim Peters37f39822003-01-10 03:49:02 +00003292time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003293{
3294 int offset;
3295 int none;
3296
3297 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3298 /* Since utcoffset is in whole minutes, nothing can
3299 * alter the conclusion that this is nonzero.
3300 */
3301 return 1;
3302 }
3303 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003304 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003305 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003306 if (offset == -1 && PyErr_Occurred())
3307 return -1;
3308 }
3309 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3310}
3311
Tim Peters371935f2003-02-01 01:52:50 +00003312/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003313
Tim Peters33e0f382003-01-10 02:05:14 +00003314/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003315 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3316 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003317 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003318 */
3319static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003320time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003321{
3322 PyObject *basestate;
3323 PyObject *result = NULL;
3324
Tim Peters33e0f382003-01-10 02:05:14 +00003325 basestate = PyString_FromStringAndSize((char *)self->data,
3326 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003327 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003328 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003329 result = Py_BuildValue("(O)", basestate);
3330 else
3331 result = Py_BuildValue("OO", basestate, self->tzinfo);
3332 Py_DECREF(basestate);
3333 }
3334 return result;
3335}
3336
3337static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003338time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003339{
Guido van Rossum177e41a2003-01-30 22:06:23 +00003340 return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003341}
3342
Tim Peters37f39822003-01-10 03:49:02 +00003343static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003344
Tim Peters37f39822003-01-10 03:49:02 +00003345 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003346 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3347 "[+HH:MM].")},
3348
Tim Peters37f39822003-01-10 03:49:02 +00003349 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3350 PyDoc_STR("format -> strftime() style string.")},
3351
3352 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003353 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3354
Tim Peters37f39822003-01-10 03:49:02 +00003355 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003356 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3357
Tim Peters37f39822003-01-10 03:49:02 +00003358 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003359 PyDoc_STR("Return self.tzinfo.dst(self).")},
3360
Tim Peters37f39822003-01-10 03:49:02 +00003361 {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
3362 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003363
Guido van Rossum177e41a2003-01-30 22:06:23 +00003364 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3365 PyDoc_STR("__reduce__() -> (cls, state)")},
3366
Tim Peters2a799bf2002-12-16 20:18:38 +00003367 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003368};
3369
Tim Peters37f39822003-01-10 03:49:02 +00003370static char time_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003371PyDoc_STR("Time type.");
3372
Tim Peters37f39822003-01-10 03:49:02 +00003373static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003374 0, /* nb_add */
3375 0, /* nb_subtract */
3376 0, /* nb_multiply */
3377 0, /* nb_divide */
3378 0, /* nb_remainder */
3379 0, /* nb_divmod */
3380 0, /* nb_power */
3381 0, /* nb_negative */
3382 0, /* nb_positive */
3383 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003384 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003385};
3386
Tim Peters37f39822003-01-10 03:49:02 +00003387statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003388 PyObject_HEAD_INIT(NULL)
3389 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003390 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003391 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003392 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003393 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003394 0, /* tp_print */
3395 0, /* tp_getattr */
3396 0, /* tp_setattr */
3397 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003398 (reprfunc)time_repr, /* tp_repr */
3399 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003400 0, /* tp_as_sequence */
3401 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003402 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003403 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003404 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003405 PyObject_GenericGetAttr, /* tp_getattro */
3406 0, /* tp_setattro */
3407 0, /* tp_as_buffer */
3408 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3409 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003410 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003411 0, /* tp_traverse */
3412 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003413 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003414 0, /* tp_weaklistoffset */
3415 0, /* tp_iter */
3416 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003417 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003418 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003419 time_getset, /* tp_getset */
3420 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003421 0, /* tp_dict */
3422 0, /* tp_descr_get */
3423 0, /* tp_descr_set */
3424 0, /* tp_dictoffset */
3425 0, /* tp_init */
3426 0, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003427 time_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00003428 _PyObject_Del, /* tp_free */
3429};
3430
3431/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003432 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003433 */
3434
Tim Petersa9bc1682003-01-11 03:39:11 +00003435/* Accessor properties. Properties for day, month, and year are inherited
3436 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003437 */
3438
3439static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003440datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003441{
Tim Petersa9bc1682003-01-11 03:39:11 +00003442 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003443}
3444
Tim Petersa9bc1682003-01-11 03:39:11 +00003445static PyObject *
3446datetime_minute(PyDateTime_DateTime *self, void *unused)
3447{
3448 return PyInt_FromLong(DATE_GET_MINUTE(self));
3449}
3450
3451static PyObject *
3452datetime_second(PyDateTime_DateTime *self, void *unused)
3453{
3454 return PyInt_FromLong(DATE_GET_SECOND(self));
3455}
3456
3457static PyObject *
3458datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3459{
3460 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3461}
3462
3463static PyObject *
3464datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3465{
3466 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3467 Py_INCREF(result);
3468 return result;
3469}
3470
3471static PyGetSetDef datetime_getset[] = {
3472 {"hour", (getter)datetime_hour},
3473 {"minute", (getter)datetime_minute},
3474 {"second", (getter)datetime_second},
3475 {"microsecond", (getter)datetime_microsecond},
3476 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003477 {NULL}
3478};
3479
3480/*
3481 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003482 */
3483
Tim Petersa9bc1682003-01-11 03:39:11 +00003484static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003485 "year", "month", "day", "hour", "minute", "second",
3486 "microsecond", "tzinfo", NULL
3487};
3488
Tim Peters2a799bf2002-12-16 20:18:38 +00003489static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003490datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003491{
3492 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003493 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003494 int year;
3495 int month;
3496 int day;
3497 int hour = 0;
3498 int minute = 0;
3499 int second = 0;
3500 int usecond = 0;
3501 PyObject *tzinfo = Py_None;
3502
Guido van Rossum177e41a2003-01-30 22:06:23 +00003503 /* Check for invocation from pickle with __getstate__ state */
3504 if (PyTuple_GET_SIZE(args) >= 1 &&
3505 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00003506 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3507 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003508 {
Tim Peters70533e22003-02-01 04:40:04 +00003509 PyDateTime_DateTime *me;
3510 char aware;
3511
3512 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003513 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003514 if (check_tzinfo_subclass(tzinfo) < 0) {
3515 PyErr_SetString(PyExc_TypeError, "bad "
3516 "tzinfo state arg");
3517 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003518 }
3519 }
Tim Peters70533e22003-02-01 04:40:04 +00003520 aware = (char)(tzinfo != Py_None);
3521 me = alloc_datetime(aware);
3522 if (me != NULL) {
3523 char *pdata = PyString_AS_STRING(state);
3524
3525 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3526 me->hashcode = -1;
3527 me->hastzinfo = aware;
3528 if (aware) {
3529 Py_INCREF(tzinfo);
3530 me->tzinfo = tzinfo;
3531 }
3532 }
3533 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003534 }
3535
Tim Petersa9bc1682003-01-11 03:39:11 +00003536 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003537 &year, &month, &day, &hour, &minute,
3538 &second, &usecond, &tzinfo)) {
3539 if (check_date_args(year, month, day) < 0)
3540 return NULL;
3541 if (check_time_args(hour, minute, second, usecond) < 0)
3542 return NULL;
3543 if (check_tzinfo_subclass(tzinfo) < 0)
3544 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003545 self = new_datetime(year, month, day,
3546 hour, minute, second, usecond,
3547 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003548 }
3549 return self;
3550}
3551
Tim Petersa9bc1682003-01-11 03:39:11 +00003552/* TM_FUNC is the shared type of localtime() and gmtime(). */
3553typedef struct tm *(*TM_FUNC)(const time_t *timer);
3554
3555/* Internal helper.
3556 * Build datetime from a time_t and a distinct count of microseconds.
3557 * Pass localtime or gmtime for f, to control the interpretation of timet.
3558 */
3559static PyObject *
3560datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3561 PyObject *tzinfo)
3562{
3563 struct tm *tm;
3564 PyObject *result = NULL;
3565
3566 tm = f(&timet);
3567 if (tm) {
3568 /* The platform localtime/gmtime may insert leap seconds,
3569 * indicated by tm->tm_sec > 59. We don't care about them,
3570 * except to the extent that passing them on to the datetime
3571 * constructor would raise ValueError for a reason that
3572 * made no sense to the user.
3573 */
3574 if (tm->tm_sec > 59)
3575 tm->tm_sec = 59;
3576 result = PyObject_CallFunction(cls, "iiiiiiiO",
3577 tm->tm_year + 1900,
3578 tm->tm_mon + 1,
3579 tm->tm_mday,
3580 tm->tm_hour,
3581 tm->tm_min,
3582 tm->tm_sec,
3583 us,
3584 tzinfo);
3585 }
3586 else
3587 PyErr_SetString(PyExc_ValueError,
3588 "timestamp out of range for "
3589 "platform localtime()/gmtime() function");
3590 return result;
3591}
3592
3593/* Internal helper.
3594 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3595 * to control the interpretation of the timestamp. Since a double doesn't
3596 * have enough bits to cover a datetime's full range of precision, it's
3597 * better to call datetime_from_timet_and_us provided you have a way
3598 * to get that much precision (e.g., C time() isn't good enough).
3599 */
3600static PyObject *
3601datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3602 PyObject *tzinfo)
3603{
3604 time_t timet = (time_t)timestamp;
3605 double fraction = timestamp - (double)timet;
3606 int us = (int)round_to_long(fraction * 1e6);
3607
3608 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3609}
3610
3611/* Internal helper.
3612 * Build most accurate possible datetime for current time. Pass localtime or
3613 * gmtime for f as appropriate.
3614 */
3615static PyObject *
3616datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3617{
3618#ifdef HAVE_GETTIMEOFDAY
3619 struct timeval t;
3620
3621#ifdef GETTIMEOFDAY_NO_TZ
3622 gettimeofday(&t);
3623#else
3624 gettimeofday(&t, (struct timezone *)NULL);
3625#endif
3626 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3627 tzinfo);
3628
3629#else /* ! HAVE_GETTIMEOFDAY */
3630 /* No flavor of gettimeofday exists on this platform. Python's
3631 * time.time() does a lot of other platform tricks to get the
3632 * best time it can on the platform, and we're not going to do
3633 * better than that (if we could, the better code would belong
3634 * in time.time()!) We're limited by the precision of a double,
3635 * though.
3636 */
3637 PyObject *time;
3638 double dtime;
3639
3640 time = time_time();
3641 if (time == NULL)
3642 return NULL;
3643 dtime = PyFloat_AsDouble(time);
3644 Py_DECREF(time);
3645 if (dtime == -1.0 && PyErr_Occurred())
3646 return NULL;
3647 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3648#endif /* ! HAVE_GETTIMEOFDAY */
3649}
3650
Tim Peters2a799bf2002-12-16 20:18:38 +00003651/* Return best possible local time -- this isn't constrained by the
3652 * precision of a timestamp.
3653 */
3654static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003655datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003656{
Tim Peters10cadce2003-01-23 19:58:02 +00003657 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003658 PyObject *tzinfo = Py_None;
Tim Peters10cadce2003-01-23 19:58:02 +00003659 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003660
Tim Peters10cadce2003-01-23 19:58:02 +00003661 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3662 &tzinfo))
3663 return NULL;
3664 if (check_tzinfo_subclass(tzinfo) < 0)
3665 return NULL;
3666
3667 self = datetime_best_possible(cls,
3668 tzinfo == Py_None ? localtime : gmtime,
3669 tzinfo);
3670 if (self != NULL && tzinfo != Py_None) {
3671 /* Convert UTC to tzinfo's zone. */
3672 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003673 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003674 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003675 }
3676 return self;
3677}
3678
Tim Petersa9bc1682003-01-11 03:39:11 +00003679/* Return best possible UTC time -- this isn't constrained by the
3680 * precision of a timestamp.
3681 */
3682static PyObject *
3683datetime_utcnow(PyObject *cls, PyObject *dummy)
3684{
3685 return datetime_best_possible(cls, gmtime, Py_None);
3686}
3687
Tim Peters2a799bf2002-12-16 20:18:38 +00003688/* Return new local datetime from timestamp (Python timestamp -- a double). */
3689static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003690datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003691{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003692 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003693 double timestamp;
3694 PyObject *tzinfo = Py_None;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003695 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003696
Tim Peters2a44a8d2003-01-23 20:53:10 +00003697 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3698 keywords, &timestamp, &tzinfo))
3699 return NULL;
3700 if (check_tzinfo_subclass(tzinfo) < 0)
3701 return NULL;
3702
3703 self = datetime_from_timestamp(cls,
3704 tzinfo == Py_None ? localtime : gmtime,
3705 timestamp,
3706 tzinfo);
3707 if (self != NULL && tzinfo != Py_None) {
3708 /* Convert UTC to tzinfo's zone. */
3709 PyObject *temp = self;
3710 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3711 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003712 }
3713 return self;
3714}
3715
Tim Petersa9bc1682003-01-11 03:39:11 +00003716/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3717static PyObject *
3718datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3719{
3720 double timestamp;
3721 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003722
Tim Petersa9bc1682003-01-11 03:39:11 +00003723 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3724 result = datetime_from_timestamp(cls, gmtime, timestamp,
3725 Py_None);
3726 return result;
3727}
3728
3729/* Return new datetime from date/datetime and time arguments. */
3730static PyObject *
3731datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3732{
3733 static char *keywords[] = {"date", "time", NULL};
3734 PyObject *date;
3735 PyObject *time;
3736 PyObject *result = NULL;
3737
3738 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3739 &PyDateTime_DateType, &date,
3740 &PyDateTime_TimeType, &time)) {
3741 PyObject *tzinfo = Py_None;
3742
3743 if (HASTZINFO(time))
3744 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3745 result = PyObject_CallFunction(cls, "iiiiiiiO",
3746 GET_YEAR(date),
3747 GET_MONTH(date),
3748 GET_DAY(date),
3749 TIME_GET_HOUR(time),
3750 TIME_GET_MINUTE(time),
3751 TIME_GET_SECOND(time),
3752 TIME_GET_MICROSECOND(time),
3753 tzinfo);
3754 }
3755 return result;
3756}
Tim Peters2a799bf2002-12-16 20:18:38 +00003757
3758/*
3759 * Destructor.
3760 */
3761
3762static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003763datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003764{
Tim Petersa9bc1682003-01-11 03:39:11 +00003765 if (HASTZINFO(self)) {
3766 Py_XDECREF(self->tzinfo);
3767 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003768 self->ob_type->tp_free((PyObject *)self);
3769}
3770
3771/*
3772 * Indirect access to tzinfo methods.
3773 */
3774
Tim Peters2a799bf2002-12-16 20:18:38 +00003775/* These are all METH_NOARGS, so don't need to check the arglist. */
3776static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003777datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3778 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3779 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003780}
3781
3782static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003783datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3784 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3785 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003786}
3787
3788static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003789datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3790 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3791 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003792}
3793
3794/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003795 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003796 */
3797
Tim Petersa9bc1682003-01-11 03:39:11 +00003798/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3799 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003800 */
3801static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003802add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3803 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003804{
Tim Petersa9bc1682003-01-11 03:39:11 +00003805 /* Note that the C-level additions can't overflow, because of
3806 * invariant bounds on the member values.
3807 */
3808 int year = GET_YEAR(date);
3809 int month = GET_MONTH(date);
3810 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3811 int hour = DATE_GET_HOUR(date);
3812 int minute = DATE_GET_MINUTE(date);
3813 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3814 int microsecond = DATE_GET_MICROSECOND(date) +
3815 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003816
Tim Petersa9bc1682003-01-11 03:39:11 +00003817 assert(factor == 1 || factor == -1);
3818 if (normalize_datetime(&year, &month, &day,
3819 &hour, &minute, &second, &microsecond) < 0)
3820 return NULL;
3821 else
3822 return new_datetime(year, month, day,
3823 hour, minute, second, microsecond,
3824 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003825}
3826
3827static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003828datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003829{
Tim Petersa9bc1682003-01-11 03:39:11 +00003830 if (PyDateTime_Check(left)) {
3831 /* datetime + ??? */
3832 if (PyDelta_Check(right))
3833 /* datetime + delta */
3834 return add_datetime_timedelta(
3835 (PyDateTime_DateTime *)left,
3836 (PyDateTime_Delta *)right,
3837 1);
3838 }
3839 else if (PyDelta_Check(left)) {
3840 /* delta + datetime */
3841 return add_datetime_timedelta((PyDateTime_DateTime *) right,
3842 (PyDateTime_Delta *) left,
3843 1);
3844 }
3845 Py_INCREF(Py_NotImplemented);
3846 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00003847}
3848
3849static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003850datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003851{
3852 PyObject *result = Py_NotImplemented;
3853
3854 if (PyDateTime_Check(left)) {
3855 /* datetime - ??? */
3856 if (PyDateTime_Check(right)) {
3857 /* datetime - datetime */
3858 naivety n1, n2;
3859 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00003860 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00003861
Tim Peterse39a80c2002-12-30 21:28:52 +00003862 if (classify_two_utcoffsets(left, &offset1, &n1, left,
3863 right, &offset2, &n2,
3864 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00003865 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00003866 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00003867 if (n1 != n2) {
3868 PyErr_SetString(PyExc_TypeError,
3869 "can't subtract offset-naive and "
3870 "offset-aware datetimes");
3871 return NULL;
3872 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003873 delta_d = ymd_to_ord(GET_YEAR(left),
3874 GET_MONTH(left),
3875 GET_DAY(left)) -
3876 ymd_to_ord(GET_YEAR(right),
3877 GET_MONTH(right),
3878 GET_DAY(right));
3879 /* These can't overflow, since the values are
3880 * normalized. At most this gives the number of
3881 * seconds in one day.
3882 */
3883 delta_s = (DATE_GET_HOUR(left) -
3884 DATE_GET_HOUR(right)) * 3600 +
3885 (DATE_GET_MINUTE(left) -
3886 DATE_GET_MINUTE(right)) * 60 +
3887 (DATE_GET_SECOND(left) -
3888 DATE_GET_SECOND(right));
3889 delta_us = DATE_GET_MICROSECOND(left) -
3890 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00003891 /* (left - offset1) - (right - offset2) =
3892 * (left - right) + (offset2 - offset1)
3893 */
Tim Petersa9bc1682003-01-11 03:39:11 +00003894 delta_s += (offset2 - offset1) * 60;
3895 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003896 }
3897 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00003898 /* datetime - delta */
3899 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00003900 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00003901 (PyDateTime_Delta *)right,
3902 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003903 }
3904 }
3905
3906 if (result == Py_NotImplemented)
3907 Py_INCREF(result);
3908 return result;
3909}
3910
3911/* Various ways to turn a datetime into a string. */
3912
3913static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003914datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003915{
Tim Petersa9bc1682003-01-11 03:39:11 +00003916 char buffer[1000];
3917 char *typename = self->ob_type->tp_name;
3918 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003919
Tim Petersa9bc1682003-01-11 03:39:11 +00003920 if (DATE_GET_MICROSECOND(self)) {
3921 PyOS_snprintf(buffer, sizeof(buffer),
3922 "%s(%d, %d, %d, %d, %d, %d, %d)",
3923 typename,
3924 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3925 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3926 DATE_GET_SECOND(self),
3927 DATE_GET_MICROSECOND(self));
3928 }
3929 else if (DATE_GET_SECOND(self)) {
3930 PyOS_snprintf(buffer, sizeof(buffer),
3931 "%s(%d, %d, %d, %d, %d, %d)",
3932 typename,
3933 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3934 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3935 DATE_GET_SECOND(self));
3936 }
3937 else {
3938 PyOS_snprintf(buffer, sizeof(buffer),
3939 "%s(%d, %d, %d, %d, %d)",
3940 typename,
3941 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3942 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
3943 }
3944 baserepr = PyString_FromString(buffer);
3945 if (baserepr == NULL || ! HASTZINFO(self))
3946 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003947 return append_keyword_tzinfo(baserepr, self->tzinfo);
3948}
3949
Tim Petersa9bc1682003-01-11 03:39:11 +00003950static PyObject *
3951datetime_str(PyDateTime_DateTime *self)
3952{
3953 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
3954}
Tim Peters2a799bf2002-12-16 20:18:38 +00003955
3956static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003957datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003958{
Tim Petersa9bc1682003-01-11 03:39:11 +00003959 char sep = 'T';
3960 static char *keywords[] = {"sep", NULL};
3961 char buffer[100];
3962 char *cp;
3963 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003964
Tim Petersa9bc1682003-01-11 03:39:11 +00003965 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
3966 &sep))
3967 return NULL;
3968 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
3969 assert(cp != NULL);
3970 *cp++ = sep;
3971 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
3972 result = PyString_FromString(buffer);
3973 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00003974 return result;
3975
3976 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00003977 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00003978 (PyObject *)self) < 0) {
3979 Py_DECREF(result);
3980 return NULL;
3981 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003982 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00003983 return result;
3984}
3985
Tim Petersa9bc1682003-01-11 03:39:11 +00003986static PyObject *
3987datetime_ctime(PyDateTime_DateTime *self)
3988{
3989 return format_ctime((PyDateTime_Date *)self,
3990 DATE_GET_HOUR(self),
3991 DATE_GET_MINUTE(self),
3992 DATE_GET_SECOND(self));
3993}
3994
Tim Peters2a799bf2002-12-16 20:18:38 +00003995/* Miscellaneous methods. */
3996
Tim Petersa9bc1682003-01-11 03:39:11 +00003997/* This is more natural as a tp_compare, but doesn't work then: for whatever
3998 * reason, Python's try_3way_compare ignores tp_compare unless
3999 * PyInstance_Check returns true, but these aren't old-style classes.
4000 */
4001static PyObject *
4002datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4003{
4004 int diff;
4005 naivety n1, n2;
4006 int offset1, offset2;
4007
4008 if (! PyDateTime_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004009 if (PyObject_HasAttrString(other, "timetuple")) {
4010 /* A hook for other kinds of datetime objects. */
4011 Py_INCREF(Py_NotImplemented);
4012 return Py_NotImplemented;
4013 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004014 /* Stop this from falling back to address comparison. */
4015 PyErr_Format(PyExc_TypeError,
4016 "can't compare '%s' to '%s'",
4017 self->ob_type->tp_name,
4018 other->ob_type->tp_name);
4019 return NULL;
4020 }
4021
4022 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4023 (PyObject *)self,
4024 other, &offset2, &n2,
4025 other) < 0)
4026 return NULL;
4027 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4028 /* If they're both naive, or both aware and have the same offsets,
4029 * we get off cheap. Note that if they're both naive, offset1 ==
4030 * offset2 == 0 at this point.
4031 */
4032 if (n1 == n2 && offset1 == offset2) {
4033 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4034 _PyDateTime_DATETIME_DATASIZE);
4035 return diff_to_bool(diff, op);
4036 }
4037
4038 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4039 PyDateTime_Delta *delta;
4040
4041 assert(offset1 != offset2); /* else last "if" handled it */
4042 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4043 other);
4044 if (delta == NULL)
4045 return NULL;
4046 diff = GET_TD_DAYS(delta);
4047 if (diff == 0)
4048 diff = GET_TD_SECONDS(delta) |
4049 GET_TD_MICROSECONDS(delta);
4050 Py_DECREF(delta);
4051 return diff_to_bool(diff, op);
4052 }
4053
4054 assert(n1 != n2);
4055 PyErr_SetString(PyExc_TypeError,
4056 "can't compare offset-naive and "
4057 "offset-aware datetimes");
4058 return NULL;
4059}
4060
4061static long
4062datetime_hash(PyDateTime_DateTime *self)
4063{
4064 if (self->hashcode == -1) {
4065 naivety n;
4066 int offset;
4067 PyObject *temp;
4068
4069 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4070 &offset);
4071 assert(n != OFFSET_UNKNOWN);
4072 if (n == OFFSET_ERROR)
4073 return -1;
4074
4075 /* Reduce this to a hash of another object. */
4076 if (n == OFFSET_NAIVE)
4077 temp = PyString_FromStringAndSize(
4078 (char *)self->data,
4079 _PyDateTime_DATETIME_DATASIZE);
4080 else {
4081 int days;
4082 int seconds;
4083
4084 assert(n == OFFSET_AWARE);
4085 assert(HASTZINFO(self));
4086 days = ymd_to_ord(GET_YEAR(self),
4087 GET_MONTH(self),
4088 GET_DAY(self));
4089 seconds = DATE_GET_HOUR(self) * 3600 +
4090 (DATE_GET_MINUTE(self) - offset) * 60 +
4091 DATE_GET_SECOND(self);
4092 temp = new_delta(days,
4093 seconds,
4094 DATE_GET_MICROSECOND(self),
4095 1);
4096 }
4097 if (temp != NULL) {
4098 self->hashcode = PyObject_Hash(temp);
4099 Py_DECREF(temp);
4100 }
4101 }
4102 return self->hashcode;
4103}
Tim Peters2a799bf2002-12-16 20:18:38 +00004104
4105static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004106datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004107{
4108 PyObject *clone;
4109 PyObject *tuple;
4110 int y = GET_YEAR(self);
4111 int m = GET_MONTH(self);
4112 int d = GET_DAY(self);
4113 int hh = DATE_GET_HOUR(self);
4114 int mm = DATE_GET_MINUTE(self);
4115 int ss = DATE_GET_SECOND(self);
4116 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004117 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004118
4119 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004120 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004121 &y, &m, &d, &hh, &mm, &ss, &us,
4122 &tzinfo))
4123 return NULL;
4124 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4125 if (tuple == NULL)
4126 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004127 clone = datetime_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004128 Py_DECREF(tuple);
4129 return clone;
4130}
4131
4132static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004133datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004134{
Tim Peters52dcce22003-01-23 16:36:11 +00004135 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004136 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004137 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004138
Tim Peters80475bb2002-12-25 07:40:55 +00004139 PyObject *tzinfo;
4140 static char *keywords[] = {"tz", NULL};
4141
Tim Peters52dcce22003-01-23 16:36:11 +00004142 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4143 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004144 return NULL;
4145
Tim Peters52dcce22003-01-23 16:36:11 +00004146 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4147 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004148
Tim Peters52dcce22003-01-23 16:36:11 +00004149 /* Conversion to self's own time zone is a NOP. */
4150 if (self->tzinfo == tzinfo) {
4151 Py_INCREF(self);
4152 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004153 }
Tim Peters521fc152002-12-31 17:36:56 +00004154
Tim Peters52dcce22003-01-23 16:36:11 +00004155 /* Convert self to UTC. */
4156 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4157 if (offset == -1 && PyErr_Occurred())
4158 return NULL;
4159 if (none)
4160 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004161
Tim Peters52dcce22003-01-23 16:36:11 +00004162 y = GET_YEAR(self);
4163 m = GET_MONTH(self);
4164 d = GET_DAY(self);
4165 hh = DATE_GET_HOUR(self);
4166 mm = DATE_GET_MINUTE(self);
4167 ss = DATE_GET_SECOND(self);
4168 us = DATE_GET_MICROSECOND(self);
4169
4170 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004171 if ((mm < 0 || mm >= 60) &&
4172 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004173 return NULL;
4174
4175 /* Attach new tzinfo and let fromutc() do the rest. */
4176 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4177 if (result != NULL) {
4178 PyObject *temp = result;
4179
4180 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4181 Py_DECREF(temp);
4182 }
Tim Petersadf64202003-01-04 06:03:15 +00004183 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004184
Tim Peters52dcce22003-01-23 16:36:11 +00004185NeedAware:
4186 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4187 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004188 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004189}
4190
4191static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004192datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004193{
4194 int dstflag = -1;
4195
Tim Petersa9bc1682003-01-11 03:39:11 +00004196 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004197 int none;
4198
4199 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4200 if (dstflag == -1 && PyErr_Occurred())
4201 return NULL;
4202
4203 if (none)
4204 dstflag = -1;
4205 else if (dstflag != 0)
4206 dstflag = 1;
4207
4208 }
4209 return build_struct_time(GET_YEAR(self),
4210 GET_MONTH(self),
4211 GET_DAY(self),
4212 DATE_GET_HOUR(self),
4213 DATE_GET_MINUTE(self),
4214 DATE_GET_SECOND(self),
4215 dstflag);
4216}
4217
4218static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004219datetime_getdate(PyDateTime_DateTime *self)
4220{
4221 return new_date(GET_YEAR(self),
4222 GET_MONTH(self),
4223 GET_DAY(self));
4224}
4225
4226static PyObject *
4227datetime_gettime(PyDateTime_DateTime *self)
4228{
4229 return new_time(DATE_GET_HOUR(self),
4230 DATE_GET_MINUTE(self),
4231 DATE_GET_SECOND(self),
4232 DATE_GET_MICROSECOND(self),
4233 Py_None);
4234}
4235
4236static PyObject *
4237datetime_gettimetz(PyDateTime_DateTime *self)
4238{
4239 return new_time(DATE_GET_HOUR(self),
4240 DATE_GET_MINUTE(self),
4241 DATE_GET_SECOND(self),
4242 DATE_GET_MICROSECOND(self),
4243 HASTZINFO(self) ? self->tzinfo : Py_None);
4244}
4245
4246static PyObject *
4247datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004248{
4249 int y = GET_YEAR(self);
4250 int m = GET_MONTH(self);
4251 int d = GET_DAY(self);
4252 int hh = DATE_GET_HOUR(self);
4253 int mm = DATE_GET_MINUTE(self);
4254 int ss = DATE_GET_SECOND(self);
4255 int us = 0; /* microseconds are ignored in a timetuple */
4256 int offset = 0;
4257
Tim Petersa9bc1682003-01-11 03:39:11 +00004258 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004259 int none;
4260
4261 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4262 if (offset == -1 && PyErr_Occurred())
4263 return NULL;
4264 }
4265 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4266 * 0 in a UTC timetuple regardless of what dst() says.
4267 */
4268 if (offset) {
4269 /* Subtract offset minutes & normalize. */
4270 int stat;
4271
4272 mm -= offset;
4273 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4274 if (stat < 0) {
4275 /* At the edges, it's possible we overflowed
4276 * beyond MINYEAR or MAXYEAR.
4277 */
4278 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4279 PyErr_Clear();
4280 else
4281 return NULL;
4282 }
4283 }
4284 return build_struct_time(y, m, d, hh, mm, ss, 0);
4285}
4286
Tim Peters371935f2003-02-01 01:52:50 +00004287/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004288
Tim Petersa9bc1682003-01-11 03:39:11 +00004289/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004290 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4291 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004292 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004293 */
4294static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004295datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004296{
4297 PyObject *basestate;
4298 PyObject *result = NULL;
4299
Tim Peters33e0f382003-01-10 02:05:14 +00004300 basestate = PyString_FromStringAndSize((char *)self->data,
4301 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004302 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004303 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00004304 result = Py_BuildValue("(O)", basestate);
4305 else
4306 result = Py_BuildValue("OO", basestate, self->tzinfo);
4307 Py_DECREF(basestate);
4308 }
4309 return result;
4310}
4311
4312static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004313datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004314{
Guido van Rossum177e41a2003-01-30 22:06:23 +00004315 return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004316}
4317
Tim Petersa9bc1682003-01-11 03:39:11 +00004318static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004319
Tim Peters2a799bf2002-12-16 20:18:38 +00004320 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004321
Tim Petersa9bc1682003-01-11 03:39:11 +00004322 {"now", (PyCFunction)datetime_now,
Tim Peters2a799bf2002-12-16 20:18:38 +00004323 METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004324 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004325
Tim Petersa9bc1682003-01-11 03:39:11 +00004326 {"utcnow", (PyCFunction)datetime_utcnow,
4327 METH_NOARGS | METH_CLASS,
4328 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4329
4330 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Tim Peters2a799bf2002-12-16 20:18:38 +00004331 METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004332 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004333
Tim Petersa9bc1682003-01-11 03:39:11 +00004334 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4335 METH_VARARGS | METH_CLASS,
4336 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4337 "(like time.time()).")},
4338
4339 {"combine", (PyCFunction)datetime_combine,
4340 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4341 PyDoc_STR("date, time -> datetime with same date and time fields")},
4342
Tim Peters2a799bf2002-12-16 20:18:38 +00004343 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004344
Tim Petersa9bc1682003-01-11 03:39:11 +00004345 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4346 PyDoc_STR("Return date object with same year, month and day.")},
4347
4348 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4349 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4350
4351 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4352 PyDoc_STR("Return time object with same time and tzinfo.")},
4353
4354 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4355 PyDoc_STR("Return ctime() style string.")},
4356
4357 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004358 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4359
Tim Petersa9bc1682003-01-11 03:39:11 +00004360 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004361 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4362
Tim Petersa9bc1682003-01-11 03:39:11 +00004363 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004364 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4365 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4366 "sep is used to separate the year from the time, and "
4367 "defaults to 'T'.")},
4368
Tim Petersa9bc1682003-01-11 03:39:11 +00004369 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004370 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4371
Tim Petersa9bc1682003-01-11 03:39:11 +00004372 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004373 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4374
Tim Petersa9bc1682003-01-11 03:39:11 +00004375 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004376 PyDoc_STR("Return self.tzinfo.dst(self).")},
4377
Tim Petersa9bc1682003-01-11 03:39:11 +00004378 {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
4379 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004380
Tim Petersa9bc1682003-01-11 03:39:11 +00004381 {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004382 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4383
Guido van Rossum177e41a2003-01-30 22:06:23 +00004384 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4385 PyDoc_STR("__reduce__() -> (cls, state)")},
4386
Tim Peters2a799bf2002-12-16 20:18:38 +00004387 {NULL, NULL}
4388};
4389
Tim Petersa9bc1682003-01-11 03:39:11 +00004390static char datetime_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00004391PyDoc_STR("date/time type.");
4392
Tim Petersa9bc1682003-01-11 03:39:11 +00004393static PyNumberMethods datetime_as_number = {
4394 datetime_add, /* nb_add */
4395 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004396 0, /* nb_multiply */
4397 0, /* nb_divide */
4398 0, /* nb_remainder */
4399 0, /* nb_divmod */
4400 0, /* nb_power */
4401 0, /* nb_negative */
4402 0, /* nb_positive */
4403 0, /* nb_absolute */
4404 0, /* nb_nonzero */
4405};
4406
Tim Petersa9bc1682003-01-11 03:39:11 +00004407statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004408 PyObject_HEAD_INIT(NULL)
4409 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004410 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004411 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004412 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004413 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004414 0, /* tp_print */
4415 0, /* tp_getattr */
4416 0, /* tp_setattr */
4417 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004418 (reprfunc)datetime_repr, /* tp_repr */
4419 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004420 0, /* tp_as_sequence */
4421 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004422 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004423 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004424 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004425 PyObject_GenericGetAttr, /* tp_getattro */
4426 0, /* tp_setattro */
4427 0, /* tp_as_buffer */
4428 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4429 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004430 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004431 0, /* tp_traverse */
4432 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004433 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004434 0, /* tp_weaklistoffset */
4435 0, /* tp_iter */
4436 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004437 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004438 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004439 datetime_getset, /* tp_getset */
4440 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004441 0, /* tp_dict */
4442 0, /* tp_descr_get */
4443 0, /* tp_descr_set */
4444 0, /* tp_dictoffset */
4445 0, /* tp_init */
4446 0, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004447 datetime_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00004448 _PyObject_Del, /* tp_free */
4449};
4450
4451/* ---------------------------------------------------------------------------
4452 * Module methods and initialization.
4453 */
4454
4455static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004456 {NULL, NULL}
4457};
4458
4459PyMODINIT_FUNC
4460initdatetime(void)
4461{
4462 PyObject *m; /* a module object */
4463 PyObject *d; /* its dict */
4464 PyObject *x;
4465
Tim Peters2a799bf2002-12-16 20:18:38 +00004466 m = Py_InitModule3("datetime", module_methods,
4467 "Fast implementation of the datetime type.");
4468
4469 if (PyType_Ready(&PyDateTime_DateType) < 0)
4470 return;
4471 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4472 return;
4473 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4474 return;
4475 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4476 return;
4477 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4478 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004479
Tim Peters2a799bf2002-12-16 20:18:38 +00004480 /* timedelta values */
4481 d = PyDateTime_DeltaType.tp_dict;
4482
Tim Peters2a799bf2002-12-16 20:18:38 +00004483 x = new_delta(0, 0, 1, 0);
4484 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4485 return;
4486 Py_DECREF(x);
4487
4488 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4489 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4490 return;
4491 Py_DECREF(x);
4492
4493 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4494 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4495 return;
4496 Py_DECREF(x);
4497
4498 /* date values */
4499 d = PyDateTime_DateType.tp_dict;
4500
4501 x = new_date(1, 1, 1);
4502 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4503 return;
4504 Py_DECREF(x);
4505
4506 x = new_date(MAXYEAR, 12, 31);
4507 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4508 return;
4509 Py_DECREF(x);
4510
4511 x = new_delta(1, 0, 0, 0);
4512 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4513 return;
4514 Py_DECREF(x);
4515
Tim Peters37f39822003-01-10 03:49:02 +00004516 /* time values */
4517 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004518
Tim Peters37f39822003-01-10 03:49:02 +00004519 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004520 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4521 return;
4522 Py_DECREF(x);
4523
Tim Peters37f39822003-01-10 03:49:02 +00004524 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004525 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4526 return;
4527 Py_DECREF(x);
4528
4529 x = new_delta(0, 0, 1, 0);
4530 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4531 return;
4532 Py_DECREF(x);
4533
Tim Petersa9bc1682003-01-11 03:39:11 +00004534 /* datetime values */
4535 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004536
Tim Petersa9bc1682003-01-11 03:39:11 +00004537 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004538 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4539 return;
4540 Py_DECREF(x);
4541
Tim Petersa9bc1682003-01-11 03:39:11 +00004542 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004543 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4544 return;
4545 Py_DECREF(x);
4546
4547 x = new_delta(0, 0, 1, 0);
4548 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4549 return;
4550 Py_DECREF(x);
4551
Tim Peters2a799bf2002-12-16 20:18:38 +00004552 /* module initialization */
4553 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4554 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4555
4556 Py_INCREF(&PyDateTime_DateType);
4557 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4558
Tim Petersa9bc1682003-01-11 03:39:11 +00004559 Py_INCREF(&PyDateTime_DateTimeType);
4560 PyModule_AddObject(m, "datetime",
4561 (PyObject *)&PyDateTime_DateTimeType);
4562
4563 Py_INCREF(&PyDateTime_TimeType);
4564 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4565
Tim Peters2a799bf2002-12-16 20:18:38 +00004566 Py_INCREF(&PyDateTime_DeltaType);
4567 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4568
Tim Peters2a799bf2002-12-16 20:18:38 +00004569 Py_INCREF(&PyDateTime_TZInfoType);
4570 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4571
Tim Peters2a799bf2002-12-16 20:18:38 +00004572 /* A 4-year cycle has an extra leap day over what we'd get from
4573 * pasting together 4 single years.
4574 */
4575 assert(DI4Y == 4 * 365 + 1);
4576 assert(DI4Y == days_before_year(4+1));
4577
4578 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4579 * get from pasting together 4 100-year cycles.
4580 */
4581 assert(DI400Y == 4 * DI100Y + 1);
4582 assert(DI400Y == days_before_year(400+1));
4583
4584 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4585 * pasting together 25 4-year cycles.
4586 */
4587 assert(DI100Y == 25 * DI4Y - 1);
4588 assert(DI100Y == days_before_year(100+1));
4589
4590 us_per_us = PyInt_FromLong(1);
4591 us_per_ms = PyInt_FromLong(1000);
4592 us_per_second = PyInt_FromLong(1000000);
4593 us_per_minute = PyInt_FromLong(60000000);
4594 seconds_per_day = PyInt_FromLong(24 * 3600);
4595 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4596 us_per_minute == NULL || seconds_per_day == NULL)
4597 return;
4598
4599 /* The rest are too big for 32-bit ints, but even
4600 * us_per_week fits in 40 bits, so doubles should be exact.
4601 */
4602 us_per_hour = PyLong_FromDouble(3600000000.0);
4603 us_per_day = PyLong_FromDouble(86400000000.0);
4604 us_per_week = PyLong_FromDouble(604800000000.0);
4605 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4606 return;
4607}
Tim Petersf3615152003-01-01 21:51:37 +00004608
4609/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004610Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004611 x.n = x stripped of its timezone -- its naive time.
4612 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4613 return None
4614 x.d = x.dst(), and assuming that doesn't raise an exception or
4615 return None
4616 x.s = x's standard offset, x.o - x.d
4617
4618Now some derived rules, where k is a duration (timedelta).
4619
46201. x.o = x.s + x.d
4621 This follows from the definition of x.s.
4622
Tim Petersc5dc4da2003-01-02 17:55:03 +000046232. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004624 This is actually a requirement, an assumption we need to make about
4625 sane tzinfo classes.
4626
46273. The naive UTC time corresponding to x is x.n - x.o.
4628 This is again a requirement for a sane tzinfo class.
4629
46304. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004631 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004632
Tim Petersc5dc4da2003-01-02 17:55:03 +000046335. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004634 Again follows from how arithmetic is defined.
4635
Tim Peters8bb5ad22003-01-24 02:44:45 +00004636Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004637(meaning that the various tzinfo methods exist, and don't blow up or return
4638None when called).
4639
Tim Petersa9bc1682003-01-11 03:39:11 +00004640The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004641x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004642
4643By #3, we want
4644
Tim Peters8bb5ad22003-01-24 02:44:45 +00004645 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004646
4647The algorithm starts by attaching tz to x.n, and calling that y. So
4648x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4649becomes true; in effect, we want to solve [2] for k:
4650
Tim Peters8bb5ad22003-01-24 02:44:45 +00004651 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004652
4653By #1, this is the same as
4654
Tim Peters8bb5ad22003-01-24 02:44:45 +00004655 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004656
4657By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4658Substituting that into [3],
4659
Tim Peters8bb5ad22003-01-24 02:44:45 +00004660 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4661 k - (y+k).s - (y+k).d = 0; rearranging,
4662 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4663 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004664
Tim Peters8bb5ad22003-01-24 02:44:45 +00004665On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4666approximate k by ignoring the (y+k).d term at first. Note that k can't be
4667very large, since all offset-returning methods return a duration of magnitude
4668less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4669be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004670
4671In any case, the new value is
4672
Tim Peters8bb5ad22003-01-24 02:44:45 +00004673 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004674
Tim Peters8bb5ad22003-01-24 02:44:45 +00004675It's helpful to step back at look at [4] from a higher level: it's simply
4676mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004677
4678At this point, if
4679
Tim Peters8bb5ad22003-01-24 02:44:45 +00004680 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004681
4682we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004683at the start of daylight time. Picture US Eastern for concreteness. The wall
4684time 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 +00004685sense then. The docs ask that an Eastern tzinfo class consider such a time to
4686be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4687on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004688the only spelling that makes sense on the local wall clock.
4689
Tim Petersc5dc4da2003-01-02 17:55:03 +00004690In fact, if [5] holds at this point, we do have the standard-time spelling,
4691but that takes a bit of proof. We first prove a stronger result. What's the
4692difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004693
Tim Peters8bb5ad22003-01-24 02:44:45 +00004694 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004695
Tim Petersc5dc4da2003-01-02 17:55:03 +00004696Now
4697 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004698 (y + y.s).n = by #5
4699 y.n + y.s = since y.n = x.n
4700 x.n + y.s = since z and y are have the same tzinfo member,
4701 y.s = z.s by #2
4702 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004703
Tim Petersc5dc4da2003-01-02 17:55:03 +00004704Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004705
Tim Petersc5dc4da2003-01-02 17:55:03 +00004706 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004707 x.n - ((x.n + z.s) - z.o) = expanding
4708 x.n - x.n - z.s + z.o = cancelling
4709 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004710 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004711
Tim Petersc5dc4da2003-01-02 17:55:03 +00004712So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004713
Tim Petersc5dc4da2003-01-02 17:55:03 +00004714If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004715spelling we wanted in the endcase described above. We're done. Contrarily,
4716if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004717
Tim Petersc5dc4da2003-01-02 17:55:03 +00004718If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4719add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00004720local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004721
Tim Petersc5dc4da2003-01-02 17:55:03 +00004722Let
Tim Petersf3615152003-01-01 21:51:37 +00004723
Tim Peters4fede1a2003-01-04 00:26:59 +00004724 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004725
Tim Peters4fede1a2003-01-04 00:26:59 +00004726and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004727
Tim Peters8bb5ad22003-01-24 02:44:45 +00004728 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004729
Tim Peters8bb5ad22003-01-24 02:44:45 +00004730If so, we're done. If not, the tzinfo class is insane, according to the
4731assumptions we've made. This also requires a bit of proof. As before, let's
4732compute the difference between the LHS and RHS of [8] (and skipping some of
4733the justifications for the kinds of substitutions we've done several times
4734already):
Tim Peters4fede1a2003-01-04 00:26:59 +00004735
Tim Peters8bb5ad22003-01-24 02:44:45 +00004736 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
4737 x.n - (z.n + diff - z'.o) = replacing diff via [6]
4738 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
4739 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
4740 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00004741 - z.o + z'.o = #1 twice
4742 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4743 z'.d - z.d
4744
4745So 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 +00004746we've found the UTC-equivalent so are done. In fact, we stop with [7] and
4747return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00004748
Tim Peters8bb5ad22003-01-24 02:44:45 +00004749How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
4750a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
4751would have to change the result dst() returns: we start in DST, and moving
4752a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00004753
Tim Peters8bb5ad22003-01-24 02:44:45 +00004754There isn't a sane case where this can happen. The closest it gets is at
4755the end of DST, where there's an hour in UTC with no spelling in a hybrid
4756tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
4757that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
4758UTC) because the docs insist on that, but 0:MM is taken as being in daylight
4759time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
4760clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
4761standard time. Since that's what the local clock *does*, we want to map both
4762UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00004763in local time, but so it goes -- it's the way the local clock works.
4764
Tim Peters8bb5ad22003-01-24 02:44:45 +00004765When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4766so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4767z' = 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 +00004768(correctly) concludes that z' is not UTC-equivalent to x.
4769
4770Because we know z.d said z was in daylight time (else [5] would have held and
4771we would have stopped then), and we know z.d != z'.d (else [8] would have held
4772and we we have stopped then), and there are only 2 possible values dst() can
4773return in Eastern, it follows that z'.d must be 0 (which it is in the example,
4774but the reasoning doesn't depend on the example -- it depends on there being
4775two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00004776z' must be in standard time, and is the spelling we want in this case.
4777
4778Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
4779concerned (because it takes z' as being in standard time rather than the
4780daylight time we intend here), but returning it gives the real-life "local
4781clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
4782tz.
4783
4784When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
4785the 1:MM standard time spelling we want.
4786
4787So how can this break? One of the assumptions must be violated. Two
4788possibilities:
4789
47901) [2] effectively says that y.s is invariant across all y belong to a given
4791 time zone. This isn't true if, for political reasons or continental drift,
4792 a region decides to change its base offset from UTC.
4793
47942) There may be versions of "double daylight" time where the tail end of
4795 the analysis gives up a step too early. I haven't thought about that
4796 enough to say.
4797
4798In any case, it's clear that the default fromutc() is strong enough to handle
4799"almost all" time zones: so long as the standard offset is invariant, it
4800doesn't matter if daylight time transition points change from year to year, or
4801if daylight time is skipped in some years; it doesn't matter how large or
4802small dst() may get within its bounds; and it doesn't even matter if some
4803perverse time zone returns a negative dst()). So a breaking case must be
4804pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00004805--------------------------------------------------------------------------- */