blob: 225a6b16e2b9268688514186fa3ac2fec06d624e [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 Peters3f606292004-03-21 23:38:41 +000083/* M is a char or int claiming to be a valid month. The macro is equivalent
84 * to the two-sided Python test
85 * 1 <= M <= 12
86 */
87#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
88
Tim Peters2a799bf2002-12-16 20:18:38 +000089/* Forward declarations. */
90static PyTypeObject PyDateTime_DateType;
91static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +000092static PyTypeObject PyDateTime_DeltaType;
93static PyTypeObject PyDateTime_TimeType;
94static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +000095
96/* ---------------------------------------------------------------------------
97 * Math utilities.
98 */
99
100/* k = i+j overflows iff k differs in sign from both inputs,
101 * iff k^i has sign bit set and k^j has sign bit set,
102 * iff (k^i)&(k^j) has sign bit set.
103 */
104#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
105 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
106
107/* Compute Python divmod(x, y), returning the quotient and storing the
108 * remainder into *r. The quotient is the floor of x/y, and that's
109 * the real point of this. C will probably truncate instead (C99
110 * requires truncation; C89 left it implementation-defined).
111 * Simplification: we *require* that y > 0 here. That's appropriate
112 * for all the uses made of it. This simplifies the code and makes
113 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
114 * overflow case).
115 */
116static int
117divmod(int x, int y, int *r)
118{
119 int quo;
120
121 assert(y > 0);
122 quo = x / y;
123 *r = x - quo * y;
124 if (*r < 0) {
125 --quo;
126 *r += y;
127 }
128 assert(0 <= *r && *r < y);
129 return quo;
130}
131
Tim Peters5d644dd2003-01-02 16:32:54 +0000132/* Round a double to the nearest long. |x| must be small enough to fit
133 * in a C long; this is not checked.
134 */
135static long
136round_to_long(double x)
137{
138 if (x >= 0.0)
139 x = floor(x + 0.5);
140 else
141 x = ceil(x - 0.5);
142 return (long)x;
143}
144
Tim Peters2a799bf2002-12-16 20:18:38 +0000145/* ---------------------------------------------------------------------------
146 * General calendrical helper functions
147 */
148
149/* For each month ordinal in 1..12, the number of days in that month,
150 * and the number of days before that month in the same year. These
151 * are correct for non-leap years only.
152 */
153static int _days_in_month[] = {
154 0, /* unused; this vector uses 1-based indexing */
155 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
156};
157
158static int _days_before_month[] = {
159 0, /* unused; this vector uses 1-based indexing */
160 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
161};
162
163/* year -> 1 if leap year, else 0. */
164static int
165is_leap(int year)
166{
167 /* Cast year to unsigned. The result is the same either way, but
168 * C can generate faster code for unsigned mod than for signed
169 * mod (especially for % 4 -- a good compiler should just grab
170 * the last 2 bits when the LHS is unsigned).
171 */
172 const unsigned int ayear = (unsigned int)year;
173 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
174}
175
176/* year, month -> number of days in that month in that year */
177static int
178days_in_month(int year, int month)
179{
180 assert(month >= 1);
181 assert(month <= 12);
182 if (month == 2 && is_leap(year))
183 return 29;
184 else
185 return _days_in_month[month];
186}
187
188/* year, month -> number of days in year preceeding first day of month */
189static int
190days_before_month(int year, int month)
191{
192 int days;
193
194 assert(month >= 1);
195 assert(month <= 12);
196 days = _days_before_month[month];
197 if (month > 2 && is_leap(year))
198 ++days;
199 return days;
200}
201
202/* year -> number of days before January 1st of year. Remember that we
203 * start with year 1, so days_before_year(1) == 0.
204 */
205static int
206days_before_year(int year)
207{
208 int y = year - 1;
209 /* This is incorrect if year <= 0; we really want the floor
210 * here. But so long as MINYEAR is 1, the smallest year this
211 * can see is 0 (this can happen in some normalization endcases),
212 * so we'll just special-case that.
213 */
214 assert (year >= 0);
215 if (y >= 0)
216 return y*365 + y/4 - y/100 + y/400;
217 else {
218 assert(y == -1);
219 return -366;
220 }
221}
222
223/* Number of days in 4, 100, and 400 year cycles. That these have
224 * the correct values is asserted in the module init function.
225 */
226#define DI4Y 1461 /* days_before_year(5); days in 4 years */
227#define DI100Y 36524 /* days_before_year(101); days in 100 years */
228#define DI400Y 146097 /* days_before_year(401); days in 400 years */
229
230/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
231static void
232ord_to_ymd(int ordinal, int *year, int *month, int *day)
233{
234 int n, n1, n4, n100, n400, leapyear, preceding;
235
236 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
237 * leap years repeats exactly every 400 years. The basic strategy is
238 * to find the closest 400-year boundary at or before ordinal, then
239 * work with the offset from that boundary to ordinal. Life is much
240 * clearer if we subtract 1 from ordinal first -- then the values
241 * of ordinal at 400-year boundaries are exactly those divisible
242 * by DI400Y:
243 *
244 * D M Y n n-1
245 * -- --- ---- ---------- ----------------
246 * 31 Dec -400 -DI400Y -DI400Y -1
247 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
248 * ...
249 * 30 Dec 000 -1 -2
250 * 31 Dec 000 0 -1
251 * 1 Jan 001 1 0 400-year boundary
252 * 2 Jan 001 2 1
253 * 3 Jan 001 3 2
254 * ...
255 * 31 Dec 400 DI400Y DI400Y -1
256 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
257 */
258 assert(ordinal >= 1);
259 --ordinal;
260 n400 = ordinal / DI400Y;
261 n = ordinal % DI400Y;
262 *year = n400 * 400 + 1;
263
264 /* Now n is the (non-negative) offset, in days, from January 1 of
265 * year, to the desired date. Now compute how many 100-year cycles
266 * precede n.
267 * Note that it's possible for n100 to equal 4! In that case 4 full
268 * 100-year cycles precede the desired day, which implies the
269 * desired day is December 31 at the end of a 400-year cycle.
270 */
271 n100 = n / DI100Y;
272 n = n % DI100Y;
273
274 /* Now compute how many 4-year cycles precede it. */
275 n4 = n / DI4Y;
276 n = n % DI4Y;
277
278 /* And now how many single years. Again n1 can be 4, and again
279 * meaning that the desired day is December 31 at the end of the
280 * 4-year cycle.
281 */
282 n1 = n / 365;
283 n = n % 365;
284
285 *year += n100 * 100 + n4 * 4 + n1;
286 if (n1 == 4 || n100 == 4) {
287 assert(n == 0);
288 *year -= 1;
289 *month = 12;
290 *day = 31;
291 return;
292 }
293
294 /* Now the year is correct, and n is the offset from January 1. We
295 * find the month via an estimate that's either exact or one too
296 * large.
297 */
298 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
299 assert(leapyear == is_leap(*year));
300 *month = (n + 50) >> 5;
301 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
302 if (preceding > n) {
303 /* estimate is too large */
304 *month -= 1;
305 preceding -= days_in_month(*year, *month);
306 }
307 n -= preceding;
308 assert(0 <= n);
309 assert(n < days_in_month(*year, *month));
310
311 *day = n + 1;
312}
313
314/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
315static int
316ymd_to_ord(int year, int month, int day)
317{
318 return days_before_year(year) + days_before_month(year, month) + day;
319}
320
321/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
322static int
323weekday(int year, int month, int day)
324{
325 return (ymd_to_ord(year, month, day) + 6) % 7;
326}
327
328/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
329 * first calendar week containing a Thursday.
330 */
331static int
332iso_week1_monday(int year)
333{
334 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
335 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
336 int first_weekday = (first_day + 6) % 7;
337 /* ordinal of closest Monday at or before 1/1 */
338 int week1_monday = first_day - first_weekday;
339
340 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
341 week1_monday += 7;
342 return week1_monday;
343}
344
345/* ---------------------------------------------------------------------------
346 * Range checkers.
347 */
348
349/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
350 * If not, raise OverflowError and return -1.
351 */
352static int
353check_delta_day_range(int days)
354{
355 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
356 return 0;
357 PyErr_Format(PyExc_OverflowError,
358 "days=%d; must have magnitude <= %d",
Guido van Rossumbd43e912002-12-16 20:34:55 +0000359 days, MAX_DELTA_DAYS);
Tim Peters2a799bf2002-12-16 20:18:38 +0000360 return -1;
361}
362
363/* Check that date arguments are in range. Return 0 if they are. If they
364 * aren't, raise ValueError and return -1.
365 */
366static int
367check_date_args(int year, int month, int day)
368{
369
370 if (year < MINYEAR || year > MAXYEAR) {
371 PyErr_SetString(PyExc_ValueError,
372 "year is out of range");
373 return -1;
374 }
375 if (month < 1 || month > 12) {
376 PyErr_SetString(PyExc_ValueError,
377 "month must be in 1..12");
378 return -1;
379 }
380 if (day < 1 || day > days_in_month(year, month)) {
381 PyErr_SetString(PyExc_ValueError,
382 "day is out of range for month");
383 return -1;
384 }
385 return 0;
386}
387
388/* Check that time arguments are in range. Return 0 if they are. If they
389 * aren't, raise ValueError and return -1.
390 */
391static int
392check_time_args(int h, int m, int s, int us)
393{
394 if (h < 0 || h > 23) {
395 PyErr_SetString(PyExc_ValueError,
396 "hour must be in 0..23");
397 return -1;
398 }
399 if (m < 0 || m > 59) {
400 PyErr_SetString(PyExc_ValueError,
401 "minute must be in 0..59");
402 return -1;
403 }
404 if (s < 0 || s > 59) {
405 PyErr_SetString(PyExc_ValueError,
406 "second must be in 0..59");
407 return -1;
408 }
409 if (us < 0 || us > 999999) {
410 PyErr_SetString(PyExc_ValueError,
411 "microsecond must be in 0..999999");
412 return -1;
413 }
414 return 0;
415}
416
417/* ---------------------------------------------------------------------------
418 * Normalization utilities.
419 */
420
421/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
422 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
423 * at least factor, enough of *lo is converted into "hi" units so that
424 * 0 <= *lo < factor. The input values must be such that int overflow
425 * is impossible.
426 */
427static void
428normalize_pair(int *hi, int *lo, int factor)
429{
430 assert(factor > 0);
431 assert(lo != hi);
432 if (*lo < 0 || *lo >= factor) {
433 const int num_hi = divmod(*lo, factor, lo);
434 const int new_hi = *hi + num_hi;
435 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
436 *hi = new_hi;
437 }
438 assert(0 <= *lo && *lo < factor);
439}
440
441/* Fiddle days (d), seconds (s), and microseconds (us) so that
442 * 0 <= *s < 24*3600
443 * 0 <= *us < 1000000
444 * The input values must be such that the internals don't overflow.
445 * The way this routine is used, we don't get close.
446 */
447static void
448normalize_d_s_us(int *d, int *s, int *us)
449{
450 if (*us < 0 || *us >= 1000000) {
451 normalize_pair(s, us, 1000000);
452 /* |s| can't be bigger than about
453 * |original s| + |original us|/1000000 now.
454 */
455
456 }
457 if (*s < 0 || *s >= 24*3600) {
458 normalize_pair(d, s, 24*3600);
459 /* |d| can't be bigger than about
460 * |original d| +
461 * (|original s| + |original us|/1000000) / (24*3600) now.
462 */
463 }
464 assert(0 <= *s && *s < 24*3600);
465 assert(0 <= *us && *us < 1000000);
466}
467
468/* Fiddle years (y), months (m), and days (d) so that
469 * 1 <= *m <= 12
470 * 1 <= *d <= days_in_month(*y, *m)
471 * The input values must be such that the internals don't overflow.
472 * The way this routine is used, we don't get close.
473 */
474static void
475normalize_y_m_d(int *y, int *m, int *d)
476{
477 int dim; /* # of days in month */
478
479 /* This gets muddy: the proper range for day can't be determined
480 * without knowing the correct month and year, but if day is, e.g.,
481 * plus or minus a million, the current month and year values make
482 * no sense (and may also be out of bounds themselves).
483 * Saying 12 months == 1 year should be non-controversial.
484 */
485 if (*m < 1 || *m > 12) {
486 --*m;
487 normalize_pair(y, m, 12);
488 ++*m;
489 /* |y| can't be bigger than about
490 * |original y| + |original m|/12 now.
491 */
492 }
493 assert(1 <= *m && *m <= 12);
494
495 /* Now only day can be out of bounds (year may also be out of bounds
496 * for a datetime object, but we don't care about that here).
497 * If day is out of bounds, what to do is arguable, but at least the
498 * method here is principled and explainable.
499 */
500 dim = days_in_month(*y, *m);
501 if (*d < 1 || *d > dim) {
502 /* Move day-1 days from the first of the month. First try to
503 * get off cheap if we're only one day out of range
504 * (adjustments for timezone alone can't be worse than that).
505 */
506 if (*d == 0) {
507 --*m;
508 if (*m > 0)
509 *d = days_in_month(*y, *m);
510 else {
511 --*y;
512 *m = 12;
513 *d = 31;
514 }
515 }
516 else if (*d == dim + 1) {
517 /* move forward a day */
518 ++*m;
519 *d = 1;
520 if (*m > 12) {
521 *m = 1;
522 ++*y;
523 }
524 }
525 else {
526 int ordinal = ymd_to_ord(*y, *m, 1) +
527 *d - 1;
528 ord_to_ymd(ordinal, y, m, d);
529 }
530 }
531 assert(*m > 0);
532 assert(*d > 0);
533}
534
535/* Fiddle out-of-bounds months and days so that the result makes some kind
536 * of sense. The parameters are both inputs and outputs. Returns < 0 on
537 * failure, where failure means the adjusted year is out of bounds.
538 */
539static int
540normalize_date(int *year, int *month, int *day)
541{
542 int result;
543
544 normalize_y_m_d(year, month, day);
545 if (MINYEAR <= *year && *year <= MAXYEAR)
546 result = 0;
547 else {
548 PyErr_SetString(PyExc_OverflowError,
549 "date value out of range");
550 result = -1;
551 }
552 return result;
553}
554
555/* Force all the datetime fields into range. The parameters are both
556 * inputs and outputs. Returns < 0 on error.
557 */
558static int
559normalize_datetime(int *year, int *month, int *day,
560 int *hour, int *minute, int *second,
561 int *microsecond)
562{
563 normalize_pair(second, microsecond, 1000000);
564 normalize_pair(minute, second, 60);
565 normalize_pair(hour, minute, 60);
566 normalize_pair(day, hour, 24);
567 return normalize_date(year, month, day);
568}
569
570/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000571 * Basic object allocation: tp_alloc implementations. These allocate
572 * Python objects of the right size and type, and do the Python object-
573 * initialization bit. If there's not enough memory, they return NULL after
574 * setting MemoryError. All data members remain uninitialized trash.
575 *
576 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000577 * member is needed. This is ugly, imprecise, and possibly insecure.
578 * tp_basicsize for the time and datetime types is set to the size of the
579 * struct that has room for the tzinfo member, so subclasses in Python will
580 * allocate enough space for a tzinfo member whether or not one is actually
581 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
582 * part is that PyType_GenericAlloc() (which subclasses in Python end up
583 * using) just happens today to effectively ignore the nitems argument
584 * when tp_itemsize is 0, which it is for these type objects. If that
585 * changes, perhaps the callers of tp_alloc slots in this file should
586 * be changed to force a 0 nitems argument unless the type being allocated
587 * is a base type implemented in this file (so that tp_alloc is time_alloc
588 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000589 */
590
591static PyObject *
592time_alloc(PyTypeObject *type, int aware)
593{
594 PyObject *self;
595
596 self = (PyObject *)
597 PyObject_MALLOC(aware ?
598 sizeof(PyDateTime_Time) :
599 sizeof(_PyDateTime_BaseTime));
600 if (self == NULL)
601 return (PyObject *)PyErr_NoMemory();
602 PyObject_INIT(self, type);
603 return self;
604}
605
606static PyObject *
607datetime_alloc(PyTypeObject *type, int aware)
608{
609 PyObject *self;
610
611 self = (PyObject *)
612 PyObject_MALLOC(aware ?
613 sizeof(PyDateTime_DateTime) :
614 sizeof(_PyDateTime_BaseDateTime));
615 if (self == NULL)
616 return (PyObject *)PyErr_NoMemory();
617 PyObject_INIT(self, type);
618 return self;
619}
620
621/* ---------------------------------------------------------------------------
622 * Helpers for setting object fields. These work on pointers to the
623 * appropriate base class.
624 */
625
626/* For date and datetime. */
627static void
628set_date_fields(PyDateTime_Date *self, int y, int m, int d)
629{
630 self->hashcode = -1;
631 SET_YEAR(self, y);
632 SET_MONTH(self, m);
633 SET_DAY(self, d);
634}
635
636/* ---------------------------------------------------------------------------
637 * Create various objects, mostly without range checking.
638 */
639
640/* Create a date instance with no range checking. */
641static PyObject *
642new_date_ex(int year, int month, int day, PyTypeObject *type)
643{
644 PyDateTime_Date *self;
645
646 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
647 if (self != NULL)
648 set_date_fields(self, year, month, day);
649 return (PyObject *) self;
650}
651
652#define new_date(year, month, day) \
653 new_date_ex(year, month, day, &PyDateTime_DateType)
654
655/* Create a datetime instance with no range checking. */
656static PyObject *
657new_datetime_ex(int year, int month, int day, int hour, int minute,
658 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
659{
660 PyDateTime_DateTime *self;
661 char aware = tzinfo != Py_None;
662
663 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
664 if (self != NULL) {
665 self->hastzinfo = aware;
666 set_date_fields((PyDateTime_Date *)self, year, month, day);
667 DATE_SET_HOUR(self, hour);
668 DATE_SET_MINUTE(self, minute);
669 DATE_SET_SECOND(self, second);
670 DATE_SET_MICROSECOND(self, usecond);
671 if (aware) {
672 Py_INCREF(tzinfo);
673 self->tzinfo = tzinfo;
674 }
675 }
676 return (PyObject *)self;
677}
678
679#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
680 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
681 &PyDateTime_DateTimeType)
682
683/* Create a time instance with no range checking. */
684static PyObject *
685new_time_ex(int hour, int minute, int second, int usecond,
686 PyObject *tzinfo, PyTypeObject *type)
687{
688 PyDateTime_Time *self;
689 char aware = tzinfo != Py_None;
690
691 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
692 if (self != NULL) {
693 self->hastzinfo = aware;
694 self->hashcode = -1;
695 TIME_SET_HOUR(self, hour);
696 TIME_SET_MINUTE(self, minute);
697 TIME_SET_SECOND(self, second);
698 TIME_SET_MICROSECOND(self, usecond);
699 if (aware) {
700 Py_INCREF(tzinfo);
701 self->tzinfo = tzinfo;
702 }
703 }
704 return (PyObject *)self;
705}
706
707#define new_time(hh, mm, ss, us, tzinfo) \
708 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
709
710/* Create a timedelta instance. Normalize the members iff normalize is
711 * true. Passing false is a speed optimization, if you know for sure
712 * that seconds and microseconds are already in their proper ranges. In any
713 * case, raises OverflowError and returns NULL if the normalized days is out
714 * of range).
715 */
716static PyObject *
717new_delta_ex(int days, int seconds, int microseconds, int normalize,
718 PyTypeObject *type)
719{
720 PyDateTime_Delta *self;
721
722 if (normalize)
723 normalize_d_s_us(&days, &seconds, &microseconds);
724 assert(0 <= seconds && seconds < 24*3600);
725 assert(0 <= microseconds && microseconds < 1000000);
726
727 if (check_delta_day_range(days) < 0)
728 return NULL;
729
730 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
731 if (self != NULL) {
732 self->hashcode = -1;
733 SET_TD_DAYS(self, days);
734 SET_TD_SECONDS(self, seconds);
735 SET_TD_MICROSECONDS(self, microseconds);
736 }
737 return (PyObject *) self;
738}
739
740#define new_delta(d, s, us, normalize) \
741 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
742
743/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000744 * tzinfo helpers.
745 */
746
Tim Peters855fe882002-12-22 03:43:39 +0000747/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
748 * raise TypeError and return -1.
749 */
750static int
751check_tzinfo_subclass(PyObject *p)
752{
753 if (p == Py_None || PyTZInfo_Check(p))
754 return 0;
755 PyErr_Format(PyExc_TypeError,
756 "tzinfo argument must be None or of a tzinfo subclass, "
757 "not type '%s'",
758 p->ob_type->tp_name);
759 return -1;
760}
761
Tim Petersbad8ff02002-12-30 20:52:32 +0000762/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000763 * If tzinfo is None, returns None.
764 */
765static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000766call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000767{
768 PyObject *result;
769
Tim Petersbad8ff02002-12-30 20:52:32 +0000770 assert(tzinfo && methname && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000771 assert(check_tzinfo_subclass(tzinfo) >= 0);
772 if (tzinfo == Py_None) {
773 result = Py_None;
774 Py_INCREF(result);
775 }
776 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000777 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000778 return result;
779}
780
Tim Peters2a799bf2002-12-16 20:18:38 +0000781/* If self has a tzinfo member, return a BORROWED reference to it. Else
782 * return NULL, which is NOT AN ERROR. There are no error returns here,
783 * and the caller must not decref the result.
784 */
785static PyObject *
786get_tzinfo_member(PyObject *self)
787{
788 PyObject *tzinfo = NULL;
789
Tim Petersa9bc1682003-01-11 03:39:11 +0000790 if (PyDateTime_Check(self) && HASTZINFO(self))
791 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
Tim Petersa032d2e2003-01-11 00:15:54 +0000792 else if (PyTime_Check(self) && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +0000793 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000794
795 return tzinfo;
796}
797
Tim Petersbad8ff02002-12-30 20:52:32 +0000798/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000799 * result. tzinfo must be an instance of the tzinfo class. If the method
800 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000801 * return None or timedelta, TypeError is raised and this returns -1. If it
802 * returnsa timedelta and the value is out of range or isn't a whole number
803 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000804 * Else *none is set to 0 and the integer method result is returned.
805 */
806static int
807call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
808 int *none)
809{
810 PyObject *u;
Tim Peters397301e2003-01-02 21:28:08 +0000811 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000812
813 assert(tzinfo != NULL);
814 assert(PyTZInfo_Check(tzinfo));
815 assert(tzinfoarg != NULL);
816
817 *none = 0;
Tim Petersbad8ff02002-12-30 20:52:32 +0000818 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000819 if (u == NULL)
820 return -1;
821
Tim Peters27362852002-12-23 16:17:39 +0000822 else if (u == Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +0000823 result = 0;
824 *none = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000825 }
Tim Peters855fe882002-12-22 03:43:39 +0000826 else if (PyDelta_Check(u)) {
827 const int days = GET_TD_DAYS(u);
828 if (days < -1 || days > 0)
829 result = 24*60; /* trigger ValueError below */
830 else {
831 /* next line can't overflow because we know days
832 * is -1 or 0 now
833 */
834 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
835 result = divmod(ss, 60, &ss);
836 if (ss || GET_TD_MICROSECONDS(u)) {
837 PyErr_Format(PyExc_ValueError,
838 "tzinfo.%s() must return a "
839 "whole number of minutes",
840 name);
841 result = -1;
Tim Peters855fe882002-12-22 03:43:39 +0000842 }
843 }
844 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000845 else {
846 PyErr_Format(PyExc_TypeError,
Tim Peters397301e2003-01-02 21:28:08 +0000847 "tzinfo.%s() must return None or "
Tim Peters855fe882002-12-22 03:43:39 +0000848 "timedelta, not '%s'",
849 name, u->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000850 }
851
Tim Peters2a799bf2002-12-16 20:18:38 +0000852 Py_DECREF(u);
853 if (result < -1439 || result > 1439) {
854 PyErr_Format(PyExc_ValueError,
Neal Norwitz506a2242003-01-04 01:02:25 +0000855 "tzinfo.%s() returned %d; must be in "
Tim Peters2a799bf2002-12-16 20:18:38 +0000856 "-1439 .. 1439",
857 name, result);
858 result = -1;
859 }
Tim Peters397301e2003-01-02 21:28:08 +0000860 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000861}
862
863/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
864 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
865 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000866 * doesn't return None or timedelta, TypeError is raised and this returns -1.
867 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
868 * # of minutes), ValueError is raised and this returns -1. Else *none is
869 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000870 */
871static int
872call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
873{
874 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
875}
876
Tim Petersbad8ff02002-12-30 20:52:32 +0000877/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
878 */
Tim Peters855fe882002-12-22 03:43:39 +0000879static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000880offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Tim Peters855fe882002-12-22 03:43:39 +0000881 PyObject *result;
882
Tim Petersbad8ff02002-12-30 20:52:32 +0000883 assert(tzinfo && name && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000884 if (tzinfo == Py_None) {
885 result = Py_None;
886 Py_INCREF(result);
887 }
888 else {
889 int none;
Tim Petersbad8ff02002-12-30 20:52:32 +0000890 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
891 &none);
Tim Peters855fe882002-12-22 03:43:39 +0000892 if (offset < 0 && PyErr_Occurred())
893 return NULL;
894 if (none) {
895 result = Py_None;
896 Py_INCREF(result);
897 }
898 else
899 result = new_delta(0, offset * 60, 0, 1);
900 }
901 return result;
902}
903
Tim Peters2a799bf2002-12-16 20:18:38 +0000904/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
905 * result. tzinfo must be an instance of the tzinfo class. If dst()
906 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000907 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000908 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000909 * ValueError is raised and this returns -1. Else *none is set to 0 and
910 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000911 */
912static int
913call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
914{
915 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
916}
917
Tim Petersbad8ff02002-12-30 20:52:32 +0000918/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000919 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000920 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000921 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000922 */
923static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000924call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000925{
926 PyObject *result;
927
928 assert(tzinfo != NULL);
Tim Peters855fe882002-12-22 03:43:39 +0000929 assert(check_tzinfo_subclass(tzinfo) >= 0);
Tim Petersbad8ff02002-12-30 20:52:32 +0000930 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000931
Tim Peters855fe882002-12-22 03:43:39 +0000932 if (tzinfo == Py_None) {
933 result = Py_None;
934 Py_INCREF(result);
935 }
936 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000937 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000938
939 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
940 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
Tim Peters2a799bf2002-12-16 20:18:38 +0000941 "return None or a string, not '%s'",
942 result->ob_type->tp_name);
943 Py_DECREF(result);
944 result = NULL;
945 }
946 return result;
947}
948
949typedef enum {
950 /* an exception has been set; the caller should pass it on */
951 OFFSET_ERROR,
952
Tim Petersa9bc1682003-01-11 03:39:11 +0000953 /* type isn't date, datetime, or time subclass */
Tim Peters2a799bf2002-12-16 20:18:38 +0000954 OFFSET_UNKNOWN,
955
956 /* date,
Tim Petersa9bc1682003-01-11 03:39:11 +0000957 * datetime with !hastzinfo
958 * datetime with None tzinfo,
959 * datetime where utcoffset() returns None
Tim Peters37f39822003-01-10 03:49:02 +0000960 * time with !hastzinfo
961 * time with None tzinfo,
962 * time where utcoffset() returns None
Tim Peters2a799bf2002-12-16 20:18:38 +0000963 */
964 OFFSET_NAIVE,
965
Tim Petersa9bc1682003-01-11 03:39:11 +0000966 /* time or datetime where utcoffset() doesn't return None */
Tim Peters2a799bf2002-12-16 20:18:38 +0000967 OFFSET_AWARE,
968} naivety;
969
Tim Peters14b69412002-12-22 18:10:22 +0000970/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000971 * the "naivety" typedef for details. If the type is aware, *offset is set
972 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000973 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000974 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000975 */
976static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000977classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000978{
979 int none;
980 PyObject *tzinfo;
981
Tim Peterse39a80c2002-12-30 21:28:52 +0000982 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000983 *offset = 0;
Tim Peters14b69412002-12-22 18:10:22 +0000984 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
Tim Peters2a799bf2002-12-16 20:18:38 +0000985 if (tzinfo == Py_None)
986 return OFFSET_NAIVE;
Tim Peters14b69412002-12-22 18:10:22 +0000987 if (tzinfo == NULL) {
988 /* note that a datetime passes the PyDate_Check test */
989 return (PyTime_Check(op) || PyDate_Check(op)) ?
990 OFFSET_NAIVE : OFFSET_UNKNOWN;
991 }
Tim Peterse39a80c2002-12-30 21:28:52 +0000992 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000993 if (*offset == -1 && PyErr_Occurred())
994 return OFFSET_ERROR;
995 return none ? OFFSET_NAIVE : OFFSET_AWARE;
996}
997
Tim Peters00237032002-12-27 02:21:51 +0000998/* Classify two objects as to whether they're naive or offset-aware.
999 * This isn't quite the same as calling classify_utcoffset() twice: for
1000 * binary operations (comparison and subtraction), we generally want to
1001 * ignore the tzinfo members if they're identical. This is by design,
1002 * so that results match "naive" expectations when mixing objects from a
1003 * single timezone. So in that case, this sets both offsets to 0 and
1004 * both naiveties to OFFSET_NAIVE.
1005 * The function returns 0 if everything's OK, and -1 on error.
1006 */
1007static int
1008classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Tim Peterse39a80c2002-12-30 21:28:52 +00001009 PyObject *tzinfoarg1,
1010 PyObject *o2, int *offset2, naivety *n2,
1011 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001012{
1013 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1014 *offset1 = *offset2 = 0;
1015 *n1 = *n2 = OFFSET_NAIVE;
1016 }
1017 else {
Tim Peterse39a80c2002-12-30 21:28:52 +00001018 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
Tim Peters00237032002-12-27 02:21:51 +00001019 if (*n1 == OFFSET_ERROR)
1020 return -1;
Tim Peterse39a80c2002-12-30 21:28:52 +00001021 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
Tim Peters00237032002-12-27 02:21:51 +00001022 if (*n2 == OFFSET_ERROR)
1023 return -1;
1024 }
1025 return 0;
1026}
1027
Tim Peters2a799bf2002-12-16 20:18:38 +00001028/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1029 * stuff
1030 * ", tzinfo=" + repr(tzinfo)
1031 * before the closing ")".
1032 */
1033static PyObject *
1034append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1035{
1036 PyObject *temp;
1037
1038 assert(PyString_Check(repr));
1039 assert(tzinfo);
1040 if (tzinfo == Py_None)
1041 return repr;
1042 /* Get rid of the trailing ')'. */
1043 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1044 temp = PyString_FromStringAndSize(PyString_AsString(repr),
1045 PyString_Size(repr) - 1);
1046 Py_DECREF(repr);
1047 if (temp == NULL)
1048 return NULL;
1049 repr = temp;
1050
1051 /* Append ", tzinfo=". */
1052 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
1053
1054 /* Append repr(tzinfo). */
1055 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
1056
1057 /* Add a closing paren. */
1058 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
1059 return repr;
1060}
1061
1062/* ---------------------------------------------------------------------------
1063 * String format helpers.
1064 */
1065
1066static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001067format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001068{
1069 static char *DayNames[] = {
1070 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1071 };
1072 static char *MonthNames[] = {
1073 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1074 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1075 };
1076
1077 char buffer[128];
1078 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1079
1080 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
1081 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
1082 GET_DAY(date), hours, minutes, seconds,
1083 GET_YEAR(date));
1084 return PyString_FromString(buffer);
1085}
1086
1087/* Add an hours & minutes UTC offset string to buf. buf has no more than
1088 * buflen bytes remaining. The UTC offset is gotten by calling
1089 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1090 * *buf, and that's all. Else the returned value is checked for sanity (an
1091 * integer in range), and if that's OK it's converted to an hours & minutes
1092 * string of the form
1093 * sign HH sep MM
1094 * Returns 0 if everything is OK. If the return value from utcoffset() is
1095 * bogus, an appropriate exception is set and -1 is returned.
1096 */
1097static int
Tim Peters328fff72002-12-20 01:31:27 +00001098format_utcoffset(char *buf, size_t buflen, const char *sep,
Tim Peters2a799bf2002-12-16 20:18:38 +00001099 PyObject *tzinfo, PyObject *tzinfoarg)
1100{
1101 int offset;
1102 int hours;
1103 int minutes;
1104 char sign;
1105 int none;
1106
1107 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1108 if (offset == -1 && PyErr_Occurred())
1109 return -1;
1110 if (none) {
1111 *buf = '\0';
1112 return 0;
1113 }
1114 sign = '+';
1115 if (offset < 0) {
1116 sign = '-';
1117 offset = - offset;
1118 }
1119 hours = divmod(offset, 60, &minutes);
1120 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1121 return 0;
1122}
1123
1124/* I sure don't want to reproduce the strftime code from the time module,
1125 * so this imports the module and calls it. All the hair is due to
1126 * giving special meanings to the %z and %Z format codes via a preprocessing
1127 * step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001128 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1129 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001130 */
1131static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001132wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
1133 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001134{
1135 PyObject *result = NULL; /* guilty until proved innocent */
1136
1137 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1138 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1139
1140 char *pin; /* pointer to next char in input format */
1141 char ch; /* next char in input format */
1142
1143 PyObject *newfmt = NULL; /* py string, the output format */
1144 char *pnew; /* pointer to available byte in output format */
1145 char totalnew; /* number bytes total in output format buffer,
1146 exclusive of trailing \0 */
1147 char usednew; /* number bytes used so far in output format buffer */
1148
1149 char *ptoappend; /* pointer to string to append to output buffer */
1150 int ntoappend; /* # of bytes to append to output buffer */
1151
Tim Peters2a799bf2002-12-16 20:18:38 +00001152 assert(object && format && timetuple);
1153 assert(PyString_Check(format));
1154
Tim Petersd6844152002-12-22 20:58:42 +00001155 /* Give up if the year is before 1900.
1156 * Python strftime() plays games with the year, and different
1157 * games depending on whether envar PYTHON2K is set. This makes
1158 * years before 1900 a nightmare, even if the platform strftime
1159 * supports them (and not all do).
1160 * We could get a lot farther here by avoiding Python's strftime
1161 * wrapper and calling the C strftime() directly, but that isn't
1162 * an option in the Python implementation of this module.
1163 */
1164 {
1165 long year;
1166 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1167 if (pyyear == NULL) return NULL;
1168 assert(PyInt_Check(pyyear));
1169 year = PyInt_AsLong(pyyear);
1170 Py_DECREF(pyyear);
1171 if (year < 1900) {
1172 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1173 "1900; the datetime strftime() "
1174 "methods require year >= 1900",
1175 year);
1176 return NULL;
1177 }
1178 }
1179
Tim Peters2a799bf2002-12-16 20:18:38 +00001180 /* Scan the input format, looking for %z and %Z escapes, building
Tim Peters328fff72002-12-20 01:31:27 +00001181 * a new format. Since computing the replacements for those codes
1182 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +00001183 */
Raymond Hettingerf69d9f62003-06-27 08:14:17 +00001184 totalnew = PyString_Size(format) + 1; /* realistic if no %z/%Z */
Tim Peters2a799bf2002-12-16 20:18:38 +00001185 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1186 if (newfmt == NULL) goto Done;
1187 pnew = PyString_AsString(newfmt);
1188 usednew = 0;
1189
1190 pin = PyString_AsString(format);
1191 while ((ch = *pin++) != '\0') {
1192 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +00001193 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001194 ntoappend = 1;
1195 }
1196 else if ((ch = *pin++) == '\0') {
1197 /* There's a lone trailing %; doesn't make sense. */
1198 PyErr_SetString(PyExc_ValueError, "strftime format "
1199 "ends with raw %");
1200 goto Done;
1201 }
1202 /* A % has been seen and ch is the character after it. */
1203 else if (ch == 'z') {
1204 if (zreplacement == NULL) {
1205 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +00001206 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +00001207 PyObject *tzinfo = get_tzinfo_member(object);
1208 zreplacement = PyString_FromString("");
1209 if (zreplacement == NULL) goto Done;
1210 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001211 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001212 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001213 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001214 "",
1215 tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00001216 tzinfoarg) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001217 goto Done;
1218 Py_DECREF(zreplacement);
1219 zreplacement = PyString_FromString(buf);
1220 if (zreplacement == NULL) goto Done;
1221 }
1222 }
1223 assert(zreplacement != NULL);
1224 ptoappend = PyString_AsString(zreplacement);
1225 ntoappend = PyString_Size(zreplacement);
1226 }
1227 else if (ch == 'Z') {
1228 /* format tzname */
1229 if (Zreplacement == NULL) {
1230 PyObject *tzinfo = get_tzinfo_member(object);
1231 Zreplacement = PyString_FromString("");
1232 if (Zreplacement == NULL) goto Done;
1233 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001234 PyObject *temp;
1235 assert(tzinfoarg != NULL);
1236 temp = call_tzname(tzinfo, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001237 if (temp == NULL) goto Done;
1238 if (temp != Py_None) {
1239 assert(PyString_Check(temp));
1240 /* Since the tzname is getting
1241 * stuffed into the format, we
1242 * have to double any % signs
1243 * so that strftime doesn't
1244 * treat them as format codes.
1245 */
1246 Py_DECREF(Zreplacement);
1247 Zreplacement = PyObject_CallMethod(
1248 temp, "replace",
1249 "ss", "%", "%%");
1250 Py_DECREF(temp);
1251 if (Zreplacement == NULL)
1252 goto Done;
1253 }
1254 else
1255 Py_DECREF(temp);
1256 }
1257 }
1258 assert(Zreplacement != NULL);
1259 ptoappend = PyString_AsString(Zreplacement);
1260 ntoappend = PyString_Size(Zreplacement);
1261 }
1262 else {
Tim Peters328fff72002-12-20 01:31:27 +00001263 /* percent followed by neither z nor Z */
1264 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001265 ntoappend = 2;
1266 }
1267
1268 /* Append the ntoappend chars starting at ptoappend to
1269 * the new format.
1270 */
1271 assert(ntoappend >= 0);
1272 if (ntoappend == 0)
1273 continue;
1274 while (usednew + ntoappend > totalnew) {
1275 int bigger = totalnew << 1;
1276 if ((bigger >> 1) != totalnew) { /* overflow */
1277 PyErr_NoMemory();
1278 goto Done;
1279 }
1280 if (_PyString_Resize(&newfmt, bigger) < 0)
1281 goto Done;
1282 totalnew = bigger;
1283 pnew = PyString_AsString(newfmt) + usednew;
1284 }
1285 memcpy(pnew, ptoappend, ntoappend);
1286 pnew += ntoappend;
1287 usednew += ntoappend;
1288 assert(usednew <= totalnew);
1289 } /* end while() */
1290
1291 if (_PyString_Resize(&newfmt, usednew) < 0)
1292 goto Done;
1293 {
1294 PyObject *time = PyImport_ImportModule("time");
1295 if (time == NULL)
1296 goto Done;
1297 result = PyObject_CallMethod(time, "strftime", "OO",
1298 newfmt, timetuple);
1299 Py_DECREF(time);
1300 }
1301 Done:
1302 Py_XDECREF(zreplacement);
1303 Py_XDECREF(Zreplacement);
1304 Py_XDECREF(newfmt);
1305 return result;
1306}
1307
1308static char *
1309isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1310{
1311 int x;
1312 x = PyOS_snprintf(buffer, bufflen,
1313 "%04d-%02d-%02d",
1314 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1315 return buffer + x;
1316}
1317
1318static void
1319isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1320{
1321 int us = DATE_GET_MICROSECOND(dt);
1322
1323 PyOS_snprintf(buffer, bufflen,
1324 "%02d:%02d:%02d", /* 8 characters */
1325 DATE_GET_HOUR(dt),
1326 DATE_GET_MINUTE(dt),
1327 DATE_GET_SECOND(dt));
1328 if (us)
1329 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1330}
1331
1332/* ---------------------------------------------------------------------------
1333 * Wrap functions from the time module. These aren't directly available
1334 * from C. Perhaps they should be.
1335 */
1336
1337/* Call time.time() and return its result (a Python float). */
1338static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001339time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001340{
1341 PyObject *result = NULL;
1342 PyObject *time = PyImport_ImportModule("time");
1343
1344 if (time != NULL) {
1345 result = PyObject_CallMethod(time, "time", "()");
1346 Py_DECREF(time);
1347 }
1348 return result;
1349}
1350
1351/* Build a time.struct_time. The weekday and day number are automatically
1352 * computed from the y,m,d args.
1353 */
1354static PyObject *
1355build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1356{
1357 PyObject *time;
1358 PyObject *result = NULL;
1359
1360 time = PyImport_ImportModule("time");
1361 if (time != NULL) {
1362 result = PyObject_CallMethod(time, "struct_time",
1363 "((iiiiiiiii))",
1364 y, m, d,
1365 hh, mm, ss,
1366 weekday(y, m, d),
1367 days_before_month(y, m) + d,
1368 dstflag);
1369 Py_DECREF(time);
1370 }
1371 return result;
1372}
1373
1374/* ---------------------------------------------------------------------------
1375 * Miscellaneous helpers.
1376 */
1377
1378/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1379 * The comparisons here all most naturally compute a cmp()-like result.
1380 * This little helper turns that into a bool result for rich comparisons.
1381 */
1382static PyObject *
1383diff_to_bool(int diff, int op)
1384{
1385 PyObject *result;
1386 int istrue;
1387
1388 switch (op) {
1389 case Py_EQ: istrue = diff == 0; break;
1390 case Py_NE: istrue = diff != 0; break;
1391 case Py_LE: istrue = diff <= 0; break;
1392 case Py_GE: istrue = diff >= 0; break;
1393 case Py_LT: istrue = diff < 0; break;
1394 case Py_GT: istrue = diff > 0; break;
1395 default:
1396 assert(! "op unknown");
1397 istrue = 0; /* To shut up compiler */
1398 }
1399 result = istrue ? Py_True : Py_False;
1400 Py_INCREF(result);
1401 return result;
1402}
1403
Tim Peters07534a62003-02-07 22:50:28 +00001404/* Raises a "can't compare" TypeError and returns NULL. */
1405static PyObject *
1406cmperror(PyObject *a, PyObject *b)
1407{
1408 PyErr_Format(PyExc_TypeError,
1409 "can't compare %s to %s",
1410 a->ob_type->tp_name, b->ob_type->tp_name);
1411 return NULL;
1412}
1413
Tim Peters2a799bf2002-12-16 20:18:38 +00001414/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001415 * Cached Python objects; these are set by the module init function.
1416 */
1417
1418/* Conversion factors. */
1419static PyObject *us_per_us = NULL; /* 1 */
1420static PyObject *us_per_ms = NULL; /* 1000 */
1421static PyObject *us_per_second = NULL; /* 1000000 */
1422static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1423static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1424static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1425static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1426static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1427
Tim Peters2a799bf2002-12-16 20:18:38 +00001428/* ---------------------------------------------------------------------------
1429 * Class implementations.
1430 */
1431
1432/*
1433 * PyDateTime_Delta implementation.
1434 */
1435
1436/* Convert a timedelta to a number of us,
1437 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1438 * as a Python int or long.
1439 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1440 * due to ubiquitous overflow possibilities.
1441 */
1442static PyObject *
1443delta_to_microseconds(PyDateTime_Delta *self)
1444{
1445 PyObject *x1 = NULL;
1446 PyObject *x2 = NULL;
1447 PyObject *x3 = NULL;
1448 PyObject *result = NULL;
1449
1450 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1451 if (x1 == NULL)
1452 goto Done;
1453 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1454 if (x2 == NULL)
1455 goto Done;
1456 Py_DECREF(x1);
1457 x1 = NULL;
1458
1459 /* x2 has days in seconds */
1460 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1461 if (x1 == NULL)
1462 goto Done;
1463 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1464 if (x3 == NULL)
1465 goto Done;
1466 Py_DECREF(x1);
1467 Py_DECREF(x2);
1468 x1 = x2 = NULL;
1469
1470 /* x3 has days+seconds in seconds */
1471 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1472 if (x1 == NULL)
1473 goto Done;
1474 Py_DECREF(x3);
1475 x3 = NULL;
1476
1477 /* x1 has days+seconds in us */
1478 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1479 if (x2 == NULL)
1480 goto Done;
1481 result = PyNumber_Add(x1, x2);
1482
1483Done:
1484 Py_XDECREF(x1);
1485 Py_XDECREF(x2);
1486 Py_XDECREF(x3);
1487 return result;
1488}
1489
1490/* Convert a number of us (as a Python int or long) to a timedelta.
1491 */
1492static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001493microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001494{
1495 int us;
1496 int s;
1497 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001498 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001499
1500 PyObject *tuple = NULL;
1501 PyObject *num = NULL;
1502 PyObject *result = NULL;
1503
1504 tuple = PyNumber_Divmod(pyus, us_per_second);
1505 if (tuple == NULL)
1506 goto Done;
1507
1508 num = PyTuple_GetItem(tuple, 1); /* us */
1509 if (num == NULL)
1510 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001511 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001512 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001513 if (temp == -1 && PyErr_Occurred())
1514 goto Done;
1515 assert(0 <= temp && temp < 1000000);
1516 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001517 if (us < 0) {
1518 /* The divisor was positive, so this must be an error. */
1519 assert(PyErr_Occurred());
1520 goto Done;
1521 }
1522
1523 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1524 if (num == NULL)
1525 goto Done;
1526 Py_INCREF(num);
1527 Py_DECREF(tuple);
1528
1529 tuple = PyNumber_Divmod(num, seconds_per_day);
1530 if (tuple == NULL)
1531 goto Done;
1532 Py_DECREF(num);
1533
1534 num = PyTuple_GetItem(tuple, 1); /* seconds */
1535 if (num == NULL)
1536 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001537 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001538 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001539 if (temp == -1 && PyErr_Occurred())
1540 goto Done;
1541 assert(0 <= temp && temp < 24*3600);
1542 s = (int)temp;
1543
Tim Peters2a799bf2002-12-16 20:18:38 +00001544 if (s < 0) {
1545 /* The divisor was positive, so this must be an error. */
1546 assert(PyErr_Occurred());
1547 goto Done;
1548 }
1549
1550 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1551 if (num == NULL)
1552 goto Done;
1553 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001554 temp = PyLong_AsLong(num);
1555 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001556 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001557 d = (int)temp;
1558 if ((long)d != temp) {
1559 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1560 "large to fit in a C int");
1561 goto Done;
1562 }
Tim Petersb0c854d2003-05-17 15:57:00 +00001563 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001564
1565Done:
1566 Py_XDECREF(tuple);
1567 Py_XDECREF(num);
1568 return result;
1569}
1570
Tim Petersb0c854d2003-05-17 15:57:00 +00001571#define microseconds_to_delta(pymicros) \
1572 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1573
Tim Peters2a799bf2002-12-16 20:18:38 +00001574static PyObject *
1575multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1576{
1577 PyObject *pyus_in;
1578 PyObject *pyus_out;
1579 PyObject *result;
1580
1581 pyus_in = delta_to_microseconds(delta);
1582 if (pyus_in == NULL)
1583 return NULL;
1584
1585 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1586 Py_DECREF(pyus_in);
1587 if (pyus_out == NULL)
1588 return NULL;
1589
1590 result = microseconds_to_delta(pyus_out);
1591 Py_DECREF(pyus_out);
1592 return result;
1593}
1594
1595static PyObject *
1596divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1597{
1598 PyObject *pyus_in;
1599 PyObject *pyus_out;
1600 PyObject *result;
1601
1602 pyus_in = delta_to_microseconds(delta);
1603 if (pyus_in == NULL)
1604 return NULL;
1605
1606 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1607 Py_DECREF(pyus_in);
1608 if (pyus_out == NULL)
1609 return NULL;
1610
1611 result = microseconds_to_delta(pyus_out);
1612 Py_DECREF(pyus_out);
1613 return result;
1614}
1615
1616static PyObject *
1617delta_add(PyObject *left, PyObject *right)
1618{
1619 PyObject *result = Py_NotImplemented;
1620
1621 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1622 /* delta + delta */
1623 /* The C-level additions can't overflow because of the
1624 * invariant bounds.
1625 */
1626 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1627 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1628 int microseconds = GET_TD_MICROSECONDS(left) +
1629 GET_TD_MICROSECONDS(right);
1630 result = new_delta(days, seconds, microseconds, 1);
1631 }
1632
1633 if (result == Py_NotImplemented)
1634 Py_INCREF(result);
1635 return result;
1636}
1637
1638static PyObject *
1639delta_negative(PyDateTime_Delta *self)
1640{
1641 return new_delta(-GET_TD_DAYS(self),
1642 -GET_TD_SECONDS(self),
1643 -GET_TD_MICROSECONDS(self),
1644 1);
1645}
1646
1647static PyObject *
1648delta_positive(PyDateTime_Delta *self)
1649{
1650 /* Could optimize this (by returning self) if this isn't a
1651 * subclass -- but who uses unary + ? Approximately nobody.
1652 */
1653 return new_delta(GET_TD_DAYS(self),
1654 GET_TD_SECONDS(self),
1655 GET_TD_MICROSECONDS(self),
1656 0);
1657}
1658
1659static PyObject *
1660delta_abs(PyDateTime_Delta *self)
1661{
1662 PyObject *result;
1663
1664 assert(GET_TD_MICROSECONDS(self) >= 0);
1665 assert(GET_TD_SECONDS(self) >= 0);
1666
1667 if (GET_TD_DAYS(self) < 0)
1668 result = delta_negative(self);
1669 else
1670 result = delta_positive(self);
1671
1672 return result;
1673}
1674
1675static PyObject *
1676delta_subtract(PyObject *left, PyObject *right)
1677{
1678 PyObject *result = Py_NotImplemented;
1679
1680 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1681 /* delta - delta */
1682 PyObject *minus_right = PyNumber_Negative(right);
1683 if (minus_right) {
1684 result = delta_add(left, minus_right);
1685 Py_DECREF(minus_right);
1686 }
1687 else
1688 result = NULL;
1689 }
1690
1691 if (result == Py_NotImplemented)
1692 Py_INCREF(result);
1693 return result;
1694}
1695
1696/* This is more natural as a tp_compare, but doesn't work then: for whatever
1697 * reason, Python's try_3way_compare ignores tp_compare unless
1698 * PyInstance_Check returns true, but these aren't old-style classes.
1699 */
1700static PyObject *
1701delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1702{
Tim Peters07534a62003-02-07 22:50:28 +00001703 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001704
Tim Petersaa7d8492003-02-08 03:28:59 +00001705 if (PyDelta_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00001706 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1707 if (diff == 0) {
1708 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1709 if (diff == 0)
1710 diff = GET_TD_MICROSECONDS(self) -
1711 GET_TD_MICROSECONDS(other);
1712 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001713 }
Tim Peters07534a62003-02-07 22:50:28 +00001714 else if (op == Py_EQ || op == Py_NE)
1715 diff = 1; /* any non-zero value will do */
1716
1717 else /* stop this from falling back to address comparison */
1718 return cmperror((PyObject *)self, other);
1719
Tim Peters2a799bf2002-12-16 20:18:38 +00001720 return diff_to_bool(diff, op);
1721}
1722
1723static PyObject *delta_getstate(PyDateTime_Delta *self);
1724
1725static long
1726delta_hash(PyDateTime_Delta *self)
1727{
1728 if (self->hashcode == -1) {
1729 PyObject *temp = delta_getstate(self);
1730 if (temp != NULL) {
1731 self->hashcode = PyObject_Hash(temp);
1732 Py_DECREF(temp);
1733 }
1734 }
1735 return self->hashcode;
1736}
1737
1738static PyObject *
1739delta_multiply(PyObject *left, PyObject *right)
1740{
1741 PyObject *result = Py_NotImplemented;
1742
1743 if (PyDelta_Check(left)) {
1744 /* delta * ??? */
1745 if (PyInt_Check(right) || PyLong_Check(right))
1746 result = multiply_int_timedelta(right,
1747 (PyDateTime_Delta *) left);
1748 }
1749 else if (PyInt_Check(left) || PyLong_Check(left))
1750 result = multiply_int_timedelta(left,
1751 (PyDateTime_Delta *) right);
1752
1753 if (result == Py_NotImplemented)
1754 Py_INCREF(result);
1755 return result;
1756}
1757
1758static PyObject *
1759delta_divide(PyObject *left, PyObject *right)
1760{
1761 PyObject *result = Py_NotImplemented;
1762
1763 if (PyDelta_Check(left)) {
1764 /* delta * ??? */
1765 if (PyInt_Check(right) || PyLong_Check(right))
1766 result = divide_timedelta_int(
1767 (PyDateTime_Delta *)left,
1768 right);
1769 }
1770
1771 if (result == Py_NotImplemented)
1772 Py_INCREF(result);
1773 return result;
1774}
1775
1776/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1777 * timedelta constructor. sofar is the # of microseconds accounted for
1778 * so far, and there are factor microseconds per current unit, the number
1779 * of which is given by num. num * factor is added to sofar in a
1780 * numerically careful way, and that's the result. Any fractional
1781 * microseconds left over (this can happen if num is a float type) are
1782 * added into *leftover.
1783 * Note that there are many ways this can give an error (NULL) return.
1784 */
1785static PyObject *
1786accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1787 double *leftover)
1788{
1789 PyObject *prod;
1790 PyObject *sum;
1791
1792 assert(num != NULL);
1793
1794 if (PyInt_Check(num) || PyLong_Check(num)) {
1795 prod = PyNumber_Multiply(num, factor);
1796 if (prod == NULL)
1797 return NULL;
1798 sum = PyNumber_Add(sofar, prod);
1799 Py_DECREF(prod);
1800 return sum;
1801 }
1802
1803 if (PyFloat_Check(num)) {
1804 double dnum;
1805 double fracpart;
1806 double intpart;
1807 PyObject *x;
1808 PyObject *y;
1809
1810 /* The Plan: decompose num into an integer part and a
1811 * fractional part, num = intpart + fracpart.
1812 * Then num * factor ==
1813 * intpart * factor + fracpart * factor
1814 * and the LHS can be computed exactly in long arithmetic.
1815 * The RHS is again broken into an int part and frac part.
1816 * and the frac part is added into *leftover.
1817 */
1818 dnum = PyFloat_AsDouble(num);
1819 if (dnum == -1.0 && PyErr_Occurred())
1820 return NULL;
1821 fracpart = modf(dnum, &intpart);
1822 x = PyLong_FromDouble(intpart);
1823 if (x == NULL)
1824 return NULL;
1825
1826 prod = PyNumber_Multiply(x, factor);
1827 Py_DECREF(x);
1828 if (prod == NULL)
1829 return NULL;
1830
1831 sum = PyNumber_Add(sofar, prod);
1832 Py_DECREF(prod);
1833 if (sum == NULL)
1834 return NULL;
1835
1836 if (fracpart == 0.0)
1837 return sum;
1838 /* So far we've lost no information. Dealing with the
1839 * fractional part requires float arithmetic, and may
1840 * lose a little info.
1841 */
1842 assert(PyInt_Check(factor) || PyLong_Check(factor));
1843 if (PyInt_Check(factor))
1844 dnum = (double)PyInt_AsLong(factor);
1845 else
1846 dnum = PyLong_AsDouble(factor);
1847
1848 dnum *= fracpart;
1849 fracpart = modf(dnum, &intpart);
1850 x = PyLong_FromDouble(intpart);
1851 if (x == NULL) {
1852 Py_DECREF(sum);
1853 return NULL;
1854 }
1855
1856 y = PyNumber_Add(sum, x);
1857 Py_DECREF(sum);
1858 Py_DECREF(x);
1859 *leftover += fracpart;
1860 return y;
1861 }
1862
1863 PyErr_Format(PyExc_TypeError,
1864 "unsupported type for timedelta %s component: %s",
1865 tag, num->ob_type->tp_name);
1866 return NULL;
1867}
1868
1869static PyObject *
1870delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1871{
1872 PyObject *self = NULL;
1873
1874 /* Argument objects. */
1875 PyObject *day = NULL;
1876 PyObject *second = NULL;
1877 PyObject *us = NULL;
1878 PyObject *ms = NULL;
1879 PyObject *minute = NULL;
1880 PyObject *hour = NULL;
1881 PyObject *week = NULL;
1882
1883 PyObject *x = NULL; /* running sum of microseconds */
1884 PyObject *y = NULL; /* temp sum of microseconds */
1885 double leftover_us = 0.0;
1886
1887 static char *keywords[] = {
1888 "days", "seconds", "microseconds", "milliseconds",
1889 "minutes", "hours", "weeks", NULL
1890 };
1891
1892 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1893 keywords,
1894 &day, &second, &us,
1895 &ms, &minute, &hour, &week) == 0)
1896 goto Done;
1897
1898 x = PyInt_FromLong(0);
1899 if (x == NULL)
1900 goto Done;
1901
1902#define CLEANUP \
1903 Py_DECREF(x); \
1904 x = y; \
1905 if (x == NULL) \
1906 goto Done
1907
1908 if (us) {
1909 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1910 CLEANUP;
1911 }
1912 if (ms) {
1913 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1914 CLEANUP;
1915 }
1916 if (second) {
1917 y = accum("seconds", x, second, us_per_second, &leftover_us);
1918 CLEANUP;
1919 }
1920 if (minute) {
1921 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1922 CLEANUP;
1923 }
1924 if (hour) {
1925 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1926 CLEANUP;
1927 }
1928 if (day) {
1929 y = accum("days", x, day, us_per_day, &leftover_us);
1930 CLEANUP;
1931 }
1932 if (week) {
1933 y = accum("weeks", x, week, us_per_week, &leftover_us);
1934 CLEANUP;
1935 }
1936 if (leftover_us) {
1937 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001938 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001939 if (temp == NULL) {
1940 Py_DECREF(x);
1941 goto Done;
1942 }
1943 y = PyNumber_Add(x, temp);
1944 Py_DECREF(temp);
1945 CLEANUP;
1946 }
1947
Tim Petersb0c854d2003-05-17 15:57:00 +00001948 self = microseconds_to_delta_ex(x, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001949 Py_DECREF(x);
1950Done:
1951 return self;
1952
1953#undef CLEANUP
1954}
1955
1956static int
1957delta_nonzero(PyDateTime_Delta *self)
1958{
1959 return (GET_TD_DAYS(self) != 0
1960 || GET_TD_SECONDS(self) != 0
1961 || GET_TD_MICROSECONDS(self) != 0);
1962}
1963
1964static PyObject *
1965delta_repr(PyDateTime_Delta *self)
1966{
1967 if (GET_TD_MICROSECONDS(self) != 0)
1968 return PyString_FromFormat("%s(%d, %d, %d)",
1969 self->ob_type->tp_name,
1970 GET_TD_DAYS(self),
1971 GET_TD_SECONDS(self),
1972 GET_TD_MICROSECONDS(self));
1973 if (GET_TD_SECONDS(self) != 0)
1974 return PyString_FromFormat("%s(%d, %d)",
1975 self->ob_type->tp_name,
1976 GET_TD_DAYS(self),
1977 GET_TD_SECONDS(self));
1978
1979 return PyString_FromFormat("%s(%d)",
1980 self->ob_type->tp_name,
1981 GET_TD_DAYS(self));
1982}
1983
1984static PyObject *
1985delta_str(PyDateTime_Delta *self)
1986{
1987 int days = GET_TD_DAYS(self);
1988 int seconds = GET_TD_SECONDS(self);
1989 int us = GET_TD_MICROSECONDS(self);
1990 int hours;
1991 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001992 char buf[100];
1993 char *pbuf = buf;
1994 size_t buflen = sizeof(buf);
1995 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001996
1997 minutes = divmod(seconds, 60, &seconds);
1998 hours = divmod(minutes, 60, &minutes);
1999
2000 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00002001 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2002 (days == 1 || days == -1) ? "" : "s");
2003 if (n < 0 || (size_t)n >= buflen)
2004 goto Fail;
2005 pbuf += n;
2006 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002007 }
2008
Tim Petersba873472002-12-18 20:19:21 +00002009 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2010 hours, minutes, seconds);
2011 if (n < 0 || (size_t)n >= buflen)
2012 goto Fail;
2013 pbuf += n;
2014 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002015
2016 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00002017 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2018 if (n < 0 || (size_t)n >= buflen)
2019 goto Fail;
2020 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002021 }
2022
Tim Petersba873472002-12-18 20:19:21 +00002023 return PyString_FromStringAndSize(buf, pbuf - buf);
2024
2025 Fail:
2026 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2027 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002028}
2029
Tim Peters371935f2003-02-01 01:52:50 +00002030/* Pickle support, a simple use of __reduce__. */
2031
Tim Petersb57f8f02003-02-01 02:54:15 +00002032/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002033static PyObject *
2034delta_getstate(PyDateTime_Delta *self)
2035{
2036 return Py_BuildValue("iii", GET_TD_DAYS(self),
2037 GET_TD_SECONDS(self),
2038 GET_TD_MICROSECONDS(self));
2039}
2040
Tim Peters2a799bf2002-12-16 20:18:38 +00002041static PyObject *
2042delta_reduce(PyDateTime_Delta* self)
2043{
Tim Peters8a60c222003-02-01 01:47:29 +00002044 return Py_BuildValue("ON", self->ob_type, delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002045}
2046
2047#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2048
2049static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002050
Neal Norwitzdfb80862002-12-19 02:30:56 +00002051 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002052 PyDoc_STR("Number of days.")},
2053
Neal Norwitzdfb80862002-12-19 02:30:56 +00002054 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002055 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2056
Neal Norwitzdfb80862002-12-19 02:30:56 +00002057 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002058 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2059 {NULL}
2060};
2061
2062static PyMethodDef delta_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002063 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2064 PyDoc_STR("__reduce__() -> (cls, state)")},
2065
Tim Peters2a799bf2002-12-16 20:18:38 +00002066 {NULL, NULL},
2067};
2068
2069static char delta_doc[] =
2070PyDoc_STR("Difference between two datetime values.");
2071
2072static PyNumberMethods delta_as_number = {
2073 delta_add, /* nb_add */
2074 delta_subtract, /* nb_subtract */
2075 delta_multiply, /* nb_multiply */
2076 delta_divide, /* nb_divide */
2077 0, /* nb_remainder */
2078 0, /* nb_divmod */
2079 0, /* nb_power */
2080 (unaryfunc)delta_negative, /* nb_negative */
2081 (unaryfunc)delta_positive, /* nb_positive */
2082 (unaryfunc)delta_abs, /* nb_absolute */
2083 (inquiry)delta_nonzero, /* nb_nonzero */
2084 0, /*nb_invert*/
2085 0, /*nb_lshift*/
2086 0, /*nb_rshift*/
2087 0, /*nb_and*/
2088 0, /*nb_xor*/
2089 0, /*nb_or*/
2090 0, /*nb_coerce*/
2091 0, /*nb_int*/
2092 0, /*nb_long*/
2093 0, /*nb_float*/
2094 0, /*nb_oct*/
2095 0, /*nb_hex*/
2096 0, /*nb_inplace_add*/
2097 0, /*nb_inplace_subtract*/
2098 0, /*nb_inplace_multiply*/
2099 0, /*nb_inplace_divide*/
2100 0, /*nb_inplace_remainder*/
2101 0, /*nb_inplace_power*/
2102 0, /*nb_inplace_lshift*/
2103 0, /*nb_inplace_rshift*/
2104 0, /*nb_inplace_and*/
2105 0, /*nb_inplace_xor*/
2106 0, /*nb_inplace_or*/
2107 delta_divide, /* nb_floor_divide */
2108 0, /* nb_true_divide */
2109 0, /* nb_inplace_floor_divide */
2110 0, /* nb_inplace_true_divide */
2111};
2112
2113static PyTypeObject PyDateTime_DeltaType = {
2114 PyObject_HEAD_INIT(NULL)
2115 0, /* ob_size */
2116 "datetime.timedelta", /* tp_name */
2117 sizeof(PyDateTime_Delta), /* tp_basicsize */
2118 0, /* tp_itemsize */
2119 0, /* tp_dealloc */
2120 0, /* tp_print */
2121 0, /* tp_getattr */
2122 0, /* tp_setattr */
2123 0, /* tp_compare */
2124 (reprfunc)delta_repr, /* tp_repr */
2125 &delta_as_number, /* tp_as_number */
2126 0, /* tp_as_sequence */
2127 0, /* tp_as_mapping */
2128 (hashfunc)delta_hash, /* tp_hash */
2129 0, /* tp_call */
2130 (reprfunc)delta_str, /* tp_str */
2131 PyObject_GenericGetAttr, /* tp_getattro */
2132 0, /* tp_setattro */
2133 0, /* tp_as_buffer */
Tim Petersb0c854d2003-05-17 15:57:00 +00002134 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2135 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters2a799bf2002-12-16 20:18:38 +00002136 delta_doc, /* tp_doc */
2137 0, /* tp_traverse */
2138 0, /* tp_clear */
2139 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2140 0, /* tp_weaklistoffset */
2141 0, /* tp_iter */
2142 0, /* tp_iternext */
2143 delta_methods, /* tp_methods */
2144 delta_members, /* tp_members */
2145 0, /* tp_getset */
2146 0, /* tp_base */
2147 0, /* tp_dict */
2148 0, /* tp_descr_get */
2149 0, /* tp_descr_set */
2150 0, /* tp_dictoffset */
2151 0, /* tp_init */
2152 0, /* tp_alloc */
2153 delta_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002154 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002155};
2156
2157/*
2158 * PyDateTime_Date implementation.
2159 */
2160
2161/* Accessor properties. */
2162
2163static PyObject *
2164date_year(PyDateTime_Date *self, void *unused)
2165{
2166 return PyInt_FromLong(GET_YEAR(self));
2167}
2168
2169static PyObject *
2170date_month(PyDateTime_Date *self, void *unused)
2171{
2172 return PyInt_FromLong(GET_MONTH(self));
2173}
2174
2175static PyObject *
2176date_day(PyDateTime_Date *self, void *unused)
2177{
2178 return PyInt_FromLong(GET_DAY(self));
2179}
2180
2181static PyGetSetDef date_getset[] = {
2182 {"year", (getter)date_year},
2183 {"month", (getter)date_month},
2184 {"day", (getter)date_day},
2185 {NULL}
2186};
2187
2188/* Constructors. */
2189
Tim Peters12bf3392002-12-24 05:41:27 +00002190static char *date_kws[] = {"year", "month", "day", NULL};
2191
Tim Peters2a799bf2002-12-16 20:18:38 +00002192static PyObject *
2193date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2194{
2195 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002196 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002197 int year;
2198 int month;
2199 int day;
2200
Guido van Rossum177e41a2003-01-30 22:06:23 +00002201 /* Check for invocation from pickle with __getstate__ state */
2202 if (PyTuple_GET_SIZE(args) == 1 &&
Tim Peters70533e22003-02-01 04:40:04 +00002203 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
Tim Peters3f606292004-03-21 23:38:41 +00002204 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2205 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00002206 {
Tim Peters70533e22003-02-01 04:40:04 +00002207 PyDateTime_Date *me;
2208
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002209 me = PyObject_New(PyDateTime_Date, type);
Tim Peters70533e22003-02-01 04:40:04 +00002210 if (me != NULL) {
2211 char *pdata = PyString_AS_STRING(state);
2212 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2213 me->hashcode = -1;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002214 }
Tim Peters70533e22003-02-01 04:40:04 +00002215 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002216 }
2217
Tim Peters12bf3392002-12-24 05:41:27 +00002218 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002219 &year, &month, &day)) {
2220 if (check_date_args(year, month, day) < 0)
2221 return NULL;
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002222 self = new_date_ex(year, month, day, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00002223 }
2224 return self;
2225}
2226
2227/* Return new date from localtime(t). */
2228static PyObject *
2229date_local_from_time_t(PyObject *cls, time_t t)
2230{
2231 struct tm *tm;
2232 PyObject *result = NULL;
2233
2234 tm = localtime(&t);
2235 if (tm)
2236 result = PyObject_CallFunction(cls, "iii",
2237 tm->tm_year + 1900,
2238 tm->tm_mon + 1,
2239 tm->tm_mday);
2240 else
2241 PyErr_SetString(PyExc_ValueError,
2242 "timestamp out of range for "
2243 "platform localtime() function");
2244 return result;
2245}
2246
2247/* Return new date from current time.
2248 * We say this is equivalent to fromtimestamp(time.time()), and the
2249 * only way to be sure of that is to *call* time.time(). That's not
2250 * generally the same as calling C's time.
2251 */
2252static PyObject *
2253date_today(PyObject *cls, PyObject *dummy)
2254{
2255 PyObject *time;
2256 PyObject *result;
2257
2258 time = time_time();
2259 if (time == NULL)
2260 return NULL;
2261
2262 /* Note well: today() is a class method, so this may not call
2263 * date.fromtimestamp. For example, it may call
2264 * datetime.fromtimestamp. That's why we need all the accuracy
2265 * time.time() delivers; if someone were gonzo about optimization,
2266 * date.today() could get away with plain C time().
2267 */
2268 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2269 Py_DECREF(time);
2270 return result;
2271}
2272
2273/* Return new date from given timestamp (Python timestamp -- a double). */
2274static PyObject *
2275date_fromtimestamp(PyObject *cls, PyObject *args)
2276{
2277 double timestamp;
2278 PyObject *result = NULL;
2279
2280 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2281 result = date_local_from_time_t(cls, (time_t)timestamp);
2282 return result;
2283}
2284
2285/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2286 * the ordinal is out of range.
2287 */
2288static PyObject *
2289date_fromordinal(PyObject *cls, PyObject *args)
2290{
2291 PyObject *result = NULL;
2292 int ordinal;
2293
2294 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2295 int year;
2296 int month;
2297 int day;
2298
2299 if (ordinal < 1)
2300 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2301 ">= 1");
2302 else {
2303 ord_to_ymd(ordinal, &year, &month, &day);
2304 result = PyObject_CallFunction(cls, "iii",
2305 year, month, day);
2306 }
2307 }
2308 return result;
2309}
2310
2311/*
2312 * Date arithmetic.
2313 */
2314
2315/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2316 * instead.
2317 */
2318static PyObject *
2319add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2320{
2321 PyObject *result = NULL;
2322 int year = GET_YEAR(date);
2323 int month = GET_MONTH(date);
2324 int deltadays = GET_TD_DAYS(delta);
2325 /* C-level overflow is impossible because |deltadays| < 1e9. */
2326 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2327
2328 if (normalize_date(&year, &month, &day) >= 0)
2329 result = new_date(year, month, day);
2330 return result;
2331}
2332
2333static PyObject *
2334date_add(PyObject *left, PyObject *right)
2335{
2336 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2337 Py_INCREF(Py_NotImplemented);
2338 return Py_NotImplemented;
2339 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002340 if (PyDate_Check(left)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002341 /* date + ??? */
2342 if (PyDelta_Check(right))
2343 /* date + delta */
2344 return add_date_timedelta((PyDateTime_Date *) left,
2345 (PyDateTime_Delta *) right,
2346 0);
2347 }
2348 else {
2349 /* ??? + date
2350 * 'right' must be one of us, or we wouldn't have been called
2351 */
2352 if (PyDelta_Check(left))
2353 /* delta + date */
2354 return add_date_timedelta((PyDateTime_Date *) right,
2355 (PyDateTime_Delta *) left,
2356 0);
2357 }
2358 Py_INCREF(Py_NotImplemented);
2359 return Py_NotImplemented;
2360}
2361
2362static PyObject *
2363date_subtract(PyObject *left, PyObject *right)
2364{
2365 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2366 Py_INCREF(Py_NotImplemented);
2367 return Py_NotImplemented;
2368 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002369 if (PyDate_Check(left)) {
2370 if (PyDate_Check(right)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002371 /* date - date */
2372 int left_ord = ymd_to_ord(GET_YEAR(left),
2373 GET_MONTH(left),
2374 GET_DAY(left));
2375 int right_ord = ymd_to_ord(GET_YEAR(right),
2376 GET_MONTH(right),
2377 GET_DAY(right));
2378 return new_delta(left_ord - right_ord, 0, 0, 0);
2379 }
2380 if (PyDelta_Check(right)) {
2381 /* date - delta */
2382 return add_date_timedelta((PyDateTime_Date *) left,
2383 (PyDateTime_Delta *) right,
2384 1);
2385 }
2386 }
2387 Py_INCREF(Py_NotImplemented);
2388 return Py_NotImplemented;
2389}
2390
2391
2392/* Various ways to turn a date into a string. */
2393
2394static PyObject *
2395date_repr(PyDateTime_Date *self)
2396{
2397 char buffer[1028];
2398 char *typename;
2399
2400 typename = self->ob_type->tp_name;
2401 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2402 typename,
2403 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2404
2405 return PyString_FromString(buffer);
2406}
2407
2408static PyObject *
2409date_isoformat(PyDateTime_Date *self)
2410{
2411 char buffer[128];
2412
2413 isoformat_date(self, buffer, sizeof(buffer));
2414 return PyString_FromString(buffer);
2415}
2416
Tim Peterse2df5ff2003-05-02 18:39:55 +00002417/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002418static PyObject *
2419date_str(PyDateTime_Date *self)
2420{
2421 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2422}
2423
2424
2425static PyObject *
2426date_ctime(PyDateTime_Date *self)
2427{
2428 return format_ctime(self, 0, 0, 0);
2429}
2430
2431static PyObject *
2432date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2433{
2434 /* This method can be inherited, and needs to call the
2435 * timetuple() method appropriate to self's class.
2436 */
2437 PyObject *result;
2438 PyObject *format;
2439 PyObject *tuple;
2440 static char *keywords[] = {"format", NULL};
2441
2442 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2443 &PyString_Type, &format))
2444 return NULL;
2445
2446 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2447 if (tuple == NULL)
2448 return NULL;
Tim Petersbad8ff02002-12-30 20:52:32 +00002449 result = wrap_strftime((PyObject *)self, format, tuple,
2450 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002451 Py_DECREF(tuple);
2452 return result;
2453}
2454
2455/* ISO methods. */
2456
2457static PyObject *
2458date_isoweekday(PyDateTime_Date *self)
2459{
2460 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2461
2462 return PyInt_FromLong(dow + 1);
2463}
2464
2465static PyObject *
2466date_isocalendar(PyDateTime_Date *self)
2467{
2468 int year = GET_YEAR(self);
2469 int week1_monday = iso_week1_monday(year);
2470 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2471 int week;
2472 int day;
2473
2474 week = divmod(today - week1_monday, 7, &day);
2475 if (week < 0) {
2476 --year;
2477 week1_monday = iso_week1_monday(year);
2478 week = divmod(today - week1_monday, 7, &day);
2479 }
2480 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2481 ++year;
2482 week = 0;
2483 }
2484 return Py_BuildValue("iii", year, week + 1, day + 1);
2485}
2486
2487/* Miscellaneous methods. */
2488
2489/* This is more natural as a tp_compare, but doesn't work then: for whatever
2490 * reason, Python's try_3way_compare ignores tp_compare unless
2491 * PyInstance_Check returns true, but these aren't old-style classes.
2492 */
2493static PyObject *
2494date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2495{
Tim Peters07534a62003-02-07 22:50:28 +00002496 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002497
Tim Peters07534a62003-02-07 22:50:28 +00002498 if (PyDate_Check(other))
2499 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2500 _PyDateTime_DATE_DATASIZE);
2501
2502 else if (PyObject_HasAttrString(other, "timetuple")) {
2503 /* A hook for other kinds of date objects. */
2504 Py_INCREF(Py_NotImplemented);
2505 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002506 }
Tim Peters07534a62003-02-07 22:50:28 +00002507 else if (op == Py_EQ || op == Py_NE)
2508 diff = 1; /* any non-zero value will do */
2509
2510 else /* stop this from falling back to address comparison */
2511 return cmperror((PyObject *)self, other);
2512
Tim Peters2a799bf2002-12-16 20:18:38 +00002513 return diff_to_bool(diff, op);
2514}
2515
2516static PyObject *
2517date_timetuple(PyDateTime_Date *self)
2518{
2519 return build_struct_time(GET_YEAR(self),
2520 GET_MONTH(self),
2521 GET_DAY(self),
2522 0, 0, 0, -1);
2523}
2524
Tim Peters12bf3392002-12-24 05:41:27 +00002525static PyObject *
2526date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2527{
2528 PyObject *clone;
2529 PyObject *tuple;
2530 int year = GET_YEAR(self);
2531 int month = GET_MONTH(self);
2532 int day = GET_DAY(self);
2533
2534 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2535 &year, &month, &day))
2536 return NULL;
2537 tuple = Py_BuildValue("iii", year, month, day);
2538 if (tuple == NULL)
2539 return NULL;
2540 clone = date_new(self->ob_type, tuple, NULL);
2541 Py_DECREF(tuple);
2542 return clone;
2543}
2544
Tim Peters2a799bf2002-12-16 20:18:38 +00002545static PyObject *date_getstate(PyDateTime_Date *self);
2546
2547static long
2548date_hash(PyDateTime_Date *self)
2549{
2550 if (self->hashcode == -1) {
2551 PyObject *temp = date_getstate(self);
2552 if (temp != NULL) {
2553 self->hashcode = PyObject_Hash(temp);
2554 Py_DECREF(temp);
2555 }
2556 }
2557 return self->hashcode;
2558}
2559
2560static PyObject *
2561date_toordinal(PyDateTime_Date *self)
2562{
2563 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2564 GET_DAY(self)));
2565}
2566
2567static PyObject *
2568date_weekday(PyDateTime_Date *self)
2569{
2570 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2571
2572 return PyInt_FromLong(dow);
2573}
2574
Tim Peters371935f2003-02-01 01:52:50 +00002575/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002576
Tim Petersb57f8f02003-02-01 02:54:15 +00002577/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002578static PyObject *
2579date_getstate(PyDateTime_Date *self)
2580{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002581 return Py_BuildValue(
2582 "(N)",
2583 PyString_FromStringAndSize((char *)self->data,
2584 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002585}
2586
2587static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002588date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002589{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002590 return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002591}
2592
2593static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002594
Tim Peters2a799bf2002-12-16 20:18:38 +00002595 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002596
Tim Peters2a799bf2002-12-16 20:18:38 +00002597 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2598 METH_CLASS,
2599 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2600 "time.time()).")},
2601
2602 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2603 METH_CLASS,
2604 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2605 "ordinal.")},
2606
2607 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2608 PyDoc_STR("Current date or datetime: same as "
2609 "self.__class__.fromtimestamp(time.time()).")},
2610
2611 /* Instance methods: */
2612
2613 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2614 PyDoc_STR("Return ctime() style string.")},
2615
2616 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2617 PyDoc_STR("format -> strftime() style string.")},
2618
2619 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2620 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2621
2622 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2623 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2624 "weekday.")},
2625
2626 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2627 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2628
2629 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2630 PyDoc_STR("Return the day of the week represented by the date.\n"
2631 "Monday == 1 ... Sunday == 7")},
2632
2633 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2634 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2635 "1 is day 1.")},
2636
2637 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2638 PyDoc_STR("Return the day of the week represented by the date.\n"
2639 "Monday == 0 ... Sunday == 6")},
2640
Tim Peters12bf3392002-12-24 05:41:27 +00002641 {"replace", (PyCFunction)date_replace, METH_KEYWORDS,
2642 PyDoc_STR("Return date with new specified fields.")},
2643
Guido van Rossum177e41a2003-01-30 22:06:23 +00002644 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2645 PyDoc_STR("__reduce__() -> (cls, state)")},
2646
Tim Peters2a799bf2002-12-16 20:18:38 +00002647 {NULL, NULL}
2648};
2649
2650static char date_doc[] =
2651PyDoc_STR("Basic date type.");
2652
2653static PyNumberMethods date_as_number = {
2654 date_add, /* nb_add */
2655 date_subtract, /* nb_subtract */
2656 0, /* nb_multiply */
2657 0, /* nb_divide */
2658 0, /* nb_remainder */
2659 0, /* nb_divmod */
2660 0, /* nb_power */
2661 0, /* nb_negative */
2662 0, /* nb_positive */
2663 0, /* nb_absolute */
2664 0, /* nb_nonzero */
2665};
2666
2667static PyTypeObject PyDateTime_DateType = {
2668 PyObject_HEAD_INIT(NULL)
2669 0, /* ob_size */
2670 "datetime.date", /* tp_name */
2671 sizeof(PyDateTime_Date), /* tp_basicsize */
2672 0, /* tp_itemsize */
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002673 0, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00002674 0, /* tp_print */
2675 0, /* tp_getattr */
2676 0, /* tp_setattr */
2677 0, /* tp_compare */
2678 (reprfunc)date_repr, /* tp_repr */
2679 &date_as_number, /* tp_as_number */
2680 0, /* tp_as_sequence */
2681 0, /* tp_as_mapping */
2682 (hashfunc)date_hash, /* tp_hash */
2683 0, /* tp_call */
2684 (reprfunc)date_str, /* tp_str */
2685 PyObject_GenericGetAttr, /* tp_getattro */
2686 0, /* tp_setattro */
2687 0, /* tp_as_buffer */
2688 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2689 Py_TPFLAGS_BASETYPE, /* tp_flags */
2690 date_doc, /* tp_doc */
2691 0, /* tp_traverse */
2692 0, /* tp_clear */
2693 (richcmpfunc)date_richcompare, /* tp_richcompare */
2694 0, /* tp_weaklistoffset */
2695 0, /* tp_iter */
2696 0, /* tp_iternext */
2697 date_methods, /* tp_methods */
2698 0, /* tp_members */
2699 date_getset, /* tp_getset */
2700 0, /* tp_base */
2701 0, /* tp_dict */
2702 0, /* tp_descr_get */
2703 0, /* tp_descr_set */
2704 0, /* tp_dictoffset */
2705 0, /* tp_init */
2706 0, /* tp_alloc */
2707 date_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002708 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002709};
2710
2711/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002712 * PyDateTime_TZInfo implementation.
2713 */
2714
2715/* This is a pure abstract base class, so doesn't do anything beyond
2716 * raising NotImplemented exceptions. Real tzinfo classes need
2717 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002718 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002719 * be subclasses of this tzinfo class, which is easy and quick to check).
2720 *
2721 * Note: For reasons having to do with pickling of subclasses, we have
2722 * to allow tzinfo objects to be instantiated. This wasn't an issue
2723 * in the Python implementation (__init__() could raise NotImplementedError
2724 * there without ill effect), but doing so in the C implementation hit a
2725 * brick wall.
2726 */
2727
2728static PyObject *
2729tzinfo_nogo(const char* methodname)
2730{
2731 PyErr_Format(PyExc_NotImplementedError,
2732 "a tzinfo subclass must implement %s()",
2733 methodname);
2734 return NULL;
2735}
2736
2737/* Methods. A subclass must implement these. */
2738
Tim Peters52dcce22003-01-23 16:36:11 +00002739static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002740tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2741{
2742 return tzinfo_nogo("tzname");
2743}
2744
Tim Peters52dcce22003-01-23 16:36:11 +00002745static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002746tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2747{
2748 return tzinfo_nogo("utcoffset");
2749}
2750
Tim Peters52dcce22003-01-23 16:36:11 +00002751static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002752tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2753{
2754 return tzinfo_nogo("dst");
2755}
2756
Tim Peters52dcce22003-01-23 16:36:11 +00002757static PyObject *
2758tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2759{
2760 int y, m, d, hh, mm, ss, us;
2761
2762 PyObject *result;
2763 int off, dst;
2764 int none;
2765 int delta;
2766
2767 if (! PyDateTime_Check(dt)) {
2768 PyErr_SetString(PyExc_TypeError,
2769 "fromutc: argument must be a datetime");
2770 return NULL;
2771 }
2772 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2773 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2774 "is not self");
2775 return NULL;
2776 }
2777
2778 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2779 if (off == -1 && PyErr_Occurred())
2780 return NULL;
2781 if (none) {
2782 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2783 "utcoffset() result required");
2784 return NULL;
2785 }
2786
2787 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2788 if (dst == -1 && PyErr_Occurred())
2789 return NULL;
2790 if (none) {
2791 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2792 "dst() result required");
2793 return NULL;
2794 }
2795
2796 y = GET_YEAR(dt);
2797 m = GET_MONTH(dt);
2798 d = GET_DAY(dt);
2799 hh = DATE_GET_HOUR(dt);
2800 mm = DATE_GET_MINUTE(dt);
2801 ss = DATE_GET_SECOND(dt);
2802 us = DATE_GET_MICROSECOND(dt);
2803
2804 delta = off - dst;
2805 mm += delta;
2806 if ((mm < 0 || mm >= 60) &&
2807 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002808 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002809 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2810 if (result == NULL)
2811 return result;
2812
2813 dst = call_dst(dt->tzinfo, result, &none);
2814 if (dst == -1 && PyErr_Occurred())
2815 goto Fail;
2816 if (none)
2817 goto Inconsistent;
2818 if (dst == 0)
2819 return result;
2820
2821 mm += dst;
2822 if ((mm < 0 || mm >= 60) &&
2823 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2824 goto Fail;
2825 Py_DECREF(result);
2826 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2827 return result;
2828
2829Inconsistent:
2830 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2831 "inconsistent results; cannot convert");
2832
2833 /* fall thru to failure */
2834Fail:
2835 Py_DECREF(result);
2836 return NULL;
2837}
2838
Tim Peters2a799bf2002-12-16 20:18:38 +00002839/*
2840 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002841 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002842 */
2843
Guido van Rossum177e41a2003-01-30 22:06:23 +00002844static PyObject *
2845tzinfo_reduce(PyObject *self)
2846{
2847 PyObject *args, *state, *tmp;
2848 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002849
Guido van Rossum177e41a2003-01-30 22:06:23 +00002850 tmp = PyTuple_New(0);
2851 if (tmp == NULL)
2852 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002853
Guido van Rossum177e41a2003-01-30 22:06:23 +00002854 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2855 if (getinitargs != NULL) {
2856 args = PyObject_CallObject(getinitargs, tmp);
2857 Py_DECREF(getinitargs);
2858 if (args == NULL) {
2859 Py_DECREF(tmp);
2860 return NULL;
2861 }
2862 }
2863 else {
2864 PyErr_Clear();
2865 args = tmp;
2866 Py_INCREF(args);
2867 }
2868
2869 getstate = PyObject_GetAttrString(self, "__getstate__");
2870 if (getstate != NULL) {
2871 state = PyObject_CallObject(getstate, tmp);
2872 Py_DECREF(getstate);
2873 if (state == NULL) {
2874 Py_DECREF(args);
2875 Py_DECREF(tmp);
2876 return NULL;
2877 }
2878 }
2879 else {
2880 PyObject **dictptr;
2881 PyErr_Clear();
2882 state = Py_None;
2883 dictptr = _PyObject_GetDictPtr(self);
2884 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2885 state = *dictptr;
2886 Py_INCREF(state);
2887 }
2888
2889 Py_DECREF(tmp);
2890
2891 if (state == Py_None) {
2892 Py_DECREF(state);
2893 return Py_BuildValue("(ON)", self->ob_type, args);
2894 }
2895 else
2896 return Py_BuildValue("(ONN)", self->ob_type, args, state);
2897}
Tim Peters2a799bf2002-12-16 20:18:38 +00002898
2899static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002900
Tim Peters2a799bf2002-12-16 20:18:38 +00002901 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2902 PyDoc_STR("datetime -> string name of time zone.")},
2903
2904 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2905 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2906 "west of UTC).")},
2907
2908 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2909 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2910
Tim Peters52dcce22003-01-23 16:36:11 +00002911 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2912 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2913
Guido van Rossum177e41a2003-01-30 22:06:23 +00002914 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2915 PyDoc_STR("-> (cls, state)")},
2916
Tim Peters2a799bf2002-12-16 20:18:38 +00002917 {NULL, NULL}
2918};
2919
2920static char tzinfo_doc[] =
2921PyDoc_STR("Abstract base class for time zone info objects.");
2922
Neal Norwitzce3d34d2003-02-04 20:45:17 +00002923statichere PyTypeObject PyDateTime_TZInfoType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00002924 PyObject_HEAD_INIT(NULL)
2925 0, /* ob_size */
2926 "datetime.tzinfo", /* tp_name */
2927 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2928 0, /* tp_itemsize */
2929 0, /* tp_dealloc */
2930 0, /* tp_print */
2931 0, /* tp_getattr */
2932 0, /* tp_setattr */
2933 0, /* tp_compare */
2934 0, /* tp_repr */
2935 0, /* tp_as_number */
2936 0, /* tp_as_sequence */
2937 0, /* tp_as_mapping */
2938 0, /* tp_hash */
2939 0, /* tp_call */
2940 0, /* tp_str */
2941 PyObject_GenericGetAttr, /* tp_getattro */
2942 0, /* tp_setattro */
2943 0, /* tp_as_buffer */
2944 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2945 Py_TPFLAGS_BASETYPE, /* tp_flags */
2946 tzinfo_doc, /* tp_doc */
2947 0, /* tp_traverse */
2948 0, /* tp_clear */
2949 0, /* tp_richcompare */
2950 0, /* tp_weaklistoffset */
2951 0, /* tp_iter */
2952 0, /* tp_iternext */
2953 tzinfo_methods, /* tp_methods */
2954 0, /* tp_members */
2955 0, /* tp_getset */
2956 0, /* tp_base */
2957 0, /* tp_dict */
2958 0, /* tp_descr_get */
2959 0, /* tp_descr_set */
2960 0, /* tp_dictoffset */
2961 0, /* tp_init */
2962 0, /* tp_alloc */
2963 PyType_GenericNew, /* tp_new */
2964 0, /* tp_free */
2965};
2966
2967/*
Tim Peters37f39822003-01-10 03:49:02 +00002968 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00002969 */
2970
Tim Peters37f39822003-01-10 03:49:02 +00002971/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00002972 */
2973
2974static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002975time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00002976{
Tim Peters37f39822003-01-10 03:49:02 +00002977 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002978}
2979
Tim Peters37f39822003-01-10 03:49:02 +00002980static PyObject *
2981time_minute(PyDateTime_Time *self, void *unused)
2982{
2983 return PyInt_FromLong(TIME_GET_MINUTE(self));
2984}
2985
2986/* The name time_second conflicted with some platform header file. */
2987static PyObject *
2988py_time_second(PyDateTime_Time *self, void *unused)
2989{
2990 return PyInt_FromLong(TIME_GET_SECOND(self));
2991}
2992
2993static PyObject *
2994time_microsecond(PyDateTime_Time *self, void *unused)
2995{
2996 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
2997}
2998
2999static PyObject *
3000time_tzinfo(PyDateTime_Time *self, void *unused)
3001{
Tim Petersa032d2e2003-01-11 00:15:54 +00003002 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00003003 Py_INCREF(result);
3004 return result;
3005}
3006
3007static PyGetSetDef time_getset[] = {
3008 {"hour", (getter)time_hour},
3009 {"minute", (getter)time_minute},
3010 {"second", (getter)py_time_second},
3011 {"microsecond", (getter)time_microsecond},
3012 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003013 {NULL}
3014};
3015
3016/*
3017 * Constructors.
3018 */
3019
Tim Peters37f39822003-01-10 03:49:02 +00003020static char *time_kws[] = {"hour", "minute", "second", "microsecond",
3021 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003022
Tim Peters2a799bf2002-12-16 20:18:38 +00003023static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003024time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003025{
3026 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003027 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003028 int hour = 0;
3029 int minute = 0;
3030 int second = 0;
3031 int usecond = 0;
3032 PyObject *tzinfo = Py_None;
3033
Guido van Rossum177e41a2003-01-30 22:06:23 +00003034 /* Check for invocation from pickle with __getstate__ state */
3035 if (PyTuple_GET_SIZE(args) >= 1 &&
3036 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00003037 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3038 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003039 {
Tim Peters70533e22003-02-01 04:40:04 +00003040 PyDateTime_Time *me;
3041 char aware;
3042
3043 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003044 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003045 if (check_tzinfo_subclass(tzinfo) < 0) {
3046 PyErr_SetString(PyExc_TypeError, "bad "
3047 "tzinfo state arg");
3048 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003049 }
3050 }
Tim Peters70533e22003-02-01 04:40:04 +00003051 aware = (char)(tzinfo != Py_None);
Tim Petersa98924a2003-05-17 05:55:19 +00003052 me = (PyDateTime_Time *) time_alloc(&PyDateTime_TimeType,
3053 aware);
Tim Peters70533e22003-02-01 04:40:04 +00003054 if (me != NULL) {
3055 char *pdata = PyString_AS_STRING(state);
3056
3057 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3058 me->hashcode = -1;
3059 me->hastzinfo = aware;
3060 if (aware) {
3061 Py_INCREF(tzinfo);
3062 me->tzinfo = tzinfo;
3063 }
3064 }
3065 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003066 }
3067
Tim Peters37f39822003-01-10 03:49:02 +00003068 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003069 &hour, &minute, &second, &usecond,
3070 &tzinfo)) {
3071 if (check_time_args(hour, minute, second, usecond) < 0)
3072 return NULL;
3073 if (check_tzinfo_subclass(tzinfo) < 0)
3074 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003075 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3076 type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003077 }
3078 return self;
3079}
3080
3081/*
3082 * Destructor.
3083 */
3084
3085static void
Tim Peters37f39822003-01-10 03:49:02 +00003086time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003087{
Tim Petersa032d2e2003-01-11 00:15:54 +00003088 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003089 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003090 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003091 self->ob_type->tp_free((PyObject *)self);
3092}
3093
3094/*
Tim Peters855fe882002-12-22 03:43:39 +00003095 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003096 */
3097
Tim Peters2a799bf2002-12-16 20:18:38 +00003098/* These are all METH_NOARGS, so don't need to check the arglist. */
3099static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003100time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003101 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003102 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003103}
3104
3105static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003106time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003107 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003108 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003109}
3110
3111static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003112time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003113 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003114 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003115}
3116
3117/*
Tim Peters37f39822003-01-10 03:49:02 +00003118 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003119 */
3120
3121static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003122time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003123{
Tim Peters37f39822003-01-10 03:49:02 +00003124 char buffer[100];
3125 char *typename = self->ob_type->tp_name;
3126 int h = TIME_GET_HOUR(self);
3127 int m = TIME_GET_MINUTE(self);
3128 int s = TIME_GET_SECOND(self);
3129 int us = TIME_GET_MICROSECOND(self);
3130 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003131
Tim Peters37f39822003-01-10 03:49:02 +00003132 if (us)
3133 PyOS_snprintf(buffer, sizeof(buffer),
3134 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3135 else if (s)
3136 PyOS_snprintf(buffer, sizeof(buffer),
3137 "%s(%d, %d, %d)", typename, h, m, s);
3138 else
3139 PyOS_snprintf(buffer, sizeof(buffer),
3140 "%s(%d, %d)", typename, h, m);
3141 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003142 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003143 result = append_keyword_tzinfo(result, self->tzinfo);
3144 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003145}
3146
Tim Peters37f39822003-01-10 03:49:02 +00003147static PyObject *
3148time_str(PyDateTime_Time *self)
3149{
3150 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3151}
Tim Peters2a799bf2002-12-16 20:18:38 +00003152
3153static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003154time_isoformat(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003155{
3156 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003157 PyObject *result;
3158 /* Reuse the time format code from the datetime type. */
3159 PyDateTime_DateTime datetime;
3160 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003161
Tim Peters37f39822003-01-10 03:49:02 +00003162 /* Copy over just the time bytes. */
3163 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3164 self->data,
3165 _PyDateTime_TIME_DATASIZE);
3166
3167 isoformat_time(pdatetime, buf, sizeof(buf));
3168 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003169 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003170 return result;
3171
3172 /* We need to append the UTC offset. */
3173 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003174 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003175 Py_DECREF(result);
3176 return NULL;
3177 }
3178 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3179 return result;
3180}
3181
Tim Peters37f39822003-01-10 03:49:02 +00003182static PyObject *
3183time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3184{
3185 PyObject *result;
3186 PyObject *format;
3187 PyObject *tuple;
3188 static char *keywords[] = {"format", NULL};
3189
3190 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3191 &PyString_Type, &format))
3192 return NULL;
3193
3194 /* Python's strftime does insane things with the year part of the
3195 * timetuple. The year is forced to (the otherwise nonsensical)
3196 * 1900 to worm around that.
3197 */
3198 tuple = Py_BuildValue("iiiiiiiii",
Brett Cannond1080a32004-03-02 04:38:10 +00003199 1900, 1, 1, /* year, month, day */
Tim Peters37f39822003-01-10 03:49:02 +00003200 TIME_GET_HOUR(self),
3201 TIME_GET_MINUTE(self),
3202 TIME_GET_SECOND(self),
Brett Cannond1080a32004-03-02 04:38:10 +00003203 0, 1, -1); /* weekday, daynum, dst */
Tim Peters37f39822003-01-10 03:49:02 +00003204 if (tuple == NULL)
3205 return NULL;
3206 assert(PyTuple_Size(tuple) == 9);
3207 result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
3208 Py_DECREF(tuple);
3209 return result;
3210}
Tim Peters2a799bf2002-12-16 20:18:38 +00003211
3212/*
3213 * Miscellaneous methods.
3214 */
3215
Tim Peters37f39822003-01-10 03:49:02 +00003216/* This is more natural as a tp_compare, but doesn't work then: for whatever
3217 * reason, Python's try_3way_compare ignores tp_compare unless
3218 * PyInstance_Check returns true, but these aren't old-style classes.
3219 */
3220static PyObject *
3221time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3222{
3223 int diff;
3224 naivety n1, n2;
3225 int offset1, offset2;
3226
3227 if (! PyTime_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00003228 if (op == Py_EQ || op == Py_NE) {
3229 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3230 Py_INCREF(result);
3231 return result;
3232 }
Tim Peters37f39822003-01-10 03:49:02 +00003233 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00003234 return cmperror((PyObject *)self, other);
Tim Peters37f39822003-01-10 03:49:02 +00003235 }
3236 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3237 other, &offset2, &n2, Py_None) < 0)
3238 return NULL;
3239 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3240 /* If they're both naive, or both aware and have the same offsets,
3241 * we get off cheap. Note that if they're both naive, offset1 ==
3242 * offset2 == 0 at this point.
3243 */
3244 if (n1 == n2 && offset1 == offset2) {
3245 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3246 _PyDateTime_TIME_DATASIZE);
3247 return diff_to_bool(diff, op);
3248 }
3249
3250 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3251 assert(offset1 != offset2); /* else last "if" handled it */
3252 /* Convert everything except microseconds to seconds. These
3253 * can't overflow (no more than the # of seconds in 2 days).
3254 */
3255 offset1 = TIME_GET_HOUR(self) * 3600 +
3256 (TIME_GET_MINUTE(self) - offset1) * 60 +
3257 TIME_GET_SECOND(self);
3258 offset2 = TIME_GET_HOUR(other) * 3600 +
3259 (TIME_GET_MINUTE(other) - offset2) * 60 +
3260 TIME_GET_SECOND(other);
3261 diff = offset1 - offset2;
3262 if (diff == 0)
3263 diff = TIME_GET_MICROSECOND(self) -
3264 TIME_GET_MICROSECOND(other);
3265 return diff_to_bool(diff, op);
3266 }
3267
3268 assert(n1 != n2);
3269 PyErr_SetString(PyExc_TypeError,
3270 "can't compare offset-naive and "
3271 "offset-aware times");
3272 return NULL;
3273}
3274
3275static long
3276time_hash(PyDateTime_Time *self)
3277{
3278 if (self->hashcode == -1) {
3279 naivety n;
3280 int offset;
3281 PyObject *temp;
3282
3283 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3284 assert(n != OFFSET_UNKNOWN);
3285 if (n == OFFSET_ERROR)
3286 return -1;
3287
3288 /* Reduce this to a hash of another object. */
3289 if (offset == 0)
3290 temp = PyString_FromStringAndSize((char *)self->data,
3291 _PyDateTime_TIME_DATASIZE);
3292 else {
3293 int hour;
3294 int minute;
3295
3296 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003297 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003298 hour = divmod(TIME_GET_HOUR(self) * 60 +
3299 TIME_GET_MINUTE(self) - offset,
3300 60,
3301 &minute);
3302 if (0 <= hour && hour < 24)
3303 temp = new_time(hour, minute,
3304 TIME_GET_SECOND(self),
3305 TIME_GET_MICROSECOND(self),
3306 Py_None);
3307 else
3308 temp = Py_BuildValue("iiii",
3309 hour, minute,
3310 TIME_GET_SECOND(self),
3311 TIME_GET_MICROSECOND(self));
3312 }
3313 if (temp != NULL) {
3314 self->hashcode = PyObject_Hash(temp);
3315 Py_DECREF(temp);
3316 }
3317 }
3318 return self->hashcode;
3319}
Tim Peters2a799bf2002-12-16 20:18:38 +00003320
Tim Peters12bf3392002-12-24 05:41:27 +00003321static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003322time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003323{
3324 PyObject *clone;
3325 PyObject *tuple;
3326 int hh = TIME_GET_HOUR(self);
3327 int mm = TIME_GET_MINUTE(self);
3328 int ss = TIME_GET_SECOND(self);
3329 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003330 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003331
3332 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003333 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003334 &hh, &mm, &ss, &us, &tzinfo))
3335 return NULL;
3336 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3337 if (tuple == NULL)
3338 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003339 clone = time_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003340 Py_DECREF(tuple);
3341 return clone;
3342}
3343
Tim Peters2a799bf2002-12-16 20:18:38 +00003344static int
Tim Peters37f39822003-01-10 03:49:02 +00003345time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003346{
3347 int offset;
3348 int none;
3349
3350 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3351 /* Since utcoffset is in whole minutes, nothing can
3352 * alter the conclusion that this is nonzero.
3353 */
3354 return 1;
3355 }
3356 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003357 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003358 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003359 if (offset == -1 && PyErr_Occurred())
3360 return -1;
3361 }
3362 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3363}
3364
Tim Peters371935f2003-02-01 01:52:50 +00003365/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003366
Tim Peters33e0f382003-01-10 02:05:14 +00003367/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003368 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3369 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003370 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003371 */
3372static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003373time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003374{
3375 PyObject *basestate;
3376 PyObject *result = NULL;
3377
Tim Peters33e0f382003-01-10 02:05:14 +00003378 basestate = PyString_FromStringAndSize((char *)self->data,
3379 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003380 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003381 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003382 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00003383 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003384 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003385 Py_DECREF(basestate);
3386 }
3387 return result;
3388}
3389
3390static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003391time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003392{
Guido van Rossum177e41a2003-01-30 22:06:23 +00003393 return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003394}
3395
Tim Peters37f39822003-01-10 03:49:02 +00003396static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003397
Tim Peters37f39822003-01-10 03:49:02 +00003398 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003399 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3400 "[+HH:MM].")},
3401
Tim Peters37f39822003-01-10 03:49:02 +00003402 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3403 PyDoc_STR("format -> strftime() style string.")},
3404
3405 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003406 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3407
Tim Peters37f39822003-01-10 03:49:02 +00003408 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003409 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3410
Tim Peters37f39822003-01-10 03:49:02 +00003411 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003412 PyDoc_STR("Return self.tzinfo.dst(self).")},
3413
Tim Peters37f39822003-01-10 03:49:02 +00003414 {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
3415 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003416
Guido van Rossum177e41a2003-01-30 22:06:23 +00003417 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3418 PyDoc_STR("__reduce__() -> (cls, state)")},
3419
Tim Peters2a799bf2002-12-16 20:18:38 +00003420 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003421};
3422
Tim Peters37f39822003-01-10 03:49:02 +00003423static char time_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003424PyDoc_STR("Time type.");
3425
Tim Peters37f39822003-01-10 03:49:02 +00003426static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003427 0, /* nb_add */
3428 0, /* nb_subtract */
3429 0, /* nb_multiply */
3430 0, /* nb_divide */
3431 0, /* nb_remainder */
3432 0, /* nb_divmod */
3433 0, /* nb_power */
3434 0, /* nb_negative */
3435 0, /* nb_positive */
3436 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003437 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003438};
3439
Tim Peters37f39822003-01-10 03:49:02 +00003440statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003441 PyObject_HEAD_INIT(NULL)
3442 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003443 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003444 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003445 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003446 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003447 0, /* tp_print */
3448 0, /* tp_getattr */
3449 0, /* tp_setattr */
3450 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003451 (reprfunc)time_repr, /* tp_repr */
3452 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003453 0, /* tp_as_sequence */
3454 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003455 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003456 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003457 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003458 PyObject_GenericGetAttr, /* tp_getattro */
3459 0, /* tp_setattro */
3460 0, /* tp_as_buffer */
3461 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3462 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003463 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003464 0, /* tp_traverse */
3465 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003466 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003467 0, /* tp_weaklistoffset */
3468 0, /* tp_iter */
3469 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003470 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003471 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003472 time_getset, /* tp_getset */
3473 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003474 0, /* tp_dict */
3475 0, /* tp_descr_get */
3476 0, /* tp_descr_set */
3477 0, /* tp_dictoffset */
3478 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00003479 time_alloc, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003480 time_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00003481 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003482};
3483
3484/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003485 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003486 */
3487
Tim Petersa9bc1682003-01-11 03:39:11 +00003488/* Accessor properties. Properties for day, month, and year are inherited
3489 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003490 */
3491
3492static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003493datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003494{
Tim Petersa9bc1682003-01-11 03:39:11 +00003495 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003496}
3497
Tim Petersa9bc1682003-01-11 03:39:11 +00003498static PyObject *
3499datetime_minute(PyDateTime_DateTime *self, void *unused)
3500{
3501 return PyInt_FromLong(DATE_GET_MINUTE(self));
3502}
3503
3504static PyObject *
3505datetime_second(PyDateTime_DateTime *self, void *unused)
3506{
3507 return PyInt_FromLong(DATE_GET_SECOND(self));
3508}
3509
3510static PyObject *
3511datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3512{
3513 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3514}
3515
3516static PyObject *
3517datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3518{
3519 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3520 Py_INCREF(result);
3521 return result;
3522}
3523
3524static PyGetSetDef datetime_getset[] = {
3525 {"hour", (getter)datetime_hour},
3526 {"minute", (getter)datetime_minute},
3527 {"second", (getter)datetime_second},
3528 {"microsecond", (getter)datetime_microsecond},
3529 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003530 {NULL}
3531};
3532
3533/*
3534 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003535 */
3536
Tim Petersa9bc1682003-01-11 03:39:11 +00003537static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003538 "year", "month", "day", "hour", "minute", "second",
3539 "microsecond", "tzinfo", NULL
3540};
3541
Tim Peters2a799bf2002-12-16 20:18:38 +00003542static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003543datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003544{
3545 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003546 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003547 int year;
3548 int month;
3549 int day;
3550 int hour = 0;
3551 int minute = 0;
3552 int second = 0;
3553 int usecond = 0;
3554 PyObject *tzinfo = Py_None;
3555
Guido van Rossum177e41a2003-01-30 22:06:23 +00003556 /* Check for invocation from pickle with __getstate__ state */
3557 if (PyTuple_GET_SIZE(args) >= 1 &&
3558 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00003559 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
Tim Peters3f606292004-03-21 23:38:41 +00003560 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3561 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003562 {
Tim Peters70533e22003-02-01 04:40:04 +00003563 PyDateTime_DateTime *me;
3564 char aware;
3565
3566 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003567 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003568 if (check_tzinfo_subclass(tzinfo) < 0) {
3569 PyErr_SetString(PyExc_TypeError, "bad "
3570 "tzinfo state arg");
3571 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003572 }
3573 }
Tim Peters70533e22003-02-01 04:40:04 +00003574 aware = (char)(tzinfo != Py_None);
Tim Petersa98924a2003-05-17 05:55:19 +00003575 me = (PyDateTime_DateTime *) datetime_alloc(
3576 &PyDateTime_DateTimeType,
3577 aware);
Tim Peters70533e22003-02-01 04:40:04 +00003578 if (me != NULL) {
3579 char *pdata = PyString_AS_STRING(state);
3580
3581 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3582 me->hashcode = -1;
3583 me->hastzinfo = aware;
3584 if (aware) {
3585 Py_INCREF(tzinfo);
3586 me->tzinfo = tzinfo;
3587 }
3588 }
3589 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003590 }
3591
Tim Petersa9bc1682003-01-11 03:39:11 +00003592 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003593 &year, &month, &day, &hour, &minute,
3594 &second, &usecond, &tzinfo)) {
3595 if (check_date_args(year, month, day) < 0)
3596 return NULL;
3597 if (check_time_args(hour, minute, second, usecond) < 0)
3598 return NULL;
3599 if (check_tzinfo_subclass(tzinfo) < 0)
3600 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003601 self = new_datetime_ex(year, month, day,
3602 hour, minute, second, usecond,
3603 tzinfo, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003604 }
3605 return self;
3606}
3607
Tim Petersa9bc1682003-01-11 03:39:11 +00003608/* TM_FUNC is the shared type of localtime() and gmtime(). */
3609typedef struct tm *(*TM_FUNC)(const time_t *timer);
3610
3611/* Internal helper.
3612 * Build datetime from a time_t and a distinct count of microseconds.
3613 * Pass localtime or gmtime for f, to control the interpretation of timet.
3614 */
3615static PyObject *
3616datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3617 PyObject *tzinfo)
3618{
3619 struct tm *tm;
3620 PyObject *result = NULL;
3621
3622 tm = f(&timet);
3623 if (tm) {
3624 /* The platform localtime/gmtime may insert leap seconds,
3625 * indicated by tm->tm_sec > 59. We don't care about them,
3626 * except to the extent that passing them on to the datetime
3627 * constructor would raise ValueError for a reason that
3628 * made no sense to the user.
3629 */
3630 if (tm->tm_sec > 59)
3631 tm->tm_sec = 59;
3632 result = PyObject_CallFunction(cls, "iiiiiiiO",
3633 tm->tm_year + 1900,
3634 tm->tm_mon + 1,
3635 tm->tm_mday,
3636 tm->tm_hour,
3637 tm->tm_min,
3638 tm->tm_sec,
3639 us,
3640 tzinfo);
3641 }
3642 else
3643 PyErr_SetString(PyExc_ValueError,
3644 "timestamp out of range for "
3645 "platform localtime()/gmtime() function");
3646 return result;
3647}
3648
3649/* Internal helper.
3650 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3651 * to control the interpretation of the timestamp. Since a double doesn't
3652 * have enough bits to cover a datetime's full range of precision, it's
3653 * better to call datetime_from_timet_and_us provided you have a way
3654 * to get that much precision (e.g., C time() isn't good enough).
3655 */
3656static PyObject *
3657datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3658 PyObject *tzinfo)
3659{
3660 time_t timet = (time_t)timestamp;
3661 double fraction = timestamp - (double)timet;
3662 int us = (int)round_to_long(fraction * 1e6);
3663
3664 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3665}
3666
3667/* Internal helper.
3668 * Build most accurate possible datetime for current time. Pass localtime or
3669 * gmtime for f as appropriate.
3670 */
3671static PyObject *
3672datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3673{
3674#ifdef HAVE_GETTIMEOFDAY
3675 struct timeval t;
3676
3677#ifdef GETTIMEOFDAY_NO_TZ
3678 gettimeofday(&t);
3679#else
3680 gettimeofday(&t, (struct timezone *)NULL);
3681#endif
3682 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3683 tzinfo);
3684
3685#else /* ! HAVE_GETTIMEOFDAY */
3686 /* No flavor of gettimeofday exists on this platform. Python's
3687 * time.time() does a lot of other platform tricks to get the
3688 * best time it can on the platform, and we're not going to do
3689 * better than that (if we could, the better code would belong
3690 * in time.time()!) We're limited by the precision of a double,
3691 * though.
3692 */
3693 PyObject *time;
3694 double dtime;
3695
3696 time = time_time();
3697 if (time == NULL)
3698 return NULL;
3699 dtime = PyFloat_AsDouble(time);
3700 Py_DECREF(time);
3701 if (dtime == -1.0 && PyErr_Occurred())
3702 return NULL;
3703 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3704#endif /* ! HAVE_GETTIMEOFDAY */
3705}
3706
Tim Peters2a799bf2002-12-16 20:18:38 +00003707/* Return best possible local time -- this isn't constrained by the
3708 * precision of a timestamp.
3709 */
3710static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003711datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003712{
Tim Peters10cadce2003-01-23 19:58:02 +00003713 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003714 PyObject *tzinfo = Py_None;
Tim Peters10cadce2003-01-23 19:58:02 +00003715 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003716
Tim Peters10cadce2003-01-23 19:58:02 +00003717 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3718 &tzinfo))
3719 return NULL;
3720 if (check_tzinfo_subclass(tzinfo) < 0)
3721 return NULL;
3722
3723 self = datetime_best_possible(cls,
3724 tzinfo == Py_None ? localtime : gmtime,
3725 tzinfo);
3726 if (self != NULL && tzinfo != Py_None) {
3727 /* Convert UTC to tzinfo's zone. */
3728 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003729 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003730 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003731 }
3732 return self;
3733}
3734
Tim Petersa9bc1682003-01-11 03:39:11 +00003735/* Return best possible UTC time -- this isn't constrained by the
3736 * precision of a timestamp.
3737 */
3738static PyObject *
3739datetime_utcnow(PyObject *cls, PyObject *dummy)
3740{
3741 return datetime_best_possible(cls, gmtime, Py_None);
3742}
3743
Tim Peters2a799bf2002-12-16 20:18:38 +00003744/* Return new local datetime from timestamp (Python timestamp -- a double). */
3745static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003746datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003747{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003748 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003749 double timestamp;
3750 PyObject *tzinfo = Py_None;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003751 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003752
Tim Peters2a44a8d2003-01-23 20:53:10 +00003753 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3754 keywords, &timestamp, &tzinfo))
3755 return NULL;
3756 if (check_tzinfo_subclass(tzinfo) < 0)
3757 return NULL;
3758
3759 self = datetime_from_timestamp(cls,
3760 tzinfo == Py_None ? localtime : gmtime,
3761 timestamp,
3762 tzinfo);
3763 if (self != NULL && tzinfo != Py_None) {
3764 /* Convert UTC to tzinfo's zone. */
3765 PyObject *temp = self;
3766 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3767 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003768 }
3769 return self;
3770}
3771
Tim Petersa9bc1682003-01-11 03:39:11 +00003772/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3773static PyObject *
3774datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3775{
3776 double timestamp;
3777 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003778
Tim Petersa9bc1682003-01-11 03:39:11 +00003779 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3780 result = datetime_from_timestamp(cls, gmtime, timestamp,
3781 Py_None);
3782 return result;
3783}
3784
3785/* Return new datetime from date/datetime and time arguments. */
3786static PyObject *
3787datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3788{
3789 static char *keywords[] = {"date", "time", NULL};
3790 PyObject *date;
3791 PyObject *time;
3792 PyObject *result = NULL;
3793
3794 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3795 &PyDateTime_DateType, &date,
3796 &PyDateTime_TimeType, &time)) {
3797 PyObject *tzinfo = Py_None;
3798
3799 if (HASTZINFO(time))
3800 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3801 result = PyObject_CallFunction(cls, "iiiiiiiO",
3802 GET_YEAR(date),
3803 GET_MONTH(date),
3804 GET_DAY(date),
3805 TIME_GET_HOUR(time),
3806 TIME_GET_MINUTE(time),
3807 TIME_GET_SECOND(time),
3808 TIME_GET_MICROSECOND(time),
3809 tzinfo);
3810 }
3811 return result;
3812}
Tim Peters2a799bf2002-12-16 20:18:38 +00003813
3814/*
3815 * Destructor.
3816 */
3817
3818static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003819datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003820{
Tim Petersa9bc1682003-01-11 03:39:11 +00003821 if (HASTZINFO(self)) {
3822 Py_XDECREF(self->tzinfo);
3823 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003824 self->ob_type->tp_free((PyObject *)self);
3825}
3826
3827/*
3828 * Indirect access to tzinfo methods.
3829 */
3830
Tim Peters2a799bf2002-12-16 20:18:38 +00003831/* These are all METH_NOARGS, so don't need to check the arglist. */
3832static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003833datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3834 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3835 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003836}
3837
3838static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003839datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3840 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3841 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003842}
3843
3844static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003845datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3846 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3847 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003848}
3849
3850/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003851 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003852 */
3853
Tim Petersa9bc1682003-01-11 03:39:11 +00003854/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3855 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003856 */
3857static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003858add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3859 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003860{
Tim Petersa9bc1682003-01-11 03:39:11 +00003861 /* Note that the C-level additions can't overflow, because of
3862 * invariant bounds on the member values.
3863 */
3864 int year = GET_YEAR(date);
3865 int month = GET_MONTH(date);
3866 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3867 int hour = DATE_GET_HOUR(date);
3868 int minute = DATE_GET_MINUTE(date);
3869 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3870 int microsecond = DATE_GET_MICROSECOND(date) +
3871 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003872
Tim Petersa9bc1682003-01-11 03:39:11 +00003873 assert(factor == 1 || factor == -1);
3874 if (normalize_datetime(&year, &month, &day,
3875 &hour, &minute, &second, &microsecond) < 0)
3876 return NULL;
3877 else
3878 return new_datetime(year, month, day,
3879 hour, minute, second, microsecond,
3880 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003881}
3882
3883static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003884datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003885{
Tim Petersa9bc1682003-01-11 03:39:11 +00003886 if (PyDateTime_Check(left)) {
3887 /* datetime + ??? */
3888 if (PyDelta_Check(right))
3889 /* datetime + delta */
3890 return add_datetime_timedelta(
3891 (PyDateTime_DateTime *)left,
3892 (PyDateTime_Delta *)right,
3893 1);
3894 }
3895 else if (PyDelta_Check(left)) {
3896 /* delta + datetime */
3897 return add_datetime_timedelta((PyDateTime_DateTime *) right,
3898 (PyDateTime_Delta *) left,
3899 1);
3900 }
3901 Py_INCREF(Py_NotImplemented);
3902 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00003903}
3904
3905static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003906datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003907{
3908 PyObject *result = Py_NotImplemented;
3909
3910 if (PyDateTime_Check(left)) {
3911 /* datetime - ??? */
3912 if (PyDateTime_Check(right)) {
3913 /* datetime - datetime */
3914 naivety n1, n2;
3915 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00003916 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00003917
Tim Peterse39a80c2002-12-30 21:28:52 +00003918 if (classify_two_utcoffsets(left, &offset1, &n1, left,
3919 right, &offset2, &n2,
3920 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00003921 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00003922 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00003923 if (n1 != n2) {
3924 PyErr_SetString(PyExc_TypeError,
3925 "can't subtract offset-naive and "
3926 "offset-aware datetimes");
3927 return NULL;
3928 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003929 delta_d = ymd_to_ord(GET_YEAR(left),
3930 GET_MONTH(left),
3931 GET_DAY(left)) -
3932 ymd_to_ord(GET_YEAR(right),
3933 GET_MONTH(right),
3934 GET_DAY(right));
3935 /* These can't overflow, since the values are
3936 * normalized. At most this gives the number of
3937 * seconds in one day.
3938 */
3939 delta_s = (DATE_GET_HOUR(left) -
3940 DATE_GET_HOUR(right)) * 3600 +
3941 (DATE_GET_MINUTE(left) -
3942 DATE_GET_MINUTE(right)) * 60 +
3943 (DATE_GET_SECOND(left) -
3944 DATE_GET_SECOND(right));
3945 delta_us = DATE_GET_MICROSECOND(left) -
3946 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00003947 /* (left - offset1) - (right - offset2) =
3948 * (left - right) + (offset2 - offset1)
3949 */
Tim Petersa9bc1682003-01-11 03:39:11 +00003950 delta_s += (offset2 - offset1) * 60;
3951 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003952 }
3953 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00003954 /* datetime - delta */
3955 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00003956 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00003957 (PyDateTime_Delta *)right,
3958 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003959 }
3960 }
3961
3962 if (result == Py_NotImplemented)
3963 Py_INCREF(result);
3964 return result;
3965}
3966
3967/* Various ways to turn a datetime into a string. */
3968
3969static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003970datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003971{
Tim Petersa9bc1682003-01-11 03:39:11 +00003972 char buffer[1000];
3973 char *typename = self->ob_type->tp_name;
3974 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003975
Tim Petersa9bc1682003-01-11 03:39:11 +00003976 if (DATE_GET_MICROSECOND(self)) {
3977 PyOS_snprintf(buffer, sizeof(buffer),
3978 "%s(%d, %d, %d, %d, %d, %d, %d)",
3979 typename,
3980 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3981 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3982 DATE_GET_SECOND(self),
3983 DATE_GET_MICROSECOND(self));
3984 }
3985 else if (DATE_GET_SECOND(self)) {
3986 PyOS_snprintf(buffer, sizeof(buffer),
3987 "%s(%d, %d, %d, %d, %d, %d)",
3988 typename,
3989 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3990 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3991 DATE_GET_SECOND(self));
3992 }
3993 else {
3994 PyOS_snprintf(buffer, sizeof(buffer),
3995 "%s(%d, %d, %d, %d, %d)",
3996 typename,
3997 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3998 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
3999 }
4000 baserepr = PyString_FromString(buffer);
4001 if (baserepr == NULL || ! HASTZINFO(self))
4002 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004003 return append_keyword_tzinfo(baserepr, self->tzinfo);
4004}
4005
Tim Petersa9bc1682003-01-11 03:39:11 +00004006static PyObject *
4007datetime_str(PyDateTime_DateTime *self)
4008{
4009 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4010}
Tim Peters2a799bf2002-12-16 20:18:38 +00004011
4012static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004013datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004014{
Tim Petersa9bc1682003-01-11 03:39:11 +00004015 char sep = 'T';
4016 static char *keywords[] = {"sep", NULL};
4017 char buffer[100];
4018 char *cp;
4019 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004020
Tim Petersa9bc1682003-01-11 03:39:11 +00004021 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4022 &sep))
4023 return NULL;
4024 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4025 assert(cp != NULL);
4026 *cp++ = sep;
4027 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4028 result = PyString_FromString(buffer);
4029 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00004030 return result;
4031
4032 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00004033 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00004034 (PyObject *)self) < 0) {
4035 Py_DECREF(result);
4036 return NULL;
4037 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004038 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00004039 return result;
4040}
4041
Tim Petersa9bc1682003-01-11 03:39:11 +00004042static PyObject *
4043datetime_ctime(PyDateTime_DateTime *self)
4044{
4045 return format_ctime((PyDateTime_Date *)self,
4046 DATE_GET_HOUR(self),
4047 DATE_GET_MINUTE(self),
4048 DATE_GET_SECOND(self));
4049}
4050
Tim Peters2a799bf2002-12-16 20:18:38 +00004051/* Miscellaneous methods. */
4052
Tim Petersa9bc1682003-01-11 03:39:11 +00004053/* This is more natural as a tp_compare, but doesn't work then: for whatever
4054 * reason, Python's try_3way_compare ignores tp_compare unless
4055 * PyInstance_Check returns true, but these aren't old-style classes.
4056 */
4057static PyObject *
4058datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4059{
4060 int diff;
4061 naivety n1, n2;
4062 int offset1, offset2;
4063
4064 if (! PyDateTime_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004065 if (PyObject_HasAttrString(other, "timetuple")) {
4066 /* A hook for other kinds of datetime objects. */
4067 Py_INCREF(Py_NotImplemented);
4068 return Py_NotImplemented;
4069 }
Tim Peters07534a62003-02-07 22:50:28 +00004070 if (op == Py_EQ || op == Py_NE) {
4071 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4072 Py_INCREF(result);
4073 return result;
4074 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004075 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00004076 return cmperror((PyObject *)self, other);
Tim Petersa9bc1682003-01-11 03:39:11 +00004077 }
4078
4079 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4080 (PyObject *)self,
4081 other, &offset2, &n2,
4082 other) < 0)
4083 return NULL;
4084 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4085 /* If they're both naive, or both aware and have the same offsets,
4086 * we get off cheap. Note that if they're both naive, offset1 ==
4087 * offset2 == 0 at this point.
4088 */
4089 if (n1 == n2 && offset1 == offset2) {
4090 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4091 _PyDateTime_DATETIME_DATASIZE);
4092 return diff_to_bool(diff, op);
4093 }
4094
4095 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4096 PyDateTime_Delta *delta;
4097
4098 assert(offset1 != offset2); /* else last "if" handled it */
4099 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4100 other);
4101 if (delta == NULL)
4102 return NULL;
4103 diff = GET_TD_DAYS(delta);
4104 if (diff == 0)
4105 diff = GET_TD_SECONDS(delta) |
4106 GET_TD_MICROSECONDS(delta);
4107 Py_DECREF(delta);
4108 return diff_to_bool(diff, op);
4109 }
4110
4111 assert(n1 != n2);
4112 PyErr_SetString(PyExc_TypeError,
4113 "can't compare offset-naive and "
4114 "offset-aware datetimes");
4115 return NULL;
4116}
4117
4118static long
4119datetime_hash(PyDateTime_DateTime *self)
4120{
4121 if (self->hashcode == -1) {
4122 naivety n;
4123 int offset;
4124 PyObject *temp;
4125
4126 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4127 &offset);
4128 assert(n != OFFSET_UNKNOWN);
4129 if (n == OFFSET_ERROR)
4130 return -1;
4131
4132 /* Reduce this to a hash of another object. */
4133 if (n == OFFSET_NAIVE)
4134 temp = PyString_FromStringAndSize(
4135 (char *)self->data,
4136 _PyDateTime_DATETIME_DATASIZE);
4137 else {
4138 int days;
4139 int seconds;
4140
4141 assert(n == OFFSET_AWARE);
4142 assert(HASTZINFO(self));
4143 days = ymd_to_ord(GET_YEAR(self),
4144 GET_MONTH(self),
4145 GET_DAY(self));
4146 seconds = DATE_GET_HOUR(self) * 3600 +
4147 (DATE_GET_MINUTE(self) - offset) * 60 +
4148 DATE_GET_SECOND(self);
4149 temp = new_delta(days,
4150 seconds,
4151 DATE_GET_MICROSECOND(self),
4152 1);
4153 }
4154 if (temp != NULL) {
4155 self->hashcode = PyObject_Hash(temp);
4156 Py_DECREF(temp);
4157 }
4158 }
4159 return self->hashcode;
4160}
Tim Peters2a799bf2002-12-16 20:18:38 +00004161
4162static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004163datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004164{
4165 PyObject *clone;
4166 PyObject *tuple;
4167 int y = GET_YEAR(self);
4168 int m = GET_MONTH(self);
4169 int d = GET_DAY(self);
4170 int hh = DATE_GET_HOUR(self);
4171 int mm = DATE_GET_MINUTE(self);
4172 int ss = DATE_GET_SECOND(self);
4173 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004174 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004175
4176 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004177 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004178 &y, &m, &d, &hh, &mm, &ss, &us,
4179 &tzinfo))
4180 return NULL;
4181 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4182 if (tuple == NULL)
4183 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004184 clone = datetime_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004185 Py_DECREF(tuple);
4186 return clone;
4187}
4188
4189static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004190datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004191{
Tim Peters52dcce22003-01-23 16:36:11 +00004192 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004193 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004194 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004195
Tim Peters80475bb2002-12-25 07:40:55 +00004196 PyObject *tzinfo;
4197 static char *keywords[] = {"tz", NULL};
4198
Tim Peters52dcce22003-01-23 16:36:11 +00004199 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4200 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004201 return NULL;
4202
Tim Peters52dcce22003-01-23 16:36:11 +00004203 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4204 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004205
Tim Peters52dcce22003-01-23 16:36:11 +00004206 /* Conversion to self's own time zone is a NOP. */
4207 if (self->tzinfo == tzinfo) {
4208 Py_INCREF(self);
4209 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004210 }
Tim Peters521fc152002-12-31 17:36:56 +00004211
Tim Peters52dcce22003-01-23 16:36:11 +00004212 /* Convert self to UTC. */
4213 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4214 if (offset == -1 && PyErr_Occurred())
4215 return NULL;
4216 if (none)
4217 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004218
Tim Peters52dcce22003-01-23 16:36:11 +00004219 y = GET_YEAR(self);
4220 m = GET_MONTH(self);
4221 d = GET_DAY(self);
4222 hh = DATE_GET_HOUR(self);
4223 mm = DATE_GET_MINUTE(self);
4224 ss = DATE_GET_SECOND(self);
4225 us = DATE_GET_MICROSECOND(self);
4226
4227 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004228 if ((mm < 0 || mm >= 60) &&
4229 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004230 return NULL;
4231
4232 /* Attach new tzinfo and let fromutc() do the rest. */
4233 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4234 if (result != NULL) {
4235 PyObject *temp = result;
4236
4237 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4238 Py_DECREF(temp);
4239 }
Tim Petersadf64202003-01-04 06:03:15 +00004240 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004241
Tim Peters52dcce22003-01-23 16:36:11 +00004242NeedAware:
4243 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4244 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004245 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004246}
4247
4248static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004249datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004250{
4251 int dstflag = -1;
4252
Tim Petersa9bc1682003-01-11 03:39:11 +00004253 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004254 int none;
4255
4256 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4257 if (dstflag == -1 && PyErr_Occurred())
4258 return NULL;
4259
4260 if (none)
4261 dstflag = -1;
4262 else if (dstflag != 0)
4263 dstflag = 1;
4264
4265 }
4266 return build_struct_time(GET_YEAR(self),
4267 GET_MONTH(self),
4268 GET_DAY(self),
4269 DATE_GET_HOUR(self),
4270 DATE_GET_MINUTE(self),
4271 DATE_GET_SECOND(self),
4272 dstflag);
4273}
4274
4275static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004276datetime_getdate(PyDateTime_DateTime *self)
4277{
4278 return new_date(GET_YEAR(self),
4279 GET_MONTH(self),
4280 GET_DAY(self));
4281}
4282
4283static PyObject *
4284datetime_gettime(PyDateTime_DateTime *self)
4285{
4286 return new_time(DATE_GET_HOUR(self),
4287 DATE_GET_MINUTE(self),
4288 DATE_GET_SECOND(self),
4289 DATE_GET_MICROSECOND(self),
4290 Py_None);
4291}
4292
4293static PyObject *
4294datetime_gettimetz(PyDateTime_DateTime *self)
4295{
4296 return new_time(DATE_GET_HOUR(self),
4297 DATE_GET_MINUTE(self),
4298 DATE_GET_SECOND(self),
4299 DATE_GET_MICROSECOND(self),
4300 HASTZINFO(self) ? self->tzinfo : Py_None);
4301}
4302
4303static PyObject *
4304datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004305{
4306 int y = GET_YEAR(self);
4307 int m = GET_MONTH(self);
4308 int d = GET_DAY(self);
4309 int hh = DATE_GET_HOUR(self);
4310 int mm = DATE_GET_MINUTE(self);
4311 int ss = DATE_GET_SECOND(self);
4312 int us = 0; /* microseconds are ignored in a timetuple */
4313 int offset = 0;
4314
Tim Petersa9bc1682003-01-11 03:39:11 +00004315 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004316 int none;
4317
4318 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4319 if (offset == -1 && PyErr_Occurred())
4320 return NULL;
4321 }
4322 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4323 * 0 in a UTC timetuple regardless of what dst() says.
4324 */
4325 if (offset) {
4326 /* Subtract offset minutes & normalize. */
4327 int stat;
4328
4329 mm -= offset;
4330 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4331 if (stat < 0) {
4332 /* At the edges, it's possible we overflowed
4333 * beyond MINYEAR or MAXYEAR.
4334 */
4335 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4336 PyErr_Clear();
4337 else
4338 return NULL;
4339 }
4340 }
4341 return build_struct_time(y, m, d, hh, mm, ss, 0);
4342}
4343
Tim Peters371935f2003-02-01 01:52:50 +00004344/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004345
Tim Petersa9bc1682003-01-11 03:39:11 +00004346/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004347 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4348 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004349 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004350 */
4351static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004352datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004353{
4354 PyObject *basestate;
4355 PyObject *result = NULL;
4356
Tim Peters33e0f382003-01-10 02:05:14 +00004357 basestate = PyString_FromStringAndSize((char *)self->data,
4358 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004359 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004360 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004361 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00004362 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004363 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004364 Py_DECREF(basestate);
4365 }
4366 return result;
4367}
4368
4369static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004370datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004371{
Guido van Rossum177e41a2003-01-30 22:06:23 +00004372 return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004373}
4374
Tim Petersa9bc1682003-01-11 03:39:11 +00004375static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004376
Tim Peters2a799bf2002-12-16 20:18:38 +00004377 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004378
Tim Petersa9bc1682003-01-11 03:39:11 +00004379 {"now", (PyCFunction)datetime_now,
Tim Peters2a799bf2002-12-16 20:18:38 +00004380 METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004381 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004382
Tim Petersa9bc1682003-01-11 03:39:11 +00004383 {"utcnow", (PyCFunction)datetime_utcnow,
4384 METH_NOARGS | METH_CLASS,
4385 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4386
4387 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Tim Peters2a799bf2002-12-16 20:18:38 +00004388 METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004389 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004390
Tim Petersa9bc1682003-01-11 03:39:11 +00004391 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4392 METH_VARARGS | METH_CLASS,
4393 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4394 "(like time.time()).")},
4395
4396 {"combine", (PyCFunction)datetime_combine,
4397 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4398 PyDoc_STR("date, time -> datetime with same date and time fields")},
4399
Tim Peters2a799bf2002-12-16 20:18:38 +00004400 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004401
Tim Petersa9bc1682003-01-11 03:39:11 +00004402 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4403 PyDoc_STR("Return date object with same year, month and day.")},
4404
4405 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4406 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4407
4408 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4409 PyDoc_STR("Return time object with same time and tzinfo.")},
4410
4411 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4412 PyDoc_STR("Return ctime() style string.")},
4413
4414 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004415 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4416
Tim Petersa9bc1682003-01-11 03:39:11 +00004417 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004418 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4419
Tim Petersa9bc1682003-01-11 03:39:11 +00004420 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004421 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4422 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4423 "sep is used to separate the year from the time, and "
4424 "defaults to 'T'.")},
4425
Tim Petersa9bc1682003-01-11 03:39:11 +00004426 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004427 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4428
Tim Petersa9bc1682003-01-11 03:39:11 +00004429 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004430 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4431
Tim Petersa9bc1682003-01-11 03:39:11 +00004432 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004433 PyDoc_STR("Return self.tzinfo.dst(self).")},
4434
Tim Petersa9bc1682003-01-11 03:39:11 +00004435 {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
4436 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004437
Tim Petersa9bc1682003-01-11 03:39:11 +00004438 {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004439 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4440
Guido van Rossum177e41a2003-01-30 22:06:23 +00004441 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4442 PyDoc_STR("__reduce__() -> (cls, state)")},
4443
Tim Peters2a799bf2002-12-16 20:18:38 +00004444 {NULL, NULL}
4445};
4446
Tim Petersa9bc1682003-01-11 03:39:11 +00004447static char datetime_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00004448PyDoc_STR("date/time type.");
4449
Tim Petersa9bc1682003-01-11 03:39:11 +00004450static PyNumberMethods datetime_as_number = {
4451 datetime_add, /* nb_add */
4452 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004453 0, /* nb_multiply */
4454 0, /* nb_divide */
4455 0, /* nb_remainder */
4456 0, /* nb_divmod */
4457 0, /* nb_power */
4458 0, /* nb_negative */
4459 0, /* nb_positive */
4460 0, /* nb_absolute */
4461 0, /* nb_nonzero */
4462};
4463
Tim Petersa9bc1682003-01-11 03:39:11 +00004464statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004465 PyObject_HEAD_INIT(NULL)
4466 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004467 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004468 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004469 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004470 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004471 0, /* tp_print */
4472 0, /* tp_getattr */
4473 0, /* tp_setattr */
4474 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004475 (reprfunc)datetime_repr, /* tp_repr */
4476 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004477 0, /* tp_as_sequence */
4478 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004479 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004480 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004481 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004482 PyObject_GenericGetAttr, /* tp_getattro */
4483 0, /* tp_setattro */
4484 0, /* tp_as_buffer */
4485 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4486 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004487 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004488 0, /* tp_traverse */
4489 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004490 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004491 0, /* tp_weaklistoffset */
4492 0, /* tp_iter */
4493 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004494 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004495 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004496 datetime_getset, /* tp_getset */
4497 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004498 0, /* tp_dict */
4499 0, /* tp_descr_get */
4500 0, /* tp_descr_set */
4501 0, /* tp_dictoffset */
4502 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00004503 datetime_alloc, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004504 datetime_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00004505 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004506};
4507
4508/* ---------------------------------------------------------------------------
4509 * Module methods and initialization.
4510 */
4511
4512static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004513 {NULL, NULL}
4514};
4515
4516PyMODINIT_FUNC
4517initdatetime(void)
4518{
4519 PyObject *m; /* a module object */
4520 PyObject *d; /* its dict */
4521 PyObject *x;
4522
Tim Peters2a799bf2002-12-16 20:18:38 +00004523 m = Py_InitModule3("datetime", module_methods,
4524 "Fast implementation of the datetime type.");
4525
4526 if (PyType_Ready(&PyDateTime_DateType) < 0)
4527 return;
4528 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4529 return;
4530 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4531 return;
4532 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4533 return;
4534 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4535 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004536
Tim Peters2a799bf2002-12-16 20:18:38 +00004537 /* timedelta values */
4538 d = PyDateTime_DeltaType.tp_dict;
4539
Tim Peters2a799bf2002-12-16 20:18:38 +00004540 x = new_delta(0, 0, 1, 0);
4541 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4542 return;
4543 Py_DECREF(x);
4544
4545 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4546 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4547 return;
4548 Py_DECREF(x);
4549
4550 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4551 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4552 return;
4553 Py_DECREF(x);
4554
4555 /* date values */
4556 d = PyDateTime_DateType.tp_dict;
4557
4558 x = new_date(1, 1, 1);
4559 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4560 return;
4561 Py_DECREF(x);
4562
4563 x = new_date(MAXYEAR, 12, 31);
4564 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4565 return;
4566 Py_DECREF(x);
4567
4568 x = new_delta(1, 0, 0, 0);
4569 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4570 return;
4571 Py_DECREF(x);
4572
Tim Peters37f39822003-01-10 03:49:02 +00004573 /* time values */
4574 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004575
Tim Peters37f39822003-01-10 03:49:02 +00004576 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004577 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4578 return;
4579 Py_DECREF(x);
4580
Tim Peters37f39822003-01-10 03:49:02 +00004581 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004582 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4583 return;
4584 Py_DECREF(x);
4585
4586 x = new_delta(0, 0, 1, 0);
4587 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4588 return;
4589 Py_DECREF(x);
4590
Tim Petersa9bc1682003-01-11 03:39:11 +00004591 /* datetime values */
4592 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004593
Tim Petersa9bc1682003-01-11 03:39:11 +00004594 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004595 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4596 return;
4597 Py_DECREF(x);
4598
Tim Petersa9bc1682003-01-11 03:39:11 +00004599 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004600 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4601 return;
4602 Py_DECREF(x);
4603
4604 x = new_delta(0, 0, 1, 0);
4605 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4606 return;
4607 Py_DECREF(x);
4608
Tim Peters2a799bf2002-12-16 20:18:38 +00004609 /* module initialization */
4610 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4611 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4612
4613 Py_INCREF(&PyDateTime_DateType);
4614 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4615
Tim Petersa9bc1682003-01-11 03:39:11 +00004616 Py_INCREF(&PyDateTime_DateTimeType);
4617 PyModule_AddObject(m, "datetime",
4618 (PyObject *)&PyDateTime_DateTimeType);
4619
4620 Py_INCREF(&PyDateTime_TimeType);
4621 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4622
Tim Peters2a799bf2002-12-16 20:18:38 +00004623 Py_INCREF(&PyDateTime_DeltaType);
4624 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4625
Tim Peters2a799bf2002-12-16 20:18:38 +00004626 Py_INCREF(&PyDateTime_TZInfoType);
4627 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4628
Tim Peters2a799bf2002-12-16 20:18:38 +00004629 /* A 4-year cycle has an extra leap day over what we'd get from
4630 * pasting together 4 single years.
4631 */
4632 assert(DI4Y == 4 * 365 + 1);
4633 assert(DI4Y == days_before_year(4+1));
4634
4635 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4636 * get from pasting together 4 100-year cycles.
4637 */
4638 assert(DI400Y == 4 * DI100Y + 1);
4639 assert(DI400Y == days_before_year(400+1));
4640
4641 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4642 * pasting together 25 4-year cycles.
4643 */
4644 assert(DI100Y == 25 * DI4Y - 1);
4645 assert(DI100Y == days_before_year(100+1));
4646
4647 us_per_us = PyInt_FromLong(1);
4648 us_per_ms = PyInt_FromLong(1000);
4649 us_per_second = PyInt_FromLong(1000000);
4650 us_per_minute = PyInt_FromLong(60000000);
4651 seconds_per_day = PyInt_FromLong(24 * 3600);
4652 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4653 us_per_minute == NULL || seconds_per_day == NULL)
4654 return;
4655
4656 /* The rest are too big for 32-bit ints, but even
4657 * us_per_week fits in 40 bits, so doubles should be exact.
4658 */
4659 us_per_hour = PyLong_FromDouble(3600000000.0);
4660 us_per_day = PyLong_FromDouble(86400000000.0);
4661 us_per_week = PyLong_FromDouble(604800000000.0);
4662 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4663 return;
4664}
Tim Petersf3615152003-01-01 21:51:37 +00004665
4666/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004667Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004668 x.n = x stripped of its timezone -- its naive time.
4669 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4670 return None
4671 x.d = x.dst(), and assuming that doesn't raise an exception or
4672 return None
4673 x.s = x's standard offset, x.o - x.d
4674
4675Now some derived rules, where k is a duration (timedelta).
4676
46771. x.o = x.s + x.d
4678 This follows from the definition of x.s.
4679
Tim Petersc5dc4da2003-01-02 17:55:03 +000046802. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004681 This is actually a requirement, an assumption we need to make about
4682 sane tzinfo classes.
4683
46843. The naive UTC time corresponding to x is x.n - x.o.
4685 This is again a requirement for a sane tzinfo class.
4686
46874. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004688 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004689
Tim Petersc5dc4da2003-01-02 17:55:03 +000046905. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004691 Again follows from how arithmetic is defined.
4692
Tim Peters8bb5ad22003-01-24 02:44:45 +00004693Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004694(meaning that the various tzinfo methods exist, and don't blow up or return
4695None when called).
4696
Tim Petersa9bc1682003-01-11 03:39:11 +00004697The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004698x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004699
4700By #3, we want
4701
Tim Peters8bb5ad22003-01-24 02:44:45 +00004702 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004703
4704The algorithm starts by attaching tz to x.n, and calling that y. So
4705x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4706becomes true; in effect, we want to solve [2] for k:
4707
Tim Peters8bb5ad22003-01-24 02:44:45 +00004708 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004709
4710By #1, this is the same as
4711
Tim Peters8bb5ad22003-01-24 02:44:45 +00004712 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004713
4714By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4715Substituting that into [3],
4716
Tim Peters8bb5ad22003-01-24 02:44:45 +00004717 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4718 k - (y+k).s - (y+k).d = 0; rearranging,
4719 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4720 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004721
Tim Peters8bb5ad22003-01-24 02:44:45 +00004722On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4723approximate k by ignoring the (y+k).d term at first. Note that k can't be
4724very large, since all offset-returning methods return a duration of magnitude
4725less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4726be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004727
4728In any case, the new value is
4729
Tim Peters8bb5ad22003-01-24 02:44:45 +00004730 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004731
Tim Peters8bb5ad22003-01-24 02:44:45 +00004732It's helpful to step back at look at [4] from a higher level: it's simply
4733mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004734
4735At this point, if
4736
Tim Peters8bb5ad22003-01-24 02:44:45 +00004737 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004738
4739we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004740at the start of daylight time. Picture US Eastern for concreteness. The wall
4741time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
Tim Peters8bb5ad22003-01-24 02:44:45 +00004742sense then. The docs ask that an Eastern tzinfo class consider such a time to
4743be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4744on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004745the only spelling that makes sense on the local wall clock.
4746
Tim Petersc5dc4da2003-01-02 17:55:03 +00004747In fact, if [5] holds at this point, we do have the standard-time spelling,
4748but that takes a bit of proof. We first prove a stronger result. What's the
4749difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004750
Tim Peters8bb5ad22003-01-24 02:44:45 +00004751 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004752
Tim Petersc5dc4da2003-01-02 17:55:03 +00004753Now
4754 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004755 (y + y.s).n = by #5
4756 y.n + y.s = since y.n = x.n
4757 x.n + y.s = since z and y are have the same tzinfo member,
4758 y.s = z.s by #2
4759 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004760
Tim Petersc5dc4da2003-01-02 17:55:03 +00004761Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004762
Tim Petersc5dc4da2003-01-02 17:55:03 +00004763 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004764 x.n - ((x.n + z.s) - z.o) = expanding
4765 x.n - x.n - z.s + z.o = cancelling
4766 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004767 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004768
Tim Petersc5dc4da2003-01-02 17:55:03 +00004769So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004770
Tim Petersc5dc4da2003-01-02 17:55:03 +00004771If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004772spelling we wanted in the endcase described above. We're done. Contrarily,
4773if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004774
Tim Petersc5dc4da2003-01-02 17:55:03 +00004775If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4776add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00004777local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004778
Tim Petersc5dc4da2003-01-02 17:55:03 +00004779Let
Tim Petersf3615152003-01-01 21:51:37 +00004780
Tim Peters4fede1a2003-01-04 00:26:59 +00004781 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004782
Tim Peters4fede1a2003-01-04 00:26:59 +00004783and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004784
Tim Peters8bb5ad22003-01-24 02:44:45 +00004785 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004786
Tim Peters8bb5ad22003-01-24 02:44:45 +00004787If so, we're done. If not, the tzinfo class is insane, according to the
4788assumptions we've made. This also requires a bit of proof. As before, let's
4789compute the difference between the LHS and RHS of [8] (and skipping some of
4790the justifications for the kinds of substitutions we've done several times
4791already):
Tim Peters4fede1a2003-01-04 00:26:59 +00004792
Tim Peters8bb5ad22003-01-24 02:44:45 +00004793 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
4794 x.n - (z.n + diff - z'.o) = replacing diff via [6]
4795 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
4796 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
4797 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00004798 - z.o + z'.o = #1 twice
4799 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4800 z'.d - z.d
4801
4802So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
Tim Peters8bb5ad22003-01-24 02:44:45 +00004803we've found the UTC-equivalent so are done. In fact, we stop with [7] and
4804return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00004805
Tim Peters8bb5ad22003-01-24 02:44:45 +00004806How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
4807a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
4808would have to change the result dst() returns: we start in DST, and moving
4809a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00004810
Tim Peters8bb5ad22003-01-24 02:44:45 +00004811There isn't a sane case where this can happen. The closest it gets is at
4812the end of DST, where there's an hour in UTC with no spelling in a hybrid
4813tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
4814that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
4815UTC) because the docs insist on that, but 0:MM is taken as being in daylight
4816time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
4817clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
4818standard time. Since that's what the local clock *does*, we want to map both
4819UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00004820in local time, but so it goes -- it's the way the local clock works.
4821
Tim Peters8bb5ad22003-01-24 02:44:45 +00004822When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4823so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4824z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
Tim Peters4fede1a2003-01-04 00:26:59 +00004825(correctly) concludes that z' is not UTC-equivalent to x.
4826
4827Because we know z.d said z was in daylight time (else [5] would have held and
4828we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004829and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00004830return in Eastern, it follows that z'.d must be 0 (which it is in the example,
4831but the reasoning doesn't depend on the example -- it depends on there being
4832two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00004833z' must be in standard time, and is the spelling we want in this case.
4834
4835Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
4836concerned (because it takes z' as being in standard time rather than the
4837daylight time we intend here), but returning it gives the real-life "local
4838clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
4839tz.
4840
4841When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
4842the 1:MM standard time spelling we want.
4843
4844So how can this break? One of the assumptions must be violated. Two
4845possibilities:
4846
48471) [2] effectively says that y.s is invariant across all y belong to a given
4848 time zone. This isn't true if, for political reasons or continental drift,
4849 a region decides to change its base offset from UTC.
4850
48512) There may be versions of "double daylight" time where the tail end of
4852 the analysis gives up a step too early. I haven't thought about that
4853 enough to say.
4854
4855In any case, it's clear that the default fromutc() is strong enough to handle
4856"almost all" time zones: so long as the standard offset is invariant, it
4857doesn't matter if daylight time transition points change from year to year, or
4858if daylight time is skipped in some years; it doesn't matter how large or
4859small dst() may get within its bounds; and it doesn't even matter if some
4860perverse time zone returns a negative dst()). So a breaking case must be
4861pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00004862--------------------------------------------------------------------------- */