blob: 164492e3b2715f2944afdc4d8e73cb4f2768d508 [file] [log] [blame]
Tim Peters2a799bf2002-12-16 20:18:38 +00001/* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5#include "Python.h"
6#include "modsupport.h"
7#include "structmember.h"
8
9#include <time.h>
10
11#include "datetime.h"
12
13/* We require that C int be at least 32 bits, and use int virtually
14 * everywhere. In just a few cases we use a temp long, where a Python
15 * API returns a C long. In such cases, we have to ensure that the
16 * final result fits in a C int (this can be an issue on 64-bit boxes).
17 */
18#if SIZEOF_INT < 4
19# error "datetime.c requires that C int have at least 32 bits"
20#endif
21
22#define MINYEAR 1
23#define MAXYEAR 9999
24
25/* Nine decimal digits is easy to communicate, and leaves enough room
26 * so that two delta days can be added w/o fear of overflowing a signed
27 * 32-bit int, and with plenty of room left over to absorb any possible
28 * carries from adding seconds.
29 */
30#define MAX_DELTA_DAYS 999999999
31
32/* Rename the long macros in datetime.h to more reasonable short names. */
33#define GET_YEAR PyDateTime_GET_YEAR
34#define GET_MONTH PyDateTime_GET_MONTH
35#define GET_DAY PyDateTime_GET_DAY
36#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
37#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
38#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
39#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
40
41/* Date accessors for date and datetime. */
42#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
43 ((o)->data[1] = ((v) & 0x00ff)))
44#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
45#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
46
47/* Date/Time accessors for datetime. */
48#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
49#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
50#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
51#define DATE_SET_MICROSECOND(o, v) \
52 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
53 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
54 ((o)->data[9] = ((v) & 0x0000ff)))
55
56/* Time accessors for time. */
57#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
58#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
59#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
60#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
61#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
62#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
63#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
64#define TIME_SET_MICROSECOND(o, v) \
65 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
66 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
67 ((o)->data[5] = ((v) & 0x0000ff)))
68
69/* Delta accessors for timedelta. */
70#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
71#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
72#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
73
74#define SET_TD_DAYS(o, v) ((o)->days = (v))
75#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
76#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
77
Tim Petersa032d2e2003-01-11 00:15:54 +000078/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
79 * p->hastzinfo.
80 */
81#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
82
Tim Peters2a799bf2002-12-16 20:18:38 +000083/* Forward declarations. */
84static PyTypeObject PyDateTime_DateType;
85static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +000086static PyTypeObject PyDateTime_DeltaType;
87static PyTypeObject PyDateTime_TimeType;
88static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +000089
90/* ---------------------------------------------------------------------------
91 * Math utilities.
92 */
93
94/* k = i+j overflows iff k differs in sign from both inputs,
95 * iff k^i has sign bit set and k^j has sign bit set,
96 * iff (k^i)&(k^j) has sign bit set.
97 */
98#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
99 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
100
101/* Compute Python divmod(x, y), returning the quotient and storing the
102 * remainder into *r. The quotient is the floor of x/y, and that's
103 * the real point of this. C will probably truncate instead (C99
104 * requires truncation; C89 left it implementation-defined).
105 * Simplification: we *require* that y > 0 here. That's appropriate
106 * for all the uses made of it. This simplifies the code and makes
107 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
108 * overflow case).
109 */
110static int
111divmod(int x, int y, int *r)
112{
113 int quo;
114
115 assert(y > 0);
116 quo = x / y;
117 *r = x - quo * y;
118 if (*r < 0) {
119 --quo;
120 *r += y;
121 }
122 assert(0 <= *r && *r < y);
123 return quo;
124}
125
Tim Peters5d644dd2003-01-02 16:32:54 +0000126/* Round a double to the nearest long. |x| must be small enough to fit
127 * in a C long; this is not checked.
128 */
129static long
130round_to_long(double x)
131{
132 if (x >= 0.0)
133 x = floor(x + 0.5);
134 else
135 x = ceil(x - 0.5);
136 return (long)x;
137}
138
Tim Peters2a799bf2002-12-16 20:18:38 +0000139/* ---------------------------------------------------------------------------
140 * General calendrical helper functions
141 */
142
143/* For each month ordinal in 1..12, the number of days in that month,
144 * and the number of days before that month in the same year. These
145 * are correct for non-leap years only.
146 */
147static int _days_in_month[] = {
148 0, /* unused; this vector uses 1-based indexing */
149 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
150};
151
152static int _days_before_month[] = {
153 0, /* unused; this vector uses 1-based indexing */
154 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
155};
156
157/* year -> 1 if leap year, else 0. */
158static int
159is_leap(int year)
160{
161 /* Cast year to unsigned. The result is the same either way, but
162 * C can generate faster code for unsigned mod than for signed
163 * mod (especially for % 4 -- a good compiler should just grab
164 * the last 2 bits when the LHS is unsigned).
165 */
166 const unsigned int ayear = (unsigned int)year;
167 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
168}
169
170/* year, month -> number of days in that month in that year */
171static int
172days_in_month(int year, int month)
173{
174 assert(month >= 1);
175 assert(month <= 12);
176 if (month == 2 && is_leap(year))
177 return 29;
178 else
179 return _days_in_month[month];
180}
181
182/* year, month -> number of days in year preceeding first day of month */
183static int
184days_before_month(int year, int month)
185{
186 int days;
187
188 assert(month >= 1);
189 assert(month <= 12);
190 days = _days_before_month[month];
191 if (month > 2 && is_leap(year))
192 ++days;
193 return days;
194}
195
196/* year -> number of days before January 1st of year. Remember that we
197 * start with year 1, so days_before_year(1) == 0.
198 */
199static int
200days_before_year(int year)
201{
202 int y = year - 1;
203 /* This is incorrect if year <= 0; we really want the floor
204 * here. But so long as MINYEAR is 1, the smallest year this
205 * can see is 0 (this can happen in some normalization endcases),
206 * so we'll just special-case that.
207 */
208 assert (year >= 0);
209 if (y >= 0)
210 return y*365 + y/4 - y/100 + y/400;
211 else {
212 assert(y == -1);
213 return -366;
214 }
215}
216
217/* Number of days in 4, 100, and 400 year cycles. That these have
218 * the correct values is asserted in the module init function.
219 */
220#define DI4Y 1461 /* days_before_year(5); days in 4 years */
221#define DI100Y 36524 /* days_before_year(101); days in 100 years */
222#define DI400Y 146097 /* days_before_year(401); days in 400 years */
223
224/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
225static void
226ord_to_ymd(int ordinal, int *year, int *month, int *day)
227{
228 int n, n1, n4, n100, n400, leapyear, preceding;
229
230 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
231 * leap years repeats exactly every 400 years. The basic strategy is
232 * to find the closest 400-year boundary at or before ordinal, then
233 * work with the offset from that boundary to ordinal. Life is much
234 * clearer if we subtract 1 from ordinal first -- then the values
235 * of ordinal at 400-year boundaries are exactly those divisible
236 * by DI400Y:
237 *
238 * D M Y n n-1
239 * -- --- ---- ---------- ----------------
240 * 31 Dec -400 -DI400Y -DI400Y -1
241 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
242 * ...
243 * 30 Dec 000 -1 -2
244 * 31 Dec 000 0 -1
245 * 1 Jan 001 1 0 400-year boundary
246 * 2 Jan 001 2 1
247 * 3 Jan 001 3 2
248 * ...
249 * 31 Dec 400 DI400Y DI400Y -1
250 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
251 */
252 assert(ordinal >= 1);
253 --ordinal;
254 n400 = ordinal / DI400Y;
255 n = ordinal % DI400Y;
256 *year = n400 * 400 + 1;
257
258 /* Now n is the (non-negative) offset, in days, from January 1 of
259 * year, to the desired date. Now compute how many 100-year cycles
260 * precede n.
261 * Note that it's possible for n100 to equal 4! In that case 4 full
262 * 100-year cycles precede the desired day, which implies the
263 * desired day is December 31 at the end of a 400-year cycle.
264 */
265 n100 = n / DI100Y;
266 n = n % DI100Y;
267
268 /* Now compute how many 4-year cycles precede it. */
269 n4 = n / DI4Y;
270 n = n % DI4Y;
271
272 /* And now how many single years. Again n1 can be 4, and again
273 * meaning that the desired day is December 31 at the end of the
274 * 4-year cycle.
275 */
276 n1 = n / 365;
277 n = n % 365;
278
279 *year += n100 * 100 + n4 * 4 + n1;
280 if (n1 == 4 || n100 == 4) {
281 assert(n == 0);
282 *year -= 1;
283 *month = 12;
284 *day = 31;
285 return;
286 }
287
288 /* Now the year is correct, and n is the offset from January 1. We
289 * find the month via an estimate that's either exact or one too
290 * large.
291 */
292 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
293 assert(leapyear == is_leap(*year));
294 *month = (n + 50) >> 5;
295 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
296 if (preceding > n) {
297 /* estimate is too large */
298 *month -= 1;
299 preceding -= days_in_month(*year, *month);
300 }
301 n -= preceding;
302 assert(0 <= n);
303 assert(n < days_in_month(*year, *month));
304
305 *day = n + 1;
306}
307
308/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
309static int
310ymd_to_ord(int year, int month, int day)
311{
312 return days_before_year(year) + days_before_month(year, month) + day;
313}
314
315/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
316static int
317weekday(int year, int month, int day)
318{
319 return (ymd_to_ord(year, month, day) + 6) % 7;
320}
321
322/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
323 * first calendar week containing a Thursday.
324 */
325static int
326iso_week1_monday(int year)
327{
328 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
329 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
330 int first_weekday = (first_day + 6) % 7;
331 /* ordinal of closest Monday at or before 1/1 */
332 int week1_monday = first_day - first_weekday;
333
334 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
335 week1_monday += 7;
336 return week1_monday;
337}
338
339/* ---------------------------------------------------------------------------
340 * Range checkers.
341 */
342
343/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
344 * If not, raise OverflowError and return -1.
345 */
346static int
347check_delta_day_range(int days)
348{
349 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
350 return 0;
351 PyErr_Format(PyExc_OverflowError,
352 "days=%d; must have magnitude <= %d",
Guido van Rossumbd43e912002-12-16 20:34:55 +0000353 days, MAX_DELTA_DAYS);
Tim Peters2a799bf2002-12-16 20:18:38 +0000354 return -1;
355}
356
357/* Check that date arguments are in range. Return 0 if they are. If they
358 * aren't, raise ValueError and return -1.
359 */
360static int
361check_date_args(int year, int month, int day)
362{
363
364 if (year < MINYEAR || year > MAXYEAR) {
365 PyErr_SetString(PyExc_ValueError,
366 "year is out of range");
367 return -1;
368 }
369 if (month < 1 || month > 12) {
370 PyErr_SetString(PyExc_ValueError,
371 "month must be in 1..12");
372 return -1;
373 }
374 if (day < 1 || day > days_in_month(year, month)) {
375 PyErr_SetString(PyExc_ValueError,
376 "day is out of range for month");
377 return -1;
378 }
379 return 0;
380}
381
382/* Check that time arguments are in range. Return 0 if they are. If they
383 * aren't, raise ValueError and return -1.
384 */
385static int
386check_time_args(int h, int m, int s, int us)
387{
388 if (h < 0 || h > 23) {
389 PyErr_SetString(PyExc_ValueError,
390 "hour must be in 0..23");
391 return -1;
392 }
393 if (m < 0 || m > 59) {
394 PyErr_SetString(PyExc_ValueError,
395 "minute must be in 0..59");
396 return -1;
397 }
398 if (s < 0 || s > 59) {
399 PyErr_SetString(PyExc_ValueError,
400 "second must be in 0..59");
401 return -1;
402 }
403 if (us < 0 || us > 999999) {
404 PyErr_SetString(PyExc_ValueError,
405 "microsecond must be in 0..999999");
406 return -1;
407 }
408 return 0;
409}
410
411/* ---------------------------------------------------------------------------
412 * Normalization utilities.
413 */
414
415/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
416 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
417 * at least factor, enough of *lo is converted into "hi" units so that
418 * 0 <= *lo < factor. The input values must be such that int overflow
419 * is impossible.
420 */
421static void
422normalize_pair(int *hi, int *lo, int factor)
423{
424 assert(factor > 0);
425 assert(lo != hi);
426 if (*lo < 0 || *lo >= factor) {
427 const int num_hi = divmod(*lo, factor, lo);
428 const int new_hi = *hi + num_hi;
429 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
430 *hi = new_hi;
431 }
432 assert(0 <= *lo && *lo < factor);
433}
434
435/* Fiddle days (d), seconds (s), and microseconds (us) so that
436 * 0 <= *s < 24*3600
437 * 0 <= *us < 1000000
438 * The input values must be such that the internals don't overflow.
439 * The way this routine is used, we don't get close.
440 */
441static void
442normalize_d_s_us(int *d, int *s, int *us)
443{
444 if (*us < 0 || *us >= 1000000) {
445 normalize_pair(s, us, 1000000);
446 /* |s| can't be bigger than about
447 * |original s| + |original us|/1000000 now.
448 */
449
450 }
451 if (*s < 0 || *s >= 24*3600) {
452 normalize_pair(d, s, 24*3600);
453 /* |d| can't be bigger than about
454 * |original d| +
455 * (|original s| + |original us|/1000000) / (24*3600) now.
456 */
457 }
458 assert(0 <= *s && *s < 24*3600);
459 assert(0 <= *us && *us < 1000000);
460}
461
462/* Fiddle years (y), months (m), and days (d) so that
463 * 1 <= *m <= 12
464 * 1 <= *d <= days_in_month(*y, *m)
465 * The input values must be such that the internals don't overflow.
466 * The way this routine is used, we don't get close.
467 */
468static void
469normalize_y_m_d(int *y, int *m, int *d)
470{
471 int dim; /* # of days in month */
472
473 /* This gets muddy: the proper range for day can't be determined
474 * without knowing the correct month and year, but if day is, e.g.,
475 * plus or minus a million, the current month and year values make
476 * no sense (and may also be out of bounds themselves).
477 * Saying 12 months == 1 year should be non-controversial.
478 */
479 if (*m < 1 || *m > 12) {
480 --*m;
481 normalize_pair(y, m, 12);
482 ++*m;
483 /* |y| can't be bigger than about
484 * |original y| + |original m|/12 now.
485 */
486 }
487 assert(1 <= *m && *m <= 12);
488
489 /* Now only day can be out of bounds (year may also be out of bounds
490 * for a datetime object, but we don't care about that here).
491 * If day is out of bounds, what to do is arguable, but at least the
492 * method here is principled and explainable.
493 */
494 dim = days_in_month(*y, *m);
495 if (*d < 1 || *d > dim) {
496 /* Move day-1 days from the first of the month. First try to
497 * get off cheap if we're only one day out of range
498 * (adjustments for timezone alone can't be worse than that).
499 */
500 if (*d == 0) {
501 --*m;
502 if (*m > 0)
503 *d = days_in_month(*y, *m);
504 else {
505 --*y;
506 *m = 12;
507 *d = 31;
508 }
509 }
510 else if (*d == dim + 1) {
511 /* move forward a day */
512 ++*m;
513 *d = 1;
514 if (*m > 12) {
515 *m = 1;
516 ++*y;
517 }
518 }
519 else {
520 int ordinal = ymd_to_ord(*y, *m, 1) +
521 *d - 1;
522 ord_to_ymd(ordinal, y, m, d);
523 }
524 }
525 assert(*m > 0);
526 assert(*d > 0);
527}
528
529/* Fiddle out-of-bounds months and days so that the result makes some kind
530 * of sense. The parameters are both inputs and outputs. Returns < 0 on
531 * failure, where failure means the adjusted year is out of bounds.
532 */
533static int
534normalize_date(int *year, int *month, int *day)
535{
536 int result;
537
538 normalize_y_m_d(year, month, day);
539 if (MINYEAR <= *year && *year <= MAXYEAR)
540 result = 0;
541 else {
542 PyErr_SetString(PyExc_OverflowError,
543 "date value out of range");
544 result = -1;
545 }
546 return result;
547}
548
549/* Force all the datetime fields into range. The parameters are both
550 * inputs and outputs. Returns < 0 on error.
551 */
552static int
553normalize_datetime(int *year, int *month, int *day,
554 int *hour, int *minute, int *second,
555 int *microsecond)
556{
557 normalize_pair(second, microsecond, 1000000);
558 normalize_pair(minute, second, 60);
559 normalize_pair(hour, minute, 60);
560 normalize_pair(day, hour, 24);
561 return normalize_date(year, month, day);
562}
563
564/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000565 * Basic object allocation: tp_alloc implementations. These allocate
566 * Python objects of the right size and type, and do the Python object-
567 * initialization bit. If there's not enough memory, they return NULL after
568 * setting MemoryError. All data members remain uninitialized trash.
569 *
570 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000571 * member is needed. This is ugly, imprecise, and possibly insecure.
572 * tp_basicsize for the time and datetime types is set to the size of the
573 * struct that has room for the tzinfo member, so subclasses in Python will
574 * allocate enough space for a tzinfo member whether or not one is actually
575 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
576 * part is that PyType_GenericAlloc() (which subclasses in Python end up
577 * using) just happens today to effectively ignore the nitems argument
578 * when tp_itemsize is 0, which it is for these type objects. If that
579 * changes, perhaps the callers of tp_alloc slots in this file should
580 * be changed to force a 0 nitems argument unless the type being allocated
581 * is a base type implemented in this file (so that tp_alloc is time_alloc
582 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000583 */
584
585static PyObject *
586time_alloc(PyTypeObject *type, int aware)
587{
588 PyObject *self;
589
590 self = (PyObject *)
591 PyObject_MALLOC(aware ?
592 sizeof(PyDateTime_Time) :
593 sizeof(_PyDateTime_BaseTime));
594 if (self == NULL)
595 return (PyObject *)PyErr_NoMemory();
596 PyObject_INIT(self, type);
597 return self;
598}
599
600static PyObject *
601datetime_alloc(PyTypeObject *type, int aware)
602{
603 PyObject *self;
604
605 self = (PyObject *)
606 PyObject_MALLOC(aware ?
607 sizeof(PyDateTime_DateTime) :
608 sizeof(_PyDateTime_BaseDateTime));
609 if (self == NULL)
610 return (PyObject *)PyErr_NoMemory();
611 PyObject_INIT(self, type);
612 return self;
613}
614
615/* ---------------------------------------------------------------------------
616 * Helpers for setting object fields. These work on pointers to the
617 * appropriate base class.
618 */
619
620/* For date and datetime. */
621static void
622set_date_fields(PyDateTime_Date *self, int y, int m, int d)
623{
624 self->hashcode = -1;
625 SET_YEAR(self, y);
626 SET_MONTH(self, m);
627 SET_DAY(self, d);
628}
629
630/* ---------------------------------------------------------------------------
631 * Create various objects, mostly without range checking.
632 */
633
634/* Create a date instance with no range checking. */
635static PyObject *
636new_date_ex(int year, int month, int day, PyTypeObject *type)
637{
638 PyDateTime_Date *self;
639
640 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
641 if (self != NULL)
642 set_date_fields(self, year, month, day);
643 return (PyObject *) self;
644}
645
646#define new_date(year, month, day) \
647 new_date_ex(year, month, day, &PyDateTime_DateType)
648
649/* Create a datetime instance with no range checking. */
650static PyObject *
651new_datetime_ex(int year, int month, int day, int hour, int minute,
652 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
653{
654 PyDateTime_DateTime *self;
655 char aware = tzinfo != Py_None;
656
657 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
658 if (self != NULL) {
659 self->hastzinfo = aware;
660 set_date_fields((PyDateTime_Date *)self, year, month, day);
661 DATE_SET_HOUR(self, hour);
662 DATE_SET_MINUTE(self, minute);
663 DATE_SET_SECOND(self, second);
664 DATE_SET_MICROSECOND(self, usecond);
665 if (aware) {
666 Py_INCREF(tzinfo);
667 self->tzinfo = tzinfo;
668 }
669 }
670 return (PyObject *)self;
671}
672
673#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
674 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
675 &PyDateTime_DateTimeType)
676
677/* Create a time instance with no range checking. */
678static PyObject *
679new_time_ex(int hour, int minute, int second, int usecond,
680 PyObject *tzinfo, PyTypeObject *type)
681{
682 PyDateTime_Time *self;
683 char aware = tzinfo != Py_None;
684
685 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
686 if (self != NULL) {
687 self->hastzinfo = aware;
688 self->hashcode = -1;
689 TIME_SET_HOUR(self, hour);
690 TIME_SET_MINUTE(self, minute);
691 TIME_SET_SECOND(self, second);
692 TIME_SET_MICROSECOND(self, usecond);
693 if (aware) {
694 Py_INCREF(tzinfo);
695 self->tzinfo = tzinfo;
696 }
697 }
698 return (PyObject *)self;
699}
700
701#define new_time(hh, mm, ss, us, tzinfo) \
702 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
703
704/* Create a timedelta instance. Normalize the members iff normalize is
705 * true. Passing false is a speed optimization, if you know for sure
706 * that seconds and microseconds are already in their proper ranges. In any
707 * case, raises OverflowError and returns NULL if the normalized days is out
708 * of range).
709 */
710static PyObject *
711new_delta_ex(int days, int seconds, int microseconds, int normalize,
712 PyTypeObject *type)
713{
714 PyDateTime_Delta *self;
715
716 if (normalize)
717 normalize_d_s_us(&days, &seconds, &microseconds);
718 assert(0 <= seconds && seconds < 24*3600);
719 assert(0 <= microseconds && microseconds < 1000000);
720
721 if (check_delta_day_range(days) < 0)
722 return NULL;
723
724 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
725 if (self != NULL) {
726 self->hashcode = -1;
727 SET_TD_DAYS(self, days);
728 SET_TD_SECONDS(self, seconds);
729 SET_TD_MICROSECONDS(self, microseconds);
730 }
731 return (PyObject *) self;
732}
733
734#define new_delta(d, s, us, normalize) \
735 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
736
737/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000738 * tzinfo helpers.
739 */
740
Tim Peters855fe882002-12-22 03:43:39 +0000741/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
742 * raise TypeError and return -1.
743 */
744static int
745check_tzinfo_subclass(PyObject *p)
746{
747 if (p == Py_None || PyTZInfo_Check(p))
748 return 0;
749 PyErr_Format(PyExc_TypeError,
750 "tzinfo argument must be None or of a tzinfo subclass, "
751 "not type '%s'",
752 p->ob_type->tp_name);
753 return -1;
754}
755
Tim Petersbad8ff02002-12-30 20:52:32 +0000756/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000757 * If tzinfo is None, returns None.
758 */
759static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000760call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000761{
762 PyObject *result;
763
Tim Petersbad8ff02002-12-30 20:52:32 +0000764 assert(tzinfo && methname && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000765 assert(check_tzinfo_subclass(tzinfo) >= 0);
766 if (tzinfo == Py_None) {
767 result = Py_None;
768 Py_INCREF(result);
769 }
770 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000771 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000772 return result;
773}
774
Tim Peters2a799bf2002-12-16 20:18:38 +0000775/* If self has a tzinfo member, return a BORROWED reference to it. Else
776 * return NULL, which is NOT AN ERROR. There are no error returns here,
777 * and the caller must not decref the result.
778 */
779static PyObject *
780get_tzinfo_member(PyObject *self)
781{
782 PyObject *tzinfo = NULL;
783
Tim Petersa9bc1682003-01-11 03:39:11 +0000784 if (PyDateTime_Check(self) && HASTZINFO(self))
785 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
Tim Petersa032d2e2003-01-11 00:15:54 +0000786 else if (PyTime_Check(self) && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +0000787 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000788
789 return tzinfo;
790}
791
Tim Petersbad8ff02002-12-30 20:52:32 +0000792/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000793 * result. tzinfo must be an instance of the tzinfo class. If the method
794 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000795 * return None or timedelta, TypeError is raised and this returns -1. If it
796 * returnsa timedelta and the value is out of range or isn't a whole number
797 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000798 * Else *none is set to 0 and the integer method result is returned.
799 */
800static int
801call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
802 int *none)
803{
804 PyObject *u;
Tim Peters397301e2003-01-02 21:28:08 +0000805 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000806
807 assert(tzinfo != NULL);
808 assert(PyTZInfo_Check(tzinfo));
809 assert(tzinfoarg != NULL);
810
811 *none = 0;
Tim Petersbad8ff02002-12-30 20:52:32 +0000812 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000813 if (u == NULL)
814 return -1;
815
Tim Peters27362852002-12-23 16:17:39 +0000816 else if (u == Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +0000817 result = 0;
818 *none = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000819 }
Tim Peters855fe882002-12-22 03:43:39 +0000820 else if (PyDelta_Check(u)) {
821 const int days = GET_TD_DAYS(u);
822 if (days < -1 || days > 0)
823 result = 24*60; /* trigger ValueError below */
824 else {
825 /* next line can't overflow because we know days
826 * is -1 or 0 now
827 */
828 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
829 result = divmod(ss, 60, &ss);
830 if (ss || GET_TD_MICROSECONDS(u)) {
831 PyErr_Format(PyExc_ValueError,
832 "tzinfo.%s() must return a "
833 "whole number of minutes",
834 name);
835 result = -1;
Tim Peters855fe882002-12-22 03:43:39 +0000836 }
837 }
838 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000839 else {
840 PyErr_Format(PyExc_TypeError,
Tim Peters397301e2003-01-02 21:28:08 +0000841 "tzinfo.%s() must return None or "
Tim Peters855fe882002-12-22 03:43:39 +0000842 "timedelta, not '%s'",
843 name, u->ob_type->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000844 }
845
Tim Peters2a799bf2002-12-16 20:18:38 +0000846 Py_DECREF(u);
847 if (result < -1439 || result > 1439) {
848 PyErr_Format(PyExc_ValueError,
Neal Norwitz506a2242003-01-04 01:02:25 +0000849 "tzinfo.%s() returned %d; must be in "
Tim Peters2a799bf2002-12-16 20:18:38 +0000850 "-1439 .. 1439",
851 name, result);
852 result = -1;
853 }
Tim Peters397301e2003-01-02 21:28:08 +0000854 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000855}
856
857/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
858 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
859 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000860 * doesn't return None or timedelta, TypeError is raised and this returns -1.
861 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
862 * # of minutes), ValueError is raised and this returns -1. Else *none is
863 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000864 */
865static int
866call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
867{
868 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
869}
870
Tim Petersbad8ff02002-12-30 20:52:32 +0000871/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
872 */
Tim Peters855fe882002-12-22 03:43:39 +0000873static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000874offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Tim Peters855fe882002-12-22 03:43:39 +0000875 PyObject *result;
876
Tim Petersbad8ff02002-12-30 20:52:32 +0000877 assert(tzinfo && name && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000878 if (tzinfo == Py_None) {
879 result = Py_None;
880 Py_INCREF(result);
881 }
882 else {
883 int none;
Tim Petersbad8ff02002-12-30 20:52:32 +0000884 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
885 &none);
Tim Peters855fe882002-12-22 03:43:39 +0000886 if (offset < 0 && PyErr_Occurred())
887 return NULL;
888 if (none) {
889 result = Py_None;
890 Py_INCREF(result);
891 }
892 else
893 result = new_delta(0, offset * 60, 0, 1);
894 }
895 return result;
896}
897
Tim Peters2a799bf2002-12-16 20:18:38 +0000898/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
899 * result. tzinfo must be an instance of the tzinfo class. If dst()
900 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000901 & doesn't return None or timedelta, TypeError is raised and this
902 * returns -1. If dst() returns an invalid timedelta for for a UTC offset,
903 * ValueError is raised and this returns -1. Else *none is set to 0 and
904 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000905 */
906static int
907call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
908{
909 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
910}
911
Tim Petersbad8ff02002-12-30 20:52:32 +0000912/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000913 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000914 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000915 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000916 */
917static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000918call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000919{
920 PyObject *result;
921
922 assert(tzinfo != NULL);
Tim Peters855fe882002-12-22 03:43:39 +0000923 assert(check_tzinfo_subclass(tzinfo) >= 0);
Tim Petersbad8ff02002-12-30 20:52:32 +0000924 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000925
Tim Peters855fe882002-12-22 03:43:39 +0000926 if (tzinfo == Py_None) {
927 result = Py_None;
928 Py_INCREF(result);
929 }
930 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000931 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000932
933 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
934 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
Tim Peters2a799bf2002-12-16 20:18:38 +0000935 "return None or a string, not '%s'",
936 result->ob_type->tp_name);
937 Py_DECREF(result);
938 result = NULL;
939 }
940 return result;
941}
942
943typedef enum {
944 /* an exception has been set; the caller should pass it on */
945 OFFSET_ERROR,
946
Tim Petersa9bc1682003-01-11 03:39:11 +0000947 /* type isn't date, datetime, or time subclass */
Tim Peters2a799bf2002-12-16 20:18:38 +0000948 OFFSET_UNKNOWN,
949
950 /* date,
Tim Petersa9bc1682003-01-11 03:39:11 +0000951 * datetime with !hastzinfo
952 * datetime with None tzinfo,
953 * datetime where utcoffset() returns None
Tim Peters37f39822003-01-10 03:49:02 +0000954 * time with !hastzinfo
955 * time with None tzinfo,
956 * time where utcoffset() returns None
Tim Peters2a799bf2002-12-16 20:18:38 +0000957 */
958 OFFSET_NAIVE,
959
Tim Petersa9bc1682003-01-11 03:39:11 +0000960 /* time or datetime where utcoffset() doesn't return None */
Tim Peters2a799bf2002-12-16 20:18:38 +0000961 OFFSET_AWARE,
962} naivety;
963
Tim Peters14b69412002-12-22 18:10:22 +0000964/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000965 * the "naivety" typedef for details. If the type is aware, *offset is set
966 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000967 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000968 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000969 */
970static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000971classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000972{
973 int none;
974 PyObject *tzinfo;
975
Tim Peterse39a80c2002-12-30 21:28:52 +0000976 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000977 *offset = 0;
Tim Peters14b69412002-12-22 18:10:22 +0000978 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
Tim Peters2a799bf2002-12-16 20:18:38 +0000979 if (tzinfo == Py_None)
980 return OFFSET_NAIVE;
Tim Peters14b69412002-12-22 18:10:22 +0000981 if (tzinfo == NULL) {
982 /* note that a datetime passes the PyDate_Check test */
983 return (PyTime_Check(op) || PyDate_Check(op)) ?
984 OFFSET_NAIVE : OFFSET_UNKNOWN;
985 }
Tim Peterse39a80c2002-12-30 21:28:52 +0000986 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +0000987 if (*offset == -1 && PyErr_Occurred())
988 return OFFSET_ERROR;
989 return none ? OFFSET_NAIVE : OFFSET_AWARE;
990}
991
Tim Peters00237032002-12-27 02:21:51 +0000992/* Classify two objects as to whether they're naive or offset-aware.
993 * This isn't quite the same as calling classify_utcoffset() twice: for
994 * binary operations (comparison and subtraction), we generally want to
995 * ignore the tzinfo members if they're identical. This is by design,
996 * so that results match "naive" expectations when mixing objects from a
997 * single timezone. So in that case, this sets both offsets to 0 and
998 * both naiveties to OFFSET_NAIVE.
999 * The function returns 0 if everything's OK, and -1 on error.
1000 */
1001static int
1002classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Tim Peterse39a80c2002-12-30 21:28:52 +00001003 PyObject *tzinfoarg1,
1004 PyObject *o2, int *offset2, naivety *n2,
1005 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001006{
1007 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1008 *offset1 = *offset2 = 0;
1009 *n1 = *n2 = OFFSET_NAIVE;
1010 }
1011 else {
Tim Peterse39a80c2002-12-30 21:28:52 +00001012 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
Tim Peters00237032002-12-27 02:21:51 +00001013 if (*n1 == OFFSET_ERROR)
1014 return -1;
Tim Peterse39a80c2002-12-30 21:28:52 +00001015 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
Tim Peters00237032002-12-27 02:21:51 +00001016 if (*n2 == OFFSET_ERROR)
1017 return -1;
1018 }
1019 return 0;
1020}
1021
Tim Peters2a799bf2002-12-16 20:18:38 +00001022/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1023 * stuff
1024 * ", tzinfo=" + repr(tzinfo)
1025 * before the closing ")".
1026 */
1027static PyObject *
1028append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1029{
1030 PyObject *temp;
1031
1032 assert(PyString_Check(repr));
1033 assert(tzinfo);
1034 if (tzinfo == Py_None)
1035 return repr;
1036 /* Get rid of the trailing ')'. */
1037 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1038 temp = PyString_FromStringAndSize(PyString_AsString(repr),
1039 PyString_Size(repr) - 1);
1040 Py_DECREF(repr);
1041 if (temp == NULL)
1042 return NULL;
1043 repr = temp;
1044
1045 /* Append ", tzinfo=". */
1046 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
1047
1048 /* Append repr(tzinfo). */
1049 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
1050
1051 /* Add a closing paren. */
1052 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
1053 return repr;
1054}
1055
1056/* ---------------------------------------------------------------------------
1057 * String format helpers.
1058 */
1059
1060static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001061format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001062{
1063 static char *DayNames[] = {
1064 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1065 };
1066 static char *MonthNames[] = {
1067 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1068 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1069 };
1070
1071 char buffer[128];
1072 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1073
1074 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
1075 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
1076 GET_DAY(date), hours, minutes, seconds,
1077 GET_YEAR(date));
1078 return PyString_FromString(buffer);
1079}
1080
1081/* Add an hours & minutes UTC offset string to buf. buf has no more than
1082 * buflen bytes remaining. The UTC offset is gotten by calling
1083 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1084 * *buf, and that's all. Else the returned value is checked for sanity (an
1085 * integer in range), and if that's OK it's converted to an hours & minutes
1086 * string of the form
1087 * sign HH sep MM
1088 * Returns 0 if everything is OK. If the return value from utcoffset() is
1089 * bogus, an appropriate exception is set and -1 is returned.
1090 */
1091static int
Tim Peters328fff72002-12-20 01:31:27 +00001092format_utcoffset(char *buf, size_t buflen, const char *sep,
Tim Peters2a799bf2002-12-16 20:18:38 +00001093 PyObject *tzinfo, PyObject *tzinfoarg)
1094{
1095 int offset;
1096 int hours;
1097 int minutes;
1098 char sign;
1099 int none;
1100
1101 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1102 if (offset == -1 && PyErr_Occurred())
1103 return -1;
1104 if (none) {
1105 *buf = '\0';
1106 return 0;
1107 }
1108 sign = '+';
1109 if (offset < 0) {
1110 sign = '-';
1111 offset = - offset;
1112 }
1113 hours = divmod(offset, 60, &minutes);
1114 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1115 return 0;
1116}
1117
1118/* I sure don't want to reproduce the strftime code from the time module,
1119 * so this imports the module and calls it. All the hair is due to
1120 * giving special meanings to the %z and %Z format codes via a preprocessing
1121 * step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001122 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1123 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001124 */
1125static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +00001126wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
1127 PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001128{
1129 PyObject *result = NULL; /* guilty until proved innocent */
1130
1131 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1132 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1133
1134 char *pin; /* pointer to next char in input format */
1135 char ch; /* next char in input format */
1136
1137 PyObject *newfmt = NULL; /* py string, the output format */
1138 char *pnew; /* pointer to available byte in output format */
1139 char totalnew; /* number bytes total in output format buffer,
1140 exclusive of trailing \0 */
1141 char usednew; /* number bytes used so far in output format buffer */
1142
1143 char *ptoappend; /* pointer to string to append to output buffer */
1144 int ntoappend; /* # of bytes to append to output buffer */
1145
Tim Peters2a799bf2002-12-16 20:18:38 +00001146 assert(object && format && timetuple);
1147 assert(PyString_Check(format));
1148
Tim Petersd6844152002-12-22 20:58:42 +00001149 /* Give up if the year is before 1900.
1150 * Python strftime() plays games with the year, and different
1151 * games depending on whether envar PYTHON2K is set. This makes
1152 * years before 1900 a nightmare, even if the platform strftime
1153 * supports them (and not all do).
1154 * We could get a lot farther here by avoiding Python's strftime
1155 * wrapper and calling the C strftime() directly, but that isn't
1156 * an option in the Python implementation of this module.
1157 */
1158 {
1159 long year;
1160 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1161 if (pyyear == NULL) return NULL;
1162 assert(PyInt_Check(pyyear));
1163 year = PyInt_AsLong(pyyear);
1164 Py_DECREF(pyyear);
1165 if (year < 1900) {
1166 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1167 "1900; the datetime strftime() "
1168 "methods require year >= 1900",
1169 year);
1170 return NULL;
1171 }
1172 }
1173
Tim Peters2a799bf2002-12-16 20:18:38 +00001174 /* Scan the input format, looking for %z and %Z escapes, building
Tim Peters328fff72002-12-20 01:31:27 +00001175 * a new format. Since computing the replacements for those codes
1176 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +00001177 */
1178 totalnew = PyString_Size(format); /* realistic if no %z/%Z */
1179 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1180 if (newfmt == NULL) goto Done;
1181 pnew = PyString_AsString(newfmt);
1182 usednew = 0;
1183
1184 pin = PyString_AsString(format);
1185 while ((ch = *pin++) != '\0') {
1186 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +00001187 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001188 ntoappend = 1;
1189 }
1190 else if ((ch = *pin++) == '\0') {
1191 /* There's a lone trailing %; doesn't make sense. */
1192 PyErr_SetString(PyExc_ValueError, "strftime format "
1193 "ends with raw %");
1194 goto Done;
1195 }
1196 /* A % has been seen and ch is the character after it. */
1197 else if (ch == 'z') {
1198 if (zreplacement == NULL) {
1199 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +00001200 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +00001201 PyObject *tzinfo = get_tzinfo_member(object);
1202 zreplacement = PyString_FromString("");
1203 if (zreplacement == NULL) goto Done;
1204 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001205 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001206 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001207 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001208 "",
1209 tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00001210 tzinfoarg) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001211 goto Done;
1212 Py_DECREF(zreplacement);
1213 zreplacement = PyString_FromString(buf);
1214 if (zreplacement == NULL) goto Done;
1215 }
1216 }
1217 assert(zreplacement != NULL);
1218 ptoappend = PyString_AsString(zreplacement);
1219 ntoappend = PyString_Size(zreplacement);
1220 }
1221 else if (ch == 'Z') {
1222 /* format tzname */
1223 if (Zreplacement == NULL) {
1224 PyObject *tzinfo = get_tzinfo_member(object);
1225 Zreplacement = PyString_FromString("");
1226 if (Zreplacement == NULL) goto Done;
1227 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001228 PyObject *temp;
1229 assert(tzinfoarg != NULL);
1230 temp = call_tzname(tzinfo, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001231 if (temp == NULL) goto Done;
1232 if (temp != Py_None) {
1233 assert(PyString_Check(temp));
1234 /* Since the tzname is getting
1235 * stuffed into the format, we
1236 * have to double any % signs
1237 * so that strftime doesn't
1238 * treat them as format codes.
1239 */
1240 Py_DECREF(Zreplacement);
1241 Zreplacement = PyObject_CallMethod(
1242 temp, "replace",
1243 "ss", "%", "%%");
1244 Py_DECREF(temp);
1245 if (Zreplacement == NULL)
1246 goto Done;
1247 }
1248 else
1249 Py_DECREF(temp);
1250 }
1251 }
1252 assert(Zreplacement != NULL);
1253 ptoappend = PyString_AsString(Zreplacement);
1254 ntoappend = PyString_Size(Zreplacement);
1255 }
1256 else {
Tim Peters328fff72002-12-20 01:31:27 +00001257 /* percent followed by neither z nor Z */
1258 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001259 ntoappend = 2;
1260 }
1261
1262 /* Append the ntoappend chars starting at ptoappend to
1263 * the new format.
1264 */
1265 assert(ntoappend >= 0);
1266 if (ntoappend == 0)
1267 continue;
1268 while (usednew + ntoappend > totalnew) {
1269 int bigger = totalnew << 1;
1270 if ((bigger >> 1) != totalnew) { /* overflow */
1271 PyErr_NoMemory();
1272 goto Done;
1273 }
1274 if (_PyString_Resize(&newfmt, bigger) < 0)
1275 goto Done;
1276 totalnew = bigger;
1277 pnew = PyString_AsString(newfmt) + usednew;
1278 }
1279 memcpy(pnew, ptoappend, ntoappend);
1280 pnew += ntoappend;
1281 usednew += ntoappend;
1282 assert(usednew <= totalnew);
1283 } /* end while() */
1284
1285 if (_PyString_Resize(&newfmt, usednew) < 0)
1286 goto Done;
1287 {
1288 PyObject *time = PyImport_ImportModule("time");
1289 if (time == NULL)
1290 goto Done;
1291 result = PyObject_CallMethod(time, "strftime", "OO",
1292 newfmt, timetuple);
1293 Py_DECREF(time);
1294 }
1295 Done:
1296 Py_XDECREF(zreplacement);
1297 Py_XDECREF(Zreplacement);
1298 Py_XDECREF(newfmt);
1299 return result;
1300}
1301
1302static char *
1303isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1304{
1305 int x;
1306 x = PyOS_snprintf(buffer, bufflen,
1307 "%04d-%02d-%02d",
1308 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1309 return buffer + x;
1310}
1311
1312static void
1313isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1314{
1315 int us = DATE_GET_MICROSECOND(dt);
1316
1317 PyOS_snprintf(buffer, bufflen,
1318 "%02d:%02d:%02d", /* 8 characters */
1319 DATE_GET_HOUR(dt),
1320 DATE_GET_MINUTE(dt),
1321 DATE_GET_SECOND(dt));
1322 if (us)
1323 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1324}
1325
1326/* ---------------------------------------------------------------------------
1327 * Wrap functions from the time module. These aren't directly available
1328 * from C. Perhaps they should be.
1329 */
1330
1331/* Call time.time() and return its result (a Python float). */
1332static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001333time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001334{
1335 PyObject *result = NULL;
1336 PyObject *time = PyImport_ImportModule("time");
1337
1338 if (time != NULL) {
1339 result = PyObject_CallMethod(time, "time", "()");
1340 Py_DECREF(time);
1341 }
1342 return result;
1343}
1344
1345/* Build a time.struct_time. The weekday and day number are automatically
1346 * computed from the y,m,d args.
1347 */
1348static PyObject *
1349build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1350{
1351 PyObject *time;
1352 PyObject *result = NULL;
1353
1354 time = PyImport_ImportModule("time");
1355 if (time != NULL) {
1356 result = PyObject_CallMethod(time, "struct_time",
1357 "((iiiiiiiii))",
1358 y, m, d,
1359 hh, mm, ss,
1360 weekday(y, m, d),
1361 days_before_month(y, m) + d,
1362 dstflag);
1363 Py_DECREF(time);
1364 }
1365 return result;
1366}
1367
1368/* ---------------------------------------------------------------------------
1369 * Miscellaneous helpers.
1370 */
1371
1372/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1373 * The comparisons here all most naturally compute a cmp()-like result.
1374 * This little helper turns that into a bool result for rich comparisons.
1375 */
1376static PyObject *
1377diff_to_bool(int diff, int op)
1378{
1379 PyObject *result;
1380 int istrue;
1381
1382 switch (op) {
1383 case Py_EQ: istrue = diff == 0; break;
1384 case Py_NE: istrue = diff != 0; break;
1385 case Py_LE: istrue = diff <= 0; break;
1386 case Py_GE: istrue = diff >= 0; break;
1387 case Py_LT: istrue = diff < 0; break;
1388 case Py_GT: istrue = diff > 0; break;
1389 default:
1390 assert(! "op unknown");
1391 istrue = 0; /* To shut up compiler */
1392 }
1393 result = istrue ? Py_True : Py_False;
1394 Py_INCREF(result);
1395 return result;
1396}
1397
Tim Peters07534a62003-02-07 22:50:28 +00001398/* Raises a "can't compare" TypeError and returns NULL. */
1399static PyObject *
1400cmperror(PyObject *a, PyObject *b)
1401{
1402 PyErr_Format(PyExc_TypeError,
1403 "can't compare %s to %s",
1404 a->ob_type->tp_name, b->ob_type->tp_name);
1405 return NULL;
1406}
1407
Tim Peters2a799bf2002-12-16 20:18:38 +00001408/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001409 * Cached Python objects; these are set by the module init function.
1410 */
1411
1412/* Conversion factors. */
1413static PyObject *us_per_us = NULL; /* 1 */
1414static PyObject *us_per_ms = NULL; /* 1000 */
1415static PyObject *us_per_second = NULL; /* 1000000 */
1416static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1417static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1418static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1419static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1420static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1421
Tim Peters2a799bf2002-12-16 20:18:38 +00001422/* ---------------------------------------------------------------------------
1423 * Class implementations.
1424 */
1425
1426/*
1427 * PyDateTime_Delta implementation.
1428 */
1429
1430/* Convert a timedelta to a number of us,
1431 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1432 * as a Python int or long.
1433 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1434 * due to ubiquitous overflow possibilities.
1435 */
1436static PyObject *
1437delta_to_microseconds(PyDateTime_Delta *self)
1438{
1439 PyObject *x1 = NULL;
1440 PyObject *x2 = NULL;
1441 PyObject *x3 = NULL;
1442 PyObject *result = NULL;
1443
1444 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1445 if (x1 == NULL)
1446 goto Done;
1447 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1448 if (x2 == NULL)
1449 goto Done;
1450 Py_DECREF(x1);
1451 x1 = NULL;
1452
1453 /* x2 has days in seconds */
1454 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1455 if (x1 == NULL)
1456 goto Done;
1457 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1458 if (x3 == NULL)
1459 goto Done;
1460 Py_DECREF(x1);
1461 Py_DECREF(x2);
1462 x1 = x2 = NULL;
1463
1464 /* x3 has days+seconds in seconds */
1465 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1466 if (x1 == NULL)
1467 goto Done;
1468 Py_DECREF(x3);
1469 x3 = NULL;
1470
1471 /* x1 has days+seconds in us */
1472 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1473 if (x2 == NULL)
1474 goto Done;
1475 result = PyNumber_Add(x1, x2);
1476
1477Done:
1478 Py_XDECREF(x1);
1479 Py_XDECREF(x2);
1480 Py_XDECREF(x3);
1481 return result;
1482}
1483
1484/* Convert a number of us (as a Python int or long) to a timedelta.
1485 */
1486static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001487microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001488{
1489 int us;
1490 int s;
1491 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001492 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001493
1494 PyObject *tuple = NULL;
1495 PyObject *num = NULL;
1496 PyObject *result = NULL;
1497
1498 tuple = PyNumber_Divmod(pyus, us_per_second);
1499 if (tuple == NULL)
1500 goto Done;
1501
1502 num = PyTuple_GetItem(tuple, 1); /* us */
1503 if (num == NULL)
1504 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001505 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001506 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001507 if (temp == -1 && PyErr_Occurred())
1508 goto Done;
1509 assert(0 <= temp && temp < 1000000);
1510 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001511 if (us < 0) {
1512 /* The divisor was positive, so this must be an error. */
1513 assert(PyErr_Occurred());
1514 goto Done;
1515 }
1516
1517 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1518 if (num == NULL)
1519 goto Done;
1520 Py_INCREF(num);
1521 Py_DECREF(tuple);
1522
1523 tuple = PyNumber_Divmod(num, seconds_per_day);
1524 if (tuple == NULL)
1525 goto Done;
1526 Py_DECREF(num);
1527
1528 num = PyTuple_GetItem(tuple, 1); /* seconds */
1529 if (num == NULL)
1530 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001531 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001532 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001533 if (temp == -1 && PyErr_Occurred())
1534 goto Done;
1535 assert(0 <= temp && temp < 24*3600);
1536 s = (int)temp;
1537
Tim Peters2a799bf2002-12-16 20:18:38 +00001538 if (s < 0) {
1539 /* The divisor was positive, so this must be an error. */
1540 assert(PyErr_Occurred());
1541 goto Done;
1542 }
1543
1544 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1545 if (num == NULL)
1546 goto Done;
1547 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001548 temp = PyLong_AsLong(num);
1549 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001550 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001551 d = (int)temp;
1552 if ((long)d != temp) {
1553 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1554 "large to fit in a C int");
1555 goto Done;
1556 }
Tim Petersb0c854d2003-05-17 15:57:00 +00001557 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001558
1559Done:
1560 Py_XDECREF(tuple);
1561 Py_XDECREF(num);
1562 return result;
1563}
1564
Tim Petersb0c854d2003-05-17 15:57:00 +00001565#define microseconds_to_delta(pymicros) \
1566 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1567
Tim Peters2a799bf2002-12-16 20:18:38 +00001568static PyObject *
1569multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1570{
1571 PyObject *pyus_in;
1572 PyObject *pyus_out;
1573 PyObject *result;
1574
1575 pyus_in = delta_to_microseconds(delta);
1576 if (pyus_in == NULL)
1577 return NULL;
1578
1579 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1580 Py_DECREF(pyus_in);
1581 if (pyus_out == NULL)
1582 return NULL;
1583
1584 result = microseconds_to_delta(pyus_out);
1585 Py_DECREF(pyus_out);
1586 return result;
1587}
1588
1589static PyObject *
1590divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1591{
1592 PyObject *pyus_in;
1593 PyObject *pyus_out;
1594 PyObject *result;
1595
1596 pyus_in = delta_to_microseconds(delta);
1597 if (pyus_in == NULL)
1598 return NULL;
1599
1600 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1601 Py_DECREF(pyus_in);
1602 if (pyus_out == NULL)
1603 return NULL;
1604
1605 result = microseconds_to_delta(pyus_out);
1606 Py_DECREF(pyus_out);
1607 return result;
1608}
1609
1610static PyObject *
1611delta_add(PyObject *left, PyObject *right)
1612{
1613 PyObject *result = Py_NotImplemented;
1614
1615 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1616 /* delta + delta */
1617 /* The C-level additions can't overflow because of the
1618 * invariant bounds.
1619 */
1620 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1621 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1622 int microseconds = GET_TD_MICROSECONDS(left) +
1623 GET_TD_MICROSECONDS(right);
1624 result = new_delta(days, seconds, microseconds, 1);
1625 }
1626
1627 if (result == Py_NotImplemented)
1628 Py_INCREF(result);
1629 return result;
1630}
1631
1632static PyObject *
1633delta_negative(PyDateTime_Delta *self)
1634{
1635 return new_delta(-GET_TD_DAYS(self),
1636 -GET_TD_SECONDS(self),
1637 -GET_TD_MICROSECONDS(self),
1638 1);
1639}
1640
1641static PyObject *
1642delta_positive(PyDateTime_Delta *self)
1643{
1644 /* Could optimize this (by returning self) if this isn't a
1645 * subclass -- but who uses unary + ? Approximately nobody.
1646 */
1647 return new_delta(GET_TD_DAYS(self),
1648 GET_TD_SECONDS(self),
1649 GET_TD_MICROSECONDS(self),
1650 0);
1651}
1652
1653static PyObject *
1654delta_abs(PyDateTime_Delta *self)
1655{
1656 PyObject *result;
1657
1658 assert(GET_TD_MICROSECONDS(self) >= 0);
1659 assert(GET_TD_SECONDS(self) >= 0);
1660
1661 if (GET_TD_DAYS(self) < 0)
1662 result = delta_negative(self);
1663 else
1664 result = delta_positive(self);
1665
1666 return result;
1667}
1668
1669static PyObject *
1670delta_subtract(PyObject *left, PyObject *right)
1671{
1672 PyObject *result = Py_NotImplemented;
1673
1674 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1675 /* delta - delta */
1676 PyObject *minus_right = PyNumber_Negative(right);
1677 if (minus_right) {
1678 result = delta_add(left, minus_right);
1679 Py_DECREF(minus_right);
1680 }
1681 else
1682 result = NULL;
1683 }
1684
1685 if (result == Py_NotImplemented)
1686 Py_INCREF(result);
1687 return result;
1688}
1689
1690/* This is more natural as a tp_compare, but doesn't work then: for whatever
1691 * reason, Python's try_3way_compare ignores tp_compare unless
1692 * PyInstance_Check returns true, but these aren't old-style classes.
1693 */
1694static PyObject *
1695delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1696{
Tim Peters07534a62003-02-07 22:50:28 +00001697 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001698
Tim Petersaa7d8492003-02-08 03:28:59 +00001699 if (PyDelta_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00001700 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1701 if (diff == 0) {
1702 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1703 if (diff == 0)
1704 diff = GET_TD_MICROSECONDS(self) -
1705 GET_TD_MICROSECONDS(other);
1706 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001707 }
Tim Peters07534a62003-02-07 22:50:28 +00001708 else if (op == Py_EQ || op == Py_NE)
1709 diff = 1; /* any non-zero value will do */
1710
1711 else /* stop this from falling back to address comparison */
1712 return cmperror((PyObject *)self, other);
1713
Tim Peters2a799bf2002-12-16 20:18:38 +00001714 return diff_to_bool(diff, op);
1715}
1716
1717static PyObject *delta_getstate(PyDateTime_Delta *self);
1718
1719static long
1720delta_hash(PyDateTime_Delta *self)
1721{
1722 if (self->hashcode == -1) {
1723 PyObject *temp = delta_getstate(self);
1724 if (temp != NULL) {
1725 self->hashcode = PyObject_Hash(temp);
1726 Py_DECREF(temp);
1727 }
1728 }
1729 return self->hashcode;
1730}
1731
1732static PyObject *
1733delta_multiply(PyObject *left, PyObject *right)
1734{
1735 PyObject *result = Py_NotImplemented;
1736
1737 if (PyDelta_Check(left)) {
1738 /* delta * ??? */
1739 if (PyInt_Check(right) || PyLong_Check(right))
1740 result = multiply_int_timedelta(right,
1741 (PyDateTime_Delta *) left);
1742 }
1743 else if (PyInt_Check(left) || PyLong_Check(left))
1744 result = multiply_int_timedelta(left,
1745 (PyDateTime_Delta *) right);
1746
1747 if (result == Py_NotImplemented)
1748 Py_INCREF(result);
1749 return result;
1750}
1751
1752static PyObject *
1753delta_divide(PyObject *left, PyObject *right)
1754{
1755 PyObject *result = Py_NotImplemented;
1756
1757 if (PyDelta_Check(left)) {
1758 /* delta * ??? */
1759 if (PyInt_Check(right) || PyLong_Check(right))
1760 result = divide_timedelta_int(
1761 (PyDateTime_Delta *)left,
1762 right);
1763 }
1764
1765 if (result == Py_NotImplemented)
1766 Py_INCREF(result);
1767 return result;
1768}
1769
1770/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1771 * timedelta constructor. sofar is the # of microseconds accounted for
1772 * so far, and there are factor microseconds per current unit, the number
1773 * of which is given by num. num * factor is added to sofar in a
1774 * numerically careful way, and that's the result. Any fractional
1775 * microseconds left over (this can happen if num is a float type) are
1776 * added into *leftover.
1777 * Note that there are many ways this can give an error (NULL) return.
1778 */
1779static PyObject *
1780accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1781 double *leftover)
1782{
1783 PyObject *prod;
1784 PyObject *sum;
1785
1786 assert(num != NULL);
1787
1788 if (PyInt_Check(num) || PyLong_Check(num)) {
1789 prod = PyNumber_Multiply(num, factor);
1790 if (prod == NULL)
1791 return NULL;
1792 sum = PyNumber_Add(sofar, prod);
1793 Py_DECREF(prod);
1794 return sum;
1795 }
1796
1797 if (PyFloat_Check(num)) {
1798 double dnum;
1799 double fracpart;
1800 double intpart;
1801 PyObject *x;
1802 PyObject *y;
1803
1804 /* The Plan: decompose num into an integer part and a
1805 * fractional part, num = intpart + fracpart.
1806 * Then num * factor ==
1807 * intpart * factor + fracpart * factor
1808 * and the LHS can be computed exactly in long arithmetic.
1809 * The RHS is again broken into an int part and frac part.
1810 * and the frac part is added into *leftover.
1811 */
1812 dnum = PyFloat_AsDouble(num);
1813 if (dnum == -1.0 && PyErr_Occurred())
1814 return NULL;
1815 fracpart = modf(dnum, &intpart);
1816 x = PyLong_FromDouble(intpart);
1817 if (x == NULL)
1818 return NULL;
1819
1820 prod = PyNumber_Multiply(x, factor);
1821 Py_DECREF(x);
1822 if (prod == NULL)
1823 return NULL;
1824
1825 sum = PyNumber_Add(sofar, prod);
1826 Py_DECREF(prod);
1827 if (sum == NULL)
1828 return NULL;
1829
1830 if (fracpart == 0.0)
1831 return sum;
1832 /* So far we've lost no information. Dealing with the
1833 * fractional part requires float arithmetic, and may
1834 * lose a little info.
1835 */
1836 assert(PyInt_Check(factor) || PyLong_Check(factor));
1837 if (PyInt_Check(factor))
1838 dnum = (double)PyInt_AsLong(factor);
1839 else
1840 dnum = PyLong_AsDouble(factor);
1841
1842 dnum *= fracpart;
1843 fracpart = modf(dnum, &intpart);
1844 x = PyLong_FromDouble(intpart);
1845 if (x == NULL) {
1846 Py_DECREF(sum);
1847 return NULL;
1848 }
1849
1850 y = PyNumber_Add(sum, x);
1851 Py_DECREF(sum);
1852 Py_DECREF(x);
1853 *leftover += fracpart;
1854 return y;
1855 }
1856
1857 PyErr_Format(PyExc_TypeError,
1858 "unsupported type for timedelta %s component: %s",
1859 tag, num->ob_type->tp_name);
1860 return NULL;
1861}
1862
1863static PyObject *
1864delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1865{
1866 PyObject *self = NULL;
1867
1868 /* Argument objects. */
1869 PyObject *day = NULL;
1870 PyObject *second = NULL;
1871 PyObject *us = NULL;
1872 PyObject *ms = NULL;
1873 PyObject *minute = NULL;
1874 PyObject *hour = NULL;
1875 PyObject *week = NULL;
1876
1877 PyObject *x = NULL; /* running sum of microseconds */
1878 PyObject *y = NULL; /* temp sum of microseconds */
1879 double leftover_us = 0.0;
1880
1881 static char *keywords[] = {
1882 "days", "seconds", "microseconds", "milliseconds",
1883 "minutes", "hours", "weeks", NULL
1884 };
1885
1886 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1887 keywords,
1888 &day, &second, &us,
1889 &ms, &minute, &hour, &week) == 0)
1890 goto Done;
1891
1892 x = PyInt_FromLong(0);
1893 if (x == NULL)
1894 goto Done;
1895
1896#define CLEANUP \
1897 Py_DECREF(x); \
1898 x = y; \
1899 if (x == NULL) \
1900 goto Done
1901
1902 if (us) {
1903 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1904 CLEANUP;
1905 }
1906 if (ms) {
1907 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1908 CLEANUP;
1909 }
1910 if (second) {
1911 y = accum("seconds", x, second, us_per_second, &leftover_us);
1912 CLEANUP;
1913 }
1914 if (minute) {
1915 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1916 CLEANUP;
1917 }
1918 if (hour) {
1919 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1920 CLEANUP;
1921 }
1922 if (day) {
1923 y = accum("days", x, day, us_per_day, &leftover_us);
1924 CLEANUP;
1925 }
1926 if (week) {
1927 y = accum("weeks", x, week, us_per_week, &leftover_us);
1928 CLEANUP;
1929 }
1930 if (leftover_us) {
1931 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001932 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001933 if (temp == NULL) {
1934 Py_DECREF(x);
1935 goto Done;
1936 }
1937 y = PyNumber_Add(x, temp);
1938 Py_DECREF(temp);
1939 CLEANUP;
1940 }
1941
Tim Petersb0c854d2003-05-17 15:57:00 +00001942 self = microseconds_to_delta_ex(x, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001943 Py_DECREF(x);
1944Done:
1945 return self;
1946
1947#undef CLEANUP
1948}
1949
1950static int
1951delta_nonzero(PyDateTime_Delta *self)
1952{
1953 return (GET_TD_DAYS(self) != 0
1954 || GET_TD_SECONDS(self) != 0
1955 || GET_TD_MICROSECONDS(self) != 0);
1956}
1957
1958static PyObject *
1959delta_repr(PyDateTime_Delta *self)
1960{
1961 if (GET_TD_MICROSECONDS(self) != 0)
1962 return PyString_FromFormat("%s(%d, %d, %d)",
1963 self->ob_type->tp_name,
1964 GET_TD_DAYS(self),
1965 GET_TD_SECONDS(self),
1966 GET_TD_MICROSECONDS(self));
1967 if (GET_TD_SECONDS(self) != 0)
1968 return PyString_FromFormat("%s(%d, %d)",
1969 self->ob_type->tp_name,
1970 GET_TD_DAYS(self),
1971 GET_TD_SECONDS(self));
1972
1973 return PyString_FromFormat("%s(%d)",
1974 self->ob_type->tp_name,
1975 GET_TD_DAYS(self));
1976}
1977
1978static PyObject *
1979delta_str(PyDateTime_Delta *self)
1980{
1981 int days = GET_TD_DAYS(self);
1982 int seconds = GET_TD_SECONDS(self);
1983 int us = GET_TD_MICROSECONDS(self);
1984 int hours;
1985 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00001986 char buf[100];
1987 char *pbuf = buf;
1988 size_t buflen = sizeof(buf);
1989 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00001990
1991 minutes = divmod(seconds, 60, &seconds);
1992 hours = divmod(minutes, 60, &minutes);
1993
1994 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00001995 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
1996 (days == 1 || days == -1) ? "" : "s");
1997 if (n < 0 || (size_t)n >= buflen)
1998 goto Fail;
1999 pbuf += n;
2000 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002001 }
2002
Tim Petersba873472002-12-18 20:19:21 +00002003 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2004 hours, minutes, seconds);
2005 if (n < 0 || (size_t)n >= buflen)
2006 goto Fail;
2007 pbuf += n;
2008 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002009
2010 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00002011 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2012 if (n < 0 || (size_t)n >= buflen)
2013 goto Fail;
2014 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002015 }
2016
Tim Petersba873472002-12-18 20:19:21 +00002017 return PyString_FromStringAndSize(buf, pbuf - buf);
2018
2019 Fail:
2020 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2021 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002022}
2023
Tim Peters371935f2003-02-01 01:52:50 +00002024/* Pickle support, a simple use of __reduce__. */
2025
Tim Petersb57f8f02003-02-01 02:54:15 +00002026/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002027static PyObject *
2028delta_getstate(PyDateTime_Delta *self)
2029{
2030 return Py_BuildValue("iii", GET_TD_DAYS(self),
2031 GET_TD_SECONDS(self),
2032 GET_TD_MICROSECONDS(self));
2033}
2034
Tim Peters2a799bf2002-12-16 20:18:38 +00002035static PyObject *
2036delta_reduce(PyDateTime_Delta* self)
2037{
Tim Peters8a60c222003-02-01 01:47:29 +00002038 return Py_BuildValue("ON", self->ob_type, delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002039}
2040
2041#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2042
2043static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002044
Neal Norwitzdfb80862002-12-19 02:30:56 +00002045 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002046 PyDoc_STR("Number of days.")},
2047
Neal Norwitzdfb80862002-12-19 02:30:56 +00002048 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002049 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2050
Neal Norwitzdfb80862002-12-19 02:30:56 +00002051 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002052 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2053 {NULL}
2054};
2055
2056static PyMethodDef delta_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002057 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2058 PyDoc_STR("__reduce__() -> (cls, state)")},
2059
Tim Peters2a799bf2002-12-16 20:18:38 +00002060 {NULL, NULL},
2061};
2062
2063static char delta_doc[] =
2064PyDoc_STR("Difference between two datetime values.");
2065
2066static PyNumberMethods delta_as_number = {
2067 delta_add, /* nb_add */
2068 delta_subtract, /* nb_subtract */
2069 delta_multiply, /* nb_multiply */
2070 delta_divide, /* nb_divide */
2071 0, /* nb_remainder */
2072 0, /* nb_divmod */
2073 0, /* nb_power */
2074 (unaryfunc)delta_negative, /* nb_negative */
2075 (unaryfunc)delta_positive, /* nb_positive */
2076 (unaryfunc)delta_abs, /* nb_absolute */
2077 (inquiry)delta_nonzero, /* nb_nonzero */
2078 0, /*nb_invert*/
2079 0, /*nb_lshift*/
2080 0, /*nb_rshift*/
2081 0, /*nb_and*/
2082 0, /*nb_xor*/
2083 0, /*nb_or*/
2084 0, /*nb_coerce*/
2085 0, /*nb_int*/
2086 0, /*nb_long*/
2087 0, /*nb_float*/
2088 0, /*nb_oct*/
2089 0, /*nb_hex*/
2090 0, /*nb_inplace_add*/
2091 0, /*nb_inplace_subtract*/
2092 0, /*nb_inplace_multiply*/
2093 0, /*nb_inplace_divide*/
2094 0, /*nb_inplace_remainder*/
2095 0, /*nb_inplace_power*/
2096 0, /*nb_inplace_lshift*/
2097 0, /*nb_inplace_rshift*/
2098 0, /*nb_inplace_and*/
2099 0, /*nb_inplace_xor*/
2100 0, /*nb_inplace_or*/
2101 delta_divide, /* nb_floor_divide */
2102 0, /* nb_true_divide */
2103 0, /* nb_inplace_floor_divide */
2104 0, /* nb_inplace_true_divide */
2105};
2106
2107static PyTypeObject PyDateTime_DeltaType = {
2108 PyObject_HEAD_INIT(NULL)
2109 0, /* ob_size */
2110 "datetime.timedelta", /* tp_name */
2111 sizeof(PyDateTime_Delta), /* tp_basicsize */
2112 0, /* tp_itemsize */
2113 0, /* tp_dealloc */
2114 0, /* tp_print */
2115 0, /* tp_getattr */
2116 0, /* tp_setattr */
2117 0, /* tp_compare */
2118 (reprfunc)delta_repr, /* tp_repr */
2119 &delta_as_number, /* tp_as_number */
2120 0, /* tp_as_sequence */
2121 0, /* tp_as_mapping */
2122 (hashfunc)delta_hash, /* tp_hash */
2123 0, /* tp_call */
2124 (reprfunc)delta_str, /* tp_str */
2125 PyObject_GenericGetAttr, /* tp_getattro */
2126 0, /* tp_setattro */
2127 0, /* tp_as_buffer */
Tim Petersb0c854d2003-05-17 15:57:00 +00002128 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2129 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters2a799bf2002-12-16 20:18:38 +00002130 delta_doc, /* tp_doc */
2131 0, /* tp_traverse */
2132 0, /* tp_clear */
2133 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2134 0, /* tp_weaklistoffset */
2135 0, /* tp_iter */
2136 0, /* tp_iternext */
2137 delta_methods, /* tp_methods */
2138 delta_members, /* tp_members */
2139 0, /* tp_getset */
2140 0, /* tp_base */
2141 0, /* tp_dict */
2142 0, /* tp_descr_get */
2143 0, /* tp_descr_set */
2144 0, /* tp_dictoffset */
2145 0, /* tp_init */
2146 0, /* tp_alloc */
2147 delta_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002148 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002149};
2150
2151/*
2152 * PyDateTime_Date implementation.
2153 */
2154
2155/* Accessor properties. */
2156
2157static PyObject *
2158date_year(PyDateTime_Date *self, void *unused)
2159{
2160 return PyInt_FromLong(GET_YEAR(self));
2161}
2162
2163static PyObject *
2164date_month(PyDateTime_Date *self, void *unused)
2165{
2166 return PyInt_FromLong(GET_MONTH(self));
2167}
2168
2169static PyObject *
2170date_day(PyDateTime_Date *self, void *unused)
2171{
2172 return PyInt_FromLong(GET_DAY(self));
2173}
2174
2175static PyGetSetDef date_getset[] = {
2176 {"year", (getter)date_year},
2177 {"month", (getter)date_month},
2178 {"day", (getter)date_day},
2179 {NULL}
2180};
2181
2182/* Constructors. */
2183
Tim Peters12bf3392002-12-24 05:41:27 +00002184static char *date_kws[] = {"year", "month", "day", NULL};
2185
Tim Peters2a799bf2002-12-16 20:18:38 +00002186static PyObject *
2187date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2188{
2189 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002190 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002191 int year;
2192 int month;
2193 int day;
2194
Guido van Rossum177e41a2003-01-30 22:06:23 +00002195 /* Check for invocation from pickle with __getstate__ state */
2196 if (PyTuple_GET_SIZE(args) == 1 &&
Tim Peters70533e22003-02-01 04:40:04 +00002197 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2198 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00002199 {
Tim Peters70533e22003-02-01 04:40:04 +00002200 PyDateTime_Date *me;
2201
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002202 me = PyObject_New(PyDateTime_Date, type);
Tim Peters70533e22003-02-01 04:40:04 +00002203 if (me != NULL) {
2204 char *pdata = PyString_AS_STRING(state);
2205 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2206 me->hashcode = -1;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002207 }
Tim Peters70533e22003-02-01 04:40:04 +00002208 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002209 }
2210
Tim Peters12bf3392002-12-24 05:41:27 +00002211 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002212 &year, &month, &day)) {
2213 if (check_date_args(year, month, day) < 0)
2214 return NULL;
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002215 self = new_date_ex(year, month, day, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00002216 }
2217 return self;
2218}
2219
2220/* Return new date from localtime(t). */
2221static PyObject *
2222date_local_from_time_t(PyObject *cls, time_t t)
2223{
2224 struct tm *tm;
2225 PyObject *result = NULL;
2226
2227 tm = localtime(&t);
2228 if (tm)
2229 result = PyObject_CallFunction(cls, "iii",
2230 tm->tm_year + 1900,
2231 tm->tm_mon + 1,
2232 tm->tm_mday);
2233 else
2234 PyErr_SetString(PyExc_ValueError,
2235 "timestamp out of range for "
2236 "platform localtime() function");
2237 return result;
2238}
2239
2240/* Return new date from current time.
2241 * We say this is equivalent to fromtimestamp(time.time()), and the
2242 * only way to be sure of that is to *call* time.time(). That's not
2243 * generally the same as calling C's time.
2244 */
2245static PyObject *
2246date_today(PyObject *cls, PyObject *dummy)
2247{
2248 PyObject *time;
2249 PyObject *result;
2250
2251 time = time_time();
2252 if (time == NULL)
2253 return NULL;
2254
2255 /* Note well: today() is a class method, so this may not call
2256 * date.fromtimestamp. For example, it may call
2257 * datetime.fromtimestamp. That's why we need all the accuracy
2258 * time.time() delivers; if someone were gonzo about optimization,
2259 * date.today() could get away with plain C time().
2260 */
2261 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2262 Py_DECREF(time);
2263 return result;
2264}
2265
2266/* Return new date from given timestamp (Python timestamp -- a double). */
2267static PyObject *
2268date_fromtimestamp(PyObject *cls, PyObject *args)
2269{
2270 double timestamp;
2271 PyObject *result = NULL;
2272
2273 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
2274 result = date_local_from_time_t(cls, (time_t)timestamp);
2275 return result;
2276}
2277
2278/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2279 * the ordinal is out of range.
2280 */
2281static PyObject *
2282date_fromordinal(PyObject *cls, PyObject *args)
2283{
2284 PyObject *result = NULL;
2285 int ordinal;
2286
2287 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2288 int year;
2289 int month;
2290 int day;
2291
2292 if (ordinal < 1)
2293 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2294 ">= 1");
2295 else {
2296 ord_to_ymd(ordinal, &year, &month, &day);
2297 result = PyObject_CallFunction(cls, "iii",
2298 year, month, day);
2299 }
2300 }
2301 return result;
2302}
2303
2304/*
2305 * Date arithmetic.
2306 */
2307
2308/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2309 * instead.
2310 */
2311static PyObject *
2312add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2313{
2314 PyObject *result = NULL;
2315 int year = GET_YEAR(date);
2316 int month = GET_MONTH(date);
2317 int deltadays = GET_TD_DAYS(delta);
2318 /* C-level overflow is impossible because |deltadays| < 1e9. */
2319 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2320
2321 if (normalize_date(&year, &month, &day) >= 0)
2322 result = new_date(year, month, day);
2323 return result;
2324}
2325
2326static PyObject *
2327date_add(PyObject *left, PyObject *right)
2328{
2329 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2330 Py_INCREF(Py_NotImplemented);
2331 return Py_NotImplemented;
2332 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002333 if (PyDate_Check(left)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002334 /* date + ??? */
2335 if (PyDelta_Check(right))
2336 /* date + delta */
2337 return add_date_timedelta((PyDateTime_Date *) left,
2338 (PyDateTime_Delta *) right,
2339 0);
2340 }
2341 else {
2342 /* ??? + date
2343 * 'right' must be one of us, or we wouldn't have been called
2344 */
2345 if (PyDelta_Check(left))
2346 /* delta + date */
2347 return add_date_timedelta((PyDateTime_Date *) right,
2348 (PyDateTime_Delta *) left,
2349 0);
2350 }
2351 Py_INCREF(Py_NotImplemented);
2352 return Py_NotImplemented;
2353}
2354
2355static PyObject *
2356date_subtract(PyObject *left, PyObject *right)
2357{
2358 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2359 Py_INCREF(Py_NotImplemented);
2360 return Py_NotImplemented;
2361 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002362 if (PyDate_Check(left)) {
2363 if (PyDate_Check(right)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002364 /* date - date */
2365 int left_ord = ymd_to_ord(GET_YEAR(left),
2366 GET_MONTH(left),
2367 GET_DAY(left));
2368 int right_ord = ymd_to_ord(GET_YEAR(right),
2369 GET_MONTH(right),
2370 GET_DAY(right));
2371 return new_delta(left_ord - right_ord, 0, 0, 0);
2372 }
2373 if (PyDelta_Check(right)) {
2374 /* date - delta */
2375 return add_date_timedelta((PyDateTime_Date *) left,
2376 (PyDateTime_Delta *) right,
2377 1);
2378 }
2379 }
2380 Py_INCREF(Py_NotImplemented);
2381 return Py_NotImplemented;
2382}
2383
2384
2385/* Various ways to turn a date into a string. */
2386
2387static PyObject *
2388date_repr(PyDateTime_Date *self)
2389{
2390 char buffer[1028];
2391 char *typename;
2392
2393 typename = self->ob_type->tp_name;
2394 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2395 typename,
2396 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2397
2398 return PyString_FromString(buffer);
2399}
2400
2401static PyObject *
2402date_isoformat(PyDateTime_Date *self)
2403{
2404 char buffer[128];
2405
2406 isoformat_date(self, buffer, sizeof(buffer));
2407 return PyString_FromString(buffer);
2408}
2409
Tim Peterse2df5ff2003-05-02 18:39:55 +00002410/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002411static PyObject *
2412date_str(PyDateTime_Date *self)
2413{
2414 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2415}
2416
2417
2418static PyObject *
2419date_ctime(PyDateTime_Date *self)
2420{
2421 return format_ctime(self, 0, 0, 0);
2422}
2423
2424static PyObject *
2425date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2426{
2427 /* This method can be inherited, and needs to call the
2428 * timetuple() method appropriate to self's class.
2429 */
2430 PyObject *result;
2431 PyObject *format;
2432 PyObject *tuple;
2433 static char *keywords[] = {"format", NULL};
2434
2435 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
2436 &PyString_Type, &format))
2437 return NULL;
2438
2439 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2440 if (tuple == NULL)
2441 return NULL;
Tim Petersbad8ff02002-12-30 20:52:32 +00002442 result = wrap_strftime((PyObject *)self, format, tuple,
2443 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002444 Py_DECREF(tuple);
2445 return result;
2446}
2447
2448/* ISO methods. */
2449
2450static PyObject *
2451date_isoweekday(PyDateTime_Date *self)
2452{
2453 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2454
2455 return PyInt_FromLong(dow + 1);
2456}
2457
2458static PyObject *
2459date_isocalendar(PyDateTime_Date *self)
2460{
2461 int year = GET_YEAR(self);
2462 int week1_monday = iso_week1_monday(year);
2463 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2464 int week;
2465 int day;
2466
2467 week = divmod(today - week1_monday, 7, &day);
2468 if (week < 0) {
2469 --year;
2470 week1_monday = iso_week1_monday(year);
2471 week = divmod(today - week1_monday, 7, &day);
2472 }
2473 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2474 ++year;
2475 week = 0;
2476 }
2477 return Py_BuildValue("iii", year, week + 1, day + 1);
2478}
2479
2480/* Miscellaneous methods. */
2481
2482/* This is more natural as a tp_compare, but doesn't work then: for whatever
2483 * reason, Python's try_3way_compare ignores tp_compare unless
2484 * PyInstance_Check returns true, but these aren't old-style classes.
2485 */
2486static PyObject *
2487date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2488{
Tim Peters07534a62003-02-07 22:50:28 +00002489 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002490
Tim Peters07534a62003-02-07 22:50:28 +00002491 if (PyDate_Check(other))
2492 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2493 _PyDateTime_DATE_DATASIZE);
2494
2495 else if (PyObject_HasAttrString(other, "timetuple")) {
2496 /* A hook for other kinds of date objects. */
2497 Py_INCREF(Py_NotImplemented);
2498 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002499 }
Tim Peters07534a62003-02-07 22:50:28 +00002500 else if (op == Py_EQ || op == Py_NE)
2501 diff = 1; /* any non-zero value will do */
2502
2503 else /* stop this from falling back to address comparison */
2504 return cmperror((PyObject *)self, other);
2505
Tim Peters2a799bf2002-12-16 20:18:38 +00002506 return diff_to_bool(diff, op);
2507}
2508
2509static PyObject *
2510date_timetuple(PyDateTime_Date *self)
2511{
2512 return build_struct_time(GET_YEAR(self),
2513 GET_MONTH(self),
2514 GET_DAY(self),
2515 0, 0, 0, -1);
2516}
2517
Tim Peters12bf3392002-12-24 05:41:27 +00002518static PyObject *
2519date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2520{
2521 PyObject *clone;
2522 PyObject *tuple;
2523 int year = GET_YEAR(self);
2524 int month = GET_MONTH(self);
2525 int day = GET_DAY(self);
2526
2527 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2528 &year, &month, &day))
2529 return NULL;
2530 tuple = Py_BuildValue("iii", year, month, day);
2531 if (tuple == NULL)
2532 return NULL;
2533 clone = date_new(self->ob_type, tuple, NULL);
2534 Py_DECREF(tuple);
2535 return clone;
2536}
2537
Tim Peters2a799bf2002-12-16 20:18:38 +00002538static PyObject *date_getstate(PyDateTime_Date *self);
2539
2540static long
2541date_hash(PyDateTime_Date *self)
2542{
2543 if (self->hashcode == -1) {
2544 PyObject *temp = date_getstate(self);
2545 if (temp != NULL) {
2546 self->hashcode = PyObject_Hash(temp);
2547 Py_DECREF(temp);
2548 }
2549 }
2550 return self->hashcode;
2551}
2552
2553static PyObject *
2554date_toordinal(PyDateTime_Date *self)
2555{
2556 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2557 GET_DAY(self)));
2558}
2559
2560static PyObject *
2561date_weekday(PyDateTime_Date *self)
2562{
2563 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2564
2565 return PyInt_FromLong(dow);
2566}
2567
Tim Peters371935f2003-02-01 01:52:50 +00002568/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002569
Tim Petersb57f8f02003-02-01 02:54:15 +00002570/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002571static PyObject *
2572date_getstate(PyDateTime_Date *self)
2573{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002574 return Py_BuildValue(
2575 "(N)",
2576 PyString_FromStringAndSize((char *)self->data,
2577 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002578}
2579
2580static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002581date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002582{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002583 return Py_BuildValue("(ON)", self->ob_type, date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002584}
2585
2586static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002587
Tim Peters2a799bf2002-12-16 20:18:38 +00002588 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002589
Tim Peters2a799bf2002-12-16 20:18:38 +00002590 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2591 METH_CLASS,
2592 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2593 "time.time()).")},
2594
2595 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2596 METH_CLASS,
2597 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2598 "ordinal.")},
2599
2600 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2601 PyDoc_STR("Current date or datetime: same as "
2602 "self.__class__.fromtimestamp(time.time()).")},
2603
2604 /* Instance methods: */
2605
2606 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2607 PyDoc_STR("Return ctime() style string.")},
2608
2609 {"strftime", (PyCFunction)date_strftime, METH_KEYWORDS,
2610 PyDoc_STR("format -> strftime() style string.")},
2611
2612 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2613 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2614
2615 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2616 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2617 "weekday.")},
2618
2619 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2620 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2621
2622 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2623 PyDoc_STR("Return the day of the week represented by the date.\n"
2624 "Monday == 1 ... Sunday == 7")},
2625
2626 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2627 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2628 "1 is day 1.")},
2629
2630 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2631 PyDoc_STR("Return the day of the week represented by the date.\n"
2632 "Monday == 0 ... Sunday == 6")},
2633
Tim Peters12bf3392002-12-24 05:41:27 +00002634 {"replace", (PyCFunction)date_replace, METH_KEYWORDS,
2635 PyDoc_STR("Return date with new specified fields.")},
2636
Guido van Rossum177e41a2003-01-30 22:06:23 +00002637 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2638 PyDoc_STR("__reduce__() -> (cls, state)")},
2639
Tim Peters2a799bf2002-12-16 20:18:38 +00002640 {NULL, NULL}
2641};
2642
2643static char date_doc[] =
2644PyDoc_STR("Basic date type.");
2645
2646static PyNumberMethods date_as_number = {
2647 date_add, /* nb_add */
2648 date_subtract, /* nb_subtract */
2649 0, /* nb_multiply */
2650 0, /* nb_divide */
2651 0, /* nb_remainder */
2652 0, /* nb_divmod */
2653 0, /* nb_power */
2654 0, /* nb_negative */
2655 0, /* nb_positive */
2656 0, /* nb_absolute */
2657 0, /* nb_nonzero */
2658};
2659
2660static PyTypeObject PyDateTime_DateType = {
2661 PyObject_HEAD_INIT(NULL)
2662 0, /* ob_size */
2663 "datetime.date", /* tp_name */
2664 sizeof(PyDateTime_Date), /* tp_basicsize */
2665 0, /* tp_itemsize */
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002666 0, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00002667 0, /* tp_print */
2668 0, /* tp_getattr */
2669 0, /* tp_setattr */
2670 0, /* tp_compare */
2671 (reprfunc)date_repr, /* tp_repr */
2672 &date_as_number, /* tp_as_number */
2673 0, /* tp_as_sequence */
2674 0, /* tp_as_mapping */
2675 (hashfunc)date_hash, /* tp_hash */
2676 0, /* tp_call */
2677 (reprfunc)date_str, /* tp_str */
2678 PyObject_GenericGetAttr, /* tp_getattro */
2679 0, /* tp_setattro */
2680 0, /* tp_as_buffer */
2681 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2682 Py_TPFLAGS_BASETYPE, /* tp_flags */
2683 date_doc, /* tp_doc */
2684 0, /* tp_traverse */
2685 0, /* tp_clear */
2686 (richcmpfunc)date_richcompare, /* tp_richcompare */
2687 0, /* tp_weaklistoffset */
2688 0, /* tp_iter */
2689 0, /* tp_iternext */
2690 date_methods, /* tp_methods */
2691 0, /* tp_members */
2692 date_getset, /* tp_getset */
2693 0, /* tp_base */
2694 0, /* tp_dict */
2695 0, /* tp_descr_get */
2696 0, /* tp_descr_set */
2697 0, /* tp_dictoffset */
2698 0, /* tp_init */
2699 0, /* tp_alloc */
2700 date_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002701 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002702};
2703
2704/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002705 * PyDateTime_TZInfo implementation.
2706 */
2707
2708/* This is a pure abstract base class, so doesn't do anything beyond
2709 * raising NotImplemented exceptions. Real tzinfo classes need
2710 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002711 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002712 * be subclasses of this tzinfo class, which is easy and quick to check).
2713 *
2714 * Note: For reasons having to do with pickling of subclasses, we have
2715 * to allow tzinfo objects to be instantiated. This wasn't an issue
2716 * in the Python implementation (__init__() could raise NotImplementedError
2717 * there without ill effect), but doing so in the C implementation hit a
2718 * brick wall.
2719 */
2720
2721static PyObject *
2722tzinfo_nogo(const char* methodname)
2723{
2724 PyErr_Format(PyExc_NotImplementedError,
2725 "a tzinfo subclass must implement %s()",
2726 methodname);
2727 return NULL;
2728}
2729
2730/* Methods. A subclass must implement these. */
2731
Tim Peters52dcce22003-01-23 16:36:11 +00002732static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002733tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2734{
2735 return tzinfo_nogo("tzname");
2736}
2737
Tim Peters52dcce22003-01-23 16:36:11 +00002738static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002739tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2740{
2741 return tzinfo_nogo("utcoffset");
2742}
2743
Tim Peters52dcce22003-01-23 16:36:11 +00002744static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002745tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2746{
2747 return tzinfo_nogo("dst");
2748}
2749
Tim Peters52dcce22003-01-23 16:36:11 +00002750static PyObject *
2751tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2752{
2753 int y, m, d, hh, mm, ss, us;
2754
2755 PyObject *result;
2756 int off, dst;
2757 int none;
2758 int delta;
2759
2760 if (! PyDateTime_Check(dt)) {
2761 PyErr_SetString(PyExc_TypeError,
2762 "fromutc: argument must be a datetime");
2763 return NULL;
2764 }
2765 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2766 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2767 "is not self");
2768 return NULL;
2769 }
2770
2771 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2772 if (off == -1 && PyErr_Occurred())
2773 return NULL;
2774 if (none) {
2775 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2776 "utcoffset() result required");
2777 return NULL;
2778 }
2779
2780 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2781 if (dst == -1 && PyErr_Occurred())
2782 return NULL;
2783 if (none) {
2784 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2785 "dst() result required");
2786 return NULL;
2787 }
2788
2789 y = GET_YEAR(dt);
2790 m = GET_MONTH(dt);
2791 d = GET_DAY(dt);
2792 hh = DATE_GET_HOUR(dt);
2793 mm = DATE_GET_MINUTE(dt);
2794 ss = DATE_GET_SECOND(dt);
2795 us = DATE_GET_MICROSECOND(dt);
2796
2797 delta = off - dst;
2798 mm += delta;
2799 if ((mm < 0 || mm >= 60) &&
2800 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002801 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002802 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2803 if (result == NULL)
2804 return result;
2805
2806 dst = call_dst(dt->tzinfo, result, &none);
2807 if (dst == -1 && PyErr_Occurred())
2808 goto Fail;
2809 if (none)
2810 goto Inconsistent;
2811 if (dst == 0)
2812 return result;
2813
2814 mm += dst;
2815 if ((mm < 0 || mm >= 60) &&
2816 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2817 goto Fail;
2818 Py_DECREF(result);
2819 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2820 return result;
2821
2822Inconsistent:
2823 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2824 "inconsistent results; cannot convert");
2825
2826 /* fall thru to failure */
2827Fail:
2828 Py_DECREF(result);
2829 return NULL;
2830}
2831
Tim Peters2a799bf2002-12-16 20:18:38 +00002832/*
2833 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002834 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002835 */
2836
Guido van Rossum177e41a2003-01-30 22:06:23 +00002837static PyObject *
2838tzinfo_reduce(PyObject *self)
2839{
2840 PyObject *args, *state, *tmp;
2841 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002842
Guido van Rossum177e41a2003-01-30 22:06:23 +00002843 tmp = PyTuple_New(0);
2844 if (tmp == NULL)
2845 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002846
Guido van Rossum177e41a2003-01-30 22:06:23 +00002847 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2848 if (getinitargs != NULL) {
2849 args = PyObject_CallObject(getinitargs, tmp);
2850 Py_DECREF(getinitargs);
2851 if (args == NULL) {
2852 Py_DECREF(tmp);
2853 return NULL;
2854 }
2855 }
2856 else {
2857 PyErr_Clear();
2858 args = tmp;
2859 Py_INCREF(args);
2860 }
2861
2862 getstate = PyObject_GetAttrString(self, "__getstate__");
2863 if (getstate != NULL) {
2864 state = PyObject_CallObject(getstate, tmp);
2865 Py_DECREF(getstate);
2866 if (state == NULL) {
2867 Py_DECREF(args);
2868 Py_DECREF(tmp);
2869 return NULL;
2870 }
2871 }
2872 else {
2873 PyObject **dictptr;
2874 PyErr_Clear();
2875 state = Py_None;
2876 dictptr = _PyObject_GetDictPtr(self);
2877 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2878 state = *dictptr;
2879 Py_INCREF(state);
2880 }
2881
2882 Py_DECREF(tmp);
2883
2884 if (state == Py_None) {
2885 Py_DECREF(state);
2886 return Py_BuildValue("(ON)", self->ob_type, args);
2887 }
2888 else
2889 return Py_BuildValue("(ONN)", self->ob_type, args, state);
2890}
Tim Peters2a799bf2002-12-16 20:18:38 +00002891
2892static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002893
Tim Peters2a799bf2002-12-16 20:18:38 +00002894 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2895 PyDoc_STR("datetime -> string name of time zone.")},
2896
2897 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2898 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2899 "west of UTC).")},
2900
2901 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2902 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2903
Tim Peters52dcce22003-01-23 16:36:11 +00002904 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2905 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2906
Guido van Rossum177e41a2003-01-30 22:06:23 +00002907 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2908 PyDoc_STR("-> (cls, state)")},
2909
Tim Peters2a799bf2002-12-16 20:18:38 +00002910 {NULL, NULL}
2911};
2912
2913static char tzinfo_doc[] =
2914PyDoc_STR("Abstract base class for time zone info objects.");
2915
Neal Norwitzce3d34d2003-02-04 20:45:17 +00002916statichere PyTypeObject PyDateTime_TZInfoType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00002917 PyObject_HEAD_INIT(NULL)
2918 0, /* ob_size */
2919 "datetime.tzinfo", /* tp_name */
2920 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
2921 0, /* tp_itemsize */
2922 0, /* tp_dealloc */
2923 0, /* tp_print */
2924 0, /* tp_getattr */
2925 0, /* tp_setattr */
2926 0, /* tp_compare */
2927 0, /* tp_repr */
2928 0, /* tp_as_number */
2929 0, /* tp_as_sequence */
2930 0, /* tp_as_mapping */
2931 0, /* tp_hash */
2932 0, /* tp_call */
2933 0, /* tp_str */
2934 PyObject_GenericGetAttr, /* tp_getattro */
2935 0, /* tp_setattro */
2936 0, /* tp_as_buffer */
2937 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2938 Py_TPFLAGS_BASETYPE, /* tp_flags */
2939 tzinfo_doc, /* tp_doc */
2940 0, /* tp_traverse */
2941 0, /* tp_clear */
2942 0, /* tp_richcompare */
2943 0, /* tp_weaklistoffset */
2944 0, /* tp_iter */
2945 0, /* tp_iternext */
2946 tzinfo_methods, /* tp_methods */
2947 0, /* tp_members */
2948 0, /* tp_getset */
2949 0, /* tp_base */
2950 0, /* tp_dict */
2951 0, /* tp_descr_get */
2952 0, /* tp_descr_set */
2953 0, /* tp_dictoffset */
2954 0, /* tp_init */
2955 0, /* tp_alloc */
2956 PyType_GenericNew, /* tp_new */
2957 0, /* tp_free */
2958};
2959
2960/*
Tim Peters37f39822003-01-10 03:49:02 +00002961 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00002962 */
2963
Tim Peters37f39822003-01-10 03:49:02 +00002964/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00002965 */
2966
2967static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00002968time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00002969{
Tim Peters37f39822003-01-10 03:49:02 +00002970 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002971}
2972
Tim Peters37f39822003-01-10 03:49:02 +00002973static PyObject *
2974time_minute(PyDateTime_Time *self, void *unused)
2975{
2976 return PyInt_FromLong(TIME_GET_MINUTE(self));
2977}
2978
2979/* The name time_second conflicted with some platform header file. */
2980static PyObject *
2981py_time_second(PyDateTime_Time *self, void *unused)
2982{
2983 return PyInt_FromLong(TIME_GET_SECOND(self));
2984}
2985
2986static PyObject *
2987time_microsecond(PyDateTime_Time *self, void *unused)
2988{
2989 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
2990}
2991
2992static PyObject *
2993time_tzinfo(PyDateTime_Time *self, void *unused)
2994{
Tim Petersa032d2e2003-01-11 00:15:54 +00002995 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00002996 Py_INCREF(result);
2997 return result;
2998}
2999
3000static PyGetSetDef time_getset[] = {
3001 {"hour", (getter)time_hour},
3002 {"minute", (getter)time_minute},
3003 {"second", (getter)py_time_second},
3004 {"microsecond", (getter)time_microsecond},
3005 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003006 {NULL}
3007};
3008
3009/*
3010 * Constructors.
3011 */
3012
Tim Peters37f39822003-01-10 03:49:02 +00003013static char *time_kws[] = {"hour", "minute", "second", "microsecond",
3014 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003015
Tim Peters2a799bf2002-12-16 20:18:38 +00003016static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003017time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003018{
3019 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003020 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003021 int hour = 0;
3022 int minute = 0;
3023 int second = 0;
3024 int usecond = 0;
3025 PyObject *tzinfo = Py_None;
3026
Guido van Rossum177e41a2003-01-30 22:06:23 +00003027 /* Check for invocation from pickle with __getstate__ state */
3028 if (PyTuple_GET_SIZE(args) >= 1 &&
3029 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00003030 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3031 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003032 {
Tim Peters70533e22003-02-01 04:40:04 +00003033 PyDateTime_Time *me;
3034 char aware;
3035
3036 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003037 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003038 if (check_tzinfo_subclass(tzinfo) < 0) {
3039 PyErr_SetString(PyExc_TypeError, "bad "
3040 "tzinfo state arg");
3041 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003042 }
3043 }
Tim Peters70533e22003-02-01 04:40:04 +00003044 aware = (char)(tzinfo != Py_None);
Tim Petersa98924a2003-05-17 05:55:19 +00003045 me = (PyDateTime_Time *) time_alloc(&PyDateTime_TimeType,
3046 aware);
Tim Peters70533e22003-02-01 04:40:04 +00003047 if (me != NULL) {
3048 char *pdata = PyString_AS_STRING(state);
3049
3050 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3051 me->hashcode = -1;
3052 me->hastzinfo = aware;
3053 if (aware) {
3054 Py_INCREF(tzinfo);
3055 me->tzinfo = tzinfo;
3056 }
3057 }
3058 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003059 }
3060
Tim Peters37f39822003-01-10 03:49:02 +00003061 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003062 &hour, &minute, &second, &usecond,
3063 &tzinfo)) {
3064 if (check_time_args(hour, minute, second, usecond) < 0)
3065 return NULL;
3066 if (check_tzinfo_subclass(tzinfo) < 0)
3067 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003068 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3069 type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003070 }
3071 return self;
3072}
3073
3074/*
3075 * Destructor.
3076 */
3077
3078static void
Tim Peters37f39822003-01-10 03:49:02 +00003079time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003080{
Tim Petersa032d2e2003-01-11 00:15:54 +00003081 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003082 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003083 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003084 self->ob_type->tp_free((PyObject *)self);
3085}
3086
3087/*
Tim Peters855fe882002-12-22 03:43:39 +00003088 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003089 */
3090
Tim Peters2a799bf2002-12-16 20:18:38 +00003091/* These are all METH_NOARGS, so don't need to check the arglist. */
3092static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003093time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003094 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003095 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003096}
3097
3098static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003099time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003100 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003101 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003102}
3103
3104static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003105time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003106 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003107 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003108}
3109
3110/*
Tim Peters37f39822003-01-10 03:49:02 +00003111 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003112 */
3113
3114static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003115time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003116{
Tim Peters37f39822003-01-10 03:49:02 +00003117 char buffer[100];
3118 char *typename = self->ob_type->tp_name;
3119 int h = TIME_GET_HOUR(self);
3120 int m = TIME_GET_MINUTE(self);
3121 int s = TIME_GET_SECOND(self);
3122 int us = TIME_GET_MICROSECOND(self);
3123 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003124
Tim Peters37f39822003-01-10 03:49:02 +00003125 if (us)
3126 PyOS_snprintf(buffer, sizeof(buffer),
3127 "%s(%d, %d, %d, %d)", typename, h, m, s, us);
3128 else if (s)
3129 PyOS_snprintf(buffer, sizeof(buffer),
3130 "%s(%d, %d, %d)", typename, h, m, s);
3131 else
3132 PyOS_snprintf(buffer, sizeof(buffer),
3133 "%s(%d, %d)", typename, h, m);
3134 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003135 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003136 result = append_keyword_tzinfo(result, self->tzinfo);
3137 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003138}
3139
Tim Peters37f39822003-01-10 03:49:02 +00003140static PyObject *
3141time_str(PyDateTime_Time *self)
3142{
3143 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3144}
Tim Peters2a799bf2002-12-16 20:18:38 +00003145
3146static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003147time_isoformat(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003148{
3149 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003150 PyObject *result;
3151 /* Reuse the time format code from the datetime type. */
3152 PyDateTime_DateTime datetime;
3153 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003154
Tim Peters37f39822003-01-10 03:49:02 +00003155 /* Copy over just the time bytes. */
3156 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3157 self->data,
3158 _PyDateTime_TIME_DATASIZE);
3159
3160 isoformat_time(pdatetime, buf, sizeof(buf));
3161 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003162 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003163 return result;
3164
3165 /* We need to append the UTC offset. */
3166 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003167 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003168 Py_DECREF(result);
3169 return NULL;
3170 }
3171 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3172 return result;
3173}
3174
Tim Peters37f39822003-01-10 03:49:02 +00003175static PyObject *
3176time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3177{
3178 PyObject *result;
3179 PyObject *format;
3180 PyObject *tuple;
3181 static char *keywords[] = {"format", NULL};
3182
3183 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
3184 &PyString_Type, &format))
3185 return NULL;
3186
3187 /* Python's strftime does insane things with the year part of the
3188 * timetuple. The year is forced to (the otherwise nonsensical)
3189 * 1900 to worm around that.
3190 */
3191 tuple = Py_BuildValue("iiiiiiiii",
3192 1900, 0, 0, /* year, month, day */
3193 TIME_GET_HOUR(self),
3194 TIME_GET_MINUTE(self),
3195 TIME_GET_SECOND(self),
3196 0, 0, -1); /* weekday, daynum, dst */
3197 if (tuple == NULL)
3198 return NULL;
3199 assert(PyTuple_Size(tuple) == 9);
3200 result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
3201 Py_DECREF(tuple);
3202 return result;
3203}
Tim Peters2a799bf2002-12-16 20:18:38 +00003204
3205/*
3206 * Miscellaneous methods.
3207 */
3208
Tim Peters37f39822003-01-10 03:49:02 +00003209/* This is more natural as a tp_compare, but doesn't work then: for whatever
3210 * reason, Python's try_3way_compare ignores tp_compare unless
3211 * PyInstance_Check returns true, but these aren't old-style classes.
3212 */
3213static PyObject *
3214time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3215{
3216 int diff;
3217 naivety n1, n2;
3218 int offset1, offset2;
3219
3220 if (! PyTime_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00003221 if (op == Py_EQ || op == Py_NE) {
3222 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3223 Py_INCREF(result);
3224 return result;
3225 }
Tim Peters37f39822003-01-10 03:49:02 +00003226 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00003227 return cmperror((PyObject *)self, other);
Tim Peters37f39822003-01-10 03:49:02 +00003228 }
3229 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3230 other, &offset2, &n2, Py_None) < 0)
3231 return NULL;
3232 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3233 /* If they're both naive, or both aware and have the same offsets,
3234 * we get off cheap. Note that if they're both naive, offset1 ==
3235 * offset2 == 0 at this point.
3236 */
3237 if (n1 == n2 && offset1 == offset2) {
3238 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3239 _PyDateTime_TIME_DATASIZE);
3240 return diff_to_bool(diff, op);
3241 }
3242
3243 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3244 assert(offset1 != offset2); /* else last "if" handled it */
3245 /* Convert everything except microseconds to seconds. These
3246 * can't overflow (no more than the # of seconds in 2 days).
3247 */
3248 offset1 = TIME_GET_HOUR(self) * 3600 +
3249 (TIME_GET_MINUTE(self) - offset1) * 60 +
3250 TIME_GET_SECOND(self);
3251 offset2 = TIME_GET_HOUR(other) * 3600 +
3252 (TIME_GET_MINUTE(other) - offset2) * 60 +
3253 TIME_GET_SECOND(other);
3254 diff = offset1 - offset2;
3255 if (diff == 0)
3256 diff = TIME_GET_MICROSECOND(self) -
3257 TIME_GET_MICROSECOND(other);
3258 return diff_to_bool(diff, op);
3259 }
3260
3261 assert(n1 != n2);
3262 PyErr_SetString(PyExc_TypeError,
3263 "can't compare offset-naive and "
3264 "offset-aware times");
3265 return NULL;
3266}
3267
3268static long
3269time_hash(PyDateTime_Time *self)
3270{
3271 if (self->hashcode == -1) {
3272 naivety n;
3273 int offset;
3274 PyObject *temp;
3275
3276 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3277 assert(n != OFFSET_UNKNOWN);
3278 if (n == OFFSET_ERROR)
3279 return -1;
3280
3281 /* Reduce this to a hash of another object. */
3282 if (offset == 0)
3283 temp = PyString_FromStringAndSize((char *)self->data,
3284 _PyDateTime_TIME_DATASIZE);
3285 else {
3286 int hour;
3287 int minute;
3288
3289 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003290 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003291 hour = divmod(TIME_GET_HOUR(self) * 60 +
3292 TIME_GET_MINUTE(self) - offset,
3293 60,
3294 &minute);
3295 if (0 <= hour && hour < 24)
3296 temp = new_time(hour, minute,
3297 TIME_GET_SECOND(self),
3298 TIME_GET_MICROSECOND(self),
3299 Py_None);
3300 else
3301 temp = Py_BuildValue("iiii",
3302 hour, minute,
3303 TIME_GET_SECOND(self),
3304 TIME_GET_MICROSECOND(self));
3305 }
3306 if (temp != NULL) {
3307 self->hashcode = PyObject_Hash(temp);
3308 Py_DECREF(temp);
3309 }
3310 }
3311 return self->hashcode;
3312}
Tim Peters2a799bf2002-12-16 20:18:38 +00003313
Tim Peters12bf3392002-12-24 05:41:27 +00003314static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003315time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003316{
3317 PyObject *clone;
3318 PyObject *tuple;
3319 int hh = TIME_GET_HOUR(self);
3320 int mm = TIME_GET_MINUTE(self);
3321 int ss = TIME_GET_SECOND(self);
3322 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003323 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003324
3325 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003326 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003327 &hh, &mm, &ss, &us, &tzinfo))
3328 return NULL;
3329 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3330 if (tuple == NULL)
3331 return NULL;
Tim Peters37f39822003-01-10 03:49:02 +00003332 clone = time_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003333 Py_DECREF(tuple);
3334 return clone;
3335}
3336
Tim Peters2a799bf2002-12-16 20:18:38 +00003337static int
Tim Peters37f39822003-01-10 03:49:02 +00003338time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003339{
3340 int offset;
3341 int none;
3342
3343 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3344 /* Since utcoffset is in whole minutes, nothing can
3345 * alter the conclusion that this is nonzero.
3346 */
3347 return 1;
3348 }
3349 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003350 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003351 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003352 if (offset == -1 && PyErr_Occurred())
3353 return -1;
3354 }
3355 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3356}
3357
Tim Peters371935f2003-02-01 01:52:50 +00003358/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003359
Tim Peters33e0f382003-01-10 02:05:14 +00003360/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003361 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3362 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003363 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003364 */
3365static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003366time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003367{
3368 PyObject *basestate;
3369 PyObject *result = NULL;
3370
Tim Peters33e0f382003-01-10 02:05:14 +00003371 basestate = PyString_FromStringAndSize((char *)self->data,
3372 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003373 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003374 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003375 result = Py_BuildValue("(O)", basestate);
3376 else
3377 result = Py_BuildValue("OO", basestate, self->tzinfo);
3378 Py_DECREF(basestate);
3379 }
3380 return result;
3381}
3382
3383static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003384time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003385{
Guido van Rossum177e41a2003-01-30 22:06:23 +00003386 return Py_BuildValue("(ON)", self->ob_type, time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003387}
3388
Tim Peters37f39822003-01-10 03:49:02 +00003389static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003390
Tim Peters37f39822003-01-10 03:49:02 +00003391 {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003392 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3393 "[+HH:MM].")},
3394
Tim Peters37f39822003-01-10 03:49:02 +00003395 {"strftime", (PyCFunction)time_strftime, METH_KEYWORDS,
3396 PyDoc_STR("format -> strftime() style string.")},
3397
3398 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003399 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3400
Tim Peters37f39822003-01-10 03:49:02 +00003401 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003402 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3403
Tim Peters37f39822003-01-10 03:49:02 +00003404 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003405 PyDoc_STR("Return self.tzinfo.dst(self).")},
3406
Tim Peters37f39822003-01-10 03:49:02 +00003407 {"replace", (PyCFunction)time_replace, METH_KEYWORDS,
3408 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003409
Guido van Rossum177e41a2003-01-30 22:06:23 +00003410 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3411 PyDoc_STR("__reduce__() -> (cls, state)")},
3412
Tim Peters2a799bf2002-12-16 20:18:38 +00003413 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003414};
3415
Tim Peters37f39822003-01-10 03:49:02 +00003416static char time_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00003417PyDoc_STR("Time type.");
3418
Tim Peters37f39822003-01-10 03:49:02 +00003419static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003420 0, /* nb_add */
3421 0, /* nb_subtract */
3422 0, /* nb_multiply */
3423 0, /* nb_divide */
3424 0, /* nb_remainder */
3425 0, /* nb_divmod */
3426 0, /* nb_power */
3427 0, /* nb_negative */
3428 0, /* nb_positive */
3429 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003430 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003431};
3432
Tim Peters37f39822003-01-10 03:49:02 +00003433statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003434 PyObject_HEAD_INIT(NULL)
3435 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003436 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003437 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003438 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003439 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003440 0, /* tp_print */
3441 0, /* tp_getattr */
3442 0, /* tp_setattr */
3443 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003444 (reprfunc)time_repr, /* tp_repr */
3445 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003446 0, /* tp_as_sequence */
3447 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003448 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003449 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003450 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003451 PyObject_GenericGetAttr, /* tp_getattro */
3452 0, /* tp_setattro */
3453 0, /* tp_as_buffer */
3454 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3455 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003456 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003457 0, /* tp_traverse */
3458 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003459 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003460 0, /* tp_weaklistoffset */
3461 0, /* tp_iter */
3462 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003463 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003464 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003465 time_getset, /* tp_getset */
3466 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003467 0, /* tp_dict */
3468 0, /* tp_descr_get */
3469 0, /* tp_descr_set */
3470 0, /* tp_dictoffset */
3471 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00003472 time_alloc, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003473 time_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00003474 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003475};
3476
3477/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003478 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003479 */
3480
Tim Petersa9bc1682003-01-11 03:39:11 +00003481/* Accessor properties. Properties for day, month, and year are inherited
3482 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003483 */
3484
3485static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003486datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003487{
Tim Petersa9bc1682003-01-11 03:39:11 +00003488 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003489}
3490
Tim Petersa9bc1682003-01-11 03:39:11 +00003491static PyObject *
3492datetime_minute(PyDateTime_DateTime *self, void *unused)
3493{
3494 return PyInt_FromLong(DATE_GET_MINUTE(self));
3495}
3496
3497static PyObject *
3498datetime_second(PyDateTime_DateTime *self, void *unused)
3499{
3500 return PyInt_FromLong(DATE_GET_SECOND(self));
3501}
3502
3503static PyObject *
3504datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3505{
3506 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3507}
3508
3509static PyObject *
3510datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3511{
3512 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3513 Py_INCREF(result);
3514 return result;
3515}
3516
3517static PyGetSetDef datetime_getset[] = {
3518 {"hour", (getter)datetime_hour},
3519 {"minute", (getter)datetime_minute},
3520 {"second", (getter)datetime_second},
3521 {"microsecond", (getter)datetime_microsecond},
3522 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003523 {NULL}
3524};
3525
3526/*
3527 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003528 */
3529
Tim Petersa9bc1682003-01-11 03:39:11 +00003530static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003531 "year", "month", "day", "hour", "minute", "second",
3532 "microsecond", "tzinfo", NULL
3533};
3534
Tim Peters2a799bf2002-12-16 20:18:38 +00003535static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003536datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003537{
3538 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003539 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003540 int year;
3541 int month;
3542 int day;
3543 int hour = 0;
3544 int minute = 0;
3545 int second = 0;
3546 int usecond = 0;
3547 PyObject *tzinfo = Py_None;
3548
Guido van Rossum177e41a2003-01-30 22:06:23 +00003549 /* Check for invocation from pickle with __getstate__ state */
3550 if (PyTuple_GET_SIZE(args) >= 1 &&
3551 PyTuple_GET_SIZE(args) <= 2 &&
Tim Peters70533e22003-02-01 04:40:04 +00003552 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3553 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003554 {
Tim Peters70533e22003-02-01 04:40:04 +00003555 PyDateTime_DateTime *me;
3556 char aware;
3557
3558 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003559 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003560 if (check_tzinfo_subclass(tzinfo) < 0) {
3561 PyErr_SetString(PyExc_TypeError, "bad "
3562 "tzinfo state arg");
3563 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003564 }
3565 }
Tim Peters70533e22003-02-01 04:40:04 +00003566 aware = (char)(tzinfo != Py_None);
Tim Petersa98924a2003-05-17 05:55:19 +00003567 me = (PyDateTime_DateTime *) datetime_alloc(
3568 &PyDateTime_DateTimeType,
3569 aware);
Tim Peters70533e22003-02-01 04:40:04 +00003570 if (me != NULL) {
3571 char *pdata = PyString_AS_STRING(state);
3572
3573 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3574 me->hashcode = -1;
3575 me->hastzinfo = aware;
3576 if (aware) {
3577 Py_INCREF(tzinfo);
3578 me->tzinfo = tzinfo;
3579 }
3580 }
3581 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003582 }
3583
Tim Petersa9bc1682003-01-11 03:39:11 +00003584 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003585 &year, &month, &day, &hour, &minute,
3586 &second, &usecond, &tzinfo)) {
3587 if (check_date_args(year, month, day) < 0)
3588 return NULL;
3589 if (check_time_args(hour, minute, second, usecond) < 0)
3590 return NULL;
3591 if (check_tzinfo_subclass(tzinfo) < 0)
3592 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003593 self = new_datetime_ex(year, month, day,
3594 hour, minute, second, usecond,
3595 tzinfo, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003596 }
3597 return self;
3598}
3599
Tim Petersa9bc1682003-01-11 03:39:11 +00003600/* TM_FUNC is the shared type of localtime() and gmtime(). */
3601typedef struct tm *(*TM_FUNC)(const time_t *timer);
3602
3603/* Internal helper.
3604 * Build datetime from a time_t and a distinct count of microseconds.
3605 * Pass localtime or gmtime for f, to control the interpretation of timet.
3606 */
3607static PyObject *
3608datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3609 PyObject *tzinfo)
3610{
3611 struct tm *tm;
3612 PyObject *result = NULL;
3613
3614 tm = f(&timet);
3615 if (tm) {
3616 /* The platform localtime/gmtime may insert leap seconds,
3617 * indicated by tm->tm_sec > 59. We don't care about them,
3618 * except to the extent that passing them on to the datetime
3619 * constructor would raise ValueError for a reason that
3620 * made no sense to the user.
3621 */
3622 if (tm->tm_sec > 59)
3623 tm->tm_sec = 59;
3624 result = PyObject_CallFunction(cls, "iiiiiiiO",
3625 tm->tm_year + 1900,
3626 tm->tm_mon + 1,
3627 tm->tm_mday,
3628 tm->tm_hour,
3629 tm->tm_min,
3630 tm->tm_sec,
3631 us,
3632 tzinfo);
3633 }
3634 else
3635 PyErr_SetString(PyExc_ValueError,
3636 "timestamp out of range for "
3637 "platform localtime()/gmtime() function");
3638 return result;
3639}
3640
3641/* Internal helper.
3642 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3643 * to control the interpretation of the timestamp. Since a double doesn't
3644 * have enough bits to cover a datetime's full range of precision, it's
3645 * better to call datetime_from_timet_and_us provided you have a way
3646 * to get that much precision (e.g., C time() isn't good enough).
3647 */
3648static PyObject *
3649datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3650 PyObject *tzinfo)
3651{
3652 time_t timet = (time_t)timestamp;
3653 double fraction = timestamp - (double)timet;
3654 int us = (int)round_to_long(fraction * 1e6);
3655
3656 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3657}
3658
3659/* Internal helper.
3660 * Build most accurate possible datetime for current time. Pass localtime or
3661 * gmtime for f as appropriate.
3662 */
3663static PyObject *
3664datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3665{
3666#ifdef HAVE_GETTIMEOFDAY
3667 struct timeval t;
3668
3669#ifdef GETTIMEOFDAY_NO_TZ
3670 gettimeofday(&t);
3671#else
3672 gettimeofday(&t, (struct timezone *)NULL);
3673#endif
3674 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3675 tzinfo);
3676
3677#else /* ! HAVE_GETTIMEOFDAY */
3678 /* No flavor of gettimeofday exists on this platform. Python's
3679 * time.time() does a lot of other platform tricks to get the
3680 * best time it can on the platform, and we're not going to do
3681 * better than that (if we could, the better code would belong
3682 * in time.time()!) We're limited by the precision of a double,
3683 * though.
3684 */
3685 PyObject *time;
3686 double dtime;
3687
3688 time = time_time();
3689 if (time == NULL)
3690 return NULL;
3691 dtime = PyFloat_AsDouble(time);
3692 Py_DECREF(time);
3693 if (dtime == -1.0 && PyErr_Occurred())
3694 return NULL;
3695 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3696#endif /* ! HAVE_GETTIMEOFDAY */
3697}
3698
Tim Peters2a799bf2002-12-16 20:18:38 +00003699/* Return best possible local time -- this isn't constrained by the
3700 * precision of a timestamp.
3701 */
3702static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003703datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003704{
Tim Peters10cadce2003-01-23 19:58:02 +00003705 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003706 PyObject *tzinfo = Py_None;
Tim Peters10cadce2003-01-23 19:58:02 +00003707 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003708
Tim Peters10cadce2003-01-23 19:58:02 +00003709 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3710 &tzinfo))
3711 return NULL;
3712 if (check_tzinfo_subclass(tzinfo) < 0)
3713 return NULL;
3714
3715 self = datetime_best_possible(cls,
3716 tzinfo == Py_None ? localtime : gmtime,
3717 tzinfo);
3718 if (self != NULL && tzinfo != Py_None) {
3719 /* Convert UTC to tzinfo's zone. */
3720 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003721 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003722 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003723 }
3724 return self;
3725}
3726
Tim Petersa9bc1682003-01-11 03:39:11 +00003727/* Return best possible UTC time -- this isn't constrained by the
3728 * precision of a timestamp.
3729 */
3730static PyObject *
3731datetime_utcnow(PyObject *cls, PyObject *dummy)
3732{
3733 return datetime_best_possible(cls, gmtime, Py_None);
3734}
3735
Tim Peters2a799bf2002-12-16 20:18:38 +00003736/* Return new local datetime from timestamp (Python timestamp -- a double). */
3737static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003738datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003739{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003740 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003741 double timestamp;
3742 PyObject *tzinfo = Py_None;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003743 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003744
Tim Peters2a44a8d2003-01-23 20:53:10 +00003745 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3746 keywords, &timestamp, &tzinfo))
3747 return NULL;
3748 if (check_tzinfo_subclass(tzinfo) < 0)
3749 return NULL;
3750
3751 self = datetime_from_timestamp(cls,
3752 tzinfo == Py_None ? localtime : gmtime,
3753 timestamp,
3754 tzinfo);
3755 if (self != NULL && tzinfo != Py_None) {
3756 /* Convert UTC to tzinfo's zone. */
3757 PyObject *temp = self;
3758 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3759 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003760 }
3761 return self;
3762}
3763
Tim Petersa9bc1682003-01-11 03:39:11 +00003764/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3765static PyObject *
3766datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3767{
3768 double timestamp;
3769 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003770
Tim Petersa9bc1682003-01-11 03:39:11 +00003771 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3772 result = datetime_from_timestamp(cls, gmtime, timestamp,
3773 Py_None);
3774 return result;
3775}
3776
3777/* Return new datetime from date/datetime and time arguments. */
3778static PyObject *
3779datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3780{
3781 static char *keywords[] = {"date", "time", NULL};
3782 PyObject *date;
3783 PyObject *time;
3784 PyObject *result = NULL;
3785
3786 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3787 &PyDateTime_DateType, &date,
3788 &PyDateTime_TimeType, &time)) {
3789 PyObject *tzinfo = Py_None;
3790
3791 if (HASTZINFO(time))
3792 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3793 result = PyObject_CallFunction(cls, "iiiiiiiO",
3794 GET_YEAR(date),
3795 GET_MONTH(date),
3796 GET_DAY(date),
3797 TIME_GET_HOUR(time),
3798 TIME_GET_MINUTE(time),
3799 TIME_GET_SECOND(time),
3800 TIME_GET_MICROSECOND(time),
3801 tzinfo);
3802 }
3803 return result;
3804}
Tim Peters2a799bf2002-12-16 20:18:38 +00003805
3806/*
3807 * Destructor.
3808 */
3809
3810static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003811datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003812{
Tim Petersa9bc1682003-01-11 03:39:11 +00003813 if (HASTZINFO(self)) {
3814 Py_XDECREF(self->tzinfo);
3815 }
Tim Peters2a799bf2002-12-16 20:18:38 +00003816 self->ob_type->tp_free((PyObject *)self);
3817}
3818
3819/*
3820 * Indirect access to tzinfo methods.
3821 */
3822
Tim Peters2a799bf2002-12-16 20:18:38 +00003823/* These are all METH_NOARGS, so don't need to check the arglist. */
3824static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003825datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
3826 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3827 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003828}
3829
3830static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003831datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
3832 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3833 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00003834}
3835
3836static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003837datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
3838 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3839 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003840}
3841
3842/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003843 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00003844 */
3845
Tim Petersa9bc1682003-01-11 03:39:11 +00003846/* factor must be 1 (to add) or -1 (to subtract). The result inherits
3847 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003848 */
3849static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003850add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
3851 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00003852{
Tim Petersa9bc1682003-01-11 03:39:11 +00003853 /* Note that the C-level additions can't overflow, because of
3854 * invariant bounds on the member values.
3855 */
3856 int year = GET_YEAR(date);
3857 int month = GET_MONTH(date);
3858 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
3859 int hour = DATE_GET_HOUR(date);
3860 int minute = DATE_GET_MINUTE(date);
3861 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
3862 int microsecond = DATE_GET_MICROSECOND(date) +
3863 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00003864
Tim Petersa9bc1682003-01-11 03:39:11 +00003865 assert(factor == 1 || factor == -1);
3866 if (normalize_datetime(&year, &month, &day,
3867 &hour, &minute, &second, &microsecond) < 0)
3868 return NULL;
3869 else
3870 return new_datetime(year, month, day,
3871 hour, minute, second, microsecond,
3872 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003873}
3874
3875static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003876datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003877{
Tim Petersa9bc1682003-01-11 03:39:11 +00003878 if (PyDateTime_Check(left)) {
3879 /* datetime + ??? */
3880 if (PyDelta_Check(right))
3881 /* datetime + delta */
3882 return add_datetime_timedelta(
3883 (PyDateTime_DateTime *)left,
3884 (PyDateTime_Delta *)right,
3885 1);
3886 }
3887 else if (PyDelta_Check(left)) {
3888 /* delta + datetime */
3889 return add_datetime_timedelta((PyDateTime_DateTime *) right,
3890 (PyDateTime_Delta *) left,
3891 1);
3892 }
3893 Py_INCREF(Py_NotImplemented);
3894 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00003895}
3896
3897static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003898datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00003899{
3900 PyObject *result = Py_NotImplemented;
3901
3902 if (PyDateTime_Check(left)) {
3903 /* datetime - ??? */
3904 if (PyDateTime_Check(right)) {
3905 /* datetime - datetime */
3906 naivety n1, n2;
3907 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00003908 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00003909
Tim Peterse39a80c2002-12-30 21:28:52 +00003910 if (classify_two_utcoffsets(left, &offset1, &n1, left,
3911 right, &offset2, &n2,
3912 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00003913 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00003914 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00003915 if (n1 != n2) {
3916 PyErr_SetString(PyExc_TypeError,
3917 "can't subtract offset-naive and "
3918 "offset-aware datetimes");
3919 return NULL;
3920 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003921 delta_d = ymd_to_ord(GET_YEAR(left),
3922 GET_MONTH(left),
3923 GET_DAY(left)) -
3924 ymd_to_ord(GET_YEAR(right),
3925 GET_MONTH(right),
3926 GET_DAY(right));
3927 /* These can't overflow, since the values are
3928 * normalized. At most this gives the number of
3929 * seconds in one day.
3930 */
3931 delta_s = (DATE_GET_HOUR(left) -
3932 DATE_GET_HOUR(right)) * 3600 +
3933 (DATE_GET_MINUTE(left) -
3934 DATE_GET_MINUTE(right)) * 60 +
3935 (DATE_GET_SECOND(left) -
3936 DATE_GET_SECOND(right));
3937 delta_us = DATE_GET_MICROSECOND(left) -
3938 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00003939 /* (left - offset1) - (right - offset2) =
3940 * (left - right) + (offset2 - offset1)
3941 */
Tim Petersa9bc1682003-01-11 03:39:11 +00003942 delta_s += (offset2 - offset1) * 60;
3943 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003944 }
3945 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00003946 /* datetime - delta */
3947 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00003948 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00003949 (PyDateTime_Delta *)right,
3950 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00003951 }
3952 }
3953
3954 if (result == Py_NotImplemented)
3955 Py_INCREF(result);
3956 return result;
3957}
3958
3959/* Various ways to turn a datetime into a string. */
3960
3961static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003962datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003963{
Tim Petersa9bc1682003-01-11 03:39:11 +00003964 char buffer[1000];
3965 char *typename = self->ob_type->tp_name;
3966 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003967
Tim Petersa9bc1682003-01-11 03:39:11 +00003968 if (DATE_GET_MICROSECOND(self)) {
3969 PyOS_snprintf(buffer, sizeof(buffer),
3970 "%s(%d, %d, %d, %d, %d, %d, %d)",
3971 typename,
3972 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3973 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3974 DATE_GET_SECOND(self),
3975 DATE_GET_MICROSECOND(self));
3976 }
3977 else if (DATE_GET_SECOND(self)) {
3978 PyOS_snprintf(buffer, sizeof(buffer),
3979 "%s(%d, %d, %d, %d, %d, %d)",
3980 typename,
3981 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
3982 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
3983 DATE_GET_SECOND(self));
3984 }
3985 else {
3986 PyOS_snprintf(buffer, sizeof(buffer),
3987 "%s(%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 }
3992 baserepr = PyString_FromString(buffer);
3993 if (baserepr == NULL || ! HASTZINFO(self))
3994 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00003995 return append_keyword_tzinfo(baserepr, self->tzinfo);
3996}
3997
Tim Petersa9bc1682003-01-11 03:39:11 +00003998static PyObject *
3999datetime_str(PyDateTime_DateTime *self)
4000{
4001 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4002}
Tim Peters2a799bf2002-12-16 20:18:38 +00004003
4004static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004005datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004006{
Tim Petersa9bc1682003-01-11 03:39:11 +00004007 char sep = 'T';
4008 static char *keywords[] = {"sep", NULL};
4009 char buffer[100];
4010 char *cp;
4011 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004012
Tim Petersa9bc1682003-01-11 03:39:11 +00004013 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4014 &sep))
4015 return NULL;
4016 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4017 assert(cp != NULL);
4018 *cp++ = sep;
4019 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4020 result = PyString_FromString(buffer);
4021 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00004022 return result;
4023
4024 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00004025 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00004026 (PyObject *)self) < 0) {
4027 Py_DECREF(result);
4028 return NULL;
4029 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004030 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00004031 return result;
4032}
4033
Tim Petersa9bc1682003-01-11 03:39:11 +00004034static PyObject *
4035datetime_ctime(PyDateTime_DateTime *self)
4036{
4037 return format_ctime((PyDateTime_Date *)self,
4038 DATE_GET_HOUR(self),
4039 DATE_GET_MINUTE(self),
4040 DATE_GET_SECOND(self));
4041}
4042
Tim Peters2a799bf2002-12-16 20:18:38 +00004043/* Miscellaneous methods. */
4044
Tim Petersa9bc1682003-01-11 03:39:11 +00004045/* This is more natural as a tp_compare, but doesn't work then: for whatever
4046 * reason, Python's try_3way_compare ignores tp_compare unless
4047 * PyInstance_Check returns true, but these aren't old-style classes.
4048 */
4049static PyObject *
4050datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4051{
4052 int diff;
4053 naivety n1, n2;
4054 int offset1, offset2;
4055
4056 if (! PyDateTime_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004057 if (PyObject_HasAttrString(other, "timetuple")) {
4058 /* A hook for other kinds of datetime objects. */
4059 Py_INCREF(Py_NotImplemented);
4060 return Py_NotImplemented;
4061 }
Tim Peters07534a62003-02-07 22:50:28 +00004062 if (op == Py_EQ || op == Py_NE) {
4063 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4064 Py_INCREF(result);
4065 return result;
4066 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004067 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00004068 return cmperror((PyObject *)self, other);
Tim Petersa9bc1682003-01-11 03:39:11 +00004069 }
4070
4071 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4072 (PyObject *)self,
4073 other, &offset2, &n2,
4074 other) < 0)
4075 return NULL;
4076 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4077 /* If they're both naive, or both aware and have the same offsets,
4078 * we get off cheap. Note that if they're both naive, offset1 ==
4079 * offset2 == 0 at this point.
4080 */
4081 if (n1 == n2 && offset1 == offset2) {
4082 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4083 _PyDateTime_DATETIME_DATASIZE);
4084 return diff_to_bool(diff, op);
4085 }
4086
4087 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4088 PyDateTime_Delta *delta;
4089
4090 assert(offset1 != offset2); /* else last "if" handled it */
4091 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4092 other);
4093 if (delta == NULL)
4094 return NULL;
4095 diff = GET_TD_DAYS(delta);
4096 if (diff == 0)
4097 diff = GET_TD_SECONDS(delta) |
4098 GET_TD_MICROSECONDS(delta);
4099 Py_DECREF(delta);
4100 return diff_to_bool(diff, op);
4101 }
4102
4103 assert(n1 != n2);
4104 PyErr_SetString(PyExc_TypeError,
4105 "can't compare offset-naive and "
4106 "offset-aware datetimes");
4107 return NULL;
4108}
4109
4110static long
4111datetime_hash(PyDateTime_DateTime *self)
4112{
4113 if (self->hashcode == -1) {
4114 naivety n;
4115 int offset;
4116 PyObject *temp;
4117
4118 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4119 &offset);
4120 assert(n != OFFSET_UNKNOWN);
4121 if (n == OFFSET_ERROR)
4122 return -1;
4123
4124 /* Reduce this to a hash of another object. */
4125 if (n == OFFSET_NAIVE)
4126 temp = PyString_FromStringAndSize(
4127 (char *)self->data,
4128 _PyDateTime_DATETIME_DATASIZE);
4129 else {
4130 int days;
4131 int seconds;
4132
4133 assert(n == OFFSET_AWARE);
4134 assert(HASTZINFO(self));
4135 days = ymd_to_ord(GET_YEAR(self),
4136 GET_MONTH(self),
4137 GET_DAY(self));
4138 seconds = DATE_GET_HOUR(self) * 3600 +
4139 (DATE_GET_MINUTE(self) - offset) * 60 +
4140 DATE_GET_SECOND(self);
4141 temp = new_delta(days,
4142 seconds,
4143 DATE_GET_MICROSECOND(self),
4144 1);
4145 }
4146 if (temp != NULL) {
4147 self->hashcode = PyObject_Hash(temp);
4148 Py_DECREF(temp);
4149 }
4150 }
4151 return self->hashcode;
4152}
Tim Peters2a799bf2002-12-16 20:18:38 +00004153
4154static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004155datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004156{
4157 PyObject *clone;
4158 PyObject *tuple;
4159 int y = GET_YEAR(self);
4160 int m = GET_MONTH(self);
4161 int d = GET_DAY(self);
4162 int hh = DATE_GET_HOUR(self);
4163 int mm = DATE_GET_MINUTE(self);
4164 int ss = DATE_GET_SECOND(self);
4165 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004166 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004167
4168 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004169 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004170 &y, &m, &d, &hh, &mm, &ss, &us,
4171 &tzinfo))
4172 return NULL;
4173 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4174 if (tuple == NULL)
4175 return NULL;
Tim Petersa9bc1682003-01-11 03:39:11 +00004176 clone = datetime_new(self->ob_type, tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004177 Py_DECREF(tuple);
4178 return clone;
4179}
4180
4181static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004182datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004183{
Tim Peters52dcce22003-01-23 16:36:11 +00004184 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004185 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004186 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004187
Tim Peters80475bb2002-12-25 07:40:55 +00004188 PyObject *tzinfo;
4189 static char *keywords[] = {"tz", NULL};
4190
Tim Peters52dcce22003-01-23 16:36:11 +00004191 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4192 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004193 return NULL;
4194
Tim Peters52dcce22003-01-23 16:36:11 +00004195 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4196 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004197
Tim Peters52dcce22003-01-23 16:36:11 +00004198 /* Conversion to self's own time zone is a NOP. */
4199 if (self->tzinfo == tzinfo) {
4200 Py_INCREF(self);
4201 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004202 }
Tim Peters521fc152002-12-31 17:36:56 +00004203
Tim Peters52dcce22003-01-23 16:36:11 +00004204 /* Convert self to UTC. */
4205 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4206 if (offset == -1 && PyErr_Occurred())
4207 return NULL;
4208 if (none)
4209 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004210
Tim Peters52dcce22003-01-23 16:36:11 +00004211 y = GET_YEAR(self);
4212 m = GET_MONTH(self);
4213 d = GET_DAY(self);
4214 hh = DATE_GET_HOUR(self);
4215 mm = DATE_GET_MINUTE(self);
4216 ss = DATE_GET_SECOND(self);
4217 us = DATE_GET_MICROSECOND(self);
4218
4219 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004220 if ((mm < 0 || mm >= 60) &&
4221 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004222 return NULL;
4223
4224 /* Attach new tzinfo and let fromutc() do the rest. */
4225 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4226 if (result != NULL) {
4227 PyObject *temp = result;
4228
4229 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4230 Py_DECREF(temp);
4231 }
Tim Petersadf64202003-01-04 06:03:15 +00004232 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004233
Tim Peters52dcce22003-01-23 16:36:11 +00004234NeedAware:
4235 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4236 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004237 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004238}
4239
4240static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004241datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004242{
4243 int dstflag = -1;
4244
Tim Petersa9bc1682003-01-11 03:39:11 +00004245 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004246 int none;
4247
4248 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4249 if (dstflag == -1 && PyErr_Occurred())
4250 return NULL;
4251
4252 if (none)
4253 dstflag = -1;
4254 else if (dstflag != 0)
4255 dstflag = 1;
4256
4257 }
4258 return build_struct_time(GET_YEAR(self),
4259 GET_MONTH(self),
4260 GET_DAY(self),
4261 DATE_GET_HOUR(self),
4262 DATE_GET_MINUTE(self),
4263 DATE_GET_SECOND(self),
4264 dstflag);
4265}
4266
4267static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004268datetime_getdate(PyDateTime_DateTime *self)
4269{
4270 return new_date(GET_YEAR(self),
4271 GET_MONTH(self),
4272 GET_DAY(self));
4273}
4274
4275static PyObject *
4276datetime_gettime(PyDateTime_DateTime *self)
4277{
4278 return new_time(DATE_GET_HOUR(self),
4279 DATE_GET_MINUTE(self),
4280 DATE_GET_SECOND(self),
4281 DATE_GET_MICROSECOND(self),
4282 Py_None);
4283}
4284
4285static PyObject *
4286datetime_gettimetz(PyDateTime_DateTime *self)
4287{
4288 return new_time(DATE_GET_HOUR(self),
4289 DATE_GET_MINUTE(self),
4290 DATE_GET_SECOND(self),
4291 DATE_GET_MICROSECOND(self),
4292 HASTZINFO(self) ? self->tzinfo : Py_None);
4293}
4294
4295static PyObject *
4296datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004297{
4298 int y = GET_YEAR(self);
4299 int m = GET_MONTH(self);
4300 int d = GET_DAY(self);
4301 int hh = DATE_GET_HOUR(self);
4302 int mm = DATE_GET_MINUTE(self);
4303 int ss = DATE_GET_SECOND(self);
4304 int us = 0; /* microseconds are ignored in a timetuple */
4305 int offset = 0;
4306
Tim Petersa9bc1682003-01-11 03:39:11 +00004307 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004308 int none;
4309
4310 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4311 if (offset == -1 && PyErr_Occurred())
4312 return NULL;
4313 }
4314 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4315 * 0 in a UTC timetuple regardless of what dst() says.
4316 */
4317 if (offset) {
4318 /* Subtract offset minutes & normalize. */
4319 int stat;
4320
4321 mm -= offset;
4322 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4323 if (stat < 0) {
4324 /* At the edges, it's possible we overflowed
4325 * beyond MINYEAR or MAXYEAR.
4326 */
4327 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4328 PyErr_Clear();
4329 else
4330 return NULL;
4331 }
4332 }
4333 return build_struct_time(y, m, d, hh, mm, ss, 0);
4334}
4335
Tim Peters371935f2003-02-01 01:52:50 +00004336/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004337
Tim Petersa9bc1682003-01-11 03:39:11 +00004338/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004339 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4340 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004341 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004342 */
4343static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004344datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004345{
4346 PyObject *basestate;
4347 PyObject *result = NULL;
4348
Tim Peters33e0f382003-01-10 02:05:14 +00004349 basestate = PyString_FromStringAndSize((char *)self->data,
4350 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004351 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004352 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00004353 result = Py_BuildValue("(O)", basestate);
4354 else
4355 result = Py_BuildValue("OO", basestate, self->tzinfo);
4356 Py_DECREF(basestate);
4357 }
4358 return result;
4359}
4360
4361static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004362datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004363{
Guido van Rossum177e41a2003-01-30 22:06:23 +00004364 return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004365}
4366
Tim Petersa9bc1682003-01-11 03:39:11 +00004367static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004368
Tim Peters2a799bf2002-12-16 20:18:38 +00004369 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004370
Tim Petersa9bc1682003-01-11 03:39:11 +00004371 {"now", (PyCFunction)datetime_now,
Tim Peters2a799bf2002-12-16 20:18:38 +00004372 METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004373 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004374
Tim Petersa9bc1682003-01-11 03:39:11 +00004375 {"utcnow", (PyCFunction)datetime_utcnow,
4376 METH_NOARGS | METH_CLASS,
4377 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4378
4379 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Tim Peters2a799bf2002-12-16 20:18:38 +00004380 METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004381 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004382
Tim Petersa9bc1682003-01-11 03:39:11 +00004383 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4384 METH_VARARGS | METH_CLASS,
4385 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4386 "(like time.time()).")},
4387
4388 {"combine", (PyCFunction)datetime_combine,
4389 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4390 PyDoc_STR("date, time -> datetime with same date and time fields")},
4391
Tim Peters2a799bf2002-12-16 20:18:38 +00004392 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004393
Tim Petersa9bc1682003-01-11 03:39:11 +00004394 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4395 PyDoc_STR("Return date object with same year, month and day.")},
4396
4397 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4398 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4399
4400 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4401 PyDoc_STR("Return time object with same time and tzinfo.")},
4402
4403 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4404 PyDoc_STR("Return ctime() style string.")},
4405
4406 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004407 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4408
Tim Petersa9bc1682003-01-11 03:39:11 +00004409 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004410 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4411
Tim Petersa9bc1682003-01-11 03:39:11 +00004412 {"isoformat", (PyCFunction)datetime_isoformat, METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004413 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4414 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4415 "sep is used to separate the year from the time, and "
4416 "defaults to 'T'.")},
4417
Tim Petersa9bc1682003-01-11 03:39:11 +00004418 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004419 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4420
Tim Petersa9bc1682003-01-11 03:39:11 +00004421 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004422 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4423
Tim Petersa9bc1682003-01-11 03:39:11 +00004424 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004425 PyDoc_STR("Return self.tzinfo.dst(self).")},
4426
Tim Petersa9bc1682003-01-11 03:39:11 +00004427 {"replace", (PyCFunction)datetime_replace, METH_KEYWORDS,
4428 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004429
Tim Petersa9bc1682003-01-11 03:39:11 +00004430 {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004431 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4432
Guido van Rossum177e41a2003-01-30 22:06:23 +00004433 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4434 PyDoc_STR("__reduce__() -> (cls, state)")},
4435
Tim Peters2a799bf2002-12-16 20:18:38 +00004436 {NULL, NULL}
4437};
4438
Tim Petersa9bc1682003-01-11 03:39:11 +00004439static char datetime_doc[] =
Tim Peters2a799bf2002-12-16 20:18:38 +00004440PyDoc_STR("date/time type.");
4441
Tim Petersa9bc1682003-01-11 03:39:11 +00004442static PyNumberMethods datetime_as_number = {
4443 datetime_add, /* nb_add */
4444 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004445 0, /* nb_multiply */
4446 0, /* nb_divide */
4447 0, /* nb_remainder */
4448 0, /* nb_divmod */
4449 0, /* nb_power */
4450 0, /* nb_negative */
4451 0, /* nb_positive */
4452 0, /* nb_absolute */
4453 0, /* nb_nonzero */
4454};
4455
Tim Petersa9bc1682003-01-11 03:39:11 +00004456statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004457 PyObject_HEAD_INIT(NULL)
4458 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004459 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004460 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004461 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004462 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004463 0, /* tp_print */
4464 0, /* tp_getattr */
4465 0, /* tp_setattr */
4466 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004467 (reprfunc)datetime_repr, /* tp_repr */
4468 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004469 0, /* tp_as_sequence */
4470 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004471 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004472 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004473 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004474 PyObject_GenericGetAttr, /* tp_getattro */
4475 0, /* tp_setattro */
4476 0, /* tp_as_buffer */
4477 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4478 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004479 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004480 0, /* tp_traverse */
4481 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004482 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004483 0, /* tp_weaklistoffset */
4484 0, /* tp_iter */
4485 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004486 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004487 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004488 datetime_getset, /* tp_getset */
4489 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004490 0, /* tp_dict */
4491 0, /* tp_descr_get */
4492 0, /* tp_descr_set */
4493 0, /* tp_dictoffset */
4494 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00004495 datetime_alloc, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004496 datetime_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00004497 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004498};
4499
4500/* ---------------------------------------------------------------------------
4501 * Module methods and initialization.
4502 */
4503
4504static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004505 {NULL, NULL}
4506};
4507
4508PyMODINIT_FUNC
4509initdatetime(void)
4510{
4511 PyObject *m; /* a module object */
4512 PyObject *d; /* its dict */
4513 PyObject *x;
4514
Tim Peters2a799bf2002-12-16 20:18:38 +00004515 m = Py_InitModule3("datetime", module_methods,
4516 "Fast implementation of the datetime type.");
4517
4518 if (PyType_Ready(&PyDateTime_DateType) < 0)
4519 return;
4520 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4521 return;
4522 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4523 return;
4524 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4525 return;
4526 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4527 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004528
Tim Peters2a799bf2002-12-16 20:18:38 +00004529 /* timedelta values */
4530 d = PyDateTime_DeltaType.tp_dict;
4531
Tim Peters2a799bf2002-12-16 20:18:38 +00004532 x = new_delta(0, 0, 1, 0);
4533 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4534 return;
4535 Py_DECREF(x);
4536
4537 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4538 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4539 return;
4540 Py_DECREF(x);
4541
4542 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4543 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4544 return;
4545 Py_DECREF(x);
4546
4547 /* date values */
4548 d = PyDateTime_DateType.tp_dict;
4549
4550 x = new_date(1, 1, 1);
4551 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4552 return;
4553 Py_DECREF(x);
4554
4555 x = new_date(MAXYEAR, 12, 31);
4556 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4557 return;
4558 Py_DECREF(x);
4559
4560 x = new_delta(1, 0, 0, 0);
4561 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4562 return;
4563 Py_DECREF(x);
4564
Tim Peters37f39822003-01-10 03:49:02 +00004565 /* time values */
4566 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004567
Tim Peters37f39822003-01-10 03:49:02 +00004568 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004569 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4570 return;
4571 Py_DECREF(x);
4572
Tim Peters37f39822003-01-10 03:49:02 +00004573 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004574 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4575 return;
4576 Py_DECREF(x);
4577
4578 x = new_delta(0, 0, 1, 0);
4579 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4580 return;
4581 Py_DECREF(x);
4582
Tim Petersa9bc1682003-01-11 03:39:11 +00004583 /* datetime values */
4584 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004585
Tim Petersa9bc1682003-01-11 03:39:11 +00004586 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004587 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4588 return;
4589 Py_DECREF(x);
4590
Tim Petersa9bc1682003-01-11 03:39:11 +00004591 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004592 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4593 return;
4594 Py_DECREF(x);
4595
4596 x = new_delta(0, 0, 1, 0);
4597 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4598 return;
4599 Py_DECREF(x);
4600
Tim Peters2a799bf2002-12-16 20:18:38 +00004601 /* module initialization */
4602 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4603 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4604
4605 Py_INCREF(&PyDateTime_DateType);
4606 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4607
Tim Petersa9bc1682003-01-11 03:39:11 +00004608 Py_INCREF(&PyDateTime_DateTimeType);
4609 PyModule_AddObject(m, "datetime",
4610 (PyObject *)&PyDateTime_DateTimeType);
4611
4612 Py_INCREF(&PyDateTime_TimeType);
4613 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4614
Tim Peters2a799bf2002-12-16 20:18:38 +00004615 Py_INCREF(&PyDateTime_DeltaType);
4616 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4617
Tim Peters2a799bf2002-12-16 20:18:38 +00004618 Py_INCREF(&PyDateTime_TZInfoType);
4619 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4620
Tim Peters2a799bf2002-12-16 20:18:38 +00004621 /* A 4-year cycle has an extra leap day over what we'd get from
4622 * pasting together 4 single years.
4623 */
4624 assert(DI4Y == 4 * 365 + 1);
4625 assert(DI4Y == days_before_year(4+1));
4626
4627 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4628 * get from pasting together 4 100-year cycles.
4629 */
4630 assert(DI400Y == 4 * DI100Y + 1);
4631 assert(DI400Y == days_before_year(400+1));
4632
4633 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4634 * pasting together 25 4-year cycles.
4635 */
4636 assert(DI100Y == 25 * DI4Y - 1);
4637 assert(DI100Y == days_before_year(100+1));
4638
4639 us_per_us = PyInt_FromLong(1);
4640 us_per_ms = PyInt_FromLong(1000);
4641 us_per_second = PyInt_FromLong(1000000);
4642 us_per_minute = PyInt_FromLong(60000000);
4643 seconds_per_day = PyInt_FromLong(24 * 3600);
4644 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4645 us_per_minute == NULL || seconds_per_day == NULL)
4646 return;
4647
4648 /* The rest are too big for 32-bit ints, but even
4649 * us_per_week fits in 40 bits, so doubles should be exact.
4650 */
4651 us_per_hour = PyLong_FromDouble(3600000000.0);
4652 us_per_day = PyLong_FromDouble(86400000000.0);
4653 us_per_week = PyLong_FromDouble(604800000000.0);
4654 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4655 return;
4656}
Tim Petersf3615152003-01-01 21:51:37 +00004657
4658/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004659Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004660 x.n = x stripped of its timezone -- its naive time.
4661 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4662 return None
4663 x.d = x.dst(), and assuming that doesn't raise an exception or
4664 return None
4665 x.s = x's standard offset, x.o - x.d
4666
4667Now some derived rules, where k is a duration (timedelta).
4668
46691. x.o = x.s + x.d
4670 This follows from the definition of x.s.
4671
Tim Petersc5dc4da2003-01-02 17:55:03 +000046722. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004673 This is actually a requirement, an assumption we need to make about
4674 sane tzinfo classes.
4675
46763. The naive UTC time corresponding to x is x.n - x.o.
4677 This is again a requirement for a sane tzinfo class.
4678
46794. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004680 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004681
Tim Petersc5dc4da2003-01-02 17:55:03 +000046825. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004683 Again follows from how arithmetic is defined.
4684
Tim Peters8bb5ad22003-01-24 02:44:45 +00004685Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004686(meaning that the various tzinfo methods exist, and don't blow up or return
4687None when called).
4688
Tim Petersa9bc1682003-01-11 03:39:11 +00004689The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004690x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004691
4692By #3, we want
4693
Tim Peters8bb5ad22003-01-24 02:44:45 +00004694 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004695
4696The algorithm starts by attaching tz to x.n, and calling that y. So
4697x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4698becomes true; in effect, we want to solve [2] for k:
4699
Tim Peters8bb5ad22003-01-24 02:44:45 +00004700 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004701
4702By #1, this is the same as
4703
Tim Peters8bb5ad22003-01-24 02:44:45 +00004704 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004705
4706By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4707Substituting that into [3],
4708
Tim Peters8bb5ad22003-01-24 02:44:45 +00004709 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4710 k - (y+k).s - (y+k).d = 0; rearranging,
4711 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4712 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004713
Tim Peters8bb5ad22003-01-24 02:44:45 +00004714On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4715approximate k by ignoring the (y+k).d term at first. Note that k can't be
4716very large, since all offset-returning methods return a duration of magnitude
4717less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4718be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004719
4720In any case, the new value is
4721
Tim Peters8bb5ad22003-01-24 02:44:45 +00004722 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004723
Tim Peters8bb5ad22003-01-24 02:44:45 +00004724It's helpful to step back at look at [4] from a higher level: it's simply
4725mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004726
4727At this point, if
4728
Tim Peters8bb5ad22003-01-24 02:44:45 +00004729 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004730
4731we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004732at the start of daylight time. Picture US Eastern for concreteness. The wall
4733time 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 +00004734sense then. The docs ask that an Eastern tzinfo class consider such a time to
4735be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4736on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004737the only spelling that makes sense on the local wall clock.
4738
Tim Petersc5dc4da2003-01-02 17:55:03 +00004739In fact, if [5] holds at this point, we do have the standard-time spelling,
4740but that takes a bit of proof. We first prove a stronger result. What's the
4741difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004742
Tim Peters8bb5ad22003-01-24 02:44:45 +00004743 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004744
Tim Petersc5dc4da2003-01-02 17:55:03 +00004745Now
4746 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004747 (y + y.s).n = by #5
4748 y.n + y.s = since y.n = x.n
4749 x.n + y.s = since z and y are have the same tzinfo member,
4750 y.s = z.s by #2
4751 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004752
Tim Petersc5dc4da2003-01-02 17:55:03 +00004753Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004754
Tim Petersc5dc4da2003-01-02 17:55:03 +00004755 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004756 x.n - ((x.n + z.s) - z.o) = expanding
4757 x.n - x.n - z.s + z.o = cancelling
4758 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004759 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004760
Tim Petersc5dc4da2003-01-02 17:55:03 +00004761So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004762
Tim Petersc5dc4da2003-01-02 17:55:03 +00004763If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004764spelling we wanted in the endcase described above. We're done. Contrarily,
4765if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004766
Tim Petersc5dc4da2003-01-02 17:55:03 +00004767If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4768add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00004769local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004770
Tim Petersc5dc4da2003-01-02 17:55:03 +00004771Let
Tim Petersf3615152003-01-01 21:51:37 +00004772
Tim Peters4fede1a2003-01-04 00:26:59 +00004773 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004774
Tim Peters4fede1a2003-01-04 00:26:59 +00004775and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004776
Tim Peters8bb5ad22003-01-24 02:44:45 +00004777 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004778
Tim Peters8bb5ad22003-01-24 02:44:45 +00004779If so, we're done. If not, the tzinfo class is insane, according to the
4780assumptions we've made. This also requires a bit of proof. As before, let's
4781compute the difference between the LHS and RHS of [8] (and skipping some of
4782the justifications for the kinds of substitutions we've done several times
4783already):
Tim Peters4fede1a2003-01-04 00:26:59 +00004784
Tim Peters8bb5ad22003-01-24 02:44:45 +00004785 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
4786 x.n - (z.n + diff - z'.o) = replacing diff via [6]
4787 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
4788 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
4789 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00004790 - z.o + z'.o = #1 twice
4791 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
4792 z'.d - z.d
4793
4794So 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 +00004795we've found the UTC-equivalent so are done. In fact, we stop with [7] and
4796return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00004797
Tim Peters8bb5ad22003-01-24 02:44:45 +00004798How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
4799a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
4800would have to change the result dst() returns: we start in DST, and moving
4801a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00004802
Tim Peters8bb5ad22003-01-24 02:44:45 +00004803There isn't a sane case where this can happen. The closest it gets is at
4804the end of DST, where there's an hour in UTC with no spelling in a hybrid
4805tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
4806that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
4807UTC) because the docs insist on that, but 0:MM is taken as being in daylight
4808time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
4809clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
4810standard time. Since that's what the local clock *does*, we want to map both
4811UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00004812in local time, but so it goes -- it's the way the local clock works.
4813
Tim Peters8bb5ad22003-01-24 02:44:45 +00004814When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
4815so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
4816z' = 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 +00004817(correctly) concludes that z' is not UTC-equivalent to x.
4818
4819Because we know z.d said z was in daylight time (else [5] would have held and
4820we would have stopped then), and we know z.d != z'.d (else [8] would have held
4821and we we have stopped then), and there are only 2 possible values dst() can
4822return in Eastern, it follows that z'.d must be 0 (which it is in the example,
4823but the reasoning doesn't depend on the example -- it depends on there being
4824two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00004825z' must be in standard time, and is the spelling we want in this case.
4826
4827Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
4828concerned (because it takes z' as being in standard time rather than the
4829daylight time we intend here), but returning it gives the real-life "local
4830clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
4831tz.
4832
4833When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
4834the 1:MM standard time spelling we want.
4835
4836So how can this break? One of the assumptions must be violated. Two
4837possibilities:
4838
48391) [2] effectively says that y.s is invariant across all y belong to a given
4840 time zone. This isn't true if, for political reasons or continental drift,
4841 a region decides to change its base offset from UTC.
4842
48432) There may be versions of "double daylight" time where the tail end of
4844 the analysis gives up a step too early. I haven't thought about that
4845 enough to say.
4846
4847In any case, it's clear that the default fromutc() is strong enough to handle
4848"almost all" time zones: so long as the standard offset is invariant, it
4849doesn't matter if daylight time transition points change from year to year, or
4850if daylight time is skipped in some years; it doesn't matter how large or
4851small dst() may get within its bounds; and it doesn't even matter if some
4852perverse time zone returns a negative dst()). So a breaking case must be
4853pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00004854--------------------------------------------------------------------------- */