blob: 0bd49b262bf8ccab2238d8d04a7d3237f9afad84 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
6#include "modsupport.h"
7#include "structmember.h"
8
9#include <time.h>
10
11#include "datetime.h"
12
13/* We require that C int be at least 32 bits, and use int virtually
14 * everywhere. In just a few cases we use a temp long, where a Python
15 * API returns a C long. In such cases, we have to ensure that the
16 * final result fits in a C int (this can be an issue on 64-bit boxes).
17 */
18#if SIZEOF_INT < 4
19# error "datetime.c requires that C int have at least 32 bits"
20#endif
21
22#define MINYEAR 1
23#define MAXYEAR 9999
24
25/* Nine decimal digits is easy to communicate, and leaves enough room
26 * so that two delta days can be added w/o fear of overflowing a signed
27 * 32-bit int, and with plenty of room left over to absorb any possible
28 * carries from adding seconds.
29 */
30#define MAX_DELTA_DAYS 999999999
31
32/* Rename the long macros in datetime.h to more reasonable short names. */
33#define GET_YEAR PyDateTime_GET_YEAR
34#define GET_MONTH PyDateTime_GET_MONTH
35#define GET_DAY PyDateTime_GET_DAY
36#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
37#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
38#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
39#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
40
41/* Date accessors for date and datetime. */
42#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
43 ((o)->data[1] = ((v) & 0x00ff)))
44#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
45#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
46
47/* Date/Time accessors for datetime. */
48#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
49#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
50#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
51#define DATE_SET_MICROSECOND(o, v) \
52 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
53 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
54 ((o)->data[9] = ((v) & 0x0000ff)))
55
56/* Time accessors for time. */
57#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
58#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
59#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
60#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
61#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
62#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
63#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
64#define TIME_SET_MICROSECOND(o, v) \
65 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
66 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
67 ((o)->data[5] = ((v) & 0x0000ff)))
68
69/* Delta accessors for timedelta. */
70#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
71#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
72#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
73
74#define SET_TD_DAYS(o, v) ((o)->days = (v))
75#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
76#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
77
Tim Petersa032d2e2003-01-11 00:15:54 +000078/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
79 * p->hastzinfo.
80 */
81#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
82
Tim Peters2a799bf2002-12-16 20:18:38 +000083/* Forward declarations. */
84static PyTypeObject PyDateTime_DateType;
85static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +000086static PyTypeObject PyDateTime_DeltaType;
87static PyTypeObject PyDateTime_TimeType;
88static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +000089
90/* ---------------------------------------------------------------------------
91 * Math utilities.
92 */
93
94/* k = i+j overflows iff k differs in sign from both inputs,
95 * iff k^i has sign bit set and k^j has sign bit set,
96 * iff (k^i)&(k^j) has sign bit set.
97 */
98#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
99 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
100
101/* Compute Python divmod(x, y), returning the quotient and storing the
102 * remainder into *r. The quotient is the floor of x/y, and that's
103 * the real point of this. C will probably truncate instead (C99
104 * requires truncation; C89 left it implementation-defined).
105 * Simplification: we *require* that y > 0 here. That's appropriate
106 * for all the uses made of it. This simplifies the code and makes
107 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
108 * overflow case).
109 */
110static int
111divmod(int x, int y, int *r)
112{
113 int quo;
114
115 assert(y > 0);
116 quo = x / y;
117 *r = x - quo * y;
118 if (*r < 0) {
119 --quo;
120 *r += y;
121 }
122 assert(0 <= *r && *r < y);
123 return quo;
124}
125
Tim Peters5d644dd2003-01-02 16:32:54 +0000126/* Round a double to the nearest long. |x| must be small enough to fit
127 * in a C long; this is not checked.
128 */
129static long
130round_to_long(double x)
131{
132 if (x >= 0.0)
133 x = floor(x + 0.5);
134 else
135 x = ceil(x - 0.5);
136 return (long)x;
137}
138
Tim Peters2a799bf2002-12-16 20:18:38 +0000139/* ---------------------------------------------------------------------------
140 * General calendrical helper functions
141 */
142
143/* For each month ordinal in 1..12, the number of days in that month,
144 * and the number of days before that month in the same year. These
145 * are correct for non-leap years only.
146 */
147static int _days_in_month[] = {
148 0, /* unused; this vector uses 1-based indexing */
149 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
150};
151
152static int _days_before_month[] = {
153 0, /* unused; this vector uses 1-based indexing */
154 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
155};
156
157/* year -> 1 if leap year, else 0. */
158static int
159is_leap(int year)
160{
161 /* Cast year to unsigned. The result is the same either way, but
162 * C can generate faster code for unsigned mod than for signed
163 * mod (especially for % 4 -- a good compiler should just grab
164 * the last 2 bits when the LHS is unsigned).
165 */
166 const unsigned int ayear = (unsigned int)year;
167 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
168}
169
170/* year, month -> number of days in that month in that year */
171static int
172days_in_month(int year, int month)
173{
174 assert(month >= 1);
175 assert(month <= 12);
176 if (month == 2 && is_leap(year))
177 return 29;
178 else
179 return _days_in_month[month];
180}
181
182/* year, month -> number of days in year preceeding first day of month */
183static int
184days_before_month(int year, int month)
185{
186 int days;
187
188 assert(month >= 1);
189 assert(month <= 12);
190 days = _days_before_month[month];
191 if (month > 2 && is_leap(year))
192 ++days;
193 return days;
194}
195
196/* year -> number of days before January 1st of year. Remember that we
197 * start with year 1, so days_before_year(1) == 0.
198 */
199static int
200days_before_year(int year)
201{
202 int y = year - 1;
203 /* This is incorrect if year <= 0; we really want the floor
204 * here. But so long as MINYEAR is 1, the smallest year this
205 * can see is 0 (this can happen in some normalization endcases),
206 * so we'll just special-case that.
207 */
208 assert (year >= 0);
209 if (y >= 0)
210 return y*365 + y/4 - y/100 + y/400;
211 else {
212 assert(y == -1);
213 return -366;
214 }
215}
216
217/* Number of days in 4, 100, and 400 year cycles. That these have
218 * the correct values is asserted in the module init function.
219 */
220#define DI4Y 1461 /* days_before_year(5); days in 4 years */
221#define DI100Y 36524 /* days_before_year(101); days in 100 years */
222#define DI400Y 146097 /* days_before_year(401); days in 400 years */
223
224/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
225static void
226ord_to_ymd(int ordinal, int *year, int *month, int *day)
227{
228 int n, n1, n4, n100, n400, leapyear, preceding;
229
230 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
231 * leap years repeats exactly every 400 years. The basic strategy is
232 * to find the closest 400-year boundary at or before ordinal, then
233 * work with the offset from that boundary to ordinal. Life is much
234 * clearer if we subtract 1 from ordinal first -- then the values
235 * of ordinal at 400-year boundaries are exactly those divisible
236 * by DI400Y:
237 *
238 * D M Y n n-1
239 * -- --- ---- ---------- ----------------
240 * 31 Dec -400 -DI400Y -DI400Y -1
241 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
242 * ...
243 * 30 Dec 000 -1 -2
244 * 31 Dec 000 0 -1
245 * 1 Jan 001 1 0 400-year boundary
246 * 2 Jan 001 2 1
247 * 3 Jan 001 3 2
248 * ...
249 * 31 Dec 400 DI400Y DI400Y -1
250 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
251 */
252 assert(ordinal >= 1);
253 --ordinal;
254 n400 = ordinal / DI400Y;
255 n = ordinal % DI400Y;
256 *year = n400 * 400 + 1;
257
258 /* Now n is the (non-negative) offset, in days, from January 1 of
259 * year, to the desired date. Now compute how many 100-year cycles
260 * precede n.
261 * Note that it's possible for n100 to equal 4! In that case 4 full
262 * 100-year cycles precede the desired day, which implies the
263 * desired day is December 31 at the end of a 400-year cycle.
264 */
265 n100 = n / DI100Y;
266 n = n % DI100Y;
267
268 /* Now compute how many 4-year cycles precede it. */
269 n4 = n / DI4Y;
270 n = n % DI4Y;
271
272 /* And now how many single years. Again n1 can be 4, and again
273 * meaning that the desired day is December 31 at the end of the
274 * 4-year cycle.
275 */
276 n1 = n / 365;
277 n = n % 365;
278
279 *year += n100 * 100 + n4 * 4 + n1;
280 if (n1 == 4 || n100 == 4) {
281 assert(n == 0);
282 *year -= 1;
283 *month = 12;
284 *day = 31;
285 return;
286 }
287
288 /* Now the year is correct, and n is the offset from January 1. We
289 * find the month via an estimate that's either exact or one too
290 * large.
291 */
292 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
293 assert(leapyear == is_leap(*year));
294 *month = (n + 50) >> 5;
295 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
296 if (preceding > n) {
297 /* estimate is too large */
298 *month -= 1;
299 preceding -= days_in_month(*year, *month);
300 }
301 n -= preceding;
302 assert(0 <= n);
303 assert(n < days_in_month(*year, *month));
304
305 *day = n + 1;
306}
307
308/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
309static int
310ymd_to_ord(int year, int month, int day)
311{
312 return days_before_year(year) + days_before_month(year, month) + day;
313}
314
315/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
316static int
317weekday(int year, int month, int day)
318{
319 return (ymd_to_ord(year, month, day) + 6) % 7;
320}
321
322/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
323 * first calendar week containing a Thursday.
324 */
325static int
326iso_week1_monday(int year)
327{
328 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
329 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
330 int first_weekday = (first_day + 6) % 7;
331 /* ordinal of closest Monday at or before 1/1 */
332 int week1_monday = first_day - first_weekday;
333
334 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
335 week1_monday += 7;
336 return week1_monday;
337}
338
339/* ---------------------------------------------------------------------------
340 * Range checkers.
341 */
342
343/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
344 * If not, raise OverflowError and return -1.
345 */
346static int
347check_delta_day_range(int days)
348{
349 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
350 return 0;
351 PyErr_Format(PyExc_OverflowError,
352 "days=%d; must have magnitude <= %d",
Guido van Rossumbd43e912002-12-16 20:34:55 +0000353 days, MAX_DELTA_DAYS);
Tim Peters2a799bf2002-12-16 20:18:38 +0000354 return -1;
355}
356
357/* Check that date arguments are in range. Return 0 if they are. If they
358 * aren't, raise ValueError and return -1.
359 */
360static int
361check_date_args(int year, int month, int day)
362{
363
364 if (year < MINYEAR || year > MAXYEAR) {
365 PyErr_SetString(PyExc_ValueError,
366 "year is out of range");
367 return -1;
368 }
369 if (month < 1 || month > 12) {
370 PyErr_SetString(PyExc_ValueError,
371 "month must be in 1..12");
372 return -1;
373 }
374 if (day < 1 || day > days_in_month(year, month)) {
375 PyErr_SetString(PyExc_ValueError,
376 "day is out of range for month");
377 return -1;
378 }
379 return 0;
380}
381
382/* Check that time arguments are in range. Return 0 if they are. If they
383 * aren't, raise ValueError and return -1.
384 */
385static int
386check_time_args(int h, int m, int s, int us)
387{
388 if (h < 0 || h > 23) {
389 PyErr_SetString(PyExc_ValueError,
390 "hour must be in 0..23");
391 return -1;
392 }
393 if (m < 0 || m > 59) {
394 PyErr_SetString(PyExc_ValueError,
395 "minute must be in 0..59");
396 return -1;
397 }
398 if (s < 0 || s > 59) {
399 PyErr_SetString(PyExc_ValueError,
400 "second must be in 0..59");
401 return -1;
402 }
403 if (us < 0 || us > 999999) {
404 PyErr_SetString(PyExc_ValueError,
405 "microsecond must be in 0..999999");
406 return -1;
407 }
408 return 0;
409}
410
411/* ---------------------------------------------------------------------------
412 * Normalization utilities.
413 */
414
415/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
416 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
417 * at least factor, enough of *lo is converted into "hi" units so that
418 * 0 <= *lo < factor. The input values must be such that int overflow
419 * is impossible.
420 */
421static void
422normalize_pair(int *hi, int *lo, int factor)
423{
424 assert(factor > 0);
425 assert(lo != hi);
426 if (*lo < 0 || *lo >= factor) {
427 const int num_hi = divmod(*lo, factor, lo);
428 const int new_hi = *hi + num_hi;
429 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
430 *hi = new_hi;
431 }
432 assert(0 <= *lo && *lo < factor);
433}
434
435/* Fiddle days (d), seconds (s), and microseconds (us) so that
436 * 0 <= *s < 24*3600
437 * 0 <= *us < 1000000
438 * The input values must be such that the internals don't overflow.
439 * The way this routine is used, we don't get close.
440 */
441static void
442normalize_d_s_us(int *d, int *s, int *us)
443{
444 if (*us < 0 || *us >= 1000000) {
445 normalize_pair(s, us, 1000000);
446 /* |s| can't be bigger than about
447 * |original s| + |original us|/1000000 now.
448 */
449
450 }
451 if (*s < 0 || *s >= 24*3600) {
452 normalize_pair(d, s, 24*3600);
453 /* |d| can't be bigger than about
454 * |original d| +
455 * (|original s| + |original us|/1000000) / (24*3600) now.
456 */
457 }
458 assert(0 <= *s && *s < 24*3600);
459 assert(0 <= *us && *us < 1000000);
460}
461
462/* Fiddle years (y), months (m), and days (d) so that
463 * 1 <= *m <= 12
464 * 1 <= *d <= days_in_month(*y, *m)
465 * The input values must be such that the internals don't overflow.
466 * The way this routine is used, we don't get close.
467 */
468static void
469normalize_y_m_d(int *y, int *m, int *d)
470{
471 int dim; /* # of days in month */
472
473 /* This gets muddy: the proper range for day can't be determined
474 * without knowing the correct month and year, but if day is, e.g.,
475 * plus or minus a million, the current month and year values make
476 * no sense (and may also be out of bounds themselves).
477 * Saying 12 months == 1 year should be non-controversial.
478 */
479 if (*m < 1 || *m > 12) {
480 --*m;
481 normalize_pair(y, m, 12);
482 ++*m;
483 /* |y| can't be bigger than about
484 * |original y| + |original m|/12 now.
485 */
486 }
487 assert(1 <= *m && *m <= 12);
488
489 /* Now only day can be out of bounds (year may also be out of bounds
490 * for a datetime object, but we don't care about that here).
491 * If day is out of bounds, what to do is arguable, but at least the
492 * method here is principled and explainable.
493 */
494 dim = days_in_month(*y, *m);
495 if (*d < 1 || *d > dim) {
496 /* Move day-1 days from the first of the month. First try to
497 * get off cheap if we're only one day out of range
498 * (adjustments for timezone alone can't be worse than that).
499 */
500 if (*d == 0) {
501 --*m;
502 if (*m > 0)
503 *d = days_in_month(*y, *m);
504 else {
505 --*y;
506 *m = 12;
507 *d = 31;
508 }
509 }
510 else if (*d == dim + 1) {
511 /* move forward a day */
512 ++*m;
513 *d = 1;
514 if (*m > 12) {
515 *m = 1;
516 ++*y;
517 }
518 }
519 else {
520 int ordinal = ymd_to_ord(*y, *m, 1) +
521 *d - 1;
522 ord_to_ymd(ordinal, y, m, d);
523 }
524 }
525 assert(*m > 0);
526 assert(*d > 0);
527}
528
529/* Fiddle out-of-bounds months and days so that the result makes some kind
530 * of sense. The parameters are both inputs and outputs. Returns < 0 on
531 * failure, where failure means the adjusted year is out of bounds.
532 */
533static int
534normalize_date(int *year, int *month, int *day)
535{
536 int result;
537
538 normalize_y_m_d(year, month, day);
539 if (MINYEAR <= *year && *year <= MAXYEAR)
540 result = 0;
541 else {
542 PyErr_SetString(PyExc_OverflowError,
543 "date value out of range");
544 result = -1;
545 }
546 return result;
547}
548
549/* Force all the datetime fields into range. The parameters are both
550 * inputs and outputs. Returns < 0 on error.
551 */
552static int
553normalize_datetime(int *year, int *month, int *day,
554 int *hour, int *minute, int *second,
555 int *microsecond)
556{
557 normalize_pair(second, microsecond, 1000000);
558 normalize_pair(minute, second, 60);
559 normalize_pair(hour, minute, 60);
560 normalize_pair(day, hour, 24);
561 return normalize_date(year, month, day);
562}
563
564/* ---------------------------------------------------------------------------
565 * tzinfo helpers.
566 */
567
Tim Peters855fe882002-12-22 03:43:39 +0000568/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
569 * raise TypeError and return -1.
570 */
571static int
572check_tzinfo_subclass(PyObject *p)
573{
574 if (p == Py_None || PyTZInfo_Check(p))
575 return 0;
576 PyErr_Format(PyExc_TypeError,
577 "tzinfo argument must be None or of a tzinfo subclass, "
578 "not type '%s'",
579 p->ob_type->tp_name);
580 return -1;
581}
582
Tim Petersbad8ff02002-12-30 20:52:32 +0000583/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000584 * If tzinfo is None, returns None.
585 */
586static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000587call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000588{
589 PyObject *result;
590
Tim Petersbad8ff02002-12-30 20:52:32 +0000591 assert(tzinfo && methname && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000592 assert(check_tzinfo_subclass(tzinfo) >= 0);
593 if (tzinfo == Py_None) {
594 result = Py_None;
595 Py_INCREF(result);
596 }
597 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000598 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000599 return result;
600}
601
Tim Peters2a799bf2002-12-16 20:18:38 +0000602/* If self has a tzinfo member, return a BORROWED reference to it. Else
603 * return NULL, which is NOT AN ERROR. There are no error returns here,
604 * and the caller must not decref the result.
605 */
606static PyObject *
607get_tzinfo_member(PyObject *self)
608{
609 PyObject *tzinfo = NULL;
610
Tim Petersa9bc1682003-01-11 03:39:11 +0000611 if (PyDateTime_Check(self) && HASTZINFO(self))
612 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
Tim Petersa032d2e2003-01-11 00:15:54 +0000613 else if (PyTime_Check(self) && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +0000614 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000615
616 return tzinfo;
617}
618
Tim Petersbad8ff02002-12-30 20:52:32 +0000619/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000620 * result. tzinfo must be an instance of the tzinfo class. If the method
621 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000622 * return None or timedelta, TypeError is raised and this returns -1. If it
623 * returnsa timedelta and the value is out of range or isn't a whole number
624 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000625 * Else *none is set to 0 and the integer method result is returned.
626 */
627static int
628call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
629 int *none)
630{
631 PyObject *u;
Tim Peters397301e2003-01-02 21:28:08 +0000632 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000633
634 assert(tzinfo != NULL);
635 assert(PyTZInfo_Check(tzinfo));
636 assert(tzinfoarg != NULL);
637
638 *none = 0;
Tim Petersbad8ff02002-12-30 20:52:32 +0000639 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000640 if (u == NULL)
641 return -1;
642
Tim Peters27362852002-12-23 16:17:39 +0000643 else if (u == Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +0000644 result = 0;
645 *none = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000646 }
Tim Peters855fe882002-12-22 03:43:39 +0000647 else if (PyDelta_Check(u)) {
648 const int days = GET_TD_DAYS(u);
649 if (days < -1 || days > 0)
650 result = 24*60; /* trigger ValueError below */
651 else {
652 /* next line can't overflow because we know days
653 * is -1 or 0 now
654 */
655 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
656 result = divmod(ss, 60, &ss);
657 if (ss || GET_TD_MICROSECONDS(u)) {
658 PyErr_Format(PyExc_ValueError,
659 "tzinfo.%s() must return a "
660 "whole number of minutes",
661 name);
662 result = -1;
Tim Peters855fe882002-12-22 03:43:39 +0000663 }
664 }
665 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000666 else {
667 PyErr_Format(PyExc_TypeError,
Tim Peters397301e2003-01-02 21:28:08 +0000668 "tzinfo.%s() must return None or "
Tim Peters855fe882002-12-22 03:43:39 +0000669 "timedelta, not '%s'",
670 name, u->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000671 }
672
Tim Peters2a799bf2002-12-16 20:18:38 +0000673 Py_DECREF(u);
674 if (result < -1439 || result > 1439) {
675 PyErr_Format(PyExc_ValueError,
Neal Norwitz506a2242003-01-04 01:02:25 +0000676 "tzinfo.%s() returned %d; must be in "
Tim Peters2a799bf2002-12-16 20:18:38 +0000677 "-1439 .. 1439",
678 name, result);
679 result = -1;
680 }
Tim Peters397301e2003-01-02 21:28:08 +0000681 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000682}
683
684/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
685 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
686 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000687 * doesn't return None or timedelta, TypeError is raised and this returns -1.
688 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
689 * # of minutes), ValueError is raised and this returns -1. Else *none is
690 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000691 */
692static int
693call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
694{
695 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
696}
697
Tim Peters855fe882002-12-22 03:43:39 +0000698static PyObject *new_delta(int d, int sec, int usec, int normalize);
699
Tim Petersbad8ff02002-12-30 20:52:32 +0000700/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
701 */
Tim Peters855fe882002-12-22 03:43:39 +0000702static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000703offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Tim Peters855fe882002-12-22 03:43:39 +0000704 PyObject *result;
705
Tim Petersbad8ff02002-12-30 20:52:32 +0000706 assert(tzinfo && name && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000707 if (tzinfo == Py_None) {
708 result = Py_None;
709 Py_INCREF(result);
710 }
711 else {
712 int none;
Tim Petersbad8ff02002-12-30 20:52:32 +0000713 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
714 &none);
Tim Peters855fe882002-12-22 03:43:39 +0000715 if (offset < 0 && PyErr_Occurred())
716 return NULL;
717 if (none) {
718 result = Py_None;
719 Py_INCREF(result);
720 }
721 else
722 result = new_delta(0, offset * 60, 0, 1);
723 }
724 return result;
725}
726
Tim Peters2a799bf2002-12-16 20:18:38 +0000727/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
728 * result. tzinfo must be an instance of the tzinfo class. If dst()
729 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000730 & doesn't return None or timedelta, TypeError is raised and this
731 * returns -1. If dst() returns an invalid timedelta for for a UTC offset,
732 * ValueError is raised and this returns -1. Else *none is set to 0 and
733 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000734 */
735static int
736call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
737{
738 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
739}
740
Tim Petersbad8ff02002-12-30 20:52:32 +0000741/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000742 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000743 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000744 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000745 */
746static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000747call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000748{
749 PyObject *result;
750
751 assert(tzinfo != NULL);
Tim Peters855fe882002-12-22 03:43:39 +0000752 assert(check_tzinfo_subclass(tzinfo) >= 0);
Tim Petersbad8ff02002-12-30 20:52:32 +0000753 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000754
Tim Peters855fe882002-12-22 03:43:39 +0000755 if (tzinfo == Py_None) {
756 result = Py_None;
757 Py_INCREF(result);
758 }
759 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000760 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000761
762 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
763 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
Tim Peters2a799bf2002-12-16 20:18:38 +0000764 "return None or a string, not '%s'",
765 result->ob_type->tp_name);
766 Py_DECREF(result);
767 result = NULL;
768 }
769 return result;
770}
771
772typedef enum {
773 /* an exception has been set; the caller should pass it on */
774 OFFSET_ERROR,
775
Tim Petersa9bc1682003-01-11 03:39:11 +0000776 /* type isn't date, datetime, or time subclass */
Tim Peters2a799bf2002-12-16 20:18:38 +0000777 OFFSET_UNKNOWN,
778
779 /* date,
Tim Petersa9bc1682003-01-11 03:39:11 +0000780 * datetime with !hastzinfo
781 * datetime with None tzinfo,
782 * datetime where utcoffset() returns None
Tim Peters37f39822003-01-10 03:49:02 +0000783 * time with !hastzinfo
784 * time with None tzinfo,
785 * time where utcoffset() returns None
Tim Peters2a799bf2002-12-16 20:18:38 +0000786 */
787 OFFSET_NAIVE,
788
Tim Petersa9bc1682003-01-11 03:39:11 +0000789 /* time or datetime where utcoffset() doesn't return None */
Tim Peters2a799bf2002-12-16 20:18:38 +0000790 OFFSET_AWARE,
791} naivety;
792
Tim Peters14b69412002-12-22 18:10:22 +0000793/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000794 * the "naivety" typedef for details. If the type is aware, *offset is set
795 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000796 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000797 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000798 */
799static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000800classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000801{
802 int none;
803 PyObject *tzinfo;
804
Tim Peterse39a80c2002-12-30 21:28:52 +0000805 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000806 *offset = 0;
Tim Peters14b69412002-12-22 18:10:22 +0000807 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
Tim Peters2a799bf2002-12-16 20:18:38 +0000808 if (tzinfo == Py_None)
809 return OFFSET_NAIVE;
Tim Peters14b69412002-12-22 18:10:22 +0000810 if (tzinfo == NULL) {
811 /* note that a datetime passes the PyDate_Check test */
812 return (PyTime_Check(op) || PyDate_Check(op)) ?
813 OFFSET_NAIVE : OFFSET_UNKNOWN;
814 }
Tim Peterse39a80c2002-12-30 21:28:52 +0000815 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000816 if (*offset == -1 && PyErr_Occurred())
817 return OFFSET_ERROR;
818 return none ? OFFSET_NAIVE : OFFSET_AWARE;
819}
820
Tim Peters00237032002-12-27 02:21:51 +0000821/* Classify two objects as to whether they're naive or offset-aware.
822 * This isn't quite the same as calling classify_utcoffset() twice: for
823 * binary operations (comparison and subtraction), we generally want to
824 * ignore the tzinfo members if they're identical. This is by design,
825 * so that results match "naive" expectations when mixing objects from a
826 * single timezone. So in that case, this sets both offsets to 0 and
827 * both naiveties to OFFSET_NAIVE.
828 * The function returns 0 if everything's OK, and -1 on error.
829 */
830static int
831classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Tim Peterse39a80c2002-12-30 21:28:52 +0000832 PyObject *tzinfoarg1,
833 PyObject *o2, int *offset2, naivety *n2,
834 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +0000835{
836 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
837 *offset1 = *offset2 = 0;
838 *n1 = *n2 = OFFSET_NAIVE;
839 }
840 else {
Tim Peterse39a80c2002-12-30 21:28:52 +0000841 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
Tim Peters00237032002-12-27 02:21:51 +0000842 if (*n1 == OFFSET_ERROR)
843 return -1;
Tim Peterse39a80c2002-12-30 21:28:52 +0000844 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
Tim Peters00237032002-12-27 02:21:51 +0000845 if (*n2 == OFFSET_ERROR)
846 return -1;
847 }
848 return 0;
849}
850
Tim Peters2a799bf2002-12-16 20:18:38 +0000851/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
852 * stuff
853 * ", tzinfo=" + repr(tzinfo)
854 * before the closing ")".
855 */
856static PyObject *
857append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
858{
859 PyObject *temp;
860
861 assert(PyString_Check(repr));
862 assert(tzinfo);
863 if (tzinfo == Py_None)
864 return repr;
865 /* Get rid of the trailing ')'. */
866 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
867 temp = PyString_FromStringAndSize(PyString_AsString(repr),
868 PyString_Size(repr) - 1);
869 Py_DECREF(repr);
870 if (temp == NULL)
871 return NULL;
872 repr = temp;
873
874 /* Append ", tzinfo=". */
875 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
876
877 /* Append repr(tzinfo). */
878 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
879
880 /* Add a closing paren. */
881 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
882 return repr;
883}
884
885/* ---------------------------------------------------------------------------
886 * String format helpers.
887 */
888
889static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +0000890format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +0000891{
892 static char *DayNames[] = {
893 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
894 };
895 static char *MonthNames[] = {
896 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
897 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
898 };
899
900 char buffer[128];
901 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
902
903 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
904 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
905 GET_DAY(date), hours, minutes, seconds,
906 GET_YEAR(date));
907 return PyString_FromString(buffer);
908}
909
910/* Add an hours & minutes UTC offset string to buf. buf has no more than
911 * buflen bytes remaining. The UTC offset is gotten by calling
912 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
913 * *buf, and that's all. Else the returned value is checked for sanity (an
914 * integer in range), and if that's OK it's converted to an hours & minutes
915 * string of the form
916 * sign HH sep MM
917 * Returns 0 if everything is OK. If the return value from utcoffset() is
918 * bogus, an appropriate exception is set and -1 is returned.
919 */
920static int
Tim Peters328fff72002-12-20 01:31:27 +0000921format_utcoffset(char *buf, size_t buflen, const char *sep,
Tim Peters2a799bf2002-12-16 20:18:38 +0000922 PyObject *tzinfo, PyObject *tzinfoarg)
923{
924 int offset;
925 int hours;
926 int minutes;
927 char sign;
928 int none;
929
930 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
931 if (offset == -1 && PyErr_Occurred())
932 return -1;
933 if (none) {
934 *buf = '\0';
935 return 0;
936 }
937 sign = '+';
938 if (offset < 0) {
939 sign = '-';
940 offset = - offset;
941 }
942 hours = divmod(offset, 60, &minutes);
943 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
944 return 0;
945}
946
947/* I sure don't want to reproduce the strftime code from the time module,
948 * so this imports the module and calls it. All the hair is due to
949 * giving special meanings to the %z and %Z format codes via a preprocessing
950 * step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +0000951 * tzinfoarg is the argument to pass to the object's tzinfo method, if
952 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +0000953 */
954static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000955wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
956 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000957{
958 PyObject *result = NULL; /* guilty until proved innocent */
959
960 PyObject *zreplacement = NULL; /* py string, replacement for %z */
961 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
962
963 char *pin; /* pointer to next char in input format */
964 char ch; /* next char in input format */
965
966 PyObject *newfmt = NULL; /* py string, the output format */
967 char *pnew; /* pointer to available byte in output format */
968 char totalnew; /* number bytes total in output format buffer,
969 exclusive of trailing \0 */
970 char usednew; /* number bytes used so far in output format buffer */
971
972 char *ptoappend; /* pointer to string to append to output buffer */
973 int ntoappend; /* # of bytes to append to output buffer */
974
Tim Peters2a799bf2002-12-16 20:18:38 +0000975 assert(object && format && timetuple);
976 assert(PyString_Check(format));
977
Tim Petersd6844152002-12-22 20:58:42 +0000978 /* Give up if the year is before 1900.
979 * Python strftime() plays games with the year, and different
980 * games depending on whether envar PYTHON2K is set. This makes
981 * years before 1900 a nightmare, even if the platform strftime
982 * supports them (and not all do).
983 * We could get a lot farther here by avoiding Python's strftime
984 * wrapper and calling the C strftime() directly, but that isn't
985 * an option in the Python implementation of this module.
986 */
987 {
988 long year;
989 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
990 if (pyyear == NULL) return NULL;
991 assert(PyInt_Check(pyyear));
992 year = PyInt_AsLong(pyyear);
993 Py_DECREF(pyyear);
994 if (year < 1900) {
995 PyErr_Format(PyExc_ValueError, "year=%ld is before "
996 "1900; the datetime strftime() "
997 "methods require year >= 1900",
998 year);
999 return NULL;
1000 }
1001 }
1002
Tim Peters2a799bf2002-12-16 20:18:38 +00001003 /* Scan the input format, looking for %z and %Z escapes, building
Tim Peters328fff72002-12-20 01:31:27 +00001004 * a new format. Since computing the replacements for those codes
1005 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +00001006 */
1007 totalnew = PyString_Size(format); /* realistic if no %z/%Z */
1008 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1009 if (newfmt == NULL) goto Done;
1010 pnew = PyString_AsString(newfmt);
1011 usednew = 0;
1012
1013 pin = PyString_AsString(format);
1014 while ((ch = *pin++) != '\0') {
1015 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +00001016 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001017 ntoappend = 1;
1018 }
1019 else if ((ch = *pin++) == '\0') {
1020 /* There's a lone trailing %; doesn't make sense. */
1021 PyErr_SetString(PyExc_ValueError, "strftime format "
1022 "ends with raw %");
1023 goto Done;
1024 }
1025 /* A % has been seen and ch is the character after it. */
1026 else if (ch == 'z') {
1027 if (zreplacement == NULL) {
1028 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +00001029 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +00001030 PyObject *tzinfo = get_tzinfo_member(object);
1031 zreplacement = PyString_FromString("");
1032 if (zreplacement == NULL) goto Done;
1033 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001034 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001035 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001036 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001037 "",
1038 tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00001039 tzinfoarg) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001040 goto Done;
1041 Py_DECREF(zreplacement);
1042 zreplacement = PyString_FromString(buf);
1043 if (zreplacement == NULL) goto Done;
1044 }
1045 }
1046 assert(zreplacement != NULL);
1047 ptoappend = PyString_AsString(zreplacement);
1048 ntoappend = PyString_Size(zreplacement);
1049 }
1050 else if (ch == 'Z') {
1051 /* format tzname */
1052 if (Zreplacement == NULL) {
1053 PyObject *tzinfo = get_tzinfo_member(object);
1054 Zreplacement = PyString_FromString("");
1055 if (Zreplacement == NULL) goto Done;
1056 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001057 PyObject *temp;
1058 assert(tzinfoarg != NULL);
1059 temp = call_tzname(tzinfo, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001060 if (temp == NULL) goto Done;
1061 if (temp != Py_None) {
1062 assert(PyString_Check(temp));
1063 /* Since the tzname is getting
1064 * stuffed into the format, we
1065 * have to double any % signs
1066 * so that strftime doesn't
1067 * treat them as format codes.
1068 */
1069 Py_DECREF(Zreplacement);
1070 Zreplacement = PyObject_CallMethod(
1071 temp, "replace",
1072 "ss", "%", "%%");
1073 Py_DECREF(temp);
1074 if (Zreplacement == NULL)
1075 goto Done;
1076 }
1077 else
1078 Py_DECREF(temp);
1079 }
1080 }
1081 assert(Zreplacement != NULL);
1082 ptoappend = PyString_AsString(Zreplacement);
1083 ntoappend = PyString_Size(Zreplacement);
1084 }
1085 else {
Tim Peters328fff72002-12-20 01:31:27 +00001086 /* percent followed by neither z nor Z */
1087 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001088 ntoappend = 2;
1089 }
1090
1091 /* Append the ntoappend chars starting at ptoappend to
1092 * the new format.
1093 */
1094 assert(ntoappend >= 0);
1095 if (ntoappend == 0)
1096 continue;
1097 while (usednew + ntoappend > totalnew) {
1098 int bigger = totalnew << 1;
1099 if ((bigger >> 1) != totalnew) { /* overflow */
1100 PyErr_NoMemory();
1101 goto Done;
1102 }
1103 if (_PyString_Resize(&newfmt, bigger) < 0)
1104 goto Done;
1105 totalnew = bigger;
1106 pnew = PyString_AsString(newfmt) + usednew;
1107 }
1108 memcpy(pnew, ptoappend, ntoappend);
1109 pnew += ntoappend;
1110 usednew += ntoappend;
1111 assert(usednew <= totalnew);
1112 } /* end while() */
1113
1114 if (_PyString_Resize(&newfmt, usednew) < 0)
1115 goto Done;
1116 {
1117 PyObject *time = PyImport_ImportModule("time");
1118 if (time == NULL)
1119 goto Done;
1120 result = PyObject_CallMethod(time, "strftime", "OO",
1121 newfmt, timetuple);
1122 Py_DECREF(time);
1123 }
1124 Done:
1125 Py_XDECREF(zreplacement);
1126 Py_XDECREF(Zreplacement);
1127 Py_XDECREF(newfmt);
1128 return result;
1129}
1130
1131static char *
1132isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1133{
1134 int x;
1135 x = PyOS_snprintf(buffer, bufflen,
1136 "%04d-%02d-%02d",
1137 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1138 return buffer + x;
1139}
1140
1141static void
1142isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1143{
1144 int us = DATE_GET_MICROSECOND(dt);
1145
1146 PyOS_snprintf(buffer, bufflen,
1147 "%02d:%02d:%02d", /* 8 characters */
1148 DATE_GET_HOUR(dt),
1149 DATE_GET_MINUTE(dt),
1150 DATE_GET_SECOND(dt));
1151 if (us)
1152 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1153}
1154
1155/* ---------------------------------------------------------------------------
1156 * Wrap functions from the time module. These aren't directly available
1157 * from C. Perhaps they should be.
1158 */
1159
1160/* Call time.time() and return its result (a Python float). */
1161static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001162time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001163{
1164 PyObject *result = NULL;
1165 PyObject *time = PyImport_ImportModule("time");
1166
1167 if (time != NULL) {
1168 result = PyObject_CallMethod(time, "time", "()");
1169 Py_DECREF(time);
1170 }
1171 return result;
1172}
1173
1174/* Build a time.struct_time. The weekday and day number are automatically
1175 * computed from the y,m,d args.
1176 */
1177static PyObject *
1178build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1179{
1180 PyObject *time;
1181 PyObject *result = NULL;
1182
1183 time = PyImport_ImportModule("time");
1184 if (time != NULL) {
1185 result = PyObject_CallMethod(time, "struct_time",
1186 "((iiiiiiiii))",
1187 y, m, d,
1188 hh, mm, ss,
1189 weekday(y, m, d),
1190 days_before_month(y, m) + d,
1191 dstflag);
1192 Py_DECREF(time);
1193 }
1194 return result;
1195}
1196
1197/* ---------------------------------------------------------------------------
1198 * Miscellaneous helpers.
1199 */
1200
1201/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1202 * The comparisons here all most naturally compute a cmp()-like result.
1203 * This little helper turns that into a bool result for rich comparisons.
1204 */
1205static PyObject *
1206diff_to_bool(int diff, int op)
1207{
1208 PyObject *result;
1209 int istrue;
1210
1211 switch (op) {
1212 case Py_EQ: istrue = diff == 0; break;
1213 case Py_NE: istrue = diff != 0; break;
1214 case Py_LE: istrue = diff <= 0; break;
1215 case Py_GE: istrue = diff >= 0; break;
1216 case Py_LT: istrue = diff < 0; break;
1217 case Py_GT: istrue = diff > 0; break;
1218 default:
1219 assert(! "op unknown");
1220 istrue = 0; /* To shut up compiler */
1221 }
1222 result = istrue ? Py_True : Py_False;
1223 Py_INCREF(result);
1224 return result;
1225}
1226
1227/* ---------------------------------------------------------------------------
1228 * Helpers for setting object fields. These work on pointers to the
1229 * appropriate base class.
1230 */
1231
Tim Petersa9bc1682003-01-11 03:39:11 +00001232/* For date and datetime. */
Tim Peters2a799bf2002-12-16 20:18:38 +00001233static void
1234set_date_fields(PyDateTime_Date *self, int y, int m, int d)
1235{
1236 self->hashcode = -1;
1237 SET_YEAR(self, y);
1238 SET_MONTH(self, m);
1239 SET_DAY(self, d);
1240}
1241
Tim Peters2a799bf2002-12-16 20:18:38 +00001242/* ---------------------------------------------------------------------------
1243 * Create various objects, mostly without range checking.
1244 */
1245
1246/* Create a date instance with no range checking. */
1247static PyObject *
1248new_date(int year, int month, int day)
1249{
1250 PyDateTime_Date *self;
1251
1252 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
1253 if (self != NULL)
1254 set_date_fields(self, year, month, day);
1255 return (PyObject *) self;
1256}
1257
1258/* Create a datetime instance with no range checking. */
1259static PyObject *
1260new_datetime(int year, int month, int day, int hour, int minute,
Tim Petersa9bc1682003-01-11 03:39:11 +00001261 int second, int usecond, PyObject *tzinfo)
Tim Peters2a799bf2002-12-16 20:18:38 +00001262{
1263 PyDateTime_DateTime *self;
Tim Petersa9bc1682003-01-11 03:39:11 +00001264 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001265
Tim Petersa9bc1682003-01-11 03:39:11 +00001266 self = (PyDateTime_DateTime *)PyObject_MALLOC(aware ?
1267 sizeof(PyDateTime_DateTime) :
1268 sizeof(_PyDateTime_BaseDateTime));
1269 if (self == NULL)
1270 return PyErr_NoMemory();
1271 self->hastzinfo = aware;
1272 set_date_fields((PyDateTime_Date *)self, year, month, day);
1273 DATE_SET_HOUR(self, hour);
1274 DATE_SET_MINUTE(self, minute);
1275 DATE_SET_SECOND(self, second);
1276 DATE_SET_MICROSECOND(self, usecond);
1277 if (aware) {
Tim Peters2a799bf2002-12-16 20:18:38 +00001278 Py_INCREF(tzinfo);
1279 self->tzinfo = tzinfo;
1280 }
Tim Petersa9bc1682003-01-11 03:39:11 +00001281 return (PyObject *)PyObject_INIT(self, &PyDateTime_DateTimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00001282}
1283
1284/* Create a time instance with no range checking. */
1285static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00001286new_time(int hour, int minute, int second, int usecond, PyObject *tzinfo)
Tim Peters2a799bf2002-12-16 20:18:38 +00001287{
1288 PyDateTime_Time *self;
Tim Peters37f39822003-01-10 03:49:02 +00001289 char aware = tzinfo != Py_None;
Tim Peters2a799bf2002-12-16 20:18:38 +00001290
Tim Peters37f39822003-01-10 03:49:02 +00001291 self = (PyDateTime_Time *)PyObject_MALLOC(aware ?
1292 sizeof(PyDateTime_Time) :
1293 sizeof(_PyDateTime_BaseTime));
1294 if (self == NULL)
1295 return PyErr_NoMemory();
1296 self->hastzinfo = aware;
Tim Petersa9bc1682003-01-11 03:39:11 +00001297 self->hashcode = -1;
1298 TIME_SET_HOUR(self, hour);
1299 TIME_SET_MINUTE(self, minute);
1300 TIME_SET_SECOND(self, second);
1301 TIME_SET_MICROSECOND(self, usecond);
Tim Peters37f39822003-01-10 03:49:02 +00001302 if (aware) {
Tim Peters2a799bf2002-12-16 20:18:38 +00001303 Py_INCREF(tzinfo);
1304 self->tzinfo = tzinfo;
1305 }
Tim Peters37f39822003-01-10 03:49:02 +00001306 return (PyObject *)PyObject_INIT(self, &PyDateTime_TimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00001307}
1308
1309/* Create a timedelta instance. Normalize the members iff normalize is
1310 * true. Passing false is a speed optimization, if you know for sure
1311 * that seconds and microseconds are already in their proper ranges. In any
1312 * case, raises OverflowError and returns NULL if the normalized days is out
1313 * of range).
1314 */
1315static PyObject *
1316new_delta(int days, int seconds, int microseconds, int normalize)
1317{
1318 PyDateTime_Delta *self;
1319
1320 if (normalize)
1321 normalize_d_s_us(&days, &seconds, &microseconds);
1322 assert(0 <= seconds && seconds < 24*3600);
1323 assert(0 <= microseconds && microseconds < 1000000);
1324
1325 if (check_delta_day_range(days) < 0)
1326 return NULL;
1327
1328 self = PyObject_New(PyDateTime_Delta, &PyDateTime_DeltaType);
1329 if (self != NULL) {
1330 self->hashcode = -1;
1331 SET_TD_DAYS(self, days);
1332 SET_TD_SECONDS(self, seconds);
1333 SET_TD_MICROSECONDS(self, microseconds);
1334 }
1335 return (PyObject *) self;
1336}
1337
1338
1339/* ---------------------------------------------------------------------------
1340 * Cached Python objects; these are set by the module init function.
1341 */
1342
1343/* Conversion factors. */
1344static PyObject *us_per_us = NULL; /* 1 */
1345static PyObject *us_per_ms = NULL; /* 1000 */
1346static PyObject *us_per_second = NULL; /* 1000000 */
1347static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1348static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1349static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1350static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1351static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1352
1353/* Callables to support unpickling. */
1354static PyObject *date_unpickler_object = NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00001355static PyObject *datetime_unpickler_object = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001356static PyObject *tzinfo_unpickler_object = NULL;
Tim Peters37f39822003-01-10 03:49:02 +00001357static PyObject *time_unpickler_object = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001358
1359/* ---------------------------------------------------------------------------
1360 * Class implementations.
1361 */
1362
1363/*
1364 * PyDateTime_Delta implementation.
1365 */
1366
1367/* Convert a timedelta to a number of us,
1368 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1369 * as a Python int or long.
1370 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1371 * due to ubiquitous overflow possibilities.
1372 */
1373static PyObject *
1374delta_to_microseconds(PyDateTime_Delta *self)
1375{
1376 PyObject *x1 = NULL;
1377 PyObject *x2 = NULL;
1378 PyObject *x3 = NULL;
1379 PyObject *result = NULL;
1380
1381 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1382 if (x1 == NULL)
1383 goto Done;
1384 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1385 if (x2 == NULL)
1386 goto Done;
1387 Py_DECREF(x1);
1388 x1 = NULL;
1389
1390 /* x2 has days in seconds */
1391 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1392 if (x1 == NULL)
1393 goto Done;
1394 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1395 if (x3 == NULL)
1396 goto Done;
1397 Py_DECREF(x1);
1398 Py_DECREF(x2);
1399 x1 = x2 = NULL;
1400
1401 /* x3 has days+seconds in seconds */
1402 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1403 if (x1 == NULL)
1404 goto Done;
1405 Py_DECREF(x3);
1406 x3 = NULL;
1407
1408 /* x1 has days+seconds in us */
1409 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1410 if (x2 == NULL)
1411 goto Done;
1412 result = PyNumber_Add(x1, x2);
1413
1414Done:
1415 Py_XDECREF(x1);
1416 Py_XDECREF(x2);
1417 Py_XDECREF(x3);
1418 return result;
1419}
1420
1421/* Convert a number of us (as a Python int or long) to a timedelta.
1422 */
1423static PyObject *
1424microseconds_to_delta(PyObject *pyus)
1425{
1426 int us;
1427 int s;
1428 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001429 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001430
1431 PyObject *tuple = NULL;
1432 PyObject *num = NULL;
1433 PyObject *result = NULL;
1434
1435 tuple = PyNumber_Divmod(pyus, us_per_second);
1436 if (tuple == NULL)
1437 goto Done;
1438
1439 num = PyTuple_GetItem(tuple, 1); /* us */
1440 if (num == NULL)
1441 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001442 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001443 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001444 if (temp == -1 && PyErr_Occurred())
1445 goto Done;
1446 assert(0 <= temp && temp < 1000000);
1447 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001448 if (us < 0) {
1449 /* The divisor was positive, so this must be an error. */
1450 assert(PyErr_Occurred());
1451 goto Done;
1452 }
1453
1454 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1455 if (num == NULL)
1456 goto Done;
1457 Py_INCREF(num);
1458 Py_DECREF(tuple);
1459
1460 tuple = PyNumber_Divmod(num, seconds_per_day);
1461 if (tuple == NULL)
1462 goto Done;
1463 Py_DECREF(num);
1464
1465 num = PyTuple_GetItem(tuple, 1); /* seconds */
1466 if (num == NULL)
1467 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001468 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001469 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001470 if (temp == -1 && PyErr_Occurred())
1471 goto Done;
1472 assert(0 <= temp && temp < 24*3600);
1473 s = (int)temp;
1474
Tim Peters2a799bf2002-12-16 20:18:38 +00001475 if (s < 0) {
1476 /* The divisor was positive, so this must be an error. */
1477 assert(PyErr_Occurred());
1478 goto Done;
1479 }
1480
1481 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1482 if (num == NULL)
1483 goto Done;
1484 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001485 temp = PyLong_AsLong(num);
1486 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001487 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001488 d = (int)temp;
1489 if ((long)d != temp) {
1490 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1491 "large to fit in a C int");
1492 goto Done;
1493 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001494 result = new_delta(d, s, us, 0);
1495
1496Done:
1497 Py_XDECREF(tuple);
1498 Py_XDECREF(num);
1499 return result;
1500}
1501
1502static PyObject *
1503multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1504{
1505 PyObject *pyus_in;
1506 PyObject *pyus_out;
1507 PyObject *result;
1508
1509 pyus_in = delta_to_microseconds(delta);
1510 if (pyus_in == NULL)
1511 return NULL;
1512
1513 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1514 Py_DECREF(pyus_in);
1515 if (pyus_out == NULL)
1516 return NULL;
1517
1518 result = microseconds_to_delta(pyus_out);
1519 Py_DECREF(pyus_out);
1520 return result;
1521}
1522
1523static PyObject *
1524divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1525{
1526 PyObject *pyus_in;
1527 PyObject *pyus_out;
1528 PyObject *result;
1529
1530 pyus_in = delta_to_microseconds(delta);
1531 if (pyus_in == NULL)
1532 return NULL;
1533
1534 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1535 Py_DECREF(pyus_in);
1536 if (pyus_out == NULL)
1537 return NULL;
1538
1539 result = microseconds_to_delta(pyus_out);
1540 Py_DECREF(pyus_out);
1541 return result;
1542}
1543
1544static PyObject *
1545delta_add(PyObject *left, PyObject *right)
1546{
1547 PyObject *result = Py_NotImplemented;
1548
1549 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1550 /* delta + delta */
1551 /* The C-level additions can't overflow because of the
1552 * invariant bounds.
1553 */
1554 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1555 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1556 int microseconds = GET_TD_MICROSECONDS(left) +
1557 GET_TD_MICROSECONDS(right);
1558 result = new_delta(days, seconds, microseconds, 1);
1559 }
1560
1561 if (result == Py_NotImplemented)
1562 Py_INCREF(result);
1563 return result;
1564}
1565
1566static PyObject *
1567delta_negative(PyDateTime_Delta *self)
1568{
1569 return new_delta(-GET_TD_DAYS(self),
1570 -GET_TD_SECONDS(self),
1571 -GET_TD_MICROSECONDS(self),
1572 1);
1573}
1574
1575static PyObject *
1576delta_positive(PyDateTime_Delta *self)
1577{
1578 /* Could optimize this (by returning self) if this isn't a
1579 * subclass -- but who uses unary + ? Approximately nobody.
1580 */
1581 return new_delta(GET_TD_DAYS(self),
1582 GET_TD_SECONDS(self),
1583 GET_TD_MICROSECONDS(self),
1584 0);
1585}
1586
1587static PyObject *
1588delta_abs(PyDateTime_Delta *self)
1589{
1590 PyObject *result;
1591
1592 assert(GET_TD_MICROSECONDS(self) >= 0);
1593 assert(GET_TD_SECONDS(self) >= 0);
1594
1595 if (GET_TD_DAYS(self) < 0)
1596 result = delta_negative(self);
1597 else
1598 result = delta_positive(self);
1599
1600 return result;
1601}
1602
1603static PyObject *
1604delta_subtract(PyObject *left, PyObject *right)
1605{
1606 PyObject *result = Py_NotImplemented;
1607
1608 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1609 /* delta - delta */
1610 PyObject *minus_right = PyNumber_Negative(right);
1611 if (minus_right) {
1612 result = delta_add(left, minus_right);
1613 Py_DECREF(minus_right);
1614 }
1615 else
1616 result = NULL;
1617 }
1618
1619 if (result == Py_NotImplemented)
1620 Py_INCREF(result);
1621 return result;
1622}
1623
1624/* This is more natural as a tp_compare, but doesn't work then: for whatever
1625 * reason, Python's try_3way_compare ignores tp_compare unless
1626 * PyInstance_Check returns true, but these aren't old-style classes.
1627 */
1628static PyObject *
1629delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1630{
1631 int diff;
1632
1633 if (! PyDelta_CheckExact(other)) {
1634 PyErr_Format(PyExc_TypeError,
1635 "can't compare %s to %s instance",
1636 self->ob_type->tp_name, other->ob_type->tp_name);
1637 return NULL;
1638 }
1639 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1640 if (diff == 0) {
1641 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1642 if (diff == 0)
1643 diff = GET_TD_MICROSECONDS(self) -
1644 GET_TD_MICROSECONDS(other);
1645 }
1646 return diff_to_bool(diff, op);
1647}
1648
1649static PyObject *delta_getstate(PyDateTime_Delta *self);
1650
1651static long
1652delta_hash(PyDateTime_Delta *self)
1653{
1654 if (self->hashcode == -1) {
1655 PyObject *temp = delta_getstate(self);
1656 if (temp != NULL) {
1657 self->hashcode = PyObject_Hash(temp);
1658 Py_DECREF(temp);
1659 }
1660 }
1661 return self->hashcode;
1662}
1663
1664static PyObject *
1665delta_multiply(PyObject *left, PyObject *right)
1666{
1667 PyObject *result = Py_NotImplemented;
1668
1669 if (PyDelta_Check(left)) {
1670 /* delta * ??? */
1671 if (PyInt_Check(right) || PyLong_Check(right))
1672 result = multiply_int_timedelta(right,
1673 (PyDateTime_Delta *) left);
1674 }
1675 else if (PyInt_Check(left) || PyLong_Check(left))
1676 result = multiply_int_timedelta(left,
1677 (PyDateTime_Delta *) right);
1678
1679 if (result == Py_NotImplemented)
1680 Py_INCREF(result);
1681 return result;
1682}
1683
1684static PyObject *
1685delta_divide(PyObject *left, PyObject *right)
1686{
1687 PyObject *result = Py_NotImplemented;
1688
1689 if (PyDelta_Check(left)) {
1690 /* delta * ??? */
1691 if (PyInt_Check(right) || PyLong_Check(right))
1692 result = divide_timedelta_int(
1693 (PyDateTime_Delta *)left,
1694 right);
1695 }
1696
1697 if (result == Py_NotImplemented)
1698 Py_INCREF(result);
1699 return result;
1700}
1701
1702/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1703 * timedelta constructor. sofar is the # of microseconds accounted for
1704 * so far, and there are factor microseconds per current unit, the number
1705 * of which is given by num. num * factor is added to sofar in a
1706 * numerically careful way, and that's the result. Any fractional
1707 * microseconds left over (this can happen if num is a float type) are
1708 * added into *leftover.
1709 * Note that there are many ways this can give an error (NULL) return.
1710 */
1711static PyObject *
1712accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1713 double *leftover)
1714{
1715 PyObject *prod;
1716 PyObject *sum;
1717
1718 assert(num != NULL);
1719
1720 if (PyInt_Check(num) || PyLong_Check(num)) {
1721 prod = PyNumber_Multiply(num, factor);
1722 if (prod == NULL)
1723 return NULL;
1724 sum = PyNumber_Add(sofar, prod);
1725 Py_DECREF(prod);
1726 return sum;
1727 }
1728
1729 if (PyFloat_Check(num)) {
1730 double dnum;
1731 double fracpart;
1732 double intpart;
1733 PyObject *x;
1734 PyObject *y;
1735
1736 /* The Plan: decompose num into an integer part and a
1737 * fractional part, num = intpart + fracpart.
1738 * Then num * factor ==
1739 * intpart * factor + fracpart * factor
1740 * and the LHS can be computed exactly in long arithmetic.
1741 * The RHS is again broken into an int part and frac part.
1742 * and the frac part is added into *leftover.
1743 */
1744 dnum = PyFloat_AsDouble(num);
1745 if (dnum == -1.0 && PyErr_Occurred())
1746 return NULL;
1747 fracpart = modf(dnum, &intpart);
1748 x = PyLong_FromDouble(intpart);
1749 if (x == NULL)
1750 return NULL;
1751
1752 prod = PyNumber_Multiply(x, factor);
1753 Py_DECREF(x);
1754 if (prod == NULL)
1755 return NULL;
1756
1757 sum = PyNumber_Add(sofar, prod);
1758 Py_DECREF(prod);
1759 if (sum == NULL)
1760 return NULL;
1761
1762 if (fracpart == 0.0)
1763 return sum;
1764 /* So far we've lost no information. Dealing with the
1765 * fractional part requires float arithmetic, and may
1766 * lose a little info.
1767 */
1768 assert(PyInt_Check(factor) || PyLong_Check(factor));
1769 if (PyInt_Check(factor))
1770 dnum = (double)PyInt_AsLong(factor);
1771 else
1772 dnum = PyLong_AsDouble(factor);
1773
1774 dnum *= fracpart;
1775 fracpart = modf(dnum, &intpart);
1776 x = PyLong_FromDouble(intpart);
1777 if (x == NULL) {
1778 Py_DECREF(sum);
1779 return NULL;
1780 }
1781
1782 y = PyNumber_Add(sum, x);
1783 Py_DECREF(sum);
1784 Py_DECREF(x);
1785 *leftover += fracpart;
1786 return y;
1787 }
1788
1789 PyErr_Format(PyExc_TypeError,
1790 "unsupported type for timedelta %s component: %s",
1791 tag, num->ob_type->tp_name);
1792 return NULL;
1793}
1794
1795static PyObject *
1796delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1797{
1798 PyObject *self = NULL;
1799
1800 /* Argument objects. */
1801 PyObject *day = NULL;
1802 PyObject *second = NULL;
1803 PyObject *us = NULL;
1804 PyObject *ms = NULL;
1805 PyObject *minute = NULL;
1806 PyObject *hour = NULL;
1807 PyObject *week = NULL;
1808
1809 PyObject *x = NULL; /* running sum of microseconds */
1810 PyObject *y = NULL; /* temp sum of microseconds */
1811 double leftover_us = 0.0;
1812
1813 static char *keywords[] = {
1814 "days", "seconds", "microseconds", "milliseconds",
1815 "minutes", "hours", "weeks", NULL
1816 };
1817
1818 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1819 keywords,
1820 &day, &second, &us,
1821 &ms, &minute, &hour, &week) == 0)
1822 goto Done;
1823
1824 x = PyInt_FromLong(0);
1825 if (x == NULL)
1826 goto Done;
1827
1828#define CLEANUP \
1829 Py_DECREF(x); \
1830 x = y; \
1831 if (x == NULL) \
1832 goto Done
1833
1834 if (us) {
1835 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1836 CLEANUP;
1837 }
1838 if (ms) {
1839 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1840 CLEANUP;
1841 }
1842 if (second) {
1843 y = accum("seconds", x, second, us_per_second, &leftover_us);
1844 CLEANUP;
1845 }
1846 if (minute) {
1847 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1848 CLEANUP;
1849 }
1850 if (hour) {
1851 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1852 CLEANUP;
1853 }
1854 if (day) {
1855 y = accum("days", x, day, us_per_day, &leftover_us);
1856 CLEANUP;
1857 }
1858 if (week) {
1859 y = accum("weeks", x, week, us_per_week, &leftover_us);
1860 CLEANUP;
1861 }
1862 if (leftover_us) {
1863 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001864 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001865 if (temp == NULL) {
1866 Py_DECREF(x);
1867 goto Done;
1868 }
1869 y = PyNumber_Add(x, temp);
1870 Py_DECREF(temp);
1871 CLEANUP;
1872 }
1873
1874 self = microseconds_to_delta(x);
1875 Py_DECREF(x);
1876Done:
1877 return self;
1878
1879#undef CLEANUP
1880}
1881
1882static int
1883delta_nonzero(PyDateTime_Delta *self)
1884{
1885 return (GET_TD_DAYS(self) != 0
1886 || GET_TD_SECONDS(self) != 0
1887 || GET_TD_MICROSECONDS(self) != 0);
1888}
1889
1890static PyObject *
1891delta_repr(PyDateTime_Delta *self)
1892{
1893 if (GET_TD_MICROSECONDS(self) != 0)
1894 return PyString_FromFormat("%s(%d, %d, %d)",
1895 self->ob_type->tp_name,
1896 GET_TD_DAYS(self),
1897 GET_TD_SECONDS(self),
1898 GET_TD_MICROSECONDS(self));
1899 if (GET_TD_SECONDS(self) != 0)
1900 return PyString_FromFormat("%s(%d, %d)",
1901 self->ob_type->tp_name,
1902 GET_TD_DAYS(self),
1903 GET_TD_SECONDS(self));
1904
1905 return PyString_FromFormat("%s(%d)",
1906 self->ob_type->tp_name,
1907 GET_TD_DAYS(self));
1908}
1909
1910static PyObject *
1911delta_str(PyDateTime_Delta *self)
1912{
1913 int days = GET_TD_DAYS(self);
1914 int seconds = GET_TD_SECONDS(self);
1915 int us = GET_TD_MICROSECONDS(self);
1916 int hours;
1917 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001918 char buf[100];
1919 char *pbuf = buf;
1920 size_t buflen = sizeof(buf);
1921 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001922
1923 minutes = divmod(seconds, 60, &seconds);
1924 hours = divmod(minutes, 60, &minutes);
1925
1926 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00001927 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
1928 (days == 1 || days == -1) ? "" : "s");
1929 if (n < 0 || (size_t)n >= buflen)
1930 goto Fail;
1931 pbuf += n;
1932 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001933 }
1934
Tim Petersba873472002-12-18 20:19:21 +00001935 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
1936 hours, minutes, seconds);
1937 if (n < 0 || (size_t)n >= buflen)
1938 goto Fail;
1939 pbuf += n;
1940 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001941
1942 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00001943 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
1944 if (n < 0 || (size_t)n >= buflen)
1945 goto Fail;
1946 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001947 }
1948
Tim Petersba873472002-12-18 20:19:21 +00001949 return PyString_FromStringAndSize(buf, pbuf - buf);
1950
1951 Fail:
1952 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
1953 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00001954}
1955
1956/* Pickle support. Quite a maze! While __getstate__/__setstate__ sufficed
1957 * in the Python implementation, the C implementation also requires
1958 * __reduce__, and a __safe_for_unpickling__ attr in the type object.
1959 */
1960static PyObject *
1961delta_getstate(PyDateTime_Delta *self)
1962{
1963 return Py_BuildValue("iii", GET_TD_DAYS(self),
1964 GET_TD_SECONDS(self),
1965 GET_TD_MICROSECONDS(self));
1966}
1967
1968static PyObject *
1969delta_setstate(PyDateTime_Delta *self, PyObject *state)
1970{
1971 int day;
1972 int second;
1973 int us;
1974
1975 if (!PyArg_ParseTuple(state, "iii:__setstate__", &day, &second, &us))
1976 return NULL;
1977
1978 self->hashcode = -1;
1979 SET_TD_DAYS(self, day);
1980 SET_TD_SECONDS(self, second);
1981 SET_TD_MICROSECONDS(self, us);
1982
1983 Py_INCREF(Py_None);
1984 return Py_None;
1985}
1986
1987static PyObject *
1988delta_reduce(PyDateTime_Delta* self)
1989{
1990 PyObject* result = NULL;
1991 PyObject* state = delta_getstate(self);
1992
1993 if (state != NULL) {
1994 /* The funky "()" in the format string creates an empty
1995 * tuple as the 2nd component of the result 3-tuple.
1996 */
1997 result = Py_BuildValue("O()O", self->ob_type, state);
1998 Py_DECREF(state);
1999 }
2000 return result;
2001}
2002
2003#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2004
2005static PyMemberDef delta_members[] = {
Neal Norwitzdfb80862002-12-19 02:30:56 +00002006 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002007 PyDoc_STR("Number of days.")},
2008
Neal Norwitzdfb80862002-12-19 02:30:56 +00002009 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002010 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2011
Neal Norwitzdfb80862002-12-19 02:30:56 +00002012 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002013 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2014 {NULL}
2015};
2016
2017static PyMethodDef delta_methods[] = {
2018 {"__setstate__", (PyCFunction)delta_setstate, METH_O,
2019 PyDoc_STR("__setstate__(state)")},
2020
2021 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2022 PyDoc_STR("__setstate__(state)")},
2023
2024 {"__getstate__", (PyCFunction)delta_getstate, METH_NOARGS,
2025 PyDoc_STR("__getstate__() -> state")},
2026 {NULL, NULL},
2027};
2028
2029static char delta_doc[] =
2030PyDoc_STR("Difference between two datetime values.");
2031
2032static PyNumberMethods delta_as_number = {
2033 delta_add, /* nb_add */
2034 delta_subtract, /* nb_subtract */
2035 delta_multiply, /* nb_multiply */
2036 delta_divide, /* nb_divide */
2037 0, /* nb_remainder */
2038 0, /* nb_divmod */
2039 0, /* nb_power */
2040 (unaryfunc)delta_negative, /* nb_negative */
2041 (unaryfunc)delta_positive, /* nb_positive */
2042 (unaryfunc)delta_abs, /* nb_absolute */
2043 (inquiry)delta_nonzero, /* nb_nonzero */
2044 0, /*nb_invert*/
2045 0, /*nb_lshift*/
2046 0, /*nb_rshift*/
2047 0, /*nb_and*/
2048 0, /*nb_xor*/
2049 0, /*nb_or*/
2050 0, /*nb_coerce*/
2051 0, /*nb_int*/
2052 0, /*nb_long*/
2053 0, /*nb_float*/
2054 0, /*nb_oct*/
2055 0, /*nb_hex*/
2056 0, /*nb_inplace_add*/
2057 0, /*nb_inplace_subtract*/
2058 0, /*nb_inplace_multiply*/
2059 0, /*nb_inplace_divide*/
2060 0, /*nb_inplace_remainder*/
2061 0, /*nb_inplace_power*/
2062 0, /*nb_inplace_lshift*/
2063 0, /*nb_inplace_rshift*/
2064 0, /*nb_inplace_and*/
2065 0, /*nb_inplace_xor*/
2066 0, /*nb_inplace_or*/
2067 delta_divide, /* nb_floor_divide */
2068 0, /* nb_true_divide */
2069 0, /* nb_inplace_floor_divide */
2070 0, /* nb_inplace_true_divide */
2071};
2072
2073static PyTypeObject PyDateTime_DeltaType = {
2074 PyObject_HEAD_INIT(NULL)
2075 0, /* ob_size */
2076 "datetime.timedelta", /* tp_name */
2077 sizeof(PyDateTime_Delta), /* tp_basicsize */
2078 0, /* tp_itemsize */
2079 0, /* tp_dealloc */
2080 0, /* tp_print */
2081 0, /* tp_getattr */
2082 0, /* tp_setattr */
2083 0, /* tp_compare */
2084 (reprfunc)delta_repr, /* tp_repr */
2085 &delta_as_number, /* tp_as_number */
2086 0, /* tp_as_sequence */
2087 0, /* tp_as_mapping */
2088 (hashfunc)delta_hash, /* tp_hash */
2089 0, /* tp_call */
2090 (reprfunc)delta_str, /* tp_str */
2091 PyObject_GenericGetAttr, /* tp_getattro */
2092 0, /* tp_setattro */
2093 0, /* tp_as_buffer */
2094 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
2095 delta_doc, /* tp_doc */
2096 0, /* tp_traverse */
2097 0, /* tp_clear */
2098 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2099 0, /* tp_weaklistoffset */
2100 0, /* tp_iter */
2101 0, /* tp_iternext */
2102 delta_methods, /* tp_methods */
2103 delta_members, /* tp_members */
2104 0, /* tp_getset */
2105 0, /* tp_base */
2106 0, /* tp_dict */
2107 0, /* tp_descr_get */
2108 0, /* tp_descr_set */
2109 0, /* tp_dictoffset */
2110 0, /* tp_init */
2111 0, /* tp_alloc */
2112 delta_new, /* tp_new */
2113 _PyObject_Del, /* tp_free */
2114};
2115
2116/*
2117 * PyDateTime_Date implementation.
2118 */
2119
2120/* Accessor properties. */
2121
2122static PyObject *
2123date_year(PyDateTime_Date *self, void *unused)
2124{
2125 return PyInt_FromLong(GET_YEAR(self));
2126}
2127
2128static PyObject *
2129date_month(PyDateTime_Date *self, void *unused)
2130{
2131 return PyInt_FromLong(GET_MONTH(self));
2132}
2133
2134static PyObject *
2135date_day(PyDateTime_Date *self, void *unused)
2136{
2137 return PyInt_FromLong(GET_DAY(self));
2138}
2139
2140static PyGetSetDef date_getset[] = {
2141 {"year", (getter)date_year},
2142 {"month", (getter)date_month},
2143 {"day", (getter)date_day},
2144 {NULL}
2145};
2146
2147/* Constructors. */
2148
Tim Peters12bf3392002-12-24 05:41:27 +00002149static char *date_kws[] = {"year", "month", "day", NULL};
2150
Tim Peters2a799bf2002-12-16 20:18:38 +00002151static PyObject *
2152date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2153{
2154 PyObject *self = NULL;
2155 int year;
2156 int month;
2157 int day;
2158
Tim Peters12bf3392002-12-24 05:41:27 +00002159 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002160 &year, &month, &day)) {
2161 if (check_date_args(year, month, day) < 0)
2162 return NULL;
2163 self = new_date(year, month, day);
2164 }
2165 return self;
2166}
2167
2168/* Return new date from localtime(t). */
2169static PyObject *
2170date_local_from_time_t(PyObject *cls, time_t t)
2171{
2172 struct tm *tm;
2173 PyObject *result = NULL;
2174
2175 tm = localtime(&t);
2176 if (tm)
2177 result = PyObject_CallFunction(cls, "iii",
2178 tm->tm_year + 1900,
2179 tm->tm_mon + 1,
2180 tm->tm_mday);
2181 else
2182 PyErr_SetString(PyExc_ValueError,
2183 "timestamp out of range for "
2184 "platform localtime() function");
2185 return result;
2186}
2187
2188/* Return new date from current time.
2189 * We say this is equivalent to fromtimestamp(time.time()), and the
2190 * only way to be sure of that is to *call* time.time(). That's not
2191 * generally the same as calling C's time.
2192 */
2193static PyObject *
2194date_today(PyObject *cls, PyObject *dummy)
2195{
2196 PyObject *time;
2197 PyObject *result;
2198
2199 time = time_time();
2200 if (time == NULL)
2201 return NULL;
2202
2203 /* Note well: today() is a class method, so this may not call
2204 * date.fromtimestamp. For example, it may call
2205 * datetime.fromtimestamp. That's why we need all the accuracy
2206 * time.time() delivers; if someone were gonzo about optimization,
2207 * date.today() could get away with plain C time().
2208 */
2209 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2210 Py_DECREF(time);
2211 return result;
2212}
2213
2214/* Return new date from given timestamp (Python timestamp -- a double). */
2215static PyObject *
2216date_fromtimestamp(PyObject *cls, PyObject *args)
2217{
2218 double timestamp;
2219 PyObject *result = NULL;
2220
2221 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2222 result = date_local_from_time_t(cls, (time_t)timestamp);
2223 return result;
2224}
2225
2226/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2227 * the ordinal is out of range.
2228 */
2229static PyObject *
2230date_fromordinal(PyObject *cls, PyObject *args)
2231{
2232 PyObject *result = NULL;
2233 int ordinal;
2234
2235 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2236 int year;
2237 int month;
2238 int day;
2239
2240 if (ordinal < 1)
2241 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2242 ">= 1");
2243 else {
2244 ord_to_ymd(ordinal, &year, &month, &day);
2245 result = PyObject_CallFunction(cls, "iii",
2246 year, month, day);
2247 }
2248 }
2249 return result;
2250}
2251
2252/*
2253 * Date arithmetic.
2254 */
2255
2256/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2257 * instead.
2258 */
2259static PyObject *
2260add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2261{
2262 PyObject *result = NULL;
2263 int year = GET_YEAR(date);
2264 int month = GET_MONTH(date);
2265 int deltadays = GET_TD_DAYS(delta);
2266 /* C-level overflow is impossible because |deltadays| < 1e9. */
2267 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2268
2269 if (normalize_date(&year, &month, &day) >= 0)
2270 result = new_date(year, month, day);
2271 return result;
2272}
2273
2274static PyObject *
2275date_add(PyObject *left, PyObject *right)
2276{
2277 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2278 Py_INCREF(Py_NotImplemented);
2279 return Py_NotImplemented;
2280 }
2281 if (PyDate_CheckExact(left)) {
2282 /* date + ??? */
2283 if (PyDelta_Check(right))
2284 /* date + delta */
2285 return add_date_timedelta((PyDateTime_Date *) left,
2286 (PyDateTime_Delta *) right,
2287 0);
2288 }
2289 else {
2290 /* ??? + date
2291 * 'right' must be one of us, or we wouldn't have been called
2292 */
2293 if (PyDelta_Check(left))
2294 /* delta + date */
2295 return add_date_timedelta((PyDateTime_Date *) right,
2296 (PyDateTime_Delta *) left,
2297 0);
2298 }
2299 Py_INCREF(Py_NotImplemented);
2300 return Py_NotImplemented;
2301}
2302
2303static PyObject *
2304date_subtract(PyObject *left, PyObject *right)
2305{
2306 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2307 Py_INCREF(Py_NotImplemented);
2308 return Py_NotImplemented;
2309 }
2310 if (PyDate_CheckExact(left)) {
2311 if (PyDate_CheckExact(right)) {
2312 /* date - date */
2313 int left_ord = ymd_to_ord(GET_YEAR(left),
2314 GET_MONTH(left),
2315 GET_DAY(left));
2316 int right_ord = ymd_to_ord(GET_YEAR(right),
2317 GET_MONTH(right),
2318 GET_DAY(right));
2319 return new_delta(left_ord - right_ord, 0, 0, 0);
2320 }
2321 if (PyDelta_Check(right)) {
2322 /* date - delta */
2323 return add_date_timedelta((PyDateTime_Date *) left,
2324 (PyDateTime_Delta *) right,
2325 1);
2326 }
2327 }
2328 Py_INCREF(Py_NotImplemented);
2329 return Py_NotImplemented;
2330}
2331
2332
2333/* Various ways to turn a date into a string. */
2334
2335static PyObject *
2336date_repr(PyDateTime_Date *self)
2337{
2338 char buffer[1028];
2339 char *typename;
2340
2341 typename = self->ob_type->tp_name;
2342 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2343 typename,
2344 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2345
2346 return PyString_FromString(buffer);
2347}
2348
2349static PyObject *
2350date_isoformat(PyDateTime_Date *self)
2351{
2352 char buffer[128];
2353
2354 isoformat_date(self, buffer, sizeof(buffer));
2355 return PyString_FromString(buffer);
2356}
2357
2358/* str() calls the appropriate isofomat() method. */
2359static PyObject *
2360date_str(PyDateTime_Date *self)
2361{
2362 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2363}
2364
2365
2366static PyObject *
2367date_ctime(PyDateTime_Date *self)
2368{
2369 return format_ctime(self, 0, 0, 0);
2370}
2371
2372static PyObject *
2373date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2374{
2375 /* This method can be inherited, and needs to call the
2376 * timetuple() method appropriate to self's class.
2377 */
2378 PyObject *result;
2379 PyObject *format;
2380 PyObject *tuple;
2381 static char *keywords[] = {"format", NULL};
2382
2383 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2384 &PyString_Type, &format))
2385 return NULL;
2386
2387 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2388 if (tuple == NULL)
2389 return NULL;
Tim Petersbad8ff02002-12-30 20:52:32 +00002390 result = wrap_strftime((PyObject *)self, format, tuple,
2391 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002392 Py_DECREF(tuple);
2393 return result;
2394}
2395
2396/* ISO methods. */
2397
2398static PyObject *
2399date_isoweekday(PyDateTime_Date *self)
2400{
2401 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2402
2403 return PyInt_FromLong(dow + 1);
2404}
2405
2406static PyObject *
2407date_isocalendar(PyDateTime_Date *self)
2408{
2409 int year = GET_YEAR(self);
2410 int week1_monday = iso_week1_monday(year);
2411 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2412 int week;
2413 int day;
2414
2415 week = divmod(today - week1_monday, 7, &day);
2416 if (week < 0) {
2417 --year;
2418 week1_monday = iso_week1_monday(year);
2419 week = divmod(today - week1_monday, 7, &day);
2420 }
2421 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2422 ++year;
2423 week = 0;
2424 }
2425 return Py_BuildValue("iii", year, week + 1, day + 1);
2426}
2427
2428/* Miscellaneous methods. */
2429
2430/* This is more natural as a tp_compare, but doesn't work then: for whatever
2431 * reason, Python's try_3way_compare ignores tp_compare unless
2432 * PyInstance_Check returns true, but these aren't old-style classes.
2433 */
2434static PyObject *
2435date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2436{
2437 int diff;
2438
2439 if (! PyDate_Check(other)) {
2440 PyErr_Format(PyExc_TypeError,
2441 "can't compare date to %s instance",
2442 other->ob_type->tp_name);
2443 return NULL;
2444 }
2445 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2446 _PyDateTime_DATE_DATASIZE);
2447 return diff_to_bool(diff, op);
2448}
2449
2450static PyObject *
2451date_timetuple(PyDateTime_Date *self)
2452{
2453 return build_struct_time(GET_YEAR(self),
2454 GET_MONTH(self),
2455 GET_DAY(self),
2456 0, 0, 0, -1);
2457}
2458
Tim Peters12bf3392002-12-24 05:41:27 +00002459static PyObject *
2460date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2461{
2462 PyObject *clone;
2463 PyObject *tuple;
2464 int year = GET_YEAR(self);
2465 int month = GET_MONTH(self);
2466 int day = GET_DAY(self);
2467
2468 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2469 &year, &month, &day))
2470 return NULL;
2471 tuple = Py_BuildValue("iii", year, month, day);
2472 if (tuple == NULL)
2473 return NULL;
2474 clone = date_new(self->ob_type, tuple, NULL);
2475 Py_DECREF(tuple);
2476 return clone;
2477}
2478
Tim Peters2a799bf2002-12-16 20:18:38 +00002479static PyObject *date_getstate(PyDateTime_Date *self);
2480
2481static long
2482date_hash(PyDateTime_Date *self)
2483{
2484 if (self->hashcode == -1) {
2485 PyObject *temp = date_getstate(self);
2486 if (temp != NULL) {
2487 self->hashcode = PyObject_Hash(temp);
2488 Py_DECREF(temp);
2489 }
2490 }
2491 return self->hashcode;
2492}
2493
2494static PyObject *
2495date_toordinal(PyDateTime_Date *self)
2496{
2497 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2498 GET_DAY(self)));
2499}
2500
2501static PyObject *
2502date_weekday(PyDateTime_Date *self)
2503{
2504 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2505
2506 return PyInt_FromLong(dow);
2507}
2508
2509/* Pickle support. Quite a maze! */
2510
2511static PyObject *
2512date_getstate(PyDateTime_Date *self)
2513{
Jack Jansenb8941f22003-01-08 16:28:45 +00002514 return PyString_FromStringAndSize((char *)self->data,
Tim Peters2a799bf2002-12-16 20:18:38 +00002515 _PyDateTime_DATE_DATASIZE);
2516}
2517
2518static PyObject *
2519date_setstate(PyDateTime_Date *self, PyObject *state)
2520{
2521 const int len = PyString_Size(state);
2522 unsigned char *pdata = (unsigned char*)PyString_AsString(state);
2523
2524 if (! PyString_Check(state) ||
2525 len != _PyDateTime_DATE_DATASIZE) {
2526 PyErr_SetString(PyExc_TypeError,
2527 "bad argument to date.__setstate__");
2528 return NULL;
2529 }
2530 memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE);
2531 self->hashcode = -1;
2532
2533 Py_INCREF(Py_None);
2534 return Py_None;
2535}
2536
2537/* XXX This seems a ridiculously inefficient way to pickle a short string. */
2538static PyObject *
2539date_pickler(PyObject *module, PyDateTime_Date *date)
2540{
2541 PyObject *state;
2542 PyObject *result = NULL;
2543
2544 if (! PyDate_CheckExact(date)) {
2545 PyErr_Format(PyExc_TypeError,
2546 "bad type passed to date pickler: %s",
2547 date->ob_type->tp_name);
2548 return NULL;
2549 }
2550 state = date_getstate(date);
2551 if (state) {
2552 result = Py_BuildValue("O(O)", date_unpickler_object, state);
2553 Py_DECREF(state);
2554 }
2555 return result;
2556}
2557
2558static PyObject *
2559date_unpickler(PyObject *module, PyObject *arg)
2560{
2561 PyDateTime_Date *self;
2562
2563 if (! PyString_CheckExact(arg)) {
2564 PyErr_Format(PyExc_TypeError,
2565 "bad type passed to date unpickler: %s",
2566 arg->ob_type->tp_name);
2567 return NULL;
2568 }
2569 self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
2570 if (self != NULL) {
2571 PyObject *res = date_setstate(self, arg);
2572 if (res == NULL) {
2573 Py_DECREF(self);
2574 return NULL;
2575 }
2576 Py_DECREF(res);
2577 }
2578 return (PyObject *)self;
2579}
2580
2581static PyMethodDef date_methods[] = {
2582 /* Class methods: */
2583 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2584 METH_CLASS,
2585 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2586 "time.time()).")},
2587
2588 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2589 METH_CLASS,
2590 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2591 "ordinal.")},
2592
2593 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2594 PyDoc_STR("Current date or datetime: same as "
2595 "self.__class__.fromtimestamp(time.time()).")},
2596
2597 /* Instance methods: */
2598
2599 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2600 PyDoc_STR("Return ctime() style string.")},
2601
2602 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2603 PyDoc_STR("format -> strftime() style string.")},
2604
2605 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2606 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2607
2608 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2609 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2610 "weekday.")},
2611
2612 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2613 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2614
2615 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2616 PyDoc_STR("Return the day of the week represented by the date.\n"
2617 "Monday == 1 ... Sunday == 7")},
2618
2619 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2620 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2621 "1 is day 1.")},
2622
2623 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2624 PyDoc_STR("Return the day of the week represented by the date.\n"
2625 "Monday == 0 ... Sunday == 6")},
2626
Tim Peters12bf3392002-12-24 05:41:27 +00002627 {"replace", (PyCFunction)date_replace, METH_KEYWORDS,
2628 PyDoc_STR("Return date with new specified fields.")},
2629
Tim Peters2a799bf2002-12-16 20:18:38 +00002630 {"__setstate__", (PyCFunction)date_setstate, METH_O,
2631 PyDoc_STR("__setstate__(state)")},
2632
2633 {"__getstate__", (PyCFunction)date_getstate, METH_NOARGS,
2634 PyDoc_STR("__getstate__() -> state")},
2635
2636 {NULL, NULL}
2637};
2638
2639static char date_doc[] =
2640PyDoc_STR("Basic date type.");
2641
2642static PyNumberMethods date_as_number = {
2643 date_add, /* nb_add */
2644 date_subtract, /* nb_subtract */
2645 0, /* nb_multiply */
2646 0, /* nb_divide */
2647 0, /* nb_remainder */
2648 0, /* nb_divmod */
2649 0, /* nb_power */
2650 0, /* nb_negative */
2651 0, /* nb_positive */
2652 0, /* nb_absolute */
2653 0, /* nb_nonzero */
2654};
2655
2656static PyTypeObject PyDateTime_DateType = {
2657 PyObject_HEAD_INIT(NULL)
2658 0, /* ob_size */
2659 "datetime.date", /* tp_name */
2660 sizeof(PyDateTime_Date), /* tp_basicsize */
2661 0, /* tp_itemsize */
2662 (destructor)PyObject_Del, /* tp_dealloc */
2663 0, /* tp_print */
2664 0, /* tp_getattr */
2665 0, /* tp_setattr */
2666 0, /* tp_compare */
2667 (reprfunc)date_repr, /* tp_repr */
2668 &date_as_number, /* tp_as_number */
2669 0, /* tp_as_sequence */
2670 0, /* tp_as_mapping */
2671 (hashfunc)date_hash, /* tp_hash */
2672 0, /* tp_call */
2673 (reprfunc)date_str, /* tp_str */
2674 PyObject_GenericGetAttr, /* tp_getattro */
2675 0, /* tp_setattro */
2676 0, /* tp_as_buffer */
2677 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2678 Py_TPFLAGS_BASETYPE, /* tp_flags */
2679 date_doc, /* tp_doc */
2680 0, /* tp_traverse */
2681 0, /* tp_clear */
2682 (richcmpfunc)date_richcompare, /* tp_richcompare */
2683 0, /* tp_weaklistoffset */
2684 0, /* tp_iter */
2685 0, /* tp_iternext */
2686 date_methods, /* tp_methods */
2687 0, /* tp_members */
2688 date_getset, /* tp_getset */
2689 0, /* tp_base */
2690 0, /* tp_dict */
2691 0, /* tp_descr_get */
2692 0, /* tp_descr_set */
2693 0, /* tp_dictoffset */
2694 0, /* tp_init */
2695 0, /* tp_alloc */
2696 date_new, /* tp_new */
2697 _PyObject_Del, /* tp_free */
2698};
2699
2700/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002701 * PyDateTime_TZInfo implementation.
2702 */
2703
2704/* This is a pure abstract base class, so doesn't do anything beyond
2705 * raising NotImplemented exceptions. Real tzinfo classes need
2706 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002707 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002708 * be subclasses of this tzinfo class, which is easy and quick to check).
2709 *
2710 * Note: For reasons having to do with pickling of subclasses, we have
2711 * to allow tzinfo objects to be instantiated. This wasn't an issue
2712 * in the Python implementation (__init__() could raise NotImplementedError
2713 * there without ill effect), but doing so in the C implementation hit a
2714 * brick wall.
2715 */
2716
2717static PyObject *
2718tzinfo_nogo(const char* methodname)
2719{
2720 PyErr_Format(PyExc_NotImplementedError,
2721 "a tzinfo subclass must implement %s()",
2722 methodname);
2723 return NULL;
2724}
2725
2726/* Methods. A subclass must implement these. */
2727
2728static PyObject*
2729tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2730{
2731 return tzinfo_nogo("tzname");
2732}
2733
2734static PyObject*
2735tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2736{
2737 return tzinfo_nogo("utcoffset");
2738}
2739
2740static PyObject*
2741tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2742{
2743 return tzinfo_nogo("dst");
2744}
2745
2746/*
2747 * Pickle support. This is solely so that tzinfo subclasses can use
2748 * pickling -- tzinfo itself is supposed to be uninstantiable. The
2749 * pickler and unpickler functions are given module-level private
2750 * names, and registered with copy_reg, by the module init function.
2751 */
2752
2753static PyObject*
2754tzinfo_pickler(PyDateTime_TZInfo *self) {
2755 return Py_BuildValue("O()", tzinfo_unpickler_object);
2756}
2757
2758static PyObject*
2759tzinfo_unpickler(PyObject * unused) {
2760 return PyType_GenericNew(&PyDateTime_TZInfoType, NULL, NULL);
2761}
2762
2763
2764static PyMethodDef tzinfo_methods[] = {
2765 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2766 PyDoc_STR("datetime -> string name of time zone.")},
2767
2768 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2769 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2770 "west of UTC).")},
2771
2772 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2773 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2774
2775 {NULL, NULL}
2776};
2777
2778static char tzinfo_doc[] =
2779PyDoc_STR("Abstract base class for time zone info objects.");
2780
2781 statichere PyTypeObject PyDateTime_TZInfoType = {
2782 PyObject_HEAD_INIT(NULL)
2783 0, /* ob_size */
2784 "datetime.tzinfo", /* tp_name */
2785 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2786 0, /* tp_itemsize */
2787 0, /* tp_dealloc */
2788 0, /* tp_print */
2789 0, /* tp_getattr */
2790 0, /* tp_setattr */
2791 0, /* tp_compare */
2792 0, /* tp_repr */
2793 0, /* tp_as_number */
2794 0, /* tp_as_sequence */
2795 0, /* tp_as_mapping */
2796 0, /* tp_hash */
2797 0, /* tp_call */
2798 0, /* tp_str */
2799 PyObject_GenericGetAttr, /* tp_getattro */
2800 0, /* tp_setattro */
2801 0, /* tp_as_buffer */
2802 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2803 Py_TPFLAGS_BASETYPE, /* tp_flags */
2804 tzinfo_doc, /* tp_doc */
2805 0, /* tp_traverse */
2806 0, /* tp_clear */
2807 0, /* tp_richcompare */
2808 0, /* tp_weaklistoffset */
2809 0, /* tp_iter */
2810 0, /* tp_iternext */
2811 tzinfo_methods, /* tp_methods */
2812 0, /* tp_members */
2813 0, /* tp_getset */
2814 0, /* tp_base */
2815 0, /* tp_dict */
2816 0, /* tp_descr_get */
2817 0, /* tp_descr_set */
2818 0, /* tp_dictoffset */
2819 0, /* tp_init */
2820 0, /* tp_alloc */
2821 PyType_GenericNew, /* tp_new */
2822 0, /* tp_free */
2823};
2824
2825/*
Tim Peters37f39822003-01-10 03:49:02 +00002826 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00002827 */
2828
Tim Peters37f39822003-01-10 03:49:02 +00002829/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00002830 */
2831
2832static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002833time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00002834{
Tim Peters37f39822003-01-10 03:49:02 +00002835 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002836}
2837
Tim Peters37f39822003-01-10 03:49:02 +00002838static PyObject *
2839time_minute(PyDateTime_Time *self, void *unused)
2840{
2841 return PyInt_FromLong(TIME_GET_MINUTE(self));
2842}
2843
2844/* The name time_second conflicted with some platform header file. */
2845static PyObject *
2846py_time_second(PyDateTime_Time *self, void *unused)
2847{
2848 return PyInt_FromLong(TIME_GET_SECOND(self));
2849}
2850
2851static PyObject *
2852time_microsecond(PyDateTime_Time *self, void *unused)
2853{
2854 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
2855}
2856
2857static PyObject *
2858time_tzinfo(PyDateTime_Time *self, void *unused)
2859{
Tim Petersa032d2e2003-01-11 00:15:54 +00002860 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00002861 Py_INCREF(result);
2862 return result;
2863}
2864
2865static PyGetSetDef time_getset[] = {
2866 {"hour", (getter)time_hour},
2867 {"minute", (getter)time_minute},
2868 {"second", (getter)py_time_second},
2869 {"microsecond", (getter)time_microsecond},
2870 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00002871 {NULL}
2872};
2873
2874/*
2875 * Constructors.
2876 */
2877
Tim Peters37f39822003-01-10 03:49:02 +00002878static char *time_kws[] = {"hour", "minute", "second", "microsecond",
2879 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002880
Tim Peters2a799bf2002-12-16 20:18:38 +00002881static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002882time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00002883{
2884 PyObject *self = NULL;
2885 int hour = 0;
2886 int minute = 0;
2887 int second = 0;
2888 int usecond = 0;
2889 PyObject *tzinfo = Py_None;
2890
Tim Peters37f39822003-01-10 03:49:02 +00002891 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002892 &hour, &minute, &second, &usecond,
2893 &tzinfo)) {
2894 if (check_time_args(hour, minute, second, usecond) < 0)
2895 return NULL;
2896 if (check_tzinfo_subclass(tzinfo) < 0)
2897 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00002898 self = new_time(hour, minute, second, usecond, tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00002899 }
2900 return self;
2901}
2902
2903/*
2904 * Destructor.
2905 */
2906
2907static void
Tim Peters37f39822003-01-10 03:49:02 +00002908time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002909{
Tim Petersa032d2e2003-01-11 00:15:54 +00002910 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00002911 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00002912 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002913 self->ob_type->tp_free((PyObject *)self);
2914}
2915
2916/*
Tim Peters855fe882002-12-22 03:43:39 +00002917 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00002918 */
2919
Tim Peters2a799bf2002-12-16 20:18:38 +00002920/* These are all METH_NOARGS, so don't need to check the arglist. */
2921static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002922time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00002923 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00002924 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00002925}
2926
2927static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002928time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00002929 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00002930 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00002931}
2932
2933static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002934time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00002935 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00002936 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00002937}
2938
2939/*
Tim Peters37f39822003-01-10 03:49:02 +00002940 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00002941 */
2942
2943static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002944time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002945{
Tim Peters37f39822003-01-10 03:49:02 +00002946 char buffer[100];
2947 char *typename = self->ob_type->tp_name;
2948 int h = TIME_GET_HOUR(self);
2949 int m = TIME_GET_MINUTE(self);
2950 int s = TIME_GET_SECOND(self);
2951 int us = TIME_GET_MICROSECOND(self);
2952 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002953
Tim Peters37f39822003-01-10 03:49:02 +00002954 if (us)
2955 PyOS_snprintf(buffer, sizeof(buffer),
2956 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
2957 else if (s)
2958 PyOS_snprintf(buffer, sizeof(buffer),
2959 "%s(%d, %d, %d)", typename, h, m, s);
2960 else
2961 PyOS_snprintf(buffer, sizeof(buffer),
2962 "%s(%d, %d)", typename, h, m);
2963 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00002964 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00002965 result = append_keyword_tzinfo(result, self->tzinfo);
2966 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002967}
2968
Tim Peters37f39822003-01-10 03:49:02 +00002969static PyObject *
2970time_str(PyDateTime_Time *self)
2971{
2972 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2973}
Tim Peters2a799bf2002-12-16 20:18:38 +00002974
2975static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002976time_isoformat(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002977{
2978 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00002979 PyObject *result;
2980 /* Reuse the time format code from the datetime type. */
2981 PyDateTime_DateTime datetime;
2982 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00002983
Tim Peters37f39822003-01-10 03:49:02 +00002984 /* Copy over just the time bytes. */
2985 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
2986 self->data,
2987 _PyDateTime_TIME_DATASIZE);
2988
2989 isoformat_time(pdatetime, buf, sizeof(buf));
2990 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00002991 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00002992 return result;
2993
2994 /* We need to append the UTC offset. */
2995 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00002996 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002997 Py_DECREF(result);
2998 return NULL;
2999 }
3000 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3001 return result;
3002}
3003
Tim Peters37f39822003-01-10 03:49:02 +00003004static PyObject *
3005time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3006{
3007 PyObject *result;
3008 PyObject *format;
3009 PyObject *tuple;
3010 static char *keywords[] = {"format", NULL};
3011
3012 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3013 &PyString_Type, &format))
3014 return NULL;
3015
3016 /* Python's strftime does insane things with the year part of the
3017 * timetuple. The year is forced to (the otherwise nonsensical)
3018 * 1900 to worm around that.
3019 */
3020 tuple = Py_BuildValue("iiiiiiiii",
3021 1900, 0, 0, /* year, month, day */
3022 TIME_GET_HOUR(self),
3023 TIME_GET_MINUTE(self),
3024 TIME_GET_SECOND(self),
3025 0, 0, -1); /* weekday, daynum, dst */
3026 if (tuple == NULL)
3027 return NULL;
3028 assert(PyTuple_Size(tuple) == 9);
3029 result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
3030 Py_DECREF(tuple);
3031 return result;
3032}
Tim Peters2a799bf2002-12-16 20:18:38 +00003033
3034/*
3035 * Miscellaneous methods.
3036 */
3037
Tim Peters37f39822003-01-10 03:49:02 +00003038/* This is more natural as a tp_compare, but doesn't work then: for whatever
3039 * reason, Python's try_3way_compare ignores tp_compare unless
3040 * PyInstance_Check returns true, but these aren't old-style classes.
3041 */
3042static PyObject *
3043time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3044{
3045 int diff;
3046 naivety n1, n2;
3047 int offset1, offset2;
3048
3049 if (! PyTime_Check(other)) {
3050 /* Stop this from falling back to address comparison. */
3051 PyErr_Format(PyExc_TypeError,
3052 "can't compare '%s' to '%s'",
3053 self->ob_type->tp_name,
3054 other->ob_type->tp_name);
3055 return NULL;
3056 }
3057 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3058 other, &offset2, &n2, Py_None) < 0)
3059 return NULL;
3060 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3061 /* If they're both naive, or both aware and have the same offsets,
3062 * we get off cheap. Note that if they're both naive, offset1 ==
3063 * offset2 == 0 at this point.
3064 */
3065 if (n1 == n2 && offset1 == offset2) {
3066 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3067 _PyDateTime_TIME_DATASIZE);
3068 return diff_to_bool(diff, op);
3069 }
3070
3071 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3072 assert(offset1 != offset2); /* else last "if" handled it */
3073 /* Convert everything except microseconds to seconds. These
3074 * can't overflow (no more than the # of seconds in 2 days).
3075 */
3076 offset1 = TIME_GET_HOUR(self) * 3600 +
3077 (TIME_GET_MINUTE(self) - offset1) * 60 +
3078 TIME_GET_SECOND(self);
3079 offset2 = TIME_GET_HOUR(other) * 3600 +
3080 (TIME_GET_MINUTE(other) - offset2) * 60 +
3081 TIME_GET_SECOND(other);
3082 diff = offset1 - offset2;
3083 if (diff == 0)
3084 diff = TIME_GET_MICROSECOND(self) -
3085 TIME_GET_MICROSECOND(other);
3086 return diff_to_bool(diff, op);
3087 }
3088
3089 assert(n1 != n2);
3090 PyErr_SetString(PyExc_TypeError,
3091 "can't compare offset-naive and "
3092 "offset-aware times");
3093 return NULL;
3094}
3095
3096static long
3097time_hash(PyDateTime_Time *self)
3098{
3099 if (self->hashcode == -1) {
3100 naivety n;
3101 int offset;
3102 PyObject *temp;
3103
3104 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3105 assert(n != OFFSET_UNKNOWN);
3106 if (n == OFFSET_ERROR)
3107 return -1;
3108
3109 /* Reduce this to a hash of another object. */
3110 if (offset == 0)
3111 temp = PyString_FromStringAndSize((char *)self->data,
3112 _PyDateTime_TIME_DATASIZE);
3113 else {
3114 int hour;
3115 int minute;
3116
3117 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003118 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003119 hour = divmod(TIME_GET_HOUR(self) * 60 +
3120 TIME_GET_MINUTE(self) - offset,
3121 60,
3122 &minute);
3123 if (0 <= hour && hour < 24)
3124 temp = new_time(hour, minute,
3125 TIME_GET_SECOND(self),
3126 TIME_GET_MICROSECOND(self),
3127 Py_None);
3128 else
3129 temp = Py_BuildValue("iiii",
3130 hour, minute,
3131 TIME_GET_SECOND(self),
3132 TIME_GET_MICROSECOND(self));
3133 }
3134 if (temp != NULL) {
3135 self->hashcode = PyObject_Hash(temp);
3136 Py_DECREF(temp);
3137 }
3138 }
3139 return self->hashcode;
3140}
Tim Peters2a799bf2002-12-16 20:18:38 +00003141
Tim Peters12bf3392002-12-24 05:41:27 +00003142static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003143time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003144{
3145 PyObject *clone;
3146 PyObject *tuple;
3147 int hh = TIME_GET_HOUR(self);
3148 int mm = TIME_GET_MINUTE(self);
3149 int ss = TIME_GET_SECOND(self);
3150 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003151 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003152
3153 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003154 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003155 &hh, &mm, &ss, &us, &tzinfo))
3156 return NULL;
3157 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3158 if (tuple == NULL)
3159 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003160 clone = time_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003161 Py_DECREF(tuple);
3162 return clone;
3163}
3164
Tim Peters2a799bf2002-12-16 20:18:38 +00003165static int
Tim Peters37f39822003-01-10 03:49:02 +00003166time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003167{
3168 int offset;
3169 int none;
3170
3171 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3172 /* Since utcoffset is in whole minutes, nothing can
3173 * alter the conclusion that this is nonzero.
3174 */
3175 return 1;
3176 }
3177 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003178 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003179 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003180 if (offset == -1 && PyErr_Occurred())
3181 return -1;
3182 }
3183 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3184}
3185
3186/*
3187 * Pickle support. Quite a maze!
3188 */
3189
Tim Peters33e0f382003-01-10 02:05:14 +00003190/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003191 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3192 * So it's a tuple in any (non-error) case.
3193 */
3194static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003195time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003196{
3197 PyObject *basestate;
3198 PyObject *result = NULL;
3199
Tim Peters33e0f382003-01-10 02:05:14 +00003200 basestate = PyString_FromStringAndSize((char *)self->data,
3201 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003202 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003203 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003204 result = Py_BuildValue("(O)", basestate);
3205 else
3206 result = Py_BuildValue("OO", basestate, self->tzinfo);
3207 Py_DECREF(basestate);
3208 }
3209 return result;
3210}
3211
3212static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003213time_setstate(PyDateTime_Time *self, PyObject *state)
Tim Peters2a799bf2002-12-16 20:18:38 +00003214{
Tim Peters2a799bf2002-12-16 20:18:38 +00003215 PyObject *basestate;
3216 PyObject *tzinfo = Py_None;
3217
3218 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
3219 &PyString_Type, &basestate,
3220 &tzinfo))
3221 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00003222 if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE ||
3223 check_tzinfo_subclass(tzinfo) < 0) {
3224 PyErr_SetString(PyExc_TypeError,
3225 "bad argument to time.__setstate__");
Tim Peters2a799bf2002-12-16 20:18:38 +00003226 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00003227 }
Tim Petersa032d2e2003-01-11 00:15:54 +00003228 if (tzinfo != Py_None && ! HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003229 PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't "
3230 "add a non-None tzinfo to a time object that "
3231 "doesn't have one already");
3232 return NULL;
3233 }
Tim Peters33e0f382003-01-10 02:05:14 +00003234 memcpy((char *)self->data,
3235 PyString_AsString(basestate),
3236 _PyDateTime_TIME_DATASIZE);
3237 self->hashcode = -1;
Tim Petersa032d2e2003-01-11 00:15:54 +00003238 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003239 Py_INCREF(tzinfo);
3240 Py_XDECREF(self->tzinfo);
3241 self->tzinfo = tzinfo;
3242 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003243 Py_INCREF(Py_None);
3244 return Py_None;
3245}
3246
3247static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003248time_pickler(PyObject *module, PyDateTime_Time *time)
Tim Peters2a799bf2002-12-16 20:18:38 +00003249{
3250 PyObject *state;
3251 PyObject *result = NULL;
3252
Tim Peters37f39822003-01-10 03:49:02 +00003253 if (! PyTime_CheckExact(time)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003254 PyErr_Format(PyExc_TypeError,
Tim Peters37f39822003-01-10 03:49:02 +00003255 "bad type passed to time pickler: %s",
3256 time->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00003257 return NULL;
3258 }
Tim Peters37f39822003-01-10 03:49:02 +00003259 state = time_getstate(time);
Tim Peters2a799bf2002-12-16 20:18:38 +00003260 if (state) {
3261 result = Py_BuildValue("O(O)",
Tim Peters37f39822003-01-10 03:49:02 +00003262 time_unpickler_object,
Tim Peters2a799bf2002-12-16 20:18:38 +00003263 state);
3264 Py_DECREF(state);
3265 }
3266 return result;
3267}
3268
3269static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003270time_unpickler(PyObject *module, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003271{
Tim Peters37f39822003-01-10 03:49:02 +00003272 PyDateTime_Time *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003273
Tim Peters37f39822003-01-10 03:49:02 +00003274 /* We don't want to allocate space for tzinfo if it's not needed.
3275 * Figuring that out in advance is irritating, so for now we
3276 * realloc later.
3277 */
3278 self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00003279 if (self != NULL) {
3280 PyObject *res;
3281
Tim Peters37f39822003-01-10 03:49:02 +00003282 self->tzinfo = Py_None;
3283 Py_INCREF(self->tzinfo);
3284 self->hastzinfo = (char)1; /* true */
3285 res = time_setstate(self, arg);
Tim Peters2a799bf2002-12-16 20:18:38 +00003286 if (res == NULL) {
3287 Py_DECREF(self);
3288 return NULL;
3289 }
3290 Py_DECREF(res);
Tim Peters37f39822003-01-10 03:49:02 +00003291 if (self->tzinfo == Py_None) {
3292 /* shrinking; can't fail */
3293 Py_DECREF(self->tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003294 self = (PyDateTime_Time *)PyObject_Realloc(self,
3295 sizeof(_PyDateTime_BaseTime));
3296 assert(self != NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003297 self->hastzinfo = (char)0;
3298 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003299 }
3300 return (PyObject *)self;
3301}
3302
Tim Peters37f39822003-01-10 03:49:02 +00003303static PyMethodDef time_methods[] = {
3304 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003305 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3306 "[+HH:MM].")},
3307
Tim Peters37f39822003-01-10 03:49:02 +00003308 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3309 PyDoc_STR("format -> strftime() style string.")},
3310
3311 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003312 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3313
Tim Peters37f39822003-01-10 03:49:02 +00003314 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003315 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3316
Tim Peters37f39822003-01-10 03:49:02 +00003317 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003318 PyDoc_STR("Return self.tzinfo.dst(self).")},
3319
Tim Peters37f39822003-01-10 03:49:02 +00003320 {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
3321 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003322
Tim Peters37f39822003-01-10 03:49:02 +00003323 {"__setstate__", (PyCFunction)time_setstate, METH_O,
Tim Peters2a799bf2002-12-16 20:18:38 +00003324 PyDoc_STR("__setstate__(state)")},
3325
Tim Peters37f39822003-01-10 03:49:02 +00003326 {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003327 PyDoc_STR("__getstate__() -> state")},
3328 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003329};
3330
Tim Peters37f39822003-01-10 03:49:02 +00003331static char time_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003332PyDoc_STR("Time type.");
3333
Tim Peters37f39822003-01-10 03:49:02 +00003334static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003335 0, /* nb_add */
3336 0, /* nb_subtract */
3337 0, /* nb_multiply */
3338 0, /* nb_divide */
3339 0, /* nb_remainder */
3340 0, /* nb_divmod */
3341 0, /* nb_power */
3342 0, /* nb_negative */
3343 0, /* nb_positive */
3344 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003345 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003346};
3347
Tim Peters37f39822003-01-10 03:49:02 +00003348statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003349 PyObject_HEAD_INIT(NULL)
3350 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003351 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003352 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003353 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003354 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003355 0, /* tp_print */
3356 0, /* tp_getattr */
3357 0, /* tp_setattr */
3358 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003359 (reprfunc)time_repr, /* tp_repr */
3360 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003361 0, /* tp_as_sequence */
3362 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003363 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003364 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003365 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003366 PyObject_GenericGetAttr, /* tp_getattro */
3367 0, /* tp_setattro */
3368 0, /* tp_as_buffer */
3369 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3370 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003371 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003372 0, /* tp_traverse */
3373 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003374 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003375 0, /* tp_weaklistoffset */
3376 0, /* tp_iter */
3377 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003378 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003379 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003380 time_getset, /* tp_getset */
3381 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003382 0, /* tp_dict */
3383 0, /* tp_descr_get */
3384 0, /* tp_descr_set */
3385 0, /* tp_dictoffset */
3386 0, /* tp_init */
3387 0, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003388 time_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00003389 _PyObject_Del, /* tp_free */
3390};
3391
3392/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003393 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003394 */
3395
Tim Petersa9bc1682003-01-11 03:39:11 +00003396/* Accessor properties. Properties for day, month, and year are inherited
3397 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003398 */
3399
3400static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003401datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003402{
Tim Petersa9bc1682003-01-11 03:39:11 +00003403 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003404}
3405
Tim Petersa9bc1682003-01-11 03:39:11 +00003406static PyObject *
3407datetime_minute(PyDateTime_DateTime *self, void *unused)
3408{
3409 return PyInt_FromLong(DATE_GET_MINUTE(self));
3410}
3411
3412static PyObject *
3413datetime_second(PyDateTime_DateTime *self, void *unused)
3414{
3415 return PyInt_FromLong(DATE_GET_SECOND(self));
3416}
3417
3418static PyObject *
3419datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3420{
3421 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3422}
3423
3424static PyObject *
3425datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3426{
3427 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3428 Py_INCREF(result);
3429 return result;
3430}
3431
3432static PyGetSetDef datetime_getset[] = {
3433 {"hour", (getter)datetime_hour},
3434 {"minute", (getter)datetime_minute},
3435 {"second", (getter)datetime_second},
3436 {"microsecond", (getter)datetime_microsecond},
3437 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003438 {NULL}
3439};
3440
3441/*
3442 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003443 */
3444
Tim Petersa9bc1682003-01-11 03:39:11 +00003445static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003446 "year", "month", "day", "hour", "minute", "second",
3447 "microsecond", "tzinfo", NULL
3448};
3449
Tim Peters2a799bf2002-12-16 20:18:38 +00003450static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003451datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003452{
3453 PyObject *self = NULL;
3454 int year;
3455 int month;
3456 int day;
3457 int hour = 0;
3458 int minute = 0;
3459 int second = 0;
3460 int usecond = 0;
3461 PyObject *tzinfo = Py_None;
3462
Tim Petersa9bc1682003-01-11 03:39:11 +00003463 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003464 &year, &month, &day, &hour, &minute,
3465 &second, &usecond, &tzinfo)) {
3466 if (check_date_args(year, month, day) < 0)
3467 return NULL;
3468 if (check_time_args(hour, minute, second, usecond) < 0)
3469 return NULL;
3470 if (check_tzinfo_subclass(tzinfo) < 0)
3471 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003472 self = new_datetime(year, month, day,
3473 hour, minute, second, usecond,
3474 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003475 }
3476 return self;
3477}
3478
Tim Petersa9bc1682003-01-11 03:39:11 +00003479/* TM_FUNC is the shared type of localtime() and gmtime(). */
3480typedef struct tm *(*TM_FUNC)(const time_t *timer);
3481
3482/* Internal helper.
3483 * Build datetime from a time_t and a distinct count of microseconds.
3484 * Pass localtime or gmtime for f, to control the interpretation of timet.
3485 */
3486static PyObject *
3487datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3488 PyObject *tzinfo)
3489{
3490 struct tm *tm;
3491 PyObject *result = NULL;
3492
3493 tm = f(&timet);
3494 if (tm) {
3495 /* The platform localtime/gmtime may insert leap seconds,
3496 * indicated by tm->tm_sec > 59. We don't care about them,
3497 * except to the extent that passing them on to the datetime
3498 * constructor would raise ValueError for a reason that
3499 * made no sense to the user.
3500 */
3501 if (tm->tm_sec > 59)
3502 tm->tm_sec = 59;
3503 result = PyObject_CallFunction(cls, "iiiiiiiO",
3504 tm->tm_year + 1900,
3505 tm->tm_mon + 1,
3506 tm->tm_mday,
3507 tm->tm_hour,
3508 tm->tm_min,
3509 tm->tm_sec,
3510 us,
3511 tzinfo);
3512 }
3513 else
3514 PyErr_SetString(PyExc_ValueError,
3515 "timestamp out of range for "
3516 "platform localtime()/gmtime() function");
3517 return result;
3518}
3519
3520/* Internal helper.
3521 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3522 * to control the interpretation of the timestamp. Since a double doesn't
3523 * have enough bits to cover a datetime's full range of precision, it's
3524 * better to call datetime_from_timet_and_us provided you have a way
3525 * to get that much precision (e.g., C time() isn't good enough).
3526 */
3527static PyObject *
3528datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3529 PyObject *tzinfo)
3530{
3531 time_t timet = (time_t)timestamp;
3532 double fraction = timestamp - (double)timet;
3533 int us = (int)round_to_long(fraction * 1e6);
3534
3535 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3536}
3537
3538/* Internal helper.
3539 * Build most accurate possible datetime for current time. Pass localtime or
3540 * gmtime for f as appropriate.
3541 */
3542static PyObject *
3543datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3544{
3545#ifdef HAVE_GETTIMEOFDAY
3546 struct timeval t;
3547
3548#ifdef GETTIMEOFDAY_NO_TZ
3549 gettimeofday(&t);
3550#else
3551 gettimeofday(&t, (struct timezone *)NULL);
3552#endif
3553 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3554 tzinfo);
3555
3556#else /* ! HAVE_GETTIMEOFDAY */
3557 /* No flavor of gettimeofday exists on this platform. Python's
3558 * time.time() does a lot of other platform tricks to get the
3559 * best time it can on the platform, and we're not going to do
3560 * better than that (if we could, the better code would belong
3561 * in time.time()!) We're limited by the precision of a double,
3562 * though.
3563 */
3564 PyObject *time;
3565 double dtime;
3566
3567 time = time_time();
3568 if (time == NULL)
3569 return NULL;
3570 dtime = PyFloat_AsDouble(time);
3571 Py_DECREF(time);
3572 if (dtime == -1.0 && PyErr_Occurred())
3573 return NULL;
3574 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3575#endif /* ! HAVE_GETTIMEOFDAY */
3576}
3577
Tim Peters2a799bf2002-12-16 20:18:38 +00003578/* Return best possible local time -- this isn't constrained by the
3579 * precision of a timestamp.
3580 */
3581static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003582datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003583{
3584 PyObject *self = NULL;
3585 PyObject *tzinfo = Py_None;
3586 static char *keywords[] = {"tzinfo", NULL};
3587
3588 if (PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3589 &tzinfo)) {
3590 if (check_tzinfo_subclass(tzinfo) < 0)
3591 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003592 self = datetime_best_possible(cls, localtime, tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003593 }
3594 return self;
3595}
3596
Tim Petersa9bc1682003-01-11 03:39:11 +00003597/* Return best possible UTC time -- this isn't constrained by the
3598 * precision of a timestamp.
3599 */
3600static PyObject *
3601datetime_utcnow(PyObject *cls, PyObject *dummy)
3602{
3603 return datetime_best_possible(cls, gmtime, Py_None);
3604}
3605
Tim Peters2a799bf2002-12-16 20:18:38 +00003606/* Return new local datetime from timestamp (Python timestamp -- a double). */
3607static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003608datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003609{
3610 PyObject *self = NULL;
3611 double timestamp;
3612 PyObject *tzinfo = Py_None;
3613 static char *keywords[] = {"timestamp", "tzinfo", NULL};
3614
3615 if (PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3616 keywords, &timestamp, &tzinfo)) {
3617 if (check_tzinfo_subclass(tzinfo) < 0)
3618 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003619 self = datetime_from_timestamp(cls, localtime, timestamp,
3620 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003621 }
3622 return self;
3623}
3624
Tim Petersa9bc1682003-01-11 03:39:11 +00003625/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3626static PyObject *
3627datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3628{
3629 double timestamp;
3630 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003631
Tim Petersa9bc1682003-01-11 03:39:11 +00003632 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3633 result = datetime_from_timestamp(cls, gmtime, timestamp,
3634 Py_None);
3635 return result;
3636}
3637
3638/* Return new datetime from date/datetime and time arguments. */
3639static PyObject *
3640datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3641{
3642 static char *keywords[] = {"date", "time", NULL};
3643 PyObject *date;
3644 PyObject *time;
3645 PyObject *result = NULL;
3646
3647 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3648 &PyDateTime_DateType, &date,
3649 &PyDateTime_TimeType, &time)) {
3650 PyObject *tzinfo = Py_None;
3651
3652 if (HASTZINFO(time))
3653 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3654 result = PyObject_CallFunction(cls, "iiiiiiiO",
3655 GET_YEAR(date),
3656 GET_MONTH(date),
3657 GET_DAY(date),
3658 TIME_GET_HOUR(time),
3659 TIME_GET_MINUTE(time),
3660 TIME_GET_SECOND(time),
3661 TIME_GET_MICROSECOND(time),
3662 tzinfo);
3663 }
3664 return result;
3665}
Tim Peters2a799bf2002-12-16 20:18:38 +00003666
3667/*
3668 * Destructor.
3669 */
3670
3671static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003672datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003673{
Tim Petersa9bc1682003-01-11 03:39:11 +00003674 if (HASTZINFO(self)) {
3675 Py_XDECREF(self->tzinfo);
3676 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003677 self->ob_type->tp_free((PyObject *)self);
3678}
3679
3680/*
3681 * Indirect access to tzinfo methods.
3682 */
3683
Tim Peters2a799bf2002-12-16 20:18:38 +00003684/* These are all METH_NOARGS, so don't need to check the arglist. */
3685static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003686datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3687 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3688 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003689}
3690
3691static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003692datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3693 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3694 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003695}
3696
3697static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003698datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3699 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3700 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003701}
3702
3703/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003704 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003705 */
3706
Tim Petersa9bc1682003-01-11 03:39:11 +00003707/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3708 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003709 */
3710static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003711add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3712 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003713{
Tim Petersa9bc1682003-01-11 03:39:11 +00003714 /* Note that the C-level additions can't overflow, because of
3715 * invariant bounds on the member values.
3716 */
3717 int year = GET_YEAR(date);
3718 int month = GET_MONTH(date);
3719 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3720 int hour = DATE_GET_HOUR(date);
3721 int minute = DATE_GET_MINUTE(date);
3722 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3723 int microsecond = DATE_GET_MICROSECOND(date) +
3724 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003725
Tim Petersa9bc1682003-01-11 03:39:11 +00003726 assert(factor == 1 || factor == -1);
3727 if (normalize_datetime(&year, &month, &day,
3728 &hour, &minute, &second, &microsecond) < 0)
3729 return NULL;
3730 else
3731 return new_datetime(year, month, day,
3732 hour, minute, second, microsecond,
3733 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003734}
3735
3736static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003737datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003738{
Tim Petersa9bc1682003-01-11 03:39:11 +00003739 if (PyDateTime_Check(left)) {
3740 /* datetime + ??? */
3741 if (PyDelta_Check(right))
3742 /* datetime + delta */
3743 return add_datetime_timedelta(
3744 (PyDateTime_DateTime *)left,
3745 (PyDateTime_Delta *)right,
3746 1);
3747 }
3748 else if (PyDelta_Check(left)) {
3749 /* delta + datetime */
3750 return add_datetime_timedelta((PyDateTime_DateTime *) right,
3751 (PyDateTime_Delta *) left,
3752 1);
3753 }
3754 Py_INCREF(Py_NotImplemented);
3755 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00003756}
3757
3758static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003759datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003760{
3761 PyObject *result = Py_NotImplemented;
3762
3763 if (PyDateTime_Check(left)) {
3764 /* datetime - ??? */
3765 if (PyDateTime_Check(right)) {
3766 /* datetime - datetime */
3767 naivety n1, n2;
3768 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00003769 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00003770
Tim Peterse39a80c2002-12-30 21:28:52 +00003771 if (classify_two_utcoffsets(left, &offset1, &n1, left,
3772 right, &offset2, &n2,
3773 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00003774 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00003775 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00003776 if (n1 != n2) {
3777 PyErr_SetString(PyExc_TypeError,
3778 "can't subtract offset-naive and "
3779 "offset-aware datetimes");
3780 return NULL;
3781 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003782 delta_d = ymd_to_ord(GET_YEAR(left),
3783 GET_MONTH(left),
3784 GET_DAY(left)) -
3785 ymd_to_ord(GET_YEAR(right),
3786 GET_MONTH(right),
3787 GET_DAY(right));
3788 /* These can't overflow, since the values are
3789 * normalized. At most this gives the number of
3790 * seconds in one day.
3791 */
3792 delta_s = (DATE_GET_HOUR(left) -
3793 DATE_GET_HOUR(right)) * 3600 +
3794 (DATE_GET_MINUTE(left) -
3795 DATE_GET_MINUTE(right)) * 60 +
3796 (DATE_GET_SECOND(left) -
3797 DATE_GET_SECOND(right));
3798 delta_us = DATE_GET_MICROSECOND(left) -
3799 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00003800 /* (left - offset1) - (right - offset2) =
3801 * (left - right) + (offset2 - offset1)
3802 */
Tim Petersa9bc1682003-01-11 03:39:11 +00003803 delta_s += (offset2 - offset1) * 60;
3804 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003805 }
3806 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00003807 /* datetime - delta */
3808 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00003809 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00003810 (PyDateTime_Delta *)right,
3811 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003812 }
3813 }
3814
3815 if (result == Py_NotImplemented)
3816 Py_INCREF(result);
3817 return result;
3818}
3819
3820/* Various ways to turn a datetime into a string. */
3821
3822static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003823datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003824{
Tim Petersa9bc1682003-01-11 03:39:11 +00003825 char buffer[1000];
3826 char *typename = self->ob_type->tp_name;
3827 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003828
Tim Petersa9bc1682003-01-11 03:39:11 +00003829 if (DATE_GET_MICROSECOND(self)) {
3830 PyOS_snprintf(buffer, sizeof(buffer),
3831 "%s(%d, %d, %d, %d, %d, %d, %d)",
3832 typename,
3833 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3834 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3835 DATE_GET_SECOND(self),
3836 DATE_GET_MICROSECOND(self));
3837 }
3838 else if (DATE_GET_SECOND(self)) {
3839 PyOS_snprintf(buffer, sizeof(buffer),
3840 "%s(%d, %d, %d, %d, %d, %d)",
3841 typename,
3842 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3843 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3844 DATE_GET_SECOND(self));
3845 }
3846 else {
3847 PyOS_snprintf(buffer, sizeof(buffer),
3848 "%s(%d, %d, %d, %d, %d)",
3849 typename,
3850 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3851 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
3852 }
3853 baserepr = PyString_FromString(buffer);
3854 if (baserepr == NULL || ! HASTZINFO(self))
3855 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003856 return append_keyword_tzinfo(baserepr, self->tzinfo);
3857}
3858
Tim Petersa9bc1682003-01-11 03:39:11 +00003859static PyObject *
3860datetime_str(PyDateTime_DateTime *self)
3861{
3862 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
3863}
Tim Peters2a799bf2002-12-16 20:18:38 +00003864
3865static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003866datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003867{
Tim Petersa9bc1682003-01-11 03:39:11 +00003868 char sep = 'T';
3869 static char *keywords[] = {"sep", NULL};
3870 char buffer[100];
3871 char *cp;
3872 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003873
Tim Petersa9bc1682003-01-11 03:39:11 +00003874 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
3875 &sep))
3876 return NULL;
3877 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
3878 assert(cp != NULL);
3879 *cp++ = sep;
3880 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
3881 result = PyString_FromString(buffer);
3882 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00003883 return result;
3884
3885 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00003886 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00003887 (PyObject *)self) < 0) {
3888 Py_DECREF(result);
3889 return NULL;
3890 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003891 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00003892 return result;
3893}
3894
Tim Petersa9bc1682003-01-11 03:39:11 +00003895static PyObject *
3896datetime_ctime(PyDateTime_DateTime *self)
3897{
3898 return format_ctime((PyDateTime_Date *)self,
3899 DATE_GET_HOUR(self),
3900 DATE_GET_MINUTE(self),
3901 DATE_GET_SECOND(self));
3902}
3903
Tim Peters2a799bf2002-12-16 20:18:38 +00003904/* Miscellaneous methods. */
3905
Tim Petersa9bc1682003-01-11 03:39:11 +00003906/* This is more natural as a tp_compare, but doesn't work then: for whatever
3907 * reason, Python's try_3way_compare ignores tp_compare unless
3908 * PyInstance_Check returns true, but these aren't old-style classes.
3909 */
3910static PyObject *
3911datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
3912{
3913 int diff;
3914 naivety n1, n2;
3915 int offset1, offset2;
3916
3917 if (! PyDateTime_Check(other)) {
3918 /* Stop this from falling back to address comparison. */
3919 PyErr_Format(PyExc_TypeError,
3920 "can't compare '%s' to '%s'",
3921 self->ob_type->tp_name,
3922 other->ob_type->tp_name);
3923 return NULL;
3924 }
3925
3926 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
3927 (PyObject *)self,
3928 other, &offset2, &n2,
3929 other) < 0)
3930 return NULL;
3931 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3932 /* If they're both naive, or both aware and have the same offsets,
3933 * we get off cheap. Note that if they're both naive, offset1 ==
3934 * offset2 == 0 at this point.
3935 */
3936 if (n1 == n2 && offset1 == offset2) {
3937 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
3938 _PyDateTime_DATETIME_DATASIZE);
3939 return diff_to_bool(diff, op);
3940 }
3941
3942 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3943 PyDateTime_Delta *delta;
3944
3945 assert(offset1 != offset2); /* else last "if" handled it */
3946 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
3947 other);
3948 if (delta == NULL)
3949 return NULL;
3950 diff = GET_TD_DAYS(delta);
3951 if (diff == 0)
3952 diff = GET_TD_SECONDS(delta) |
3953 GET_TD_MICROSECONDS(delta);
3954 Py_DECREF(delta);
3955 return diff_to_bool(diff, op);
3956 }
3957
3958 assert(n1 != n2);
3959 PyErr_SetString(PyExc_TypeError,
3960 "can't compare offset-naive and "
3961 "offset-aware datetimes");
3962 return NULL;
3963}
3964
3965static long
3966datetime_hash(PyDateTime_DateTime *self)
3967{
3968 if (self->hashcode == -1) {
3969 naivety n;
3970 int offset;
3971 PyObject *temp;
3972
3973 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
3974 &offset);
3975 assert(n != OFFSET_UNKNOWN);
3976 if (n == OFFSET_ERROR)
3977 return -1;
3978
3979 /* Reduce this to a hash of another object. */
3980 if (n == OFFSET_NAIVE)
3981 temp = PyString_FromStringAndSize(
3982 (char *)self->data,
3983 _PyDateTime_DATETIME_DATASIZE);
3984 else {
3985 int days;
3986 int seconds;
3987
3988 assert(n == OFFSET_AWARE);
3989 assert(HASTZINFO(self));
3990 days = ymd_to_ord(GET_YEAR(self),
3991 GET_MONTH(self),
3992 GET_DAY(self));
3993 seconds = DATE_GET_HOUR(self) * 3600 +
3994 (DATE_GET_MINUTE(self) - offset) * 60 +
3995 DATE_GET_SECOND(self);
3996 temp = new_delta(days,
3997 seconds,
3998 DATE_GET_MICROSECOND(self),
3999 1);
4000 }
4001 if (temp != NULL) {
4002 self->hashcode = PyObject_Hash(temp);
4003 Py_DECREF(temp);
4004 }
4005 }
4006 return self->hashcode;
4007}
Tim Peters2a799bf2002-12-16 20:18:38 +00004008
4009static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004010datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004011{
4012 PyObject *clone;
4013 PyObject *tuple;
4014 int y = GET_YEAR(self);
4015 int m = GET_MONTH(self);
4016 int d = GET_DAY(self);
4017 int hh = DATE_GET_HOUR(self);
4018 int mm = DATE_GET_MINUTE(self);
4019 int ss = DATE_GET_SECOND(self);
4020 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004021 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004022
4023 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004024 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004025 &y, &m, &d, &hh, &mm, &ss, &us,
4026 &tzinfo))
4027 return NULL;
4028 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4029 if (tuple == NULL)
4030 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004031 clone = datetime_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004032 Py_DECREF(tuple);
4033 return clone;
4034}
4035
4036static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004037datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004038{
4039 int y = GET_YEAR(self);
4040 int m = GET_MONTH(self);
4041 int d = GET_DAY(self);
4042 int hh = DATE_GET_HOUR(self);
4043 int mm = DATE_GET_MINUTE(self);
4044 int ss = DATE_GET_SECOND(self);
4045 int us = DATE_GET_MICROSECOND(self);
4046
Tim Peters521fc152002-12-31 17:36:56 +00004047 PyObject *result;
4048 PyObject *temp;
Tim Petersadf64202003-01-04 06:03:15 +00004049 int selfoff, resoff, dst1, dst2;
Tim Peters521fc152002-12-31 17:36:56 +00004050 int none;
Tim Petersf3615152003-01-01 21:51:37 +00004051 int delta;
Tim Peters521fc152002-12-31 17:36:56 +00004052
Tim Peters80475bb2002-12-25 07:40:55 +00004053 PyObject *tzinfo;
4054 static char *keywords[] = {"tz", NULL};
4055
4056 if (! PyArg_ParseTupleAndKeywords(args, kw, "O:astimezone", keywords,
4057 &tzinfo))
4058 return NULL;
4059 if (check_tzinfo_subclass(tzinfo) < 0)
4060 return NULL;
4061
Tim Peters521fc152002-12-31 17:36:56 +00004062 /* Don't call utcoffset unless necessary. */
Tim Petersa9bc1682003-01-11 03:39:11 +00004063 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
Tim Peters521fc152002-12-31 17:36:56 +00004064 if (result == NULL ||
4065 tzinfo == Py_None ||
Tim Petersa9bc1682003-01-11 03:39:11 +00004066 ! HASTZINFO(self) ||
Tim Peters521fc152002-12-31 17:36:56 +00004067 self->tzinfo == Py_None ||
4068 self->tzinfo == tzinfo)
4069 return result;
4070
4071 /* Get the offsets. If either object turns out to be naive, again
4072 * there's no conversion of date or time fields.
4073 */
Tim Petersb5a16f32003-01-01 04:48:01 +00004074 selfoff = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4075 if (selfoff == -1 && PyErr_Occurred())
Tim Peters521fc152002-12-31 17:36:56 +00004076 goto Fail;
4077 if (none)
4078 return result;
4079
Tim Petersb5a16f32003-01-01 04:48:01 +00004080 resoff = call_utcoffset(tzinfo, result, &none);
4081 if (resoff == -1 && PyErr_Occurred())
Tim Peters521fc152002-12-31 17:36:56 +00004082 goto Fail;
4083 if (none)
4084 return result;
4085
Tim Petersf3615152003-01-01 21:51:37 +00004086 /* See the long comment block at the end of this file for an
4087 * explanation of this algorithm. That it always works requires a
Tim Petersadf64202003-01-04 06:03:15 +00004088 * pretty intricate proof. There are many equivalent ways to code
4089 * up the proof as an algorithm. This way favors calling dst() over
4090 * calling utcoffset(), because "the usual" utcoffset() calls dst()
4091 * itself, and calling the latter instead saves a Python-level
4092 * function call. This way of coding it also follows the proof
4093 * closely, w/ x=self, y=result, z=result, and z'=temp.
Tim Peters521fc152002-12-31 17:36:56 +00004094 */
Tim Petersadf64202003-01-04 06:03:15 +00004095 dst1 = call_dst(tzinfo, result, &none);
4096 if (dst1 == -1 && PyErr_Occurred())
Tim Peters521fc152002-12-31 17:36:56 +00004097 goto Fail;
Tim Peters710fb152003-01-02 19:35:54 +00004098 if (none) {
4099 PyErr_SetString(PyExc_ValueError, "astimezone(): utcoffset() "
4100 "returned a duration but dst() returned None");
4101 goto Fail;
4102 }
Tim Petersadf64202003-01-04 06:03:15 +00004103 delta = resoff - dst1 - selfoff;
4104 if (delta) {
4105 mm += delta;
Tim Petersb5a16f32003-01-01 04:48:01 +00004106 if ((mm < 0 || mm >= 60) &&
4107 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters521fc152002-12-31 17:36:56 +00004108 goto Fail;
Tim Petersa9bc1682003-01-11 03:39:11 +00004109 temp = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
Tim Peters521fc152002-12-31 17:36:56 +00004110 if (temp == NULL)
4111 goto Fail;
4112 Py_DECREF(result);
4113 result = temp;
4114
Tim Petersadf64202003-01-04 06:03:15 +00004115 dst1 = call_dst(tzinfo, result, &none);
4116 if (dst1 == -1 && PyErr_Occurred())
Tim Peters521fc152002-12-31 17:36:56 +00004117 goto Fail;
4118 if (none)
4119 goto Inconsistent;
Tim Petersf3615152003-01-01 21:51:37 +00004120 }
Tim Petersadf64202003-01-04 06:03:15 +00004121 if (dst1 == 0)
Tim Petersf3615152003-01-01 21:51:37 +00004122 return result;
4123
Tim Petersadf64202003-01-04 06:03:15 +00004124 mm += dst1;
Tim Petersf3615152003-01-01 21:51:37 +00004125 if ((mm < 0 || mm >= 60) &&
4126 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters521fc152002-12-31 17:36:56 +00004127 goto Fail;
Tim Petersa9bc1682003-01-11 03:39:11 +00004128 temp = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
Tim Peters521fc152002-12-31 17:36:56 +00004129 if (temp == NULL)
4130 goto Fail;
Tim Peters521fc152002-12-31 17:36:56 +00004131
Tim Petersadf64202003-01-04 06:03:15 +00004132 dst2 = call_dst(tzinfo, temp, &none);
4133 if (dst2 == -1 && PyErr_Occurred()) {
4134 Py_DECREF(temp);
Tim Petersf3615152003-01-01 21:51:37 +00004135 goto Fail;
Tim Petersadf64202003-01-04 06:03:15 +00004136 }
4137 if (none) {
4138 Py_DECREF(temp);
Tim Petersf3615152003-01-01 21:51:37 +00004139 goto Inconsistent;
Tim Petersadf64202003-01-04 06:03:15 +00004140 }
Tim Petersf3615152003-01-01 21:51:37 +00004141
Tim Petersadf64202003-01-04 06:03:15 +00004142 if (dst1 == dst2) {
4143 /* The normal case: we want temp, not result. */
4144 Py_DECREF(result);
4145 result = temp;
4146 }
4147 else {
4148 /* The "unspellable hour" at the end of DST. */
4149 Py_DECREF(temp);
4150 }
4151 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004152
4153Inconsistent:
Tim Petersadf64202003-01-04 06:03:15 +00004154 PyErr_SetString(PyExc_ValueError, "astimezone(): tz.dst() gave"
4155 "inconsistent results; cannot convert");
Tim Peters521fc152002-12-31 17:36:56 +00004156
4157 /* fall thru to failure */
4158Fail:
4159 Py_DECREF(result);
4160 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004161}
4162
4163static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004164datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004165{
4166 int dstflag = -1;
4167
Tim Petersa9bc1682003-01-11 03:39:11 +00004168 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004169 int none;
4170
4171 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4172 if (dstflag == -1 && PyErr_Occurred())
4173 return NULL;
4174
4175 if (none)
4176 dstflag = -1;
4177 else if (dstflag != 0)
4178 dstflag = 1;
4179
4180 }
4181 return build_struct_time(GET_YEAR(self),
4182 GET_MONTH(self),
4183 GET_DAY(self),
4184 DATE_GET_HOUR(self),
4185 DATE_GET_MINUTE(self),
4186 DATE_GET_SECOND(self),
4187 dstflag);
4188}
4189
4190static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004191datetime_getdate(PyDateTime_DateTime *self)
4192{
4193 return new_date(GET_YEAR(self),
4194 GET_MONTH(self),
4195 GET_DAY(self));
4196}
4197
4198static PyObject *
4199datetime_gettime(PyDateTime_DateTime *self)
4200{
4201 return new_time(DATE_GET_HOUR(self),
4202 DATE_GET_MINUTE(self),
4203 DATE_GET_SECOND(self),
4204 DATE_GET_MICROSECOND(self),
4205 Py_None);
4206}
4207
4208static PyObject *
4209datetime_gettimetz(PyDateTime_DateTime *self)
4210{
4211 return new_time(DATE_GET_HOUR(self),
4212 DATE_GET_MINUTE(self),
4213 DATE_GET_SECOND(self),
4214 DATE_GET_MICROSECOND(self),
4215 HASTZINFO(self) ? self->tzinfo : Py_None);
4216}
4217
4218static PyObject *
4219datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004220{
4221 int y = GET_YEAR(self);
4222 int m = GET_MONTH(self);
4223 int d = GET_DAY(self);
4224 int hh = DATE_GET_HOUR(self);
4225 int mm = DATE_GET_MINUTE(self);
4226 int ss = DATE_GET_SECOND(self);
4227 int us = 0; /* microseconds are ignored in a timetuple */
4228 int offset = 0;
4229
Tim Petersa9bc1682003-01-11 03:39:11 +00004230 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004231 int none;
4232
4233 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4234 if (offset == -1 && PyErr_Occurred())
4235 return NULL;
4236 }
4237 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4238 * 0 in a UTC timetuple regardless of what dst() says.
4239 */
4240 if (offset) {
4241 /* Subtract offset minutes & normalize. */
4242 int stat;
4243
4244 mm -= offset;
4245 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4246 if (stat < 0) {
4247 /* At the edges, it's possible we overflowed
4248 * beyond MINYEAR or MAXYEAR.
4249 */
4250 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4251 PyErr_Clear();
4252 else
4253 return NULL;
4254 }
4255 }
4256 return build_struct_time(y, m, d, hh, mm, ss, 0);
4257}
4258
Tim Peters33e0f382003-01-10 02:05:14 +00004259/* Pickle support. Quite a maze! */
4260
Tim Petersa9bc1682003-01-11 03:39:11 +00004261/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004262 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4263 * So it's a tuple in any (non-error) case.
4264 */
4265static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004266datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004267{
4268 PyObject *basestate;
4269 PyObject *result = NULL;
4270
Tim Peters33e0f382003-01-10 02:05:14 +00004271 basestate = PyString_FromStringAndSize((char *)self->data,
4272 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004273 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004274 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00004275 result = Py_BuildValue("(O)", basestate);
4276 else
4277 result = Py_BuildValue("OO", basestate, self->tzinfo);
4278 Py_DECREF(basestate);
4279 }
4280 return result;
4281}
4282
4283static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004284datetime_setstate(PyDateTime_DateTime *self, PyObject *state)
Tim Peters2a799bf2002-12-16 20:18:38 +00004285{
Tim Peters2a799bf2002-12-16 20:18:38 +00004286 PyObject *basestate;
4287 PyObject *tzinfo = Py_None;
4288
4289 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
4290 &PyString_Type, &basestate,
4291 &tzinfo))
4292 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00004293 if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE ||
4294 check_tzinfo_subclass(tzinfo) < 0) {
4295 PyErr_SetString(PyExc_TypeError,
4296 "bad argument to datetime.__setstate__");
Tim Peters2a799bf2002-12-16 20:18:38 +00004297 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00004298 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004299 if (tzinfo != Py_None && ! HASTZINFO(self)) {
4300 PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ "
4301 "can't add a non-None tzinfo to a datetime "
4302 "object that doesn't have one already");
4303 return NULL;
4304 }
Tim Peters33e0f382003-01-10 02:05:14 +00004305 memcpy((char *)self->data,
4306 PyString_AsString(basestate),
4307 _PyDateTime_DATETIME_DATASIZE);
4308 self->hashcode = -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004309 if (HASTZINFO(self)) {
4310 Py_INCREF(tzinfo);
4311 Py_XDECREF(self->tzinfo);
4312 self->tzinfo = tzinfo;
4313 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004314 Py_INCREF(Py_None);
4315 return Py_None;
4316}
4317
4318static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004319datetime_pickler(PyObject *module, PyDateTime_DateTime *datetime)
Tim Peters2a799bf2002-12-16 20:18:38 +00004320{
4321 PyObject *state;
4322 PyObject *result = NULL;
4323
Tim Petersa9bc1682003-01-11 03:39:11 +00004324 if (! PyDateTime_CheckExact(datetime)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004325 PyErr_Format(PyExc_TypeError,
Tim Petersa9bc1682003-01-11 03:39:11 +00004326 "bad type passed to datetime pickler: %s",
4327 datetime->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00004328 return NULL;
4329 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004330 state = datetime_getstate(datetime);
Tim Peters2a799bf2002-12-16 20:18:38 +00004331 if (state) {
4332 result = Py_BuildValue("O(O)",
Tim Petersa9bc1682003-01-11 03:39:11 +00004333 datetime_unpickler_object,
Tim Peters2a799bf2002-12-16 20:18:38 +00004334 state);
4335 Py_DECREF(state);
4336 }
4337 return result;
4338}
4339
4340static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004341datetime_unpickler(PyObject *module, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004342{
Tim Petersa9bc1682003-01-11 03:39:11 +00004343 PyDateTime_DateTime *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004344
Tim Petersa9bc1682003-01-11 03:39:11 +00004345 /* We don't want to allocate space for tzinfo if it's not needed.
4346 * Figuring that out in advance is irritating, so for now we
4347 * realloc later.
4348 */
4349 self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004350 if (self != NULL) {
4351 PyObject *res;
4352
Tim Petersa9bc1682003-01-11 03:39:11 +00004353 self->tzinfo = Py_None;
4354 Py_INCREF(self->tzinfo);
4355 self->hastzinfo = (char)1; /* true */
4356 res = datetime_setstate(self, arg);
Tim Peters2a799bf2002-12-16 20:18:38 +00004357 if (res == NULL) {
4358 Py_DECREF(self);
4359 return NULL;
4360 }
4361 Py_DECREF(res);
Tim Petersa9bc1682003-01-11 03:39:11 +00004362 if (self->tzinfo == Py_None) {
4363 /* shrinking; can't fail */
4364 Py_DECREF(self->tzinfo);
4365 self = (PyDateTime_DateTime *)PyObject_Realloc(self,
4366 sizeof(_PyDateTime_BaseDateTime));
4367 assert(self != NULL);
4368 self->hastzinfo = (char)0;
4369 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004370 }
4371 return (PyObject *)self;
4372}
4373
4374
Tim Petersa9bc1682003-01-11 03:39:11 +00004375static PyMethodDef datetime_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004376 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004377
Tim Petersa9bc1682003-01-11 03:39:11 +00004378 {"now", (PyCFunction)datetime_now,
Tim Peters2a799bf2002-12-16 20:18:38 +00004379 METH_KEYWORDS | METH_CLASS,
Tim Petersa9bc1682003-01-11 03:39:11 +00004380 PyDoc_STR("[tzinfo] -> new datetime with local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004381
Tim Petersa9bc1682003-01-11 03:39:11 +00004382 {"utcnow", (PyCFunction)datetime_utcnow,
4383 METH_NOARGS | METH_CLASS,
4384 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4385
4386 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Tim Peters2a799bf2002-12-16 20:18:38 +00004387 METH_KEYWORDS | METH_CLASS,
4388 PyDoc_STR("timestamp[, tzinfo] -> local time from POSIX timestamp.")},
4389
Tim Petersa9bc1682003-01-11 03:39:11 +00004390 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4391 METH_VARARGS | METH_CLASS,
4392 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4393 "(like time.time()).")},
4394
4395 {"combine", (PyCFunction)datetime_combine,
4396 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4397 PyDoc_STR("date, time -> datetime with same date and time fields")},
4398
Tim Peters2a799bf2002-12-16 20:18:38 +00004399 /* Instance methods: */
Tim Petersa9bc1682003-01-11 03:39:11 +00004400 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4401 PyDoc_STR("Return date object with same year, month and day.")},
4402
4403 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4404 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4405
4406 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4407 PyDoc_STR("Return time object with same time and tzinfo.")},
4408
4409 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4410 PyDoc_STR("Return ctime() style string.")},
4411
4412 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004413 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4414
Tim Petersa9bc1682003-01-11 03:39:11 +00004415 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004416 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4417
Tim Petersa9bc1682003-01-11 03:39:11 +00004418 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004419 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4420 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4421 "sep is used to separate the year from the time, and "
4422 "defaults to 'T'.")},
4423
Tim Petersa9bc1682003-01-11 03:39:11 +00004424 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004425 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4426
Tim Petersa9bc1682003-01-11 03:39:11 +00004427 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004428 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4429
Tim Petersa9bc1682003-01-11 03:39:11 +00004430 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004431 PyDoc_STR("Return self.tzinfo.dst(self).")},
4432
Tim Petersa9bc1682003-01-11 03:39:11 +00004433 {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
4434 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004435
Tim Petersa9bc1682003-01-11 03:39:11 +00004436 {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004437 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4438
Tim Petersa9bc1682003-01-11 03:39:11 +00004439 {"__setstate__", (PyCFunction)datetime_setstate, METH_O,
Tim Peters2a799bf2002-12-16 20:18:38 +00004440 PyDoc_STR("__setstate__(state)")},
4441
Tim Petersa9bc1682003-01-11 03:39:11 +00004442 {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004443 PyDoc_STR("__getstate__() -> state")},
4444 {NULL, NULL}
4445};
4446
Tim Petersa9bc1682003-01-11 03:39:11 +00004447static char datetime_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00004448PyDoc_STR("date/time type.");
4449
Tim Petersa9bc1682003-01-11 03:39:11 +00004450static PyNumberMethods datetime_as_number = {
4451 datetime_add, /* nb_add */
4452 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004453 0, /* nb_multiply */
4454 0, /* nb_divide */
4455 0, /* nb_remainder */
4456 0, /* nb_divmod */
4457 0, /* nb_power */
4458 0, /* nb_negative */
4459 0, /* nb_positive */
4460 0, /* nb_absolute */
4461 0, /* nb_nonzero */
4462};
4463
Tim Petersa9bc1682003-01-11 03:39:11 +00004464statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004465 PyObject_HEAD_INIT(NULL)
4466 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004467 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004468 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004469 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004470 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004471 0, /* tp_print */
4472 0, /* tp_getattr */
4473 0, /* tp_setattr */
4474 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004475 (reprfunc)datetime_repr, /* tp_repr */
4476 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004477 0, /* tp_as_sequence */
4478 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004479 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004480 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004481 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004482 PyObject_GenericGetAttr, /* tp_getattro */
4483 0, /* tp_setattro */
4484 0, /* tp_as_buffer */
4485 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4486 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004487 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004488 0, /* tp_traverse */
4489 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004490 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004491 0, /* tp_weaklistoffset */
4492 0, /* tp_iter */
4493 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004494 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004495 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004496 datetime_getset, /* tp_getset */
4497 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004498 0, /* tp_dict */
4499 0, /* tp_descr_get */
4500 0, /* tp_descr_set */
4501 0, /* tp_dictoffset */
4502 0, /* tp_init */
4503 0, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004504 datetime_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00004505 _PyObject_Del, /* tp_free */
4506};
4507
4508/* ---------------------------------------------------------------------------
4509 * Module methods and initialization.
4510 */
4511
4512static PyMethodDef module_methods[] = {
4513 /* Private functions for pickling support, registered with the
4514 * copy_reg module by the module init function.
4515 */
4516 {"_date_pickler", (PyCFunction)date_pickler, METH_O, NULL},
4517 {"_date_unpickler", (PyCFunction)date_unpickler, METH_O, NULL},
Tim Petersa9bc1682003-01-11 03:39:11 +00004518 {"_datetime_pickler", (PyCFunction)datetime_pickler, METH_O, NULL},
4519 {"_datetime_unpickler", (PyCFunction)datetime_unpickler,METH_O, NULL},
Tim Peters37f39822003-01-10 03:49:02 +00004520 {"_time_pickler", (PyCFunction)time_pickler, METH_O, NULL},
4521 {"_time_unpickler", (PyCFunction)time_unpickler, METH_O, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00004522 {"_tzinfo_pickler", (PyCFunction)tzinfo_pickler, METH_O, NULL},
4523 {"_tzinfo_unpickler", (PyCFunction)tzinfo_unpickler, METH_NOARGS,
4524 NULL},
4525 {NULL, NULL}
4526};
4527
4528PyMODINIT_FUNC
4529initdatetime(void)
4530{
4531 PyObject *m; /* a module object */
4532 PyObject *d; /* its dict */
4533 PyObject *x;
4534
4535 /* Types that use __reduce__ for pickling need to set the following
4536 * magical attr in the type dict, with a true value.
4537 */
4538 PyObject *safepickle = PyString_FromString("__safe_for_unpickling__");
4539 if (safepickle == NULL)
4540 return;
4541
4542 m = Py_InitModule3("datetime", module_methods,
4543 "Fast implementation of the datetime type.");
4544
4545 if (PyType_Ready(&PyDateTime_DateType) < 0)
4546 return;
4547 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4548 return;
4549 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4550 return;
4551 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4552 return;
4553 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4554 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004555
4556 /* Pickling support, via registering functions with copy_reg. */
4557 {
4558 PyObject *pickler;
4559 PyObject *copyreg = PyImport_ImportModule("copy_reg");
4560
4561 if (copyreg == NULL) return;
4562
4563 pickler = PyObject_GetAttrString(m, "_date_pickler");
4564 if (pickler == NULL) return;
4565 date_unpickler_object = PyObject_GetAttrString(m,
4566 "_date_unpickler");
4567 if (date_unpickler_object == NULL) return;
4568 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4569 &PyDateTime_DateType,
4570 pickler,
4571 date_unpickler_object);
4572 if (x == NULL) return;
4573 Py_DECREF(x);
4574 Py_DECREF(pickler);
4575
Tim Peters37f39822003-01-10 03:49:02 +00004576 pickler = PyObject_GetAttrString(m, "_time_pickler");
Tim Peters2a799bf2002-12-16 20:18:38 +00004577 if (pickler == NULL) return;
Tim Peters37f39822003-01-10 03:49:02 +00004578 time_unpickler_object = PyObject_GetAttrString(m,
4579 "_time_unpickler");
4580 if (time_unpickler_object == NULL) return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004581 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
Tim Peters37f39822003-01-10 03:49:02 +00004582 &PyDateTime_TimeType,
Tim Peters2a799bf2002-12-16 20:18:38 +00004583 pickler,
Tim Peters37f39822003-01-10 03:49:02 +00004584 time_unpickler_object);
Tim Peters2a799bf2002-12-16 20:18:38 +00004585 if (x == NULL) return;
4586 Py_DECREF(x);
4587 Py_DECREF(pickler);
4588
4589 pickler = PyObject_GetAttrString(m, "_tzinfo_pickler");
4590 if (pickler == NULL) return;
4591 tzinfo_unpickler_object = PyObject_GetAttrString(m,
4592 "_tzinfo_unpickler");
4593 if (tzinfo_unpickler_object == NULL) return;
4594 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4595 &PyDateTime_TZInfoType,
4596 pickler,
4597 tzinfo_unpickler_object);
4598 if (x== NULL) return;
4599 Py_DECREF(x);
4600 Py_DECREF(pickler);
4601
Tim Petersa9bc1682003-01-11 03:39:11 +00004602 pickler = PyObject_GetAttrString(m, "_datetime_pickler");
Tim Peters2a799bf2002-12-16 20:18:38 +00004603 if (pickler == NULL) return;
Tim Petersa9bc1682003-01-11 03:39:11 +00004604 datetime_unpickler_object = PyObject_GetAttrString(m,
4605 "_datetime_unpickler");
4606 if (datetime_unpickler_object == NULL) return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004607 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
Tim Petersa9bc1682003-01-11 03:39:11 +00004608 &PyDateTime_DateTimeType,
Tim Peters2a799bf2002-12-16 20:18:38 +00004609 pickler,
Tim Petersa9bc1682003-01-11 03:39:11 +00004610 datetime_unpickler_object);
Tim Peters2a799bf2002-12-16 20:18:38 +00004611 if (x== NULL) return;
4612 Py_DECREF(x);
4613 Py_DECREF(pickler);
4614
4615 Py_DECREF(copyreg);
4616 }
4617
4618 /* timedelta values */
4619 d = PyDateTime_DeltaType.tp_dict;
4620
4621 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
4622 return;
4623
4624 x = new_delta(0, 0, 1, 0);
4625 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4626 return;
4627 Py_DECREF(x);
4628
4629 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4630 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4631 return;
4632 Py_DECREF(x);
4633
4634 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4635 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4636 return;
4637 Py_DECREF(x);
4638
4639 /* date values */
4640 d = PyDateTime_DateType.tp_dict;
4641
4642 x = new_date(1, 1, 1);
4643 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4644 return;
4645 Py_DECREF(x);
4646
4647 x = new_date(MAXYEAR, 12, 31);
4648 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4649 return;
4650 Py_DECREF(x);
4651
4652 x = new_delta(1, 0, 0, 0);
4653 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4654 return;
4655 Py_DECREF(x);
4656
Tim Peters37f39822003-01-10 03:49:02 +00004657 /* time values */
4658 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004659
Tim Peters37f39822003-01-10 03:49:02 +00004660 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004661 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4662 return;
4663 Py_DECREF(x);
4664
Tim Peters37f39822003-01-10 03:49:02 +00004665 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004666 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4667 return;
4668 Py_DECREF(x);
4669
4670 x = new_delta(0, 0, 1, 0);
4671 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4672 return;
4673 Py_DECREF(x);
4674
Tim Petersa9bc1682003-01-11 03:39:11 +00004675 /* datetime values */
4676 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004677
Tim Petersa9bc1682003-01-11 03:39:11 +00004678 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004679 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4680 return;
4681 Py_DECREF(x);
4682
Tim Petersa9bc1682003-01-11 03:39:11 +00004683 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004684 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4685 return;
4686 Py_DECREF(x);
4687
4688 x = new_delta(0, 0, 1, 0);
4689 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4690 return;
4691 Py_DECREF(x);
4692
4693 Py_DECREF(safepickle);
4694
4695 /* module initialization */
4696 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4697 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4698
4699 Py_INCREF(&PyDateTime_DateType);
4700 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4701
Tim Petersa9bc1682003-01-11 03:39:11 +00004702 Py_INCREF(&PyDateTime_DateTimeType);
4703 PyModule_AddObject(m, "datetime",
4704 (PyObject *)&PyDateTime_DateTimeType);
4705
4706 Py_INCREF(&PyDateTime_TimeType);
4707 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4708
Tim Peters2a799bf2002-12-16 20:18:38 +00004709 Py_INCREF(&PyDateTime_DeltaType);
4710 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4711
Tim Peters2a799bf2002-12-16 20:18:38 +00004712 Py_INCREF(&PyDateTime_TZInfoType);
4713 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4714
Tim Peters2a799bf2002-12-16 20:18:38 +00004715 /* A 4-year cycle has an extra leap day over what we'd get from
4716 * pasting together 4 single years.
4717 */
4718 assert(DI4Y == 4 * 365 + 1);
4719 assert(DI4Y == days_before_year(4+1));
4720
4721 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4722 * get from pasting together 4 100-year cycles.
4723 */
4724 assert(DI400Y == 4 * DI100Y + 1);
4725 assert(DI400Y == days_before_year(400+1));
4726
4727 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4728 * pasting together 25 4-year cycles.
4729 */
4730 assert(DI100Y == 25 * DI4Y - 1);
4731 assert(DI100Y == days_before_year(100+1));
4732
4733 us_per_us = PyInt_FromLong(1);
4734 us_per_ms = PyInt_FromLong(1000);
4735 us_per_second = PyInt_FromLong(1000000);
4736 us_per_minute = PyInt_FromLong(60000000);
4737 seconds_per_day = PyInt_FromLong(24 * 3600);
4738 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4739 us_per_minute == NULL || seconds_per_day == NULL)
4740 return;
4741
4742 /* The rest are too big for 32-bit ints, but even
4743 * us_per_week fits in 40 bits, so doubles should be exact.
4744 */
4745 us_per_hour = PyLong_FromDouble(3600000000.0);
4746 us_per_day = PyLong_FromDouble(86400000000.0);
4747 us_per_week = PyLong_FromDouble(604800000000.0);
4748 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4749 return;
4750}
Tim Petersf3615152003-01-01 21:51:37 +00004751
4752/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004753Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004754 x.n = x stripped of its timezone -- its naive time.
4755 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4756 return None
4757 x.d = x.dst(), and assuming that doesn't raise an exception or
4758 return None
4759 x.s = x's standard offset, x.o - x.d
4760
4761Now some derived rules, where k is a duration (timedelta).
4762
47631. x.o = x.s + x.d
4764 This follows from the definition of x.s.
4765
Tim Petersc5dc4da2003-01-02 17:55:03 +000047662. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004767 This is actually a requirement, an assumption we need to make about
4768 sane tzinfo classes.
4769
47703. The naive UTC time corresponding to x is x.n - x.o.
4771 This is again a requirement for a sane tzinfo class.
4772
47734. (x+k).s = x.s
Tim Petersa9bc1682003-01-11 03:39:11 +00004774 This follows from #2, and that datimetime+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004775
Tim Petersc5dc4da2003-01-02 17:55:03 +000047765. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004777 Again follows from how arithmetic is defined.
4778
4779Now we can explain x.astimezone(tz). Let's assume it's an interesting case
4780(meaning that the various tzinfo methods exist, and don't blow up or return
4781None when called).
4782
Tim Petersa9bc1682003-01-11 03:39:11 +00004783The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Petersf3615152003-01-01 21:51:37 +00004784
4785By #3, we want
4786
4787 y.n - y.o = x.n - x.o [1]
4788
4789The algorithm starts by attaching tz to x.n, and calling that y. So
4790x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4791becomes true; in effect, we want to solve [2] for k:
4792
4793 (y+k).n - (y+k).o = x.n - x.o [2]
4794
4795By #1, this is the same as
4796
4797 (y+k).n - ((y+k).s + (y+k).d) = x.n - x.o [3]
4798
4799By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4800Substituting that into [3],
4801
4802 x.n + k - (y+k).s - (y+k).d = x.n - x.o; the x.n terms cancel, leaving
4803 k - (y+k).s - (y+k).d = - x.o; rearranging,
4804 k = (y+k).s - x.o - (y+k).d; by #4, (y+k).s == y.s, so
4805 k = y.s - x.o - (y+k).d; then by #1, y.s = y.o - y.d, so
4806 k = y.o - y.d - x.o - (y+k).d
4807
4808On the RHS, (y+k).d can't be computed directly, but all the rest can be, and
4809we approximate k by ignoring the (y+k).d term at first. Note that k can't
4810be very large, since all offset-returning methods return a duration of
4811magnitude less than 24 hours. For that reason, if y is firmly in std time,
4812(y+k).d must be 0, so ignoring it has no consequence then.
4813
4814In any case, the new value is
4815
Tim Petersc5dc4da2003-01-02 17:55:03 +00004816 z = y + y.o - y.d - x.o [4]
Tim Petersf3615152003-01-01 21:51:37 +00004817
Tim Petersc5dc4da2003-01-02 17:55:03 +00004818It's helpful to step back at look at [4] from a higher level: rewrite it as
Tim Petersf3615152003-01-01 21:51:37 +00004819
Tim Petersc5dc4da2003-01-02 17:55:03 +00004820 z = (y - x.o) + (y.o - y.d)
4821
4822(y - x.o).n = [by #5] y.n - x.o = [since y.n=x.n] x.n - x.o = [by #3] x's
4823UTC equivalent time. So the y-x.o part essentially converts x to UTC. Then
4824the y.o-y.d part essentially converts x's UTC equivalent into tz's standard
4825time (y.o-y.d=y.s by #1).
4826
4827At this point, if
4828
4829 z.n - z.o = x.n - x.o [5]
4830
4831we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004832at the start of daylight time. Picture US Eastern for concreteness. The wall
4833time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
4834sense then. A sensible Eastern tzinfo class will consider such a time to be
4835EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST on the
4836day DST starts. We want to return the 1:MM EST spelling because that's
4837the only spelling that makes sense on the local wall clock.
4838
Tim Petersc5dc4da2003-01-02 17:55:03 +00004839In fact, if [5] holds at this point, we do have the standard-time spelling,
4840but that takes a bit of proof. We first prove a stronger result. What's the
4841difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004842
Tim Petersc5dc4da2003-01-02 17:55:03 +00004843 diff = (x.n - x.o) - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004844
Tim Petersc5dc4da2003-01-02 17:55:03 +00004845Now
4846 z.n = by [4]
4847 (y + y.o - y.d - x.o).n = by #5
4848 y.n + y.o - y.d - x.o = since y.n = x.n
4849 x.n + y.o - y.d - x.o = since y.o = y.s + y.d by #1
4850 x.n + (y.s + y.d) - y.d - x.o = cancelling the y.d terms
4851 x.n + y.s - x.o = since z and y are have the same tzinfo member,
4852 y.s = z.s by #2
4853 x.n + z.s - x.o
Tim Petersf3615152003-01-01 21:51:37 +00004854
Tim Petersc5dc4da2003-01-02 17:55:03 +00004855Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004856
Tim Petersc5dc4da2003-01-02 17:55:03 +00004857 diff =
4858 (x.n - x.o) - ((x.n + z.s - x.o) - z.o) = expanding
4859 x.n - x.o - x.n - z.s + x.o + z.o = cancelling
4860 - z.s + z.o = by #2
4861 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004862
Tim Petersc5dc4da2003-01-02 17:55:03 +00004863So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004864
Tim Petersc5dc4da2003-01-02 17:55:03 +00004865If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
4866spelling we wanted in the endcase described above. We're done.
Tim Petersf3615152003-01-01 21:51:37 +00004867
Tim Petersc5dc4da2003-01-02 17:55:03 +00004868If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4869add to z (in effect, z is in tz's standard time, and we need to shift the
4870offset into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004871
Tim Petersc5dc4da2003-01-02 17:55:03 +00004872Let
Tim Petersf3615152003-01-01 21:51:37 +00004873
Tim Peters4fede1a2003-01-04 00:26:59 +00004874 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004875
Tim Peters4fede1a2003-01-04 00:26:59 +00004876and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004877
Tim Peters4fede1a2003-01-04 00:26:59 +00004878 z'.n - z'.o = x.n - x.o [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004879
4880If so, we're done. If not, the tzinfo class is insane, or we're trying to
Tim Peters4fede1a2003-01-04 00:26:59 +00004881convert to the hour that can't be spelled in tz. This also requires a
4882bit of proof. As before, let's compute the difference between the LHS and
4883RHS of [8] (and skipping some of the justifications for the kinds of
4884substitutions we've done several times already):
4885
4886 diff' = (x.n - x.o) - (z'.n - z'.o) = replacing z'.n via [7]
4887 (x.n - x.o) - (z.n + diff - z'.o) = replacing diff via [6]
4888 (x.n - x.o) - (z.n + (x.n - x.o) - (z.n - z.o) - z'.o) =
4889 x.n - x.o - z.n - x.n + x.o + z.n - z.o + z'.o = cancel x.n
4890 - x.o - z.n + x.o + z.n - z.o + z'.o = cancel x.o
4891 - z.n + z.n - z.o + z'.o = cancel z.n
4892 - z.o + z'.o = #1 twice
4893 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4894 z'.d - z.d
4895
4896So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
4897we've found the UTC-equivalent so are done.
4898
4899How could they differ? z' = z + z.d [7], so merely moving z' by a dst()
4900offset, and starting *from* a time already in DST (we know z.d != 0), would
4901have to change the result dst() returns: we start in DST, and moving a
4902little further into it takes us out of DST.
4903
4904There's (only) one sane case where this can happen: at the end of DST,
4905there's an hour in UTC with no spelling in a hybrid tzinfo class. In US
4906Eastern, that's 6:MM UTC = 1:MM EST = 2:MM EDT. During that hour, on an
4907Eastern clock 1:MM is taken as being in daylight time (5:MM UTC), but 2:MM is
4908taken as being in standard time (7:MM UTC). There is no local time mapping to
49096:MM UTC. The local clock jumps from 1:59 back to 1:00 again, and repeats the
49101:MM hour in standard time. Since that's what the local clock *does*, we want
4911to map both UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
4912in local time, but so it goes -- it's the way the local clock works.
4913
4914When x = 6:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4915so z=1:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4916z' = z + z.d = 2:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
4917(correctly) concludes that z' is not UTC-equivalent to x.
4918
4919Because we know z.d said z was in daylight time (else [5] would have held and
4920we would have stopped then), and we know z.d != z'.d (else [8] would have held
4921and we we have stopped then), and there are only 2 possible values dst() can
4922return in Eastern, it follows that z'.d must be 0 (which it is in the example,
4923but the reasoning doesn't depend on the example -- it depends on there being
4924two possible dst() outcomes, one zero and the other non-zero). Therefore
4925z' must be in standard time, and is not the spelling we want in this case.
4926z is in daylight time, and is the spelling we want. Note again that z is
4927not UTC-equivalent as far as the hybrid tzinfo class is concerned (because
4928it takes z as being in standard time rather than the daylight time we intend
4929here), but returning it gives the real-life "local clock repeats an hour"
4930behavior when mapping the "unspellable" UTC hour into tz.
Tim Petersf3615152003-01-01 21:51:37 +00004931--------------------------------------------------------------------------- */