blob: d81d5636f7d67f24aec604245334bc477e8f6140 [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
Tim Peters52dcce22003-01-23 16:36:11 +00002728static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002729tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2730{
2731 return tzinfo_nogo("tzname");
2732}
2733
Tim Peters52dcce22003-01-23 16:36:11 +00002734static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002735tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2736{
2737 return tzinfo_nogo("utcoffset");
2738}
2739
Tim Peters52dcce22003-01-23 16:36:11 +00002740static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002741tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2742{
2743 return tzinfo_nogo("dst");
2744}
2745
Tim Peters52dcce22003-01-23 16:36:11 +00002746static PyObject *
2747tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2748{
2749 int y, m, d, hh, mm, ss, us;
2750
2751 PyObject *result;
2752 int off, dst;
2753 int none;
2754 int delta;
2755
2756 if (! PyDateTime_Check(dt)) {
2757 PyErr_SetString(PyExc_TypeError,
2758 "fromutc: argument must be a datetime");
2759 return NULL;
2760 }
2761 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2762 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2763 "is not self");
2764 return NULL;
2765 }
2766
2767 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2768 if (off == -1 && PyErr_Occurred())
2769 return NULL;
2770 if (none) {
2771 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2772 "utcoffset() result required");
2773 return NULL;
2774 }
2775
2776 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2777 if (dst == -1 && PyErr_Occurred())
2778 return NULL;
2779 if (none) {
2780 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2781 "dst() result required");
2782 return NULL;
2783 }
2784
2785 y = GET_YEAR(dt);
2786 m = GET_MONTH(dt);
2787 d = GET_DAY(dt);
2788 hh = DATE_GET_HOUR(dt);
2789 mm = DATE_GET_MINUTE(dt);
2790 ss = DATE_GET_SECOND(dt);
2791 us = DATE_GET_MICROSECOND(dt);
2792
2793 delta = off - dst;
2794 mm += delta;
2795 if ((mm < 0 || mm >= 60) &&
2796 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002797 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002798 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2799 if (result == NULL)
2800 return result;
2801
2802 dst = call_dst(dt->tzinfo, result, &none);
2803 if (dst == -1 && PyErr_Occurred())
2804 goto Fail;
2805 if (none)
2806 goto Inconsistent;
2807 if (dst == 0)
2808 return result;
2809
2810 mm += dst;
2811 if ((mm < 0 || mm >= 60) &&
2812 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2813 goto Fail;
2814 Py_DECREF(result);
2815 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2816 return result;
2817
2818Inconsistent:
2819 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2820 "inconsistent results; cannot convert");
2821
2822 /* fall thru to failure */
2823Fail:
2824 Py_DECREF(result);
2825 return NULL;
2826}
2827
Tim Peters2a799bf2002-12-16 20:18:38 +00002828/*
2829 * Pickle support. This is solely so that tzinfo subclasses can use
2830 * pickling -- tzinfo itself is supposed to be uninstantiable. The
2831 * pickler and unpickler functions are given module-level private
2832 * names, and registered with copy_reg, by the module init function.
2833 */
2834
2835static PyObject*
2836tzinfo_pickler(PyDateTime_TZInfo *self) {
2837 return Py_BuildValue("O()", tzinfo_unpickler_object);
2838}
2839
2840static PyObject*
2841tzinfo_unpickler(PyObject * unused) {
2842 return PyType_GenericNew(&PyDateTime_TZInfoType, NULL, NULL);
2843}
2844
2845
2846static PyMethodDef tzinfo_methods[] = {
2847 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2848 PyDoc_STR("datetime -> string name of time zone.")},
2849
2850 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2851 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2852 "west of UTC).")},
2853
2854 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2855 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2856
Tim Peters52dcce22003-01-23 16:36:11 +00002857 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2858 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2859
Tim Peters2a799bf2002-12-16 20:18:38 +00002860 {NULL, NULL}
2861};
2862
2863static char tzinfo_doc[] =
2864PyDoc_STR("Abstract base class for time zone info objects.");
2865
2866 statichere PyTypeObject PyDateTime_TZInfoType = {
2867 PyObject_HEAD_INIT(NULL)
2868 0, /* ob_size */
2869 "datetime.tzinfo", /* tp_name */
2870 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2871 0, /* tp_itemsize */
2872 0, /* tp_dealloc */
2873 0, /* tp_print */
2874 0, /* tp_getattr */
2875 0, /* tp_setattr */
2876 0, /* tp_compare */
2877 0, /* tp_repr */
2878 0, /* tp_as_number */
2879 0, /* tp_as_sequence */
2880 0, /* tp_as_mapping */
2881 0, /* tp_hash */
2882 0, /* tp_call */
2883 0, /* tp_str */
2884 PyObject_GenericGetAttr, /* tp_getattro */
2885 0, /* tp_setattro */
2886 0, /* tp_as_buffer */
2887 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2888 Py_TPFLAGS_BASETYPE, /* tp_flags */
2889 tzinfo_doc, /* tp_doc */
2890 0, /* tp_traverse */
2891 0, /* tp_clear */
2892 0, /* tp_richcompare */
2893 0, /* tp_weaklistoffset */
2894 0, /* tp_iter */
2895 0, /* tp_iternext */
2896 tzinfo_methods, /* tp_methods */
2897 0, /* tp_members */
2898 0, /* tp_getset */
2899 0, /* tp_base */
2900 0, /* tp_dict */
2901 0, /* tp_descr_get */
2902 0, /* tp_descr_set */
2903 0, /* tp_dictoffset */
2904 0, /* tp_init */
2905 0, /* tp_alloc */
2906 PyType_GenericNew, /* tp_new */
2907 0, /* tp_free */
2908};
2909
2910/*
Tim Peters37f39822003-01-10 03:49:02 +00002911 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00002912 */
2913
Tim Peters37f39822003-01-10 03:49:02 +00002914/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00002915 */
2916
2917static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002918time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00002919{
Tim Peters37f39822003-01-10 03:49:02 +00002920 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002921}
2922
Tim Peters37f39822003-01-10 03:49:02 +00002923static PyObject *
2924time_minute(PyDateTime_Time *self, void *unused)
2925{
2926 return PyInt_FromLong(TIME_GET_MINUTE(self));
2927}
2928
2929/* The name time_second conflicted with some platform header file. */
2930static PyObject *
2931py_time_second(PyDateTime_Time *self, void *unused)
2932{
2933 return PyInt_FromLong(TIME_GET_SECOND(self));
2934}
2935
2936static PyObject *
2937time_microsecond(PyDateTime_Time *self, void *unused)
2938{
2939 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
2940}
2941
2942static PyObject *
2943time_tzinfo(PyDateTime_Time *self, void *unused)
2944{
Tim Petersa032d2e2003-01-11 00:15:54 +00002945 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00002946 Py_INCREF(result);
2947 return result;
2948}
2949
2950static PyGetSetDef time_getset[] = {
2951 {"hour", (getter)time_hour},
2952 {"minute", (getter)time_minute},
2953 {"second", (getter)py_time_second},
2954 {"microsecond", (getter)time_microsecond},
2955 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00002956 {NULL}
2957};
2958
2959/*
2960 * Constructors.
2961 */
2962
Tim Peters37f39822003-01-10 03:49:02 +00002963static char *time_kws[] = {"hour", "minute", "second", "microsecond",
2964 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002965
Tim Peters2a799bf2002-12-16 20:18:38 +00002966static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002967time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00002968{
2969 PyObject *self = NULL;
2970 int hour = 0;
2971 int minute = 0;
2972 int second = 0;
2973 int usecond = 0;
2974 PyObject *tzinfo = Py_None;
2975
Tim Peters37f39822003-01-10 03:49:02 +00002976 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002977 &hour, &minute, &second, &usecond,
2978 &tzinfo)) {
2979 if (check_time_args(hour, minute, second, usecond) < 0)
2980 return NULL;
2981 if (check_tzinfo_subclass(tzinfo) < 0)
2982 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00002983 self = new_time(hour, minute, second, usecond, tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00002984 }
2985 return self;
2986}
2987
2988/*
2989 * Destructor.
2990 */
2991
2992static void
Tim Peters37f39822003-01-10 03:49:02 +00002993time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00002994{
Tim Petersa032d2e2003-01-11 00:15:54 +00002995 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00002996 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00002997 }
Tim Peters2a799bf2002-12-16 20:18:38 +00002998 self->ob_type->tp_free((PyObject *)self);
2999}
3000
3001/*
Tim Peters855fe882002-12-22 03:43:39 +00003002 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003003 */
3004
Tim Peters2a799bf2002-12-16 20:18:38 +00003005/* These are all METH_NOARGS, so don't need to check the arglist. */
3006static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003007time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003008 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003009 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003010}
3011
3012static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003013time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003014 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003015 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003016}
3017
3018static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003019time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003020 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003021 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003022}
3023
3024/*
Tim Peters37f39822003-01-10 03:49:02 +00003025 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003026 */
3027
3028static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003029time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003030{
Tim Peters37f39822003-01-10 03:49:02 +00003031 char buffer[100];
3032 char *typename = self->ob_type->tp_name;
3033 int h = TIME_GET_HOUR(self);
3034 int m = TIME_GET_MINUTE(self);
3035 int s = TIME_GET_SECOND(self);
3036 int us = TIME_GET_MICROSECOND(self);
3037 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003038
Tim Peters37f39822003-01-10 03:49:02 +00003039 if (us)
3040 PyOS_snprintf(buffer, sizeof(buffer),
3041 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3042 else if (s)
3043 PyOS_snprintf(buffer, sizeof(buffer),
3044 "%s(%d, %d, %d)", typename, h, m, s);
3045 else
3046 PyOS_snprintf(buffer, sizeof(buffer),
3047 "%s(%d, %d)", typename, h, m);
3048 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003049 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003050 result = append_keyword_tzinfo(result, self->tzinfo);
3051 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003052}
3053
Tim Peters37f39822003-01-10 03:49:02 +00003054static PyObject *
3055time_str(PyDateTime_Time *self)
3056{
3057 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3058}
Tim Peters2a799bf2002-12-16 20:18:38 +00003059
3060static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003061time_isoformat(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003062{
3063 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003064 PyObject *result;
3065 /* Reuse the time format code from the datetime type. */
3066 PyDateTime_DateTime datetime;
3067 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003068
Tim Peters37f39822003-01-10 03:49:02 +00003069 /* Copy over just the time bytes. */
3070 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3071 self->data,
3072 _PyDateTime_TIME_DATASIZE);
3073
3074 isoformat_time(pdatetime, buf, sizeof(buf));
3075 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003076 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003077 return result;
3078
3079 /* We need to append the UTC offset. */
3080 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003081 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003082 Py_DECREF(result);
3083 return NULL;
3084 }
3085 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3086 return result;
3087}
3088
Tim Peters37f39822003-01-10 03:49:02 +00003089static PyObject *
3090time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3091{
3092 PyObject *result;
3093 PyObject *format;
3094 PyObject *tuple;
3095 static char *keywords[] = {"format", NULL};
3096
3097 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3098 &PyString_Type, &format))
3099 return NULL;
3100
3101 /* Python's strftime does insane things with the year part of the
3102 * timetuple. The year is forced to (the otherwise nonsensical)
3103 * 1900 to worm around that.
3104 */
3105 tuple = Py_BuildValue("iiiiiiiii",
3106 1900, 0, 0, /* year, month, day */
3107 TIME_GET_HOUR(self),
3108 TIME_GET_MINUTE(self),
3109 TIME_GET_SECOND(self),
3110 0, 0, -1); /* weekday, daynum, dst */
3111 if (tuple == NULL)
3112 return NULL;
3113 assert(PyTuple_Size(tuple) == 9);
3114 result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
3115 Py_DECREF(tuple);
3116 return result;
3117}
Tim Peters2a799bf2002-12-16 20:18:38 +00003118
3119/*
3120 * Miscellaneous methods.
3121 */
3122
Tim Peters37f39822003-01-10 03:49:02 +00003123/* This is more natural as a tp_compare, but doesn't work then: for whatever
3124 * reason, Python's try_3way_compare ignores tp_compare unless
3125 * PyInstance_Check returns true, but these aren't old-style classes.
3126 */
3127static PyObject *
3128time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3129{
3130 int diff;
3131 naivety n1, n2;
3132 int offset1, offset2;
3133
3134 if (! PyTime_Check(other)) {
3135 /* Stop this from falling back to address comparison. */
3136 PyErr_Format(PyExc_TypeError,
3137 "can't compare '%s' to '%s'",
3138 self->ob_type->tp_name,
3139 other->ob_type->tp_name);
3140 return NULL;
3141 }
3142 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3143 other, &offset2, &n2, Py_None) < 0)
3144 return NULL;
3145 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3146 /* If they're both naive, or both aware and have the same offsets,
3147 * we get off cheap. Note that if they're both naive, offset1 ==
3148 * offset2 == 0 at this point.
3149 */
3150 if (n1 == n2 && offset1 == offset2) {
3151 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3152 _PyDateTime_TIME_DATASIZE);
3153 return diff_to_bool(diff, op);
3154 }
3155
3156 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3157 assert(offset1 != offset2); /* else last "if" handled it */
3158 /* Convert everything except microseconds to seconds. These
3159 * can't overflow (no more than the # of seconds in 2 days).
3160 */
3161 offset1 = TIME_GET_HOUR(self) * 3600 +
3162 (TIME_GET_MINUTE(self) - offset1) * 60 +
3163 TIME_GET_SECOND(self);
3164 offset2 = TIME_GET_HOUR(other) * 3600 +
3165 (TIME_GET_MINUTE(other) - offset2) * 60 +
3166 TIME_GET_SECOND(other);
3167 diff = offset1 - offset2;
3168 if (diff == 0)
3169 diff = TIME_GET_MICROSECOND(self) -
3170 TIME_GET_MICROSECOND(other);
3171 return diff_to_bool(diff, op);
3172 }
3173
3174 assert(n1 != n2);
3175 PyErr_SetString(PyExc_TypeError,
3176 "can't compare offset-naive and "
3177 "offset-aware times");
3178 return NULL;
3179}
3180
3181static long
3182time_hash(PyDateTime_Time *self)
3183{
3184 if (self->hashcode == -1) {
3185 naivety n;
3186 int offset;
3187 PyObject *temp;
3188
3189 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3190 assert(n != OFFSET_UNKNOWN);
3191 if (n == OFFSET_ERROR)
3192 return -1;
3193
3194 /* Reduce this to a hash of another object. */
3195 if (offset == 0)
3196 temp = PyString_FromStringAndSize((char *)self->data,
3197 _PyDateTime_TIME_DATASIZE);
3198 else {
3199 int hour;
3200 int minute;
3201
3202 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003203 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003204 hour = divmod(TIME_GET_HOUR(self) * 60 +
3205 TIME_GET_MINUTE(self) - offset,
3206 60,
3207 &minute);
3208 if (0 <= hour && hour < 24)
3209 temp = new_time(hour, minute,
3210 TIME_GET_SECOND(self),
3211 TIME_GET_MICROSECOND(self),
3212 Py_None);
3213 else
3214 temp = Py_BuildValue("iiii",
3215 hour, minute,
3216 TIME_GET_SECOND(self),
3217 TIME_GET_MICROSECOND(self));
3218 }
3219 if (temp != NULL) {
3220 self->hashcode = PyObject_Hash(temp);
3221 Py_DECREF(temp);
3222 }
3223 }
3224 return self->hashcode;
3225}
Tim Peters2a799bf2002-12-16 20:18:38 +00003226
Tim Peters12bf3392002-12-24 05:41:27 +00003227static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003228time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003229{
3230 PyObject *clone;
3231 PyObject *tuple;
3232 int hh = TIME_GET_HOUR(self);
3233 int mm = TIME_GET_MINUTE(self);
3234 int ss = TIME_GET_SECOND(self);
3235 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003236 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003237
3238 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003239 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003240 &hh, &mm, &ss, &us, &tzinfo))
3241 return NULL;
3242 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3243 if (tuple == NULL)
3244 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003245 clone = time_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003246 Py_DECREF(tuple);
3247 return clone;
3248}
3249
Tim Peters2a799bf2002-12-16 20:18:38 +00003250static int
Tim Peters37f39822003-01-10 03:49:02 +00003251time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003252{
3253 int offset;
3254 int none;
3255
3256 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3257 /* Since utcoffset is in whole minutes, nothing can
3258 * alter the conclusion that this is nonzero.
3259 */
3260 return 1;
3261 }
3262 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003263 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003264 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003265 if (offset == -1 && PyErr_Occurred())
3266 return -1;
3267 }
3268 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3269}
3270
3271/*
3272 * Pickle support. Quite a maze!
3273 */
3274
Tim Peters33e0f382003-01-10 02:05:14 +00003275/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003276 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3277 * So it's a tuple in any (non-error) case.
3278 */
3279static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003280time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003281{
3282 PyObject *basestate;
3283 PyObject *result = NULL;
3284
Tim Peters33e0f382003-01-10 02:05:14 +00003285 basestate = PyString_FromStringAndSize((char *)self->data,
3286 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003287 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003288 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003289 result = Py_BuildValue("(O)", basestate);
3290 else
3291 result = Py_BuildValue("OO", basestate, self->tzinfo);
3292 Py_DECREF(basestate);
3293 }
3294 return result;
3295}
3296
3297static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003298time_setstate(PyDateTime_Time *self, PyObject *state)
Tim Peters2a799bf2002-12-16 20:18:38 +00003299{
Tim Peters2a799bf2002-12-16 20:18:38 +00003300 PyObject *basestate;
3301 PyObject *tzinfo = Py_None;
3302
3303 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
3304 &PyString_Type, &basestate,
3305 &tzinfo))
3306 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00003307 if (PyString_Size(basestate) != _PyDateTime_TIME_DATASIZE ||
3308 check_tzinfo_subclass(tzinfo) < 0) {
3309 PyErr_SetString(PyExc_TypeError,
3310 "bad argument to time.__setstate__");
Tim Peters2a799bf2002-12-16 20:18:38 +00003311 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00003312 }
Tim Petersa032d2e2003-01-11 00:15:54 +00003313 if (tzinfo != Py_None && ! HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003314 PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't "
3315 "add a non-None tzinfo to a time object that "
3316 "doesn't have one already");
3317 return NULL;
3318 }
Tim Peters33e0f382003-01-10 02:05:14 +00003319 memcpy((char *)self->data,
3320 PyString_AsString(basestate),
3321 _PyDateTime_TIME_DATASIZE);
3322 self->hashcode = -1;
Tim Petersa032d2e2003-01-11 00:15:54 +00003323 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003324 Py_INCREF(tzinfo);
3325 Py_XDECREF(self->tzinfo);
3326 self->tzinfo = tzinfo;
3327 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003328 Py_INCREF(Py_None);
3329 return Py_None;
3330}
3331
3332static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003333time_pickler(PyObject *module, PyDateTime_Time *time)
Tim Peters2a799bf2002-12-16 20:18:38 +00003334{
3335 PyObject *state;
3336 PyObject *result = NULL;
3337
Tim Peters37f39822003-01-10 03:49:02 +00003338 if (! PyTime_CheckExact(time)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003339 PyErr_Format(PyExc_TypeError,
Tim Peters37f39822003-01-10 03:49:02 +00003340 "bad type passed to time pickler: %s",
3341 time->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00003342 return NULL;
3343 }
Tim Peters37f39822003-01-10 03:49:02 +00003344 state = time_getstate(time);
Tim Peters2a799bf2002-12-16 20:18:38 +00003345 if (state) {
3346 result = Py_BuildValue("O(O)",
Tim Peters37f39822003-01-10 03:49:02 +00003347 time_unpickler_object,
Tim Peters2a799bf2002-12-16 20:18:38 +00003348 state);
3349 Py_DECREF(state);
3350 }
3351 return result;
3352}
3353
3354static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003355time_unpickler(PyObject *module, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003356{
Tim Peters37f39822003-01-10 03:49:02 +00003357 PyDateTime_Time *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003358
Tim Peters37f39822003-01-10 03:49:02 +00003359 /* We don't want to allocate space for tzinfo if it's not needed.
3360 * Figuring that out in advance is irritating, so for now we
3361 * realloc later.
3362 */
3363 self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00003364 if (self != NULL) {
3365 PyObject *res;
3366
Tim Peters37f39822003-01-10 03:49:02 +00003367 self->tzinfo = Py_None;
3368 Py_INCREF(self->tzinfo);
3369 self->hastzinfo = (char)1; /* true */
3370 res = time_setstate(self, arg);
Tim Peters2a799bf2002-12-16 20:18:38 +00003371 if (res == NULL) {
3372 Py_DECREF(self);
3373 return NULL;
3374 }
3375 Py_DECREF(res);
Tim Peters37f39822003-01-10 03:49:02 +00003376 if (self->tzinfo == Py_None) {
3377 /* shrinking; can't fail */
3378 Py_DECREF(self->tzinfo);
Tim Petersa9bc1682003-01-11 03:39:11 +00003379 self = (PyDateTime_Time *)PyObject_Realloc(self,
3380 sizeof(_PyDateTime_BaseTime));
3381 assert(self != NULL);
Tim Peters37f39822003-01-10 03:49:02 +00003382 self->hastzinfo = (char)0;
3383 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003384 }
3385 return (PyObject *)self;
3386}
3387
Tim Peters37f39822003-01-10 03:49:02 +00003388static PyMethodDef time_methods[] = {
3389 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003390 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3391 "[+HH:MM].")},
3392
Tim Peters37f39822003-01-10 03:49:02 +00003393 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3394 PyDoc_STR("format -> strftime() style string.")},
3395
3396 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003397 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3398
Tim Peters37f39822003-01-10 03:49:02 +00003399 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003400 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3401
Tim Peters37f39822003-01-10 03:49:02 +00003402 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003403 PyDoc_STR("Return self.tzinfo.dst(self).")},
3404
Tim Peters37f39822003-01-10 03:49:02 +00003405 {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
3406 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003407
Tim Peters37f39822003-01-10 03:49:02 +00003408 {"__setstate__", (PyCFunction)time_setstate, METH_O,
Tim Peters2a799bf2002-12-16 20:18:38 +00003409 PyDoc_STR("__setstate__(state)")},
3410
Tim Peters37f39822003-01-10 03:49:02 +00003411 {"__getstate__", (PyCFunction)time_getstate, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003412 PyDoc_STR("__getstate__() -> state")},
3413 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003414};
3415
Tim Peters37f39822003-01-10 03:49:02 +00003416static char time_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003417PyDoc_STR("Time type.");
3418
Tim Peters37f39822003-01-10 03:49:02 +00003419static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003420 0, /* nb_add */
3421 0, /* nb_subtract */
3422 0, /* nb_multiply */
3423 0, /* nb_divide */
3424 0, /* nb_remainder */
3425 0, /* nb_divmod */
3426 0, /* nb_power */
3427 0, /* nb_negative */
3428 0, /* nb_positive */
3429 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003430 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003431};
3432
Tim Peters37f39822003-01-10 03:49:02 +00003433statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003434 PyObject_HEAD_INIT(NULL)
3435 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003436 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003437 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003438 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003439 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003440 0, /* tp_print */
3441 0, /* tp_getattr */
3442 0, /* tp_setattr */
3443 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003444 (reprfunc)time_repr, /* tp_repr */
3445 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003446 0, /* tp_as_sequence */
3447 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003448 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003449 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003450 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003451 PyObject_GenericGetAttr, /* tp_getattro */
3452 0, /* tp_setattro */
3453 0, /* tp_as_buffer */
3454 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3455 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003456 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003457 0, /* tp_traverse */
3458 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003459 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003460 0, /* tp_weaklistoffset */
3461 0, /* tp_iter */
3462 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003463 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003464 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003465 time_getset, /* tp_getset */
3466 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003467 0, /* tp_dict */
3468 0, /* tp_descr_get */
3469 0, /* tp_descr_set */
3470 0, /* tp_dictoffset */
3471 0, /* tp_init */
3472 0, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003473 time_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00003474 _PyObject_Del, /* tp_free */
3475};
3476
3477/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003478 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003479 */
3480
Tim Petersa9bc1682003-01-11 03:39:11 +00003481/* Accessor properties. Properties for day, month, and year are inherited
3482 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003483 */
3484
3485static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003486datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003487{
Tim Petersa9bc1682003-01-11 03:39:11 +00003488 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003489}
3490
Tim Petersa9bc1682003-01-11 03:39:11 +00003491static PyObject *
3492datetime_minute(PyDateTime_DateTime *self, void *unused)
3493{
3494 return PyInt_FromLong(DATE_GET_MINUTE(self));
3495}
3496
3497static PyObject *
3498datetime_second(PyDateTime_DateTime *self, void *unused)
3499{
3500 return PyInt_FromLong(DATE_GET_SECOND(self));
3501}
3502
3503static PyObject *
3504datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3505{
3506 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3507}
3508
3509static PyObject *
3510datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3511{
3512 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3513 Py_INCREF(result);
3514 return result;
3515}
3516
3517static PyGetSetDef datetime_getset[] = {
3518 {"hour", (getter)datetime_hour},
3519 {"minute", (getter)datetime_minute},
3520 {"second", (getter)datetime_second},
3521 {"microsecond", (getter)datetime_microsecond},
3522 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003523 {NULL}
3524};
3525
3526/*
3527 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003528 */
3529
Tim Petersa9bc1682003-01-11 03:39:11 +00003530static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003531 "year", "month", "day", "hour", "minute", "second",
3532 "microsecond", "tzinfo", NULL
3533};
3534
Tim Peters2a799bf2002-12-16 20:18:38 +00003535static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003536datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003537{
3538 PyObject *self = NULL;
3539 int year;
3540 int month;
3541 int day;
3542 int hour = 0;
3543 int minute = 0;
3544 int second = 0;
3545 int usecond = 0;
3546 PyObject *tzinfo = Py_None;
3547
Tim Petersa9bc1682003-01-11 03:39:11 +00003548 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003549 &year, &month, &day, &hour, &minute,
3550 &second, &usecond, &tzinfo)) {
3551 if (check_date_args(year, month, day) < 0)
3552 return NULL;
3553 if (check_time_args(hour, minute, second, usecond) < 0)
3554 return NULL;
3555 if (check_tzinfo_subclass(tzinfo) < 0)
3556 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003557 self = new_datetime(year, month, day,
3558 hour, minute, second, usecond,
3559 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003560 }
3561 return self;
3562}
3563
Tim Petersa9bc1682003-01-11 03:39:11 +00003564/* TM_FUNC is the shared type of localtime() and gmtime(). */
3565typedef struct tm *(*TM_FUNC)(const time_t *timer);
3566
3567/* Internal helper.
3568 * Build datetime from a time_t and a distinct count of microseconds.
3569 * Pass localtime or gmtime for f, to control the interpretation of timet.
3570 */
3571static PyObject *
3572datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3573 PyObject *tzinfo)
3574{
3575 struct tm *tm;
3576 PyObject *result = NULL;
3577
3578 tm = f(&timet);
3579 if (tm) {
3580 /* The platform localtime/gmtime may insert leap seconds,
3581 * indicated by tm->tm_sec > 59. We don't care about them,
3582 * except to the extent that passing them on to the datetime
3583 * constructor would raise ValueError for a reason that
3584 * made no sense to the user.
3585 */
3586 if (tm->tm_sec > 59)
3587 tm->tm_sec = 59;
3588 result = PyObject_CallFunction(cls, "iiiiiiiO",
3589 tm->tm_year + 1900,
3590 tm->tm_mon + 1,
3591 tm->tm_mday,
3592 tm->tm_hour,
3593 tm->tm_min,
3594 tm->tm_sec,
3595 us,
3596 tzinfo);
3597 }
3598 else
3599 PyErr_SetString(PyExc_ValueError,
3600 "timestamp out of range for "
3601 "platform localtime()/gmtime() function");
3602 return result;
3603}
3604
3605/* Internal helper.
3606 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3607 * to control the interpretation of the timestamp. Since a double doesn't
3608 * have enough bits to cover a datetime's full range of precision, it's
3609 * better to call datetime_from_timet_and_us provided you have a way
3610 * to get that much precision (e.g., C time() isn't good enough).
3611 */
3612static PyObject *
3613datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3614 PyObject *tzinfo)
3615{
3616 time_t timet = (time_t)timestamp;
3617 double fraction = timestamp - (double)timet;
3618 int us = (int)round_to_long(fraction * 1e6);
3619
3620 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3621}
3622
3623/* Internal helper.
3624 * Build most accurate possible datetime for current time. Pass localtime or
3625 * gmtime for f as appropriate.
3626 */
3627static PyObject *
3628datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3629{
3630#ifdef HAVE_GETTIMEOFDAY
3631 struct timeval t;
3632
3633#ifdef GETTIMEOFDAY_NO_TZ
3634 gettimeofday(&t);
3635#else
3636 gettimeofday(&t, (struct timezone *)NULL);
3637#endif
3638 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3639 tzinfo);
3640
3641#else /* ! HAVE_GETTIMEOFDAY */
3642 /* No flavor of gettimeofday exists on this platform. Python's
3643 * time.time() does a lot of other platform tricks to get the
3644 * best time it can on the platform, and we're not going to do
3645 * better than that (if we could, the better code would belong
3646 * in time.time()!) We're limited by the precision of a double,
3647 * though.
3648 */
3649 PyObject *time;
3650 double dtime;
3651
3652 time = time_time();
3653 if (time == NULL)
3654 return NULL;
3655 dtime = PyFloat_AsDouble(time);
3656 Py_DECREF(time);
3657 if (dtime == -1.0 && PyErr_Occurred())
3658 return NULL;
3659 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3660#endif /* ! HAVE_GETTIMEOFDAY */
3661}
3662
Tim Peters2a799bf2002-12-16 20:18:38 +00003663/* Return best possible local time -- this isn't constrained by the
3664 * precision of a timestamp.
3665 */
3666static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003667datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003668{
Tim Peters10cadce2003-01-23 19:58:02 +00003669 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003670 PyObject *tzinfo = Py_None;
Tim Peters10cadce2003-01-23 19:58:02 +00003671 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003672
Tim Peters10cadce2003-01-23 19:58:02 +00003673 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3674 &tzinfo))
3675 return NULL;
3676 if (check_tzinfo_subclass(tzinfo) < 0)
3677 return NULL;
3678
3679 self = datetime_best_possible(cls,
3680 tzinfo == Py_None ? localtime : gmtime,
3681 tzinfo);
3682 if (self != NULL && tzinfo != Py_None) {
3683 /* Convert UTC to tzinfo's zone. */
3684 PyObject *temp = self;
3685 self = PyObject_CallMethod(tzinfo, "fromutc",
3686 "O", self);
3687 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003688 }
3689 return self;
3690}
3691
Tim Petersa9bc1682003-01-11 03:39:11 +00003692/* Return best possible UTC time -- this isn't constrained by the
3693 * precision of a timestamp.
3694 */
3695static PyObject *
3696datetime_utcnow(PyObject *cls, PyObject *dummy)
3697{
3698 return datetime_best_possible(cls, gmtime, Py_None);
3699}
3700
Tim Peters2a799bf2002-12-16 20:18:38 +00003701/* Return new local datetime from timestamp (Python timestamp -- a double). */
3702static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003703datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003704{
3705 PyObject *self = NULL;
3706 double timestamp;
3707 PyObject *tzinfo = Py_None;
3708 static char *keywords[] = {"timestamp", "tzinfo", NULL};
3709
3710 if (PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3711 keywords, &timestamp, &tzinfo)) {
3712 if (check_tzinfo_subclass(tzinfo) < 0)
3713 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00003714 self = datetime_from_timestamp(cls, localtime, timestamp,
3715 tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003716 }
3717 return self;
3718}
3719
Tim Petersa9bc1682003-01-11 03:39:11 +00003720/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3721static PyObject *
3722datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3723{
3724 double timestamp;
3725 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003726
Tim Petersa9bc1682003-01-11 03:39:11 +00003727 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3728 result = datetime_from_timestamp(cls, gmtime, timestamp,
3729 Py_None);
3730 return result;
3731}
3732
3733/* Return new datetime from date/datetime and time arguments. */
3734static PyObject *
3735datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3736{
3737 static char *keywords[] = {"date", "time", NULL};
3738 PyObject *date;
3739 PyObject *time;
3740 PyObject *result = NULL;
3741
3742 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3743 &PyDateTime_DateType, &date,
3744 &PyDateTime_TimeType, &time)) {
3745 PyObject *tzinfo = Py_None;
3746
3747 if (HASTZINFO(time))
3748 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3749 result = PyObject_CallFunction(cls, "iiiiiiiO",
3750 GET_YEAR(date),
3751 GET_MONTH(date),
3752 GET_DAY(date),
3753 TIME_GET_HOUR(time),
3754 TIME_GET_MINUTE(time),
3755 TIME_GET_SECOND(time),
3756 TIME_GET_MICROSECOND(time),
3757 tzinfo);
3758 }
3759 return result;
3760}
Tim Peters2a799bf2002-12-16 20:18:38 +00003761
3762/*
3763 * Destructor.
3764 */
3765
3766static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003767datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003768{
Tim Petersa9bc1682003-01-11 03:39:11 +00003769 if (HASTZINFO(self)) {
3770 Py_XDECREF(self->tzinfo);
3771 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003772 self->ob_type->tp_free((PyObject *)self);
3773}
3774
3775/*
3776 * Indirect access to tzinfo methods.
3777 */
3778
Tim Peters2a799bf2002-12-16 20:18:38 +00003779/* These are all METH_NOARGS, so don't need to check the arglist. */
3780static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003781datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3782 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3783 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003784}
3785
3786static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003787datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3788 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3789 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003790}
3791
3792static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003793datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3794 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3795 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003796}
3797
3798/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003799 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003800 */
3801
Tim Petersa9bc1682003-01-11 03:39:11 +00003802/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3803 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003804 */
3805static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003806add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3807 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003808{
Tim Petersa9bc1682003-01-11 03:39:11 +00003809 /* Note that the C-level additions can't overflow, because of
3810 * invariant bounds on the member values.
3811 */
3812 int year = GET_YEAR(date);
3813 int month = GET_MONTH(date);
3814 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3815 int hour = DATE_GET_HOUR(date);
3816 int minute = DATE_GET_MINUTE(date);
3817 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3818 int microsecond = DATE_GET_MICROSECOND(date) +
3819 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003820
Tim Petersa9bc1682003-01-11 03:39:11 +00003821 assert(factor == 1 || factor == -1);
3822 if (normalize_datetime(&year, &month, &day,
3823 &hour, &minute, &second, &microsecond) < 0)
3824 return NULL;
3825 else
3826 return new_datetime(year, month, day,
3827 hour, minute, second, microsecond,
3828 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003829}
3830
3831static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003832datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003833{
Tim Petersa9bc1682003-01-11 03:39:11 +00003834 if (PyDateTime_Check(left)) {
3835 /* datetime + ??? */
3836 if (PyDelta_Check(right))
3837 /* datetime + delta */
3838 return add_datetime_timedelta(
3839 (PyDateTime_DateTime *)left,
3840 (PyDateTime_Delta *)right,
3841 1);
3842 }
3843 else if (PyDelta_Check(left)) {
3844 /* delta + datetime */
3845 return add_datetime_timedelta((PyDateTime_DateTime *) right,
3846 (PyDateTime_Delta *) left,
3847 1);
3848 }
3849 Py_INCREF(Py_NotImplemented);
3850 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00003851}
3852
3853static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003854datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003855{
3856 PyObject *result = Py_NotImplemented;
3857
3858 if (PyDateTime_Check(left)) {
3859 /* datetime - ??? */
3860 if (PyDateTime_Check(right)) {
3861 /* datetime - datetime */
3862 naivety n1, n2;
3863 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00003864 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00003865
Tim Peterse39a80c2002-12-30 21:28:52 +00003866 if (classify_two_utcoffsets(left, &offset1, &n1, left,
3867 right, &offset2, &n2,
3868 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00003869 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00003870 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00003871 if (n1 != n2) {
3872 PyErr_SetString(PyExc_TypeError,
3873 "can't subtract offset-naive and "
3874 "offset-aware datetimes");
3875 return NULL;
3876 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003877 delta_d = ymd_to_ord(GET_YEAR(left),
3878 GET_MONTH(left),
3879 GET_DAY(left)) -
3880 ymd_to_ord(GET_YEAR(right),
3881 GET_MONTH(right),
3882 GET_DAY(right));
3883 /* These can't overflow, since the values are
3884 * normalized. At most this gives the number of
3885 * seconds in one day.
3886 */
3887 delta_s = (DATE_GET_HOUR(left) -
3888 DATE_GET_HOUR(right)) * 3600 +
3889 (DATE_GET_MINUTE(left) -
3890 DATE_GET_MINUTE(right)) * 60 +
3891 (DATE_GET_SECOND(left) -
3892 DATE_GET_SECOND(right));
3893 delta_us = DATE_GET_MICROSECOND(left) -
3894 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00003895 /* (left - offset1) - (right - offset2) =
3896 * (left - right) + (offset2 - offset1)
3897 */
Tim Petersa9bc1682003-01-11 03:39:11 +00003898 delta_s += (offset2 - offset1) * 60;
3899 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003900 }
3901 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00003902 /* datetime - delta */
3903 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00003904 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00003905 (PyDateTime_Delta *)right,
3906 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003907 }
3908 }
3909
3910 if (result == Py_NotImplemented)
3911 Py_INCREF(result);
3912 return result;
3913}
3914
3915/* Various ways to turn a datetime into a string. */
3916
3917static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003918datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003919{
Tim Petersa9bc1682003-01-11 03:39:11 +00003920 char buffer[1000];
3921 char *typename = self->ob_type->tp_name;
3922 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003923
Tim Petersa9bc1682003-01-11 03:39:11 +00003924 if (DATE_GET_MICROSECOND(self)) {
3925 PyOS_snprintf(buffer, sizeof(buffer),
3926 "%s(%d, %d, %d, %d, %d, %d, %d)",
3927 typename,
3928 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3929 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3930 DATE_GET_SECOND(self),
3931 DATE_GET_MICROSECOND(self));
3932 }
3933 else if (DATE_GET_SECOND(self)) {
3934 PyOS_snprintf(buffer, sizeof(buffer),
3935 "%s(%d, %d, %d, %d, %d, %d)",
3936 typename,
3937 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3938 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3939 DATE_GET_SECOND(self));
3940 }
3941 else {
3942 PyOS_snprintf(buffer, sizeof(buffer),
3943 "%s(%d, %d, %d, %d, %d)",
3944 typename,
3945 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3946 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
3947 }
3948 baserepr = PyString_FromString(buffer);
3949 if (baserepr == NULL || ! HASTZINFO(self))
3950 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003951 return append_keyword_tzinfo(baserepr, self->tzinfo);
3952}
3953
Tim Petersa9bc1682003-01-11 03:39:11 +00003954static PyObject *
3955datetime_str(PyDateTime_DateTime *self)
3956{
3957 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
3958}
Tim Peters2a799bf2002-12-16 20:18:38 +00003959
3960static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003961datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003962{
Tim Petersa9bc1682003-01-11 03:39:11 +00003963 char sep = 'T';
3964 static char *keywords[] = {"sep", NULL};
3965 char buffer[100];
3966 char *cp;
3967 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003968
Tim Petersa9bc1682003-01-11 03:39:11 +00003969 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
3970 &sep))
3971 return NULL;
3972 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
3973 assert(cp != NULL);
3974 *cp++ = sep;
3975 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
3976 result = PyString_FromString(buffer);
3977 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00003978 return result;
3979
3980 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00003981 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00003982 (PyObject *)self) < 0) {
3983 Py_DECREF(result);
3984 return NULL;
3985 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003986 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00003987 return result;
3988}
3989
Tim Petersa9bc1682003-01-11 03:39:11 +00003990static PyObject *
3991datetime_ctime(PyDateTime_DateTime *self)
3992{
3993 return format_ctime((PyDateTime_Date *)self,
3994 DATE_GET_HOUR(self),
3995 DATE_GET_MINUTE(self),
3996 DATE_GET_SECOND(self));
3997}
3998
Tim Peters2a799bf2002-12-16 20:18:38 +00003999/* Miscellaneous methods. */
4000
Tim Petersa9bc1682003-01-11 03:39:11 +00004001/* This is more natural as a tp_compare, but doesn't work then: for whatever
4002 * reason, Python's try_3way_compare ignores tp_compare unless
4003 * PyInstance_Check returns true, but these aren't old-style classes.
4004 */
4005static PyObject *
4006datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4007{
4008 int diff;
4009 naivety n1, n2;
4010 int offset1, offset2;
4011
4012 if (! PyDateTime_Check(other)) {
4013 /* Stop this from falling back to address comparison. */
4014 PyErr_Format(PyExc_TypeError,
4015 "can't compare '%s' to '%s'",
4016 self->ob_type->tp_name,
4017 other->ob_type->tp_name);
4018 return NULL;
4019 }
4020
4021 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4022 (PyObject *)self,
4023 other, &offset2, &n2,
4024 other) < 0)
4025 return NULL;
4026 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4027 /* If they're both naive, or both aware and have the same offsets,
4028 * we get off cheap. Note that if they're both naive, offset1 ==
4029 * offset2 == 0 at this point.
4030 */
4031 if (n1 == n2 && offset1 == offset2) {
4032 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4033 _PyDateTime_DATETIME_DATASIZE);
4034 return diff_to_bool(diff, op);
4035 }
4036
4037 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4038 PyDateTime_Delta *delta;
4039
4040 assert(offset1 != offset2); /* else last "if" handled it */
4041 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4042 other);
4043 if (delta == NULL)
4044 return NULL;
4045 diff = GET_TD_DAYS(delta);
4046 if (diff == 0)
4047 diff = GET_TD_SECONDS(delta) |
4048 GET_TD_MICROSECONDS(delta);
4049 Py_DECREF(delta);
4050 return diff_to_bool(diff, op);
4051 }
4052
4053 assert(n1 != n2);
4054 PyErr_SetString(PyExc_TypeError,
4055 "can't compare offset-naive and "
4056 "offset-aware datetimes");
4057 return NULL;
4058}
4059
4060static long
4061datetime_hash(PyDateTime_DateTime *self)
4062{
4063 if (self->hashcode == -1) {
4064 naivety n;
4065 int offset;
4066 PyObject *temp;
4067
4068 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4069 &offset);
4070 assert(n != OFFSET_UNKNOWN);
4071 if (n == OFFSET_ERROR)
4072 return -1;
4073
4074 /* Reduce this to a hash of another object. */
4075 if (n == OFFSET_NAIVE)
4076 temp = PyString_FromStringAndSize(
4077 (char *)self->data,
4078 _PyDateTime_DATETIME_DATASIZE);
4079 else {
4080 int days;
4081 int seconds;
4082
4083 assert(n == OFFSET_AWARE);
4084 assert(HASTZINFO(self));
4085 days = ymd_to_ord(GET_YEAR(self),
4086 GET_MONTH(self),
4087 GET_DAY(self));
4088 seconds = DATE_GET_HOUR(self) * 3600 +
4089 (DATE_GET_MINUTE(self) - offset) * 60 +
4090 DATE_GET_SECOND(self);
4091 temp = new_delta(days,
4092 seconds,
4093 DATE_GET_MICROSECOND(self),
4094 1);
4095 }
4096 if (temp != NULL) {
4097 self->hashcode = PyObject_Hash(temp);
4098 Py_DECREF(temp);
4099 }
4100 }
4101 return self->hashcode;
4102}
Tim Peters2a799bf2002-12-16 20:18:38 +00004103
4104static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004105datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004106{
4107 PyObject *clone;
4108 PyObject *tuple;
4109 int y = GET_YEAR(self);
4110 int m = GET_MONTH(self);
4111 int d = GET_DAY(self);
4112 int hh = DATE_GET_HOUR(self);
4113 int mm = DATE_GET_MINUTE(self);
4114 int ss = DATE_GET_SECOND(self);
4115 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004116 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004117
4118 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004119 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004120 &y, &m, &d, &hh, &mm, &ss, &us,
4121 &tzinfo))
4122 return NULL;
4123 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4124 if (tuple == NULL)
4125 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004126 clone = datetime_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004127 Py_DECREF(tuple);
4128 return clone;
4129}
4130
4131static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004132datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004133{
Tim Peters52dcce22003-01-23 16:36:11 +00004134 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004135 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004136 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004137
Tim Peters80475bb2002-12-25 07:40:55 +00004138 PyObject *tzinfo;
4139 static char *keywords[] = {"tz", NULL};
4140
Tim Peters52dcce22003-01-23 16:36:11 +00004141 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4142 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004143 return NULL;
4144
Tim Peters52dcce22003-01-23 16:36:11 +00004145 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4146 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004147
Tim Peters52dcce22003-01-23 16:36:11 +00004148 /* Conversion to self's own time zone is a NOP. */
4149 if (self->tzinfo == tzinfo) {
4150 Py_INCREF(self);
4151 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004152 }
Tim Peters521fc152002-12-31 17:36:56 +00004153
Tim Peters52dcce22003-01-23 16:36:11 +00004154 /* Convert self to UTC. */
4155 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4156 if (offset == -1 && PyErr_Occurred())
4157 return NULL;
4158 if (none)
4159 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004160
Tim Peters52dcce22003-01-23 16:36:11 +00004161 y = GET_YEAR(self);
4162 m = GET_MONTH(self);
4163 d = GET_DAY(self);
4164 hh = DATE_GET_HOUR(self);
4165 mm = DATE_GET_MINUTE(self);
4166 ss = DATE_GET_SECOND(self);
4167 us = DATE_GET_MICROSECOND(self);
4168
4169 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004170 if ((mm < 0 || mm >= 60) &&
4171 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004172 return NULL;
4173
4174 /* Attach new tzinfo and let fromutc() do the rest. */
4175 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4176 if (result != NULL) {
4177 PyObject *temp = result;
4178
4179 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4180 Py_DECREF(temp);
4181 }
Tim Petersadf64202003-01-04 06:03:15 +00004182 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004183
Tim Peters52dcce22003-01-23 16:36:11 +00004184NeedAware:
4185 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4186 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004187 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004188}
4189
4190static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004191datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004192{
4193 int dstflag = -1;
4194
Tim Petersa9bc1682003-01-11 03:39:11 +00004195 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004196 int none;
4197
4198 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4199 if (dstflag == -1 && PyErr_Occurred())
4200 return NULL;
4201
4202 if (none)
4203 dstflag = -1;
4204 else if (dstflag != 0)
4205 dstflag = 1;
4206
4207 }
4208 return build_struct_time(GET_YEAR(self),
4209 GET_MONTH(self),
4210 GET_DAY(self),
4211 DATE_GET_HOUR(self),
4212 DATE_GET_MINUTE(self),
4213 DATE_GET_SECOND(self),
4214 dstflag);
4215}
4216
4217static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004218datetime_getdate(PyDateTime_DateTime *self)
4219{
4220 return new_date(GET_YEAR(self),
4221 GET_MONTH(self),
4222 GET_DAY(self));
4223}
4224
4225static PyObject *
4226datetime_gettime(PyDateTime_DateTime *self)
4227{
4228 return new_time(DATE_GET_HOUR(self),
4229 DATE_GET_MINUTE(self),
4230 DATE_GET_SECOND(self),
4231 DATE_GET_MICROSECOND(self),
4232 Py_None);
4233}
4234
4235static PyObject *
4236datetime_gettimetz(PyDateTime_DateTime *self)
4237{
4238 return new_time(DATE_GET_HOUR(self),
4239 DATE_GET_MINUTE(self),
4240 DATE_GET_SECOND(self),
4241 DATE_GET_MICROSECOND(self),
4242 HASTZINFO(self) ? self->tzinfo : Py_None);
4243}
4244
4245static PyObject *
4246datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004247{
4248 int y = GET_YEAR(self);
4249 int m = GET_MONTH(self);
4250 int d = GET_DAY(self);
4251 int hh = DATE_GET_HOUR(self);
4252 int mm = DATE_GET_MINUTE(self);
4253 int ss = DATE_GET_SECOND(self);
4254 int us = 0; /* microseconds are ignored in a timetuple */
4255 int offset = 0;
4256
Tim Petersa9bc1682003-01-11 03:39:11 +00004257 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004258 int none;
4259
4260 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4261 if (offset == -1 && PyErr_Occurred())
4262 return NULL;
4263 }
4264 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4265 * 0 in a UTC timetuple regardless of what dst() says.
4266 */
4267 if (offset) {
4268 /* Subtract offset minutes & normalize. */
4269 int stat;
4270
4271 mm -= offset;
4272 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4273 if (stat < 0) {
4274 /* At the edges, it's possible we overflowed
4275 * beyond MINYEAR or MAXYEAR.
4276 */
4277 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4278 PyErr_Clear();
4279 else
4280 return NULL;
4281 }
4282 }
4283 return build_struct_time(y, m, d, hh, mm, ss, 0);
4284}
4285
Tim Peters33e0f382003-01-10 02:05:14 +00004286/* Pickle support. Quite a maze! */
4287
Tim Petersa9bc1682003-01-11 03:39:11 +00004288/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004289 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4290 * So it's a tuple in any (non-error) case.
4291 */
4292static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004293datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004294{
4295 PyObject *basestate;
4296 PyObject *result = NULL;
4297
Tim Peters33e0f382003-01-10 02:05:14 +00004298 basestate = PyString_FromStringAndSize((char *)self->data,
4299 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004300 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004301 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00004302 result = Py_BuildValue("(O)", basestate);
4303 else
4304 result = Py_BuildValue("OO", basestate, self->tzinfo);
4305 Py_DECREF(basestate);
4306 }
4307 return result;
4308}
4309
4310static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004311datetime_setstate(PyDateTime_DateTime *self, PyObject *state)
Tim Peters2a799bf2002-12-16 20:18:38 +00004312{
Tim Peters2a799bf2002-12-16 20:18:38 +00004313 PyObject *basestate;
4314 PyObject *tzinfo = Py_None;
4315
4316 if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
4317 &PyString_Type, &basestate,
4318 &tzinfo))
4319 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00004320 if (PyString_Size(basestate) != _PyDateTime_DATETIME_DATASIZE ||
4321 check_tzinfo_subclass(tzinfo) < 0) {
4322 PyErr_SetString(PyExc_TypeError,
4323 "bad argument to datetime.__setstate__");
Tim Peters2a799bf2002-12-16 20:18:38 +00004324 return NULL;
Tim Peters33e0f382003-01-10 02:05:14 +00004325 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004326 if (tzinfo != Py_None && ! HASTZINFO(self)) {
4327 PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ "
4328 "can't add a non-None tzinfo to a datetime "
4329 "object that doesn't have one already");
4330 return NULL;
4331 }
Tim Peters33e0f382003-01-10 02:05:14 +00004332 memcpy((char *)self->data,
4333 PyString_AsString(basestate),
4334 _PyDateTime_DATETIME_DATASIZE);
4335 self->hashcode = -1;
Tim Petersa9bc1682003-01-11 03:39:11 +00004336 if (HASTZINFO(self)) {
4337 Py_INCREF(tzinfo);
4338 Py_XDECREF(self->tzinfo);
4339 self->tzinfo = tzinfo;
4340 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004341 Py_INCREF(Py_None);
4342 return Py_None;
4343}
4344
4345static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004346datetime_pickler(PyObject *module, PyDateTime_DateTime *datetime)
Tim Peters2a799bf2002-12-16 20:18:38 +00004347{
4348 PyObject *state;
4349 PyObject *result = NULL;
4350
Tim Petersa9bc1682003-01-11 03:39:11 +00004351 if (! PyDateTime_CheckExact(datetime)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004352 PyErr_Format(PyExc_TypeError,
Tim Petersa9bc1682003-01-11 03:39:11 +00004353 "bad type passed to datetime pickler: %s",
4354 datetime->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00004355 return NULL;
4356 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004357 state = datetime_getstate(datetime);
Tim Peters2a799bf2002-12-16 20:18:38 +00004358 if (state) {
4359 result = Py_BuildValue("O(O)",
Tim Petersa9bc1682003-01-11 03:39:11 +00004360 datetime_unpickler_object,
Tim Peters2a799bf2002-12-16 20:18:38 +00004361 state);
4362 Py_DECREF(state);
4363 }
4364 return result;
4365}
4366
4367static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004368datetime_unpickler(PyObject *module, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004369{
Tim Petersa9bc1682003-01-11 03:39:11 +00004370 PyDateTime_DateTime *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00004371
Tim Petersa9bc1682003-01-11 03:39:11 +00004372 /* We don't want to allocate space for tzinfo if it's not needed.
4373 * Figuring that out in advance is irritating, so for now we
4374 * realloc later.
4375 */
4376 self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType);
Tim Peters2a799bf2002-12-16 20:18:38 +00004377 if (self != NULL) {
4378 PyObject *res;
4379
Tim Petersa9bc1682003-01-11 03:39:11 +00004380 self->tzinfo = Py_None;
4381 Py_INCREF(self->tzinfo);
4382 self->hastzinfo = (char)1; /* true */
4383 res = datetime_setstate(self, arg);
Tim Peters2a799bf2002-12-16 20:18:38 +00004384 if (res == NULL) {
4385 Py_DECREF(self);
4386 return NULL;
4387 }
4388 Py_DECREF(res);
Tim Petersa9bc1682003-01-11 03:39:11 +00004389 if (self->tzinfo == Py_None) {
4390 /* shrinking; can't fail */
4391 Py_DECREF(self->tzinfo);
4392 self = (PyDateTime_DateTime *)PyObject_Realloc(self,
4393 sizeof(_PyDateTime_BaseDateTime));
4394 assert(self != NULL);
4395 self->hastzinfo = (char)0;
4396 }
Tim Peters2a799bf2002-12-16 20:18:38 +00004397 }
4398 return (PyObject *)self;
4399}
4400
4401
Tim Petersa9bc1682003-01-11 03:39:11 +00004402static PyMethodDef datetime_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004403 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004404
Tim Petersa9bc1682003-01-11 03:39:11 +00004405 {"now", (PyCFunction)datetime_now,
Tim Peters2a799bf2002-12-16 20:18:38 +00004406 METH_KEYWORDS | METH_CLASS,
Tim Petersa9bc1682003-01-11 03:39:11 +00004407 PyDoc_STR("[tzinfo] -> new datetime with local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004408
Tim Petersa9bc1682003-01-11 03:39:11 +00004409 {"utcnow", (PyCFunction)datetime_utcnow,
4410 METH_NOARGS | METH_CLASS,
4411 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4412
4413 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Tim Peters2a799bf2002-12-16 20:18:38 +00004414 METH_KEYWORDS | METH_CLASS,
4415 PyDoc_STR("timestamp[, tzinfo] -> local time from POSIX timestamp.")},
4416
Tim Petersa9bc1682003-01-11 03:39:11 +00004417 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4418 METH_VARARGS | METH_CLASS,
4419 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4420 "(like time.time()).")},
4421
4422 {"combine", (PyCFunction)datetime_combine,
4423 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4424 PyDoc_STR("date, time -> datetime with same date and time fields")},
4425
Tim Peters2a799bf2002-12-16 20:18:38 +00004426 /* Instance methods: */
Tim Petersa9bc1682003-01-11 03:39:11 +00004427 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4428 PyDoc_STR("Return date object with same year, month and day.")},
4429
4430 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4431 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4432
4433 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4434 PyDoc_STR("Return time object with same time and tzinfo.")},
4435
4436 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4437 PyDoc_STR("Return ctime() style string.")},
4438
4439 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004440 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4441
Tim Petersa9bc1682003-01-11 03:39:11 +00004442 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004443 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4444
Tim Petersa9bc1682003-01-11 03:39:11 +00004445 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004446 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4447 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4448 "sep is used to separate the year from the time, and "
4449 "defaults to 'T'.")},
4450
Tim Petersa9bc1682003-01-11 03:39:11 +00004451 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004452 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4453
Tim Petersa9bc1682003-01-11 03:39:11 +00004454 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004455 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4456
Tim Petersa9bc1682003-01-11 03:39:11 +00004457 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004458 PyDoc_STR("Return self.tzinfo.dst(self).")},
4459
Tim Petersa9bc1682003-01-11 03:39:11 +00004460 {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
4461 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004462
Tim Petersa9bc1682003-01-11 03:39:11 +00004463 {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004464 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4465
Tim Petersa9bc1682003-01-11 03:39:11 +00004466 {"__setstate__", (PyCFunction)datetime_setstate, METH_O,
Tim Peters2a799bf2002-12-16 20:18:38 +00004467 PyDoc_STR("__setstate__(state)")},
4468
Tim Petersa9bc1682003-01-11 03:39:11 +00004469 {"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004470 PyDoc_STR("__getstate__() -> state")},
4471 {NULL, NULL}
4472};
4473
Tim Petersa9bc1682003-01-11 03:39:11 +00004474static char datetime_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00004475PyDoc_STR("date/time type.");
4476
Tim Petersa9bc1682003-01-11 03:39:11 +00004477static PyNumberMethods datetime_as_number = {
4478 datetime_add, /* nb_add */
4479 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004480 0, /* nb_multiply */
4481 0, /* nb_divide */
4482 0, /* nb_remainder */
4483 0, /* nb_divmod */
4484 0, /* nb_power */
4485 0, /* nb_negative */
4486 0, /* nb_positive */
4487 0, /* nb_absolute */
4488 0, /* nb_nonzero */
4489};
4490
Tim Petersa9bc1682003-01-11 03:39:11 +00004491statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004492 PyObject_HEAD_INIT(NULL)
4493 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004494 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004495 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004496 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004497 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004498 0, /* tp_print */
4499 0, /* tp_getattr */
4500 0, /* tp_setattr */
4501 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004502 (reprfunc)datetime_repr, /* tp_repr */
4503 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004504 0, /* tp_as_sequence */
4505 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004506 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004507 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004508 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004509 PyObject_GenericGetAttr, /* tp_getattro */
4510 0, /* tp_setattro */
4511 0, /* tp_as_buffer */
4512 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4513 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004514 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004515 0, /* tp_traverse */
4516 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004517 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004518 0, /* tp_weaklistoffset */
4519 0, /* tp_iter */
4520 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004521 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004522 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004523 datetime_getset, /* tp_getset */
4524 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004525 0, /* tp_dict */
4526 0, /* tp_descr_get */
4527 0, /* tp_descr_set */
4528 0, /* tp_dictoffset */
4529 0, /* tp_init */
4530 0, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004531 datetime_new, /* tp_new */
Tim Peters2a799bf2002-12-16 20:18:38 +00004532 _PyObject_Del, /* tp_free */
4533};
4534
4535/* ---------------------------------------------------------------------------
4536 * Module methods and initialization.
4537 */
4538
4539static PyMethodDef module_methods[] = {
4540 /* Private functions for pickling support, registered with the
4541 * copy_reg module by the module init function.
4542 */
4543 {"_date_pickler", (PyCFunction)date_pickler, METH_O, NULL},
4544 {"_date_unpickler", (PyCFunction)date_unpickler, METH_O, NULL},
Tim Petersa9bc1682003-01-11 03:39:11 +00004545 {"_datetime_pickler", (PyCFunction)datetime_pickler, METH_O, NULL},
4546 {"_datetime_unpickler", (PyCFunction)datetime_unpickler,METH_O, NULL},
Tim Peters37f39822003-01-10 03:49:02 +00004547 {"_time_pickler", (PyCFunction)time_pickler, METH_O, NULL},
4548 {"_time_unpickler", (PyCFunction)time_unpickler, METH_O, NULL},
Tim Peters2a799bf2002-12-16 20:18:38 +00004549 {"_tzinfo_pickler", (PyCFunction)tzinfo_pickler, METH_O, NULL},
4550 {"_tzinfo_unpickler", (PyCFunction)tzinfo_unpickler, METH_NOARGS,
4551 NULL},
4552 {NULL, NULL}
4553};
4554
4555PyMODINIT_FUNC
4556initdatetime(void)
4557{
4558 PyObject *m; /* a module object */
4559 PyObject *d; /* its dict */
4560 PyObject *x;
4561
4562 /* Types that use __reduce__ for pickling need to set the following
4563 * magical attr in the type dict, with a true value.
4564 */
4565 PyObject *safepickle = PyString_FromString("__safe_for_unpickling__");
4566 if (safepickle == NULL)
4567 return;
4568
4569 m = Py_InitModule3("datetime", module_methods,
4570 "Fast implementation of the datetime type.");
4571
4572 if (PyType_Ready(&PyDateTime_DateType) < 0)
4573 return;
4574 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4575 return;
4576 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4577 return;
4578 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4579 return;
4580 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4581 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004582
4583 /* Pickling support, via registering functions with copy_reg. */
4584 {
4585 PyObject *pickler;
4586 PyObject *copyreg = PyImport_ImportModule("copy_reg");
4587
4588 if (copyreg == NULL) return;
4589
4590 pickler = PyObject_GetAttrString(m, "_date_pickler");
4591 if (pickler == NULL) return;
4592 date_unpickler_object = PyObject_GetAttrString(m,
4593 "_date_unpickler");
4594 if (date_unpickler_object == NULL) return;
4595 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4596 &PyDateTime_DateType,
4597 pickler,
4598 date_unpickler_object);
4599 if (x == NULL) return;
4600 Py_DECREF(x);
4601 Py_DECREF(pickler);
4602
Tim Peters37f39822003-01-10 03:49:02 +00004603 pickler = PyObject_GetAttrString(m, "_time_pickler");
Tim Peters2a799bf2002-12-16 20:18:38 +00004604 if (pickler == NULL) return;
Tim Peters37f39822003-01-10 03:49:02 +00004605 time_unpickler_object = PyObject_GetAttrString(m,
4606 "_time_unpickler");
4607 if (time_unpickler_object == NULL) return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004608 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
Tim Peters37f39822003-01-10 03:49:02 +00004609 &PyDateTime_TimeType,
Tim Peters2a799bf2002-12-16 20:18:38 +00004610 pickler,
Tim Peters37f39822003-01-10 03:49:02 +00004611 time_unpickler_object);
Tim Peters2a799bf2002-12-16 20:18:38 +00004612 if (x == NULL) return;
4613 Py_DECREF(x);
4614 Py_DECREF(pickler);
4615
4616 pickler = PyObject_GetAttrString(m, "_tzinfo_pickler");
4617 if (pickler == NULL) return;
4618 tzinfo_unpickler_object = PyObject_GetAttrString(m,
4619 "_tzinfo_unpickler");
4620 if (tzinfo_unpickler_object == NULL) return;
4621 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
4622 &PyDateTime_TZInfoType,
4623 pickler,
4624 tzinfo_unpickler_object);
4625 if (x== NULL) return;
4626 Py_DECREF(x);
4627 Py_DECREF(pickler);
4628
Tim Petersa9bc1682003-01-11 03:39:11 +00004629 pickler = PyObject_GetAttrString(m, "_datetime_pickler");
Tim Peters2a799bf2002-12-16 20:18:38 +00004630 if (pickler == NULL) return;
Tim Petersa9bc1682003-01-11 03:39:11 +00004631 datetime_unpickler_object = PyObject_GetAttrString(m,
4632 "_datetime_unpickler");
4633 if (datetime_unpickler_object == NULL) return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004634 x = PyObject_CallMethod(copyreg, "pickle", "OOO",
Tim Petersa9bc1682003-01-11 03:39:11 +00004635 &PyDateTime_DateTimeType,
Tim Peters2a799bf2002-12-16 20:18:38 +00004636 pickler,
Tim Petersa9bc1682003-01-11 03:39:11 +00004637 datetime_unpickler_object);
Tim Peters2a799bf2002-12-16 20:18:38 +00004638 if (x== NULL) return;
4639 Py_DECREF(x);
4640 Py_DECREF(pickler);
4641
4642 Py_DECREF(copyreg);
4643 }
4644
4645 /* timedelta values */
4646 d = PyDateTime_DeltaType.tp_dict;
4647
4648 if (PyDict_SetItem(d, safepickle, Py_True) < 0)
4649 return;
4650
4651 x = new_delta(0, 0, 1, 0);
4652 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4653 return;
4654 Py_DECREF(x);
4655
4656 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4657 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4658 return;
4659 Py_DECREF(x);
4660
4661 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4662 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4663 return;
4664 Py_DECREF(x);
4665
4666 /* date values */
4667 d = PyDateTime_DateType.tp_dict;
4668
4669 x = new_date(1, 1, 1);
4670 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4671 return;
4672 Py_DECREF(x);
4673
4674 x = new_date(MAXYEAR, 12, 31);
4675 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4676 return;
4677 Py_DECREF(x);
4678
4679 x = new_delta(1, 0, 0, 0);
4680 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4681 return;
4682 Py_DECREF(x);
4683
Tim Peters37f39822003-01-10 03:49:02 +00004684 /* time values */
4685 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004686
Tim Peters37f39822003-01-10 03:49:02 +00004687 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004688 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4689 return;
4690 Py_DECREF(x);
4691
Tim Peters37f39822003-01-10 03:49:02 +00004692 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004693 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4694 return;
4695 Py_DECREF(x);
4696
4697 x = new_delta(0, 0, 1, 0);
4698 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4699 return;
4700 Py_DECREF(x);
4701
Tim Petersa9bc1682003-01-11 03:39:11 +00004702 /* datetime values */
4703 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004704
Tim Petersa9bc1682003-01-11 03:39:11 +00004705 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004706 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4707 return;
4708 Py_DECREF(x);
4709
Tim Petersa9bc1682003-01-11 03:39:11 +00004710 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004711 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4712 return;
4713 Py_DECREF(x);
4714
4715 x = new_delta(0, 0, 1, 0);
4716 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4717 return;
4718 Py_DECREF(x);
4719
4720 Py_DECREF(safepickle);
4721
4722 /* module initialization */
4723 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4724 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4725
4726 Py_INCREF(&PyDateTime_DateType);
4727 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4728
Tim Petersa9bc1682003-01-11 03:39:11 +00004729 Py_INCREF(&PyDateTime_DateTimeType);
4730 PyModule_AddObject(m, "datetime",
4731 (PyObject *)&PyDateTime_DateTimeType);
4732
4733 Py_INCREF(&PyDateTime_TimeType);
4734 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4735
Tim Peters2a799bf2002-12-16 20:18:38 +00004736 Py_INCREF(&PyDateTime_DeltaType);
4737 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4738
Tim Peters2a799bf2002-12-16 20:18:38 +00004739 Py_INCREF(&PyDateTime_TZInfoType);
4740 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4741
Tim Peters2a799bf2002-12-16 20:18:38 +00004742 /* A 4-year cycle has an extra leap day over what we'd get from
4743 * pasting together 4 single years.
4744 */
4745 assert(DI4Y == 4 * 365 + 1);
4746 assert(DI4Y == days_before_year(4+1));
4747
4748 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4749 * get from pasting together 4 100-year cycles.
4750 */
4751 assert(DI400Y == 4 * DI100Y + 1);
4752 assert(DI400Y == days_before_year(400+1));
4753
4754 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4755 * pasting together 25 4-year cycles.
4756 */
4757 assert(DI100Y == 25 * DI4Y - 1);
4758 assert(DI100Y == days_before_year(100+1));
4759
4760 us_per_us = PyInt_FromLong(1);
4761 us_per_ms = PyInt_FromLong(1000);
4762 us_per_second = PyInt_FromLong(1000000);
4763 us_per_minute = PyInt_FromLong(60000000);
4764 seconds_per_day = PyInt_FromLong(24 * 3600);
4765 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4766 us_per_minute == NULL || seconds_per_day == NULL)
4767 return;
4768
4769 /* The rest are too big for 32-bit ints, but even
4770 * us_per_week fits in 40 bits, so doubles should be exact.
4771 */
4772 us_per_hour = PyLong_FromDouble(3600000000.0);
4773 us_per_day = PyLong_FromDouble(86400000000.0);
4774 us_per_week = PyLong_FromDouble(604800000000.0);
4775 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4776 return;
4777}
Tim Petersf3615152003-01-01 21:51:37 +00004778
4779/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004780Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004781 x.n = x stripped of its timezone -- its naive time.
4782 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4783 return None
4784 x.d = x.dst(), and assuming that doesn't raise an exception or
4785 return None
4786 x.s = x's standard offset, x.o - x.d
4787
4788Now some derived rules, where k is a duration (timedelta).
4789
47901. x.o = x.s + x.d
4791 This follows from the definition of x.s.
4792
Tim Petersc5dc4da2003-01-02 17:55:03 +000047932. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004794 This is actually a requirement, an assumption we need to make about
4795 sane tzinfo classes.
4796
47973. The naive UTC time corresponding to x is x.n - x.o.
4798 This is again a requirement for a sane tzinfo class.
4799
48004. (x+k).s = x.s
Tim Petersa9bc1682003-01-11 03:39:11 +00004801 This follows from #2, and that datimetime+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004802
Tim Petersc5dc4da2003-01-02 17:55:03 +000048035. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004804 Again follows from how arithmetic is defined.
4805
4806Now we can explain x.astimezone(tz). Let's assume it's an interesting case
4807(meaning that the various tzinfo methods exist, and don't blow up or return
4808None when called).
4809
Tim Petersa9bc1682003-01-11 03:39:11 +00004810The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Petersf3615152003-01-01 21:51:37 +00004811
4812By #3, we want
4813
4814 y.n - y.o = x.n - x.o [1]
4815
4816The algorithm starts by attaching tz to x.n, and calling that y. So
4817x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4818becomes true; in effect, we want to solve [2] for k:
4819
4820 (y+k).n - (y+k).o = x.n - x.o [2]
4821
4822By #1, this is the same as
4823
4824 (y+k).n - ((y+k).s + (y+k).d) = x.n - x.o [3]
4825
4826By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4827Substituting that into [3],
4828
4829 x.n + k - (y+k).s - (y+k).d = x.n - x.o; the x.n terms cancel, leaving
4830 k - (y+k).s - (y+k).d = - x.o; rearranging,
4831 k = (y+k).s - x.o - (y+k).d; by #4, (y+k).s == y.s, so
4832 k = y.s - x.o - (y+k).d; then by #1, y.s = y.o - y.d, so
4833 k = y.o - y.d - x.o - (y+k).d
4834
4835On the RHS, (y+k).d can't be computed directly, but all the rest can be, and
4836we approximate k by ignoring the (y+k).d term at first. Note that k can't
4837be very large, since all offset-returning methods return a duration of
4838magnitude less than 24 hours. For that reason, if y is firmly in std time,
4839(y+k).d must be 0, so ignoring it has no consequence then.
4840
4841In any case, the new value is
4842
Tim Petersc5dc4da2003-01-02 17:55:03 +00004843 z = y + y.o - y.d - x.o [4]
Tim Petersf3615152003-01-01 21:51:37 +00004844
Tim Petersc5dc4da2003-01-02 17:55:03 +00004845It's helpful to step back at look at [4] from a higher level: rewrite it as
Tim Petersf3615152003-01-01 21:51:37 +00004846
Tim Petersc5dc4da2003-01-02 17:55:03 +00004847 z = (y - x.o) + (y.o - y.d)
4848
4849(y - x.o).n = [by #5] y.n - x.o = [since y.n=x.n] x.n - x.o = [by #3] x's
4850UTC equivalent time. So the y-x.o part essentially converts x to UTC. Then
4851the y.o-y.d part essentially converts x's UTC equivalent into tz's standard
4852time (y.o-y.d=y.s by #1).
4853
4854At this point, if
4855
4856 z.n - z.o = x.n - x.o [5]
4857
4858we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004859at the start of daylight time. Picture US Eastern for concreteness. The wall
4860time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
4861sense then. A sensible Eastern tzinfo class will consider such a time to be
4862EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST on the
4863day DST starts. We want to return the 1:MM EST spelling because that's
4864the only spelling that makes sense on the local wall clock.
4865
Tim Petersc5dc4da2003-01-02 17:55:03 +00004866In fact, if [5] holds at this point, we do have the standard-time spelling,
4867but that takes a bit of proof. We first prove a stronger result. What's the
4868difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004869
Tim Petersc5dc4da2003-01-02 17:55:03 +00004870 diff = (x.n - x.o) - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004871
Tim Petersc5dc4da2003-01-02 17:55:03 +00004872Now
4873 z.n = by [4]
4874 (y + y.o - y.d - x.o).n = by #5
4875 y.n + y.o - y.d - x.o = since y.n = x.n
4876 x.n + y.o - y.d - x.o = since y.o = y.s + y.d by #1
4877 x.n + (y.s + y.d) - y.d - x.o = cancelling the y.d terms
4878 x.n + y.s - x.o = since z and y are have the same tzinfo member,
4879 y.s = z.s by #2
4880 x.n + z.s - x.o
Tim Petersf3615152003-01-01 21:51:37 +00004881
Tim Petersc5dc4da2003-01-02 17:55:03 +00004882Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004883
Tim Petersc5dc4da2003-01-02 17:55:03 +00004884 diff =
4885 (x.n - x.o) - ((x.n + z.s - x.o) - z.o) = expanding
4886 x.n - x.o - x.n - z.s + x.o + z.o = cancelling
4887 - z.s + z.o = by #2
4888 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004889
Tim Petersc5dc4da2003-01-02 17:55:03 +00004890So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004891
Tim Petersc5dc4da2003-01-02 17:55:03 +00004892If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
4893spelling we wanted in the endcase described above. We're done.
Tim Petersf3615152003-01-01 21:51:37 +00004894
Tim Petersc5dc4da2003-01-02 17:55:03 +00004895If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4896add to z (in effect, z is in tz's standard time, and we need to shift the
4897offset into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004898
Tim Petersc5dc4da2003-01-02 17:55:03 +00004899Let
Tim Petersf3615152003-01-01 21:51:37 +00004900
Tim Peters4fede1a2003-01-04 00:26:59 +00004901 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004902
Tim Peters4fede1a2003-01-04 00:26:59 +00004903and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004904
Tim Peters4fede1a2003-01-04 00:26:59 +00004905 z'.n - z'.o = x.n - x.o [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004906
4907If so, we're done. If not, the tzinfo class is insane, or we're trying to
Tim Peters4fede1a2003-01-04 00:26:59 +00004908convert to the hour that can't be spelled in tz. This also requires a
4909bit of proof. As before, let's compute the difference between the LHS and
4910RHS of [8] (and skipping some of the justifications for the kinds of
4911substitutions we've done several times already):
4912
4913 diff' = (x.n - x.o) - (z'.n - z'.o) = replacing z'.n via [7]
4914 (x.n - x.o) - (z.n + diff - z'.o) = replacing diff via [6]
4915 (x.n - x.o) - (z.n + (x.n - x.o) - (z.n - z.o) - z'.o) =
4916 x.n - x.o - z.n - x.n + x.o + z.n - z.o + z'.o = cancel x.n
4917 - x.o - z.n + x.o + z.n - z.o + z'.o = cancel x.o
4918 - z.n + z.n - z.o + z'.o = cancel z.n
4919 - z.o + z'.o = #1 twice
4920 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4921 z'.d - z.d
4922
4923So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
4924we've found the UTC-equivalent so are done.
4925
4926How could they differ? z' = z + z.d [7], so merely moving z' by a dst()
4927offset, and starting *from* a time already in DST (we know z.d != 0), would
4928have to change the result dst() returns: we start in DST, and moving a
4929little further into it takes us out of DST.
4930
4931There's (only) one sane case where this can happen: at the end of DST,
4932there's an hour in UTC with no spelling in a hybrid tzinfo class. In US
4933Eastern, that's 6:MM UTC = 1:MM EST = 2:MM EDT. During that hour, on an
4934Eastern clock 1:MM is taken as being in daylight time (5:MM UTC), but 2:MM is
4935taken as being in standard time (7:MM UTC). There is no local time mapping to
49366:MM UTC. The local clock jumps from 1:59 back to 1:00 again, and repeats the
49371:MM hour in standard time. Since that's what the local clock *does*, we want
4938to map both UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
4939in local time, but so it goes -- it's the way the local clock works.
4940
4941When x = 6:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4942so z=1:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4943z' = z + z.d = 2:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
4944(correctly) concludes that z' is not UTC-equivalent to x.
4945
4946Because we know z.d said z was in daylight time (else [5] would have held and
4947we would have stopped then), and we know z.d != z'.d (else [8] would have held
4948and we we have stopped then), and there are only 2 possible values dst() can
4949return in Eastern, it follows that z'.d must be 0 (which it is in the example,
4950but the reasoning doesn't depend on the example -- it depends on there being
4951two possible dst() outcomes, one zero and the other non-zero). Therefore
4952z' must be in standard time, and is not the spelling we want in this case.
4953z is in daylight time, and is the spelling we want. Note again that z is
4954not UTC-equivalent as far as the hybrid tzinfo class is concerned (because
4955it takes z as being in standard time rather than the daylight time we intend
4956here), but returning it gives the real-life "local clock repeats an hour"
4957behavior when mapping the "unspellable" UTC hour into tz.
Tim Petersf3615152003-01-01 21:51:37 +00004958--------------------------------------------------------------------------- */