blob: 3adf0e2aaa30b60b45991b43d910492579c0b19c [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
Gregory P. Smith137d8242008-06-02 04:05:52 +00005#define PY_SSIZE_T_CLEAN
6
Tim Peters2a799bf2002-12-16 20:18:38 +00007#include "Python.h"
8#include "modsupport.h"
9#include "structmember.h"
10
11#include <time.h>
12
Tim Peters1b6f7a92004-06-20 02:50:16 +000013#include "timefuncs.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000014
15/* Differentiate between building the core module and building extension
16 * modules.
17 */
Kristján Valur Jónsson7a0da192007-04-30 15:17:46 +000018#ifndef Py_BUILD_CORE
Tim Peters9ddf40b2004-06-20 22:41:32 +000019#define Py_BUILD_CORE
Kristján Valur Jónsson7a0da192007-04-30 15:17:46 +000020#endif
Tim Peters2a799bf2002-12-16 20:18:38 +000021#include "datetime.h"
Tim Peters9ddf40b2004-06-20 22:41:32 +000022#undef Py_BUILD_CORE
Tim Peters2a799bf2002-12-16 20:18:38 +000023
24/* We require that C int be at least 32 bits, and use int virtually
25 * everywhere. In just a few cases we use a temp long, where a Python
26 * API returns a C long. In such cases, we have to ensure that the
27 * final result fits in a C int (this can be an issue on 64-bit boxes).
28 */
29#if SIZEOF_INT < 4
30# error "datetime.c requires that C int have at least 32 bits"
31#endif
32
33#define MINYEAR 1
34#define MAXYEAR 9999
35
36/* Nine decimal digits is easy to communicate, and leaves enough room
37 * so that two delta days can be added w/o fear of overflowing a signed
38 * 32-bit int, and with plenty of room left over to absorb any possible
39 * carries from adding seconds.
40 */
41#define MAX_DELTA_DAYS 999999999
42
43/* Rename the long macros in datetime.h to more reasonable short names. */
44#define GET_YEAR PyDateTime_GET_YEAR
45#define GET_MONTH PyDateTime_GET_MONTH
46#define GET_DAY PyDateTime_GET_DAY
47#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
48#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
49#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
50#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
51
52/* Date accessors for date and datetime. */
53#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
54 ((o)->data[1] = ((v) & 0x00ff)))
55#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
56#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
57
58/* Date/Time accessors for datetime. */
59#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
60#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
61#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
62#define DATE_SET_MICROSECOND(o, v) \
63 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
64 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
65 ((o)->data[9] = ((v) & 0x0000ff)))
66
67/* Time accessors for time. */
68#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
69#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
70#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
71#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
72#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
73#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
74#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
75#define TIME_SET_MICROSECOND(o, v) \
76 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
77 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
78 ((o)->data[5] = ((v) & 0x0000ff)))
79
80/* Delta accessors for timedelta. */
81#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
82#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
83#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
84
85#define SET_TD_DAYS(o, v) ((o)->days = (v))
86#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
87#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
88
Tim Petersa032d2e2003-01-11 00:15:54 +000089/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
90 * p->hastzinfo.
91 */
92#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
93
Tim Peters3f606292004-03-21 23:38:41 +000094/* M is a char or int claiming to be a valid month. The macro is equivalent
95 * to the two-sided Python test
96 * 1 <= M <= 12
97 */
98#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
99
Tim Peters2a799bf2002-12-16 20:18:38 +0000100/* Forward declarations. */
101static PyTypeObject PyDateTime_DateType;
102static PyTypeObject PyDateTime_DateTimeType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000103static PyTypeObject PyDateTime_DeltaType;
104static PyTypeObject PyDateTime_TimeType;
105static PyTypeObject PyDateTime_TZInfoType;
Tim Peters2a799bf2002-12-16 20:18:38 +0000106
107/* ---------------------------------------------------------------------------
108 * Math utilities.
109 */
110
111/* k = i+j overflows iff k differs in sign from both inputs,
112 * iff k^i has sign bit set and k^j has sign bit set,
113 * iff (k^i)&(k^j) has sign bit set.
114 */
115#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
116 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
117
118/* Compute Python divmod(x, y), returning the quotient and storing the
119 * remainder into *r. The quotient is the floor of x/y, and that's
120 * the real point of this. C will probably truncate instead (C99
121 * requires truncation; C89 left it implementation-defined).
122 * Simplification: we *require* that y > 0 here. That's appropriate
123 * for all the uses made of it. This simplifies the code and makes
124 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
125 * overflow case).
126 */
127static int
128divmod(int x, int y, int *r)
129{
130 int quo;
131
132 assert(y > 0);
133 quo = x / y;
134 *r = x - quo * y;
135 if (*r < 0) {
136 --quo;
137 *r += y;
138 }
139 assert(0 <= *r && *r < y);
140 return quo;
141}
142
Tim Peters5d644dd2003-01-02 16:32:54 +0000143/* Round a double to the nearest long. |x| must be small enough to fit
144 * in a C long; this is not checked.
145 */
146static long
147round_to_long(double x)
148{
149 if (x >= 0.0)
150 x = floor(x + 0.5);
151 else
152 x = ceil(x - 0.5);
153 return (long)x;
154}
155
Tim Peters2a799bf2002-12-16 20:18:38 +0000156/* ---------------------------------------------------------------------------
157 * General calendrical helper functions
158 */
159
160/* For each month ordinal in 1..12, the number of days in that month,
161 * and the number of days before that month in the same year. These
162 * are correct for non-leap years only.
163 */
164static int _days_in_month[] = {
165 0, /* unused; this vector uses 1-based indexing */
166 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
167};
168
169static int _days_before_month[] = {
170 0, /* unused; this vector uses 1-based indexing */
171 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
172};
173
174/* year -> 1 if leap year, else 0. */
175static int
176is_leap(int year)
177{
178 /* Cast year to unsigned. The result is the same either way, but
179 * C can generate faster code for unsigned mod than for signed
180 * mod (especially for % 4 -- a good compiler should just grab
181 * the last 2 bits when the LHS is unsigned).
182 */
183 const unsigned int ayear = (unsigned int)year;
184 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
185}
186
187/* year, month -> number of days in that month in that year */
188static int
189days_in_month(int year, int month)
190{
191 assert(month >= 1);
192 assert(month <= 12);
193 if (month == 2 && is_leap(year))
194 return 29;
195 else
196 return _days_in_month[month];
197}
198
199/* year, month -> number of days in year preceeding first day of month */
200static int
201days_before_month(int year, int month)
202{
203 int days;
204
205 assert(month >= 1);
206 assert(month <= 12);
207 days = _days_before_month[month];
208 if (month > 2 && is_leap(year))
209 ++days;
210 return days;
211}
212
213/* year -> number of days before January 1st of year. Remember that we
214 * start with year 1, so days_before_year(1) == 0.
215 */
216static int
217days_before_year(int year)
218{
219 int y = year - 1;
220 /* This is incorrect if year <= 0; we really want the floor
221 * here. But so long as MINYEAR is 1, the smallest year this
222 * can see is 0 (this can happen in some normalization endcases),
223 * so we'll just special-case that.
224 */
225 assert (year >= 0);
226 if (y >= 0)
227 return y*365 + y/4 - y/100 + y/400;
228 else {
229 assert(y == -1);
230 return -366;
231 }
232}
233
234/* Number of days in 4, 100, and 400 year cycles. That these have
235 * the correct values is asserted in the module init function.
236 */
237#define DI4Y 1461 /* days_before_year(5); days in 4 years */
238#define DI100Y 36524 /* days_before_year(101); days in 100 years */
239#define DI400Y 146097 /* days_before_year(401); days in 400 years */
240
241/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
242static void
243ord_to_ymd(int ordinal, int *year, int *month, int *day)
244{
245 int n, n1, n4, n100, n400, leapyear, preceding;
246
247 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
248 * leap years repeats exactly every 400 years. The basic strategy is
249 * to find the closest 400-year boundary at or before ordinal, then
250 * work with the offset from that boundary to ordinal. Life is much
251 * clearer if we subtract 1 from ordinal first -- then the values
252 * of ordinal at 400-year boundaries are exactly those divisible
253 * by DI400Y:
254 *
255 * D M Y n n-1
256 * -- --- ---- ---------- ----------------
257 * 31 Dec -400 -DI400Y -DI400Y -1
258 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
259 * ...
260 * 30 Dec 000 -1 -2
261 * 31 Dec 000 0 -1
262 * 1 Jan 001 1 0 400-year boundary
263 * 2 Jan 001 2 1
264 * 3 Jan 001 3 2
265 * ...
266 * 31 Dec 400 DI400Y DI400Y -1
267 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
268 */
269 assert(ordinal >= 1);
270 --ordinal;
271 n400 = ordinal / DI400Y;
272 n = ordinal % DI400Y;
273 *year = n400 * 400 + 1;
274
275 /* Now n is the (non-negative) offset, in days, from January 1 of
276 * year, to the desired date. Now compute how many 100-year cycles
277 * precede n.
278 * Note that it's possible for n100 to equal 4! In that case 4 full
279 * 100-year cycles precede the desired day, which implies the
280 * desired day is December 31 at the end of a 400-year cycle.
281 */
282 n100 = n / DI100Y;
283 n = n % DI100Y;
284
285 /* Now compute how many 4-year cycles precede it. */
286 n4 = n / DI4Y;
287 n = n % DI4Y;
288
289 /* And now how many single years. Again n1 can be 4, and again
290 * meaning that the desired day is December 31 at the end of the
291 * 4-year cycle.
292 */
293 n1 = n / 365;
294 n = n % 365;
295
296 *year += n100 * 100 + n4 * 4 + n1;
297 if (n1 == 4 || n100 == 4) {
298 assert(n == 0);
299 *year -= 1;
300 *month = 12;
301 *day = 31;
302 return;
303 }
304
305 /* Now the year is correct, and n is the offset from January 1. We
306 * find the month via an estimate that's either exact or one too
307 * large.
308 */
309 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
310 assert(leapyear == is_leap(*year));
311 *month = (n + 50) >> 5;
312 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
313 if (preceding > n) {
314 /* estimate is too large */
315 *month -= 1;
316 preceding -= days_in_month(*year, *month);
317 }
318 n -= preceding;
319 assert(0 <= n);
320 assert(n < days_in_month(*year, *month));
321
322 *day = n + 1;
323}
324
325/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
326static int
327ymd_to_ord(int year, int month, int day)
328{
329 return days_before_year(year) + days_before_month(year, month) + day;
330}
331
332/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
333static int
334weekday(int year, int month, int day)
335{
336 return (ymd_to_ord(year, month, day) + 6) % 7;
337}
338
339/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
340 * first calendar week containing a Thursday.
341 */
342static int
343iso_week1_monday(int year)
344{
345 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
346 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
347 int first_weekday = (first_day + 6) % 7;
348 /* ordinal of closest Monday at or before 1/1 */
349 int week1_monday = first_day - first_weekday;
350
351 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
352 week1_monday += 7;
353 return week1_monday;
354}
355
356/* ---------------------------------------------------------------------------
357 * Range checkers.
358 */
359
360/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
361 * If not, raise OverflowError and return -1.
362 */
363static int
364check_delta_day_range(int days)
365{
366 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
367 return 0;
368 PyErr_Format(PyExc_OverflowError,
369 "days=%d; must have magnitude <= %d",
Guido van Rossumbd43e912002-12-16 20:34:55 +0000370 days, MAX_DELTA_DAYS);
Tim Peters2a799bf2002-12-16 20:18:38 +0000371 return -1;
372}
373
374/* Check that date arguments are in range. Return 0 if they are. If they
375 * aren't, raise ValueError and return -1.
376 */
377static int
378check_date_args(int year, int month, int day)
379{
380
381 if (year < MINYEAR || year > MAXYEAR) {
382 PyErr_SetString(PyExc_ValueError,
383 "year is out of range");
384 return -1;
385 }
386 if (month < 1 || month > 12) {
387 PyErr_SetString(PyExc_ValueError,
388 "month must be in 1..12");
389 return -1;
390 }
391 if (day < 1 || day > days_in_month(year, month)) {
392 PyErr_SetString(PyExc_ValueError,
393 "day is out of range for month");
394 return -1;
395 }
396 return 0;
397}
398
399/* Check that time arguments are in range. Return 0 if they are. If they
400 * aren't, raise ValueError and return -1.
401 */
402static int
403check_time_args(int h, int m, int s, int us)
404{
405 if (h < 0 || h > 23) {
406 PyErr_SetString(PyExc_ValueError,
407 "hour must be in 0..23");
408 return -1;
409 }
410 if (m < 0 || m > 59) {
411 PyErr_SetString(PyExc_ValueError,
412 "minute must be in 0..59");
413 return -1;
414 }
415 if (s < 0 || s > 59) {
416 PyErr_SetString(PyExc_ValueError,
417 "second must be in 0..59");
418 return -1;
419 }
420 if (us < 0 || us > 999999) {
421 PyErr_SetString(PyExc_ValueError,
422 "microsecond must be in 0..999999");
423 return -1;
424 }
425 return 0;
426}
427
428/* ---------------------------------------------------------------------------
429 * Normalization utilities.
430 */
431
432/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
433 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
434 * at least factor, enough of *lo is converted into "hi" units so that
435 * 0 <= *lo < factor. The input values must be such that int overflow
436 * is impossible.
437 */
438static void
439normalize_pair(int *hi, int *lo, int factor)
440{
441 assert(factor > 0);
442 assert(lo != hi);
443 if (*lo < 0 || *lo >= factor) {
444 const int num_hi = divmod(*lo, factor, lo);
445 const int new_hi = *hi + num_hi;
446 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
447 *hi = new_hi;
448 }
449 assert(0 <= *lo && *lo < factor);
450}
451
452/* Fiddle days (d), seconds (s), and microseconds (us) so that
453 * 0 <= *s < 24*3600
454 * 0 <= *us < 1000000
455 * The input values must be such that the internals don't overflow.
456 * The way this routine is used, we don't get close.
457 */
458static void
459normalize_d_s_us(int *d, int *s, int *us)
460{
461 if (*us < 0 || *us >= 1000000) {
462 normalize_pair(s, us, 1000000);
463 /* |s| can't be bigger than about
464 * |original s| + |original us|/1000000 now.
465 */
466
467 }
468 if (*s < 0 || *s >= 24*3600) {
469 normalize_pair(d, s, 24*3600);
470 /* |d| can't be bigger than about
471 * |original d| +
472 * (|original s| + |original us|/1000000) / (24*3600) now.
473 */
474 }
475 assert(0 <= *s && *s < 24*3600);
476 assert(0 <= *us && *us < 1000000);
477}
478
479/* Fiddle years (y), months (m), and days (d) so that
480 * 1 <= *m <= 12
481 * 1 <= *d <= days_in_month(*y, *m)
482 * The input values must be such that the internals don't overflow.
483 * The way this routine is used, we don't get close.
484 */
485static void
486normalize_y_m_d(int *y, int *m, int *d)
487{
488 int dim; /* # of days in month */
489
490 /* This gets muddy: the proper range for day can't be determined
491 * without knowing the correct month and year, but if day is, e.g.,
492 * plus or minus a million, the current month and year values make
493 * no sense (and may also be out of bounds themselves).
494 * Saying 12 months == 1 year should be non-controversial.
495 */
496 if (*m < 1 || *m > 12) {
497 --*m;
498 normalize_pair(y, m, 12);
499 ++*m;
500 /* |y| can't be bigger than about
501 * |original y| + |original m|/12 now.
502 */
503 }
504 assert(1 <= *m && *m <= 12);
505
506 /* Now only day can be out of bounds (year may also be out of bounds
507 * for a datetime object, but we don't care about that here).
508 * If day is out of bounds, what to do is arguable, but at least the
509 * method here is principled and explainable.
510 */
511 dim = days_in_month(*y, *m);
512 if (*d < 1 || *d > dim) {
513 /* Move day-1 days from the first of the month. First try to
514 * get off cheap if we're only one day out of range
515 * (adjustments for timezone alone can't be worse than that).
516 */
517 if (*d == 0) {
518 --*m;
519 if (*m > 0)
520 *d = days_in_month(*y, *m);
521 else {
522 --*y;
523 *m = 12;
524 *d = 31;
525 }
526 }
527 else if (*d == dim + 1) {
528 /* move forward a day */
529 ++*m;
530 *d = 1;
531 if (*m > 12) {
532 *m = 1;
533 ++*y;
534 }
535 }
536 else {
537 int ordinal = ymd_to_ord(*y, *m, 1) +
538 *d - 1;
539 ord_to_ymd(ordinal, y, m, d);
540 }
541 }
542 assert(*m > 0);
543 assert(*d > 0);
544}
545
546/* Fiddle out-of-bounds months and days so that the result makes some kind
547 * of sense. The parameters are both inputs and outputs. Returns < 0 on
548 * failure, where failure means the adjusted year is out of bounds.
549 */
550static int
551normalize_date(int *year, int *month, int *day)
552{
553 int result;
554
555 normalize_y_m_d(year, month, day);
556 if (MINYEAR <= *year && *year <= MAXYEAR)
557 result = 0;
558 else {
559 PyErr_SetString(PyExc_OverflowError,
560 "date value out of range");
561 result = -1;
562 }
563 return result;
564}
565
566/* Force all the datetime fields into range. The parameters are both
567 * inputs and outputs. Returns < 0 on error.
568 */
569static int
570normalize_datetime(int *year, int *month, int *day,
571 int *hour, int *minute, int *second,
572 int *microsecond)
573{
574 normalize_pair(second, microsecond, 1000000);
575 normalize_pair(minute, second, 60);
576 normalize_pair(hour, minute, 60);
577 normalize_pair(day, hour, 24);
578 return normalize_date(year, month, day);
579}
580
581/* ---------------------------------------------------------------------------
Tim Petersb0c854d2003-05-17 15:57:00 +0000582 * Basic object allocation: tp_alloc implementations. These allocate
583 * Python objects of the right size and type, and do the Python object-
584 * initialization bit. If there's not enough memory, they return NULL after
585 * setting MemoryError. All data members remain uninitialized trash.
586 *
587 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
Tim Peters03eaf8b2003-05-18 02:24:46 +0000588 * member is needed. This is ugly, imprecise, and possibly insecure.
589 * tp_basicsize for the time and datetime types is set to the size of the
590 * struct that has room for the tzinfo member, so subclasses in Python will
591 * allocate enough space for a tzinfo member whether or not one is actually
592 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
593 * part is that PyType_GenericAlloc() (which subclasses in Python end up
594 * using) just happens today to effectively ignore the nitems argument
595 * when tp_itemsize is 0, which it is for these type objects. If that
596 * changes, perhaps the callers of tp_alloc slots in this file should
597 * be changed to force a 0 nitems argument unless the type being allocated
598 * is a base type implemented in this file (so that tp_alloc is time_alloc
599 * or datetime_alloc below, which know about the nitems abuse).
Tim Petersb0c854d2003-05-17 15:57:00 +0000600 */
601
602static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000603time_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000604{
605 PyObject *self;
606
607 self = (PyObject *)
608 PyObject_MALLOC(aware ?
609 sizeof(PyDateTime_Time) :
610 sizeof(_PyDateTime_BaseTime));
611 if (self == NULL)
612 return (PyObject *)PyErr_NoMemory();
613 PyObject_INIT(self, type);
614 return self;
615}
616
617static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000618datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
Tim Petersb0c854d2003-05-17 15:57:00 +0000619{
620 PyObject *self;
621
622 self = (PyObject *)
623 PyObject_MALLOC(aware ?
624 sizeof(PyDateTime_DateTime) :
625 sizeof(_PyDateTime_BaseDateTime));
626 if (self == NULL)
627 return (PyObject *)PyErr_NoMemory();
628 PyObject_INIT(self, type);
629 return self;
630}
631
632/* ---------------------------------------------------------------------------
633 * Helpers for setting object fields. These work on pointers to the
634 * appropriate base class.
635 */
636
637/* For date and datetime. */
638static void
639set_date_fields(PyDateTime_Date *self, int y, int m, int d)
640{
641 self->hashcode = -1;
642 SET_YEAR(self, y);
643 SET_MONTH(self, m);
644 SET_DAY(self, d);
645}
646
647/* ---------------------------------------------------------------------------
648 * Create various objects, mostly without range checking.
649 */
650
651/* Create a date instance with no range checking. */
652static PyObject *
653new_date_ex(int year, int month, int day, PyTypeObject *type)
654{
655 PyDateTime_Date *self;
656
657 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
658 if (self != NULL)
659 set_date_fields(self, year, month, day);
660 return (PyObject *) self;
661}
662
663#define new_date(year, month, day) \
664 new_date_ex(year, month, day, &PyDateTime_DateType)
665
666/* Create a datetime instance with no range checking. */
667static PyObject *
668new_datetime_ex(int year, int month, int day, int hour, int minute,
669 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
670{
671 PyDateTime_DateTime *self;
672 char aware = tzinfo != Py_None;
673
674 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
675 if (self != NULL) {
676 self->hastzinfo = aware;
677 set_date_fields((PyDateTime_Date *)self, year, month, day);
678 DATE_SET_HOUR(self, hour);
679 DATE_SET_MINUTE(self, minute);
680 DATE_SET_SECOND(self, second);
681 DATE_SET_MICROSECOND(self, usecond);
682 if (aware) {
683 Py_INCREF(tzinfo);
684 self->tzinfo = tzinfo;
685 }
686 }
687 return (PyObject *)self;
688}
689
690#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
691 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
692 &PyDateTime_DateTimeType)
693
694/* Create a time instance with no range checking. */
695static PyObject *
696new_time_ex(int hour, int minute, int second, int usecond,
697 PyObject *tzinfo, PyTypeObject *type)
698{
699 PyDateTime_Time *self;
700 char aware = tzinfo != Py_None;
701
702 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
703 if (self != NULL) {
704 self->hastzinfo = aware;
705 self->hashcode = -1;
706 TIME_SET_HOUR(self, hour);
707 TIME_SET_MINUTE(self, minute);
708 TIME_SET_SECOND(self, second);
709 TIME_SET_MICROSECOND(self, usecond);
710 if (aware) {
711 Py_INCREF(tzinfo);
712 self->tzinfo = tzinfo;
713 }
714 }
715 return (PyObject *)self;
716}
717
718#define new_time(hh, mm, ss, us, tzinfo) \
719 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
720
721/* Create a timedelta instance. Normalize the members iff normalize is
722 * true. Passing false is a speed optimization, if you know for sure
723 * that seconds and microseconds are already in their proper ranges. In any
724 * case, raises OverflowError and returns NULL if the normalized days is out
725 * of range).
726 */
727static PyObject *
728new_delta_ex(int days, int seconds, int microseconds, int normalize,
729 PyTypeObject *type)
730{
731 PyDateTime_Delta *self;
732
733 if (normalize)
734 normalize_d_s_us(&days, &seconds, &microseconds);
735 assert(0 <= seconds && seconds < 24*3600);
736 assert(0 <= microseconds && microseconds < 1000000);
737
738 if (check_delta_day_range(days) < 0)
739 return NULL;
740
741 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
742 if (self != NULL) {
743 self->hashcode = -1;
744 SET_TD_DAYS(self, days);
745 SET_TD_SECONDS(self, seconds);
746 SET_TD_MICROSECONDS(self, microseconds);
747 }
748 return (PyObject *) self;
749}
750
751#define new_delta(d, s, us, normalize) \
752 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
753
754/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +0000755 * tzinfo helpers.
756 */
757
Tim Peters855fe882002-12-22 03:43:39 +0000758/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
759 * raise TypeError and return -1.
760 */
761static int
762check_tzinfo_subclass(PyObject *p)
763{
764 if (p == Py_None || PyTZInfo_Check(p))
765 return 0;
766 PyErr_Format(PyExc_TypeError,
767 "tzinfo argument must be None or of a tzinfo subclass, "
768 "not type '%s'",
Christian Heimese93237d2007-12-19 02:37:44 +0000769 Py_TYPE(p)->tp_name);
Tim Peters855fe882002-12-22 03:43:39 +0000770 return -1;
771}
772
Tim Petersbad8ff02002-12-30 20:52:32 +0000773/* Return tzinfo.methname(tzinfoarg), without any checking of results.
Tim Peters855fe882002-12-22 03:43:39 +0000774 * If tzinfo is None, returns None.
775 */
776static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000777call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
Tim Peters855fe882002-12-22 03:43:39 +0000778{
779 PyObject *result;
780
Tim Petersbad8ff02002-12-30 20:52:32 +0000781 assert(tzinfo && methname && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000782 assert(check_tzinfo_subclass(tzinfo) >= 0);
783 if (tzinfo == Py_None) {
784 result = Py_None;
785 Py_INCREF(result);
786 }
787 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000788 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000789 return result;
790}
791
Tim Peters2a799bf2002-12-16 20:18:38 +0000792/* If self has a tzinfo member, return a BORROWED reference to it. Else
793 * return NULL, which is NOT AN ERROR. There are no error returns here,
794 * and the caller must not decref the result.
795 */
796static PyObject *
797get_tzinfo_member(PyObject *self)
798{
799 PyObject *tzinfo = NULL;
800
Tim Petersa9bc1682003-01-11 03:39:11 +0000801 if (PyDateTime_Check(self) && HASTZINFO(self))
802 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
Tim Petersa032d2e2003-01-11 00:15:54 +0000803 else if (PyTime_Check(self) && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +0000804 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
Tim Peters2a799bf2002-12-16 20:18:38 +0000805
806 return tzinfo;
807}
808
Tim Petersbad8ff02002-12-30 20:52:32 +0000809/* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
Tim Peters2a799bf2002-12-16 20:18:38 +0000810 * result. tzinfo must be an instance of the tzinfo class. If the method
811 * returns None, this returns 0 and sets *none to 1. If the method doesn't
Tim Peters397301e2003-01-02 21:28:08 +0000812 * return None or timedelta, TypeError is raised and this returns -1. If it
813 * returnsa timedelta and the value is out of range or isn't a whole number
814 * of minutes, ValueError is raised and this returns -1.
Tim Peters2a799bf2002-12-16 20:18:38 +0000815 * Else *none is set to 0 and the integer method result is returned.
816 */
817static int
818call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
819 int *none)
820{
821 PyObject *u;
Tim Peters397301e2003-01-02 21:28:08 +0000822 int result = -1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000823
824 assert(tzinfo != NULL);
825 assert(PyTZInfo_Check(tzinfo));
826 assert(tzinfoarg != NULL);
827
828 *none = 0;
Tim Petersbad8ff02002-12-30 20:52:32 +0000829 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +0000830 if (u == NULL)
831 return -1;
832
Tim Peters27362852002-12-23 16:17:39 +0000833 else if (u == Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +0000834 result = 0;
835 *none = 1;
Tim Peters2a799bf2002-12-16 20:18:38 +0000836 }
Tim Peters855fe882002-12-22 03:43:39 +0000837 else if (PyDelta_Check(u)) {
838 const int days = GET_TD_DAYS(u);
839 if (days < -1 || days > 0)
840 result = 24*60; /* trigger ValueError below */
841 else {
842 /* next line can't overflow because we know days
843 * is -1 or 0 now
844 */
845 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
846 result = divmod(ss, 60, &ss);
847 if (ss || GET_TD_MICROSECONDS(u)) {
848 PyErr_Format(PyExc_ValueError,
849 "tzinfo.%s() must return a "
850 "whole number of minutes",
851 name);
852 result = -1;
Tim Peters855fe882002-12-22 03:43:39 +0000853 }
854 }
855 }
Tim Peters2a799bf2002-12-16 20:18:38 +0000856 else {
857 PyErr_Format(PyExc_TypeError,
Tim Peters397301e2003-01-02 21:28:08 +0000858 "tzinfo.%s() must return None or "
Tim Peters855fe882002-12-22 03:43:39 +0000859 "timedelta, not '%s'",
Christian Heimese93237d2007-12-19 02:37:44 +0000860 name, Py_TYPE(u)->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000861 }
862
Tim Peters2a799bf2002-12-16 20:18:38 +0000863 Py_DECREF(u);
864 if (result < -1439 || result > 1439) {
865 PyErr_Format(PyExc_ValueError,
Neal Norwitz506a2242003-01-04 01:02:25 +0000866 "tzinfo.%s() returned %d; must be in "
Tim Peters2a799bf2002-12-16 20:18:38 +0000867 "-1439 .. 1439",
868 name, result);
869 result = -1;
870 }
Tim Peters397301e2003-01-02 21:28:08 +0000871 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +0000872}
873
874/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
875 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
876 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
Tim Peters397301e2003-01-02 21:28:08 +0000877 * doesn't return None or timedelta, TypeError is raised and this returns -1.
878 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
879 * # of minutes), ValueError is raised and this returns -1. Else *none is
880 * set to 0 and the offset is returned (as int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000881 */
882static int
883call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
884{
885 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
886}
887
Tim Petersbad8ff02002-12-30 20:52:32 +0000888/* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
889 */
Tim Peters855fe882002-12-22 03:43:39 +0000890static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000891offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
Tim Peters855fe882002-12-22 03:43:39 +0000892 PyObject *result;
893
Tim Petersbad8ff02002-12-30 20:52:32 +0000894 assert(tzinfo && name && tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000895 if (tzinfo == Py_None) {
896 result = Py_None;
897 Py_INCREF(result);
898 }
899 else {
900 int none;
Tim Petersbad8ff02002-12-30 20:52:32 +0000901 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
902 &none);
Tim Peters855fe882002-12-22 03:43:39 +0000903 if (offset < 0 && PyErr_Occurred())
904 return NULL;
905 if (none) {
906 result = Py_None;
907 Py_INCREF(result);
908 }
909 else
910 result = new_delta(0, offset * 60, 0, 1);
911 }
912 return result;
913}
914
Tim Peters2a799bf2002-12-16 20:18:38 +0000915/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
916 * result. tzinfo must be an instance of the tzinfo class. If dst()
917 * returns None, call_dst returns 0 and sets *none to 1. If dst()
Tim Peters397301e2003-01-02 21:28:08 +0000918 & doesn't return None or timedelta, TypeError is raised and this
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000919 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
Tim Peters397301e2003-01-02 21:28:08 +0000920 * ValueError is raised and this returns -1. Else *none is set to 0 and
921 * the offset is returned (as an int # of minutes east of UTC).
Tim Peters2a799bf2002-12-16 20:18:38 +0000922 */
923static int
924call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
925{
926 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
927}
928
Tim Petersbad8ff02002-12-30 20:52:32 +0000929/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
Tim Peters855fe882002-12-22 03:43:39 +0000930 * an instance of the tzinfo class or None. If tzinfo isn't None, and
Tim Petersbad8ff02002-12-30 20:52:32 +0000931 * tzname() doesn't return None or a string, TypeError is raised and this
Tim Peters855fe882002-12-22 03:43:39 +0000932 * returns NULL.
Tim Peters2a799bf2002-12-16 20:18:38 +0000933 */
934static PyObject *
Tim Petersbad8ff02002-12-30 20:52:32 +0000935call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +0000936{
937 PyObject *result;
938
939 assert(tzinfo != NULL);
Tim Peters855fe882002-12-22 03:43:39 +0000940 assert(check_tzinfo_subclass(tzinfo) >= 0);
Tim Petersbad8ff02002-12-30 20:52:32 +0000941 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000942
Tim Peters855fe882002-12-22 03:43:39 +0000943 if (tzinfo == Py_None) {
944 result = Py_None;
945 Py_INCREF(result);
946 }
947 else
Tim Petersbad8ff02002-12-30 20:52:32 +0000948 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
Tim Peters855fe882002-12-22 03:43:39 +0000949
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000950 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
Tim Peters855fe882002-12-22 03:43:39 +0000951 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
Tim Peters2a799bf2002-12-16 20:18:38 +0000952 "return None or a string, not '%s'",
Christian Heimese93237d2007-12-19 02:37:44 +0000953 Py_TYPE(result)->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +0000954 Py_DECREF(result);
955 result = NULL;
956 }
957 return result;
958}
959
960typedef enum {
961 /* an exception has been set; the caller should pass it on */
962 OFFSET_ERROR,
963
Tim Petersa9bc1682003-01-11 03:39:11 +0000964 /* type isn't date, datetime, or time subclass */
Tim Peters2a799bf2002-12-16 20:18:38 +0000965 OFFSET_UNKNOWN,
966
967 /* date,
Tim Petersa9bc1682003-01-11 03:39:11 +0000968 * datetime with !hastzinfo
969 * datetime with None tzinfo,
970 * datetime where utcoffset() returns None
Tim Peters37f39822003-01-10 03:49:02 +0000971 * time with !hastzinfo
972 * time with None tzinfo,
973 * time where utcoffset() returns None
Tim Peters2a799bf2002-12-16 20:18:38 +0000974 */
975 OFFSET_NAIVE,
976
Tim Petersa9bc1682003-01-11 03:39:11 +0000977 /* time or datetime where utcoffset() doesn't return None */
Georg Brandle810fe22006-02-19 15:28:47 +0000978 OFFSET_AWARE
Tim Peters2a799bf2002-12-16 20:18:38 +0000979} naivety;
980
Tim Peters14b69412002-12-22 18:10:22 +0000981/* Classify an object as to whether it's naive or offset-aware. See
Tim Peters2a799bf2002-12-16 20:18:38 +0000982 * the "naivety" typedef for details. If the type is aware, *offset is set
983 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
Tim Peters14b69412002-12-22 18:10:22 +0000984 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
Tim Peterse39a80c2002-12-30 21:28:52 +0000985 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
Tim Peters2a799bf2002-12-16 20:18:38 +0000986 */
987static naivety
Tim Peterse39a80c2002-12-30 21:28:52 +0000988classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
Tim Peters2a799bf2002-12-16 20:18:38 +0000989{
990 int none;
991 PyObject *tzinfo;
992
Tim Peterse39a80c2002-12-30 21:28:52 +0000993 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +0000994 *offset = 0;
Tim Peters14b69412002-12-22 18:10:22 +0000995 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
Tim Peters2a799bf2002-12-16 20:18:38 +0000996 if (tzinfo == Py_None)
997 return OFFSET_NAIVE;
Tim Peters14b69412002-12-22 18:10:22 +0000998 if (tzinfo == NULL) {
999 /* note that a datetime passes the PyDate_Check test */
1000 return (PyTime_Check(op) || PyDate_Check(op)) ?
1001 OFFSET_NAIVE : OFFSET_UNKNOWN;
1002 }
Tim Peterse39a80c2002-12-30 21:28:52 +00001003 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00001004 if (*offset == -1 && PyErr_Occurred())
1005 return OFFSET_ERROR;
1006 return none ? OFFSET_NAIVE : OFFSET_AWARE;
1007}
1008
Tim Peters00237032002-12-27 02:21:51 +00001009/* Classify two objects as to whether they're naive or offset-aware.
1010 * This isn't quite the same as calling classify_utcoffset() twice: for
1011 * binary operations (comparison and subtraction), we generally want to
1012 * ignore the tzinfo members if they're identical. This is by design,
1013 * so that results match "naive" expectations when mixing objects from a
1014 * single timezone. So in that case, this sets both offsets to 0 and
1015 * both naiveties to OFFSET_NAIVE.
1016 * The function returns 0 if everything's OK, and -1 on error.
1017 */
1018static int
1019classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
Tim Peterse39a80c2002-12-30 21:28:52 +00001020 PyObject *tzinfoarg1,
1021 PyObject *o2, int *offset2, naivety *n2,
1022 PyObject *tzinfoarg2)
Tim Peters00237032002-12-27 02:21:51 +00001023{
1024 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1025 *offset1 = *offset2 = 0;
1026 *n1 = *n2 = OFFSET_NAIVE;
1027 }
1028 else {
Tim Peterse39a80c2002-12-30 21:28:52 +00001029 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
Tim Peters00237032002-12-27 02:21:51 +00001030 if (*n1 == OFFSET_ERROR)
1031 return -1;
Tim Peterse39a80c2002-12-30 21:28:52 +00001032 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
Tim Peters00237032002-12-27 02:21:51 +00001033 if (*n2 == OFFSET_ERROR)
1034 return -1;
1035 }
1036 return 0;
1037}
1038
Tim Peters2a799bf2002-12-16 20:18:38 +00001039/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1040 * stuff
1041 * ", tzinfo=" + repr(tzinfo)
1042 * before the closing ")".
1043 */
1044static PyObject *
1045append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1046{
1047 PyObject *temp;
1048
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001049 assert(PyString_Check(repr));
Tim Peters2a799bf2002-12-16 20:18:38 +00001050 assert(tzinfo);
1051 if (tzinfo == Py_None)
1052 return repr;
1053 /* Get rid of the trailing ')'. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001054 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1055 temp = PyString_FromStringAndSize(PyString_AsString(repr),
1056 PyString_Size(repr) - 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00001057 Py_DECREF(repr);
1058 if (temp == NULL)
1059 return NULL;
1060 repr = temp;
1061
1062 /* Append ", tzinfo=". */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001063 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
Tim Peters2a799bf2002-12-16 20:18:38 +00001064
1065 /* Append repr(tzinfo). */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001066 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
Tim Peters2a799bf2002-12-16 20:18:38 +00001067
1068 /* Add a closing paren. */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001069 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
Tim Peters2a799bf2002-12-16 20:18:38 +00001070 return repr;
1071}
1072
1073/* ---------------------------------------------------------------------------
1074 * String format helpers.
1075 */
1076
1077static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00001078format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
Tim Peters2a799bf2002-12-16 20:18:38 +00001079{
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001080 static const char *DayNames[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00001081 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1082 };
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001083 static const char *MonthNames[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00001084 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1085 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1086 };
1087
1088 char buffer[128];
1089 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1090
1091 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
1092 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
1093 GET_DAY(date), hours, minutes, seconds,
1094 GET_YEAR(date));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001095 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00001096}
1097
1098/* Add an hours & minutes UTC offset string to buf. buf has no more than
1099 * buflen bytes remaining. The UTC offset is gotten by calling
1100 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1101 * *buf, and that's all. Else the returned value is checked for sanity (an
1102 * integer in range), and if that's OK it's converted to an hours & minutes
1103 * string of the form
1104 * sign HH sep MM
1105 * Returns 0 if everything is OK. If the return value from utcoffset() is
1106 * bogus, an appropriate exception is set and -1 is returned.
1107 */
1108static int
Tim Peters328fff72002-12-20 01:31:27 +00001109format_utcoffset(char *buf, size_t buflen, const char *sep,
Tim Peters2a799bf2002-12-16 20:18:38 +00001110 PyObject *tzinfo, PyObject *tzinfoarg)
1111{
1112 int offset;
1113 int hours;
1114 int minutes;
1115 char sign;
1116 int none;
1117
1118 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1119 if (offset == -1 && PyErr_Occurred())
1120 return -1;
1121 if (none) {
1122 *buf = '\0';
1123 return 0;
1124 }
1125 sign = '+';
1126 if (offset < 0) {
1127 sign = '-';
1128 offset = - offset;
1129 }
1130 hours = divmod(offset, 60, &minutes);
1131 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1132 return 0;
1133}
1134
Skip Montanarofc070d22008-03-15 16:04:45 +00001135static PyObject *
1136make_freplacement(PyObject *object)
1137{
Neal Norwitzf13572d2008-03-17 19:02:45 +00001138 char freplacement[64];
Skip Montanarofc070d22008-03-15 16:04:45 +00001139 if (PyTime_Check(object))
1140 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1141 else if (PyDateTime_Check(object))
1142 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1143 else
1144 sprintf(freplacement, "%06d", 0);
1145
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001146 return PyString_FromStringAndSize(freplacement, strlen(freplacement));
Skip Montanarofc070d22008-03-15 16:04:45 +00001147}
1148
Tim Peters2a799bf2002-12-16 20:18:38 +00001149/* I sure don't want to reproduce the strftime code from the time module,
1150 * so this imports the module and calls it. All the hair is due to
Skip Montanarofc070d22008-03-15 16:04:45 +00001151 * giving special meanings to the %z, %Z and %f format codes via a
1152 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001153 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1154 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001155 */
1156static PyObject *
Gregory P. Smith137d8242008-06-02 04:05:52 +00001157wrap_strftime(PyObject *object, const char *format, size_t format_len,
1158 PyObject *timetuple, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001159{
1160 PyObject *result = NULL; /* guilty until proved innocent */
1161
1162 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1163 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
Skip Montanarofc070d22008-03-15 16:04:45 +00001164 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001165
Gregory P. Smith137d8242008-06-02 04:05:52 +00001166 const char *pin; /* pointer to next char in input format */
1167 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001168
1169 PyObject *newfmt = NULL; /* py string, the output format */
1170 char *pnew; /* pointer to available byte in output format */
Gregory P. Smith137d8242008-06-02 04:05:52 +00001171 size_t totalnew; /* number bytes total in output format buffer,
1172 exclusive of trailing \0 */
1173 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001174
Gregory P. Smith137d8242008-06-02 04:05:52 +00001175 const char *ptoappend; /* ptr to string to append to output buffer */
1176 size_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001177
Tim Peters2a799bf2002-12-16 20:18:38 +00001178 assert(object && format && timetuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001179
Tim Petersd6844152002-12-22 20:58:42 +00001180 /* Give up if the year is before 1900.
1181 * Python strftime() plays games with the year, and different
1182 * games depending on whether envar PYTHON2K is set. This makes
1183 * years before 1900 a nightmare, even if the platform strftime
1184 * supports them (and not all do).
1185 * We could get a lot farther here by avoiding Python's strftime
1186 * wrapper and calling the C strftime() directly, but that isn't
1187 * an option in the Python implementation of this module.
1188 */
1189 {
1190 long year;
1191 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1192 if (pyyear == NULL) return NULL;
1193 assert(PyInt_Check(pyyear));
1194 year = PyInt_AsLong(pyyear);
1195 Py_DECREF(pyyear);
1196 if (year < 1900) {
1197 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1198 "1900; the datetime strftime() "
1199 "methods require year >= 1900",
1200 year);
1201 return NULL;
1202 }
1203 }
1204
Skip Montanarofc070d22008-03-15 16:04:45 +00001205 /* Scan the input format, looking for %z/%Z/%f escapes, building
Tim Peters328fff72002-12-20 01:31:27 +00001206 * a new format. Since computing the replacements for those codes
1207 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +00001208 */
Gregory P. Smith137d8242008-06-02 04:05:52 +00001209 totalnew = format_len + 1; /* realistic if no %z/%Z/%f */
Christian Heimes593daf52008-05-26 12:51:38 +00001210 newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
Tim Peters2a799bf2002-12-16 20:18:38 +00001211 if (newfmt == NULL) goto Done;
Christian Heimes593daf52008-05-26 12:51:38 +00001212 pnew = PyBytes_AsString(newfmt);
Tim Peters2a799bf2002-12-16 20:18:38 +00001213 usednew = 0;
1214
Gregory P. Smith137d8242008-06-02 04:05:52 +00001215 pin = format;
Tim Peters2a799bf2002-12-16 20:18:38 +00001216 while ((ch = *pin++) != '\0') {
1217 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +00001218 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001219 ntoappend = 1;
1220 }
1221 else if ((ch = *pin++) == '\0') {
1222 /* There's a lone trailing %; doesn't make sense. */
1223 PyErr_SetString(PyExc_ValueError, "strftime format "
1224 "ends with raw %");
1225 goto Done;
1226 }
1227 /* A % has been seen and ch is the character after it. */
1228 else if (ch == 'z') {
1229 if (zreplacement == NULL) {
1230 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +00001231 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +00001232 PyObject *tzinfo = get_tzinfo_member(object);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001233 zreplacement = PyString_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00001234 if (zreplacement == NULL) goto Done;
1235 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001236 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001237 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001238 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001239 "",
1240 tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00001241 tzinfoarg) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001242 goto Done;
1243 Py_DECREF(zreplacement);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001244 zreplacement = PyString_FromString(buf);
Tim Peters2a799bf2002-12-16 20:18:38 +00001245 if (zreplacement == NULL) goto Done;
1246 }
1247 }
1248 assert(zreplacement != NULL);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001249 ptoappend = PyString_AS_STRING(zreplacement);
1250 ntoappend = PyString_GET_SIZE(zreplacement);
Tim Peters2a799bf2002-12-16 20:18:38 +00001251 }
1252 else if (ch == 'Z') {
1253 /* format tzname */
1254 if (Zreplacement == NULL) {
1255 PyObject *tzinfo = get_tzinfo_member(object);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001256 Zreplacement = PyString_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00001257 if (Zreplacement == NULL) goto Done;
1258 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001259 PyObject *temp;
1260 assert(tzinfoarg != NULL);
1261 temp = call_tzname(tzinfo, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001262 if (temp == NULL) goto Done;
1263 if (temp != Py_None) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001264 assert(PyString_Check(temp));
Tim Peters2a799bf2002-12-16 20:18:38 +00001265 /* Since the tzname is getting
1266 * stuffed into the format, we
1267 * have to double any % signs
1268 * so that strftime doesn't
1269 * treat them as format codes.
1270 */
1271 Py_DECREF(Zreplacement);
1272 Zreplacement = PyObject_CallMethod(
1273 temp, "replace",
1274 "ss", "%", "%%");
1275 Py_DECREF(temp);
1276 if (Zreplacement == NULL)
1277 goto Done;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001278 if (!PyString_Check(Zreplacement)) {
Neal Norwitzd5b0c9b2006-03-20 01:58:39 +00001279 PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
1280 goto Done;
1281 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001282 }
1283 else
1284 Py_DECREF(temp);
1285 }
1286 }
1287 assert(Zreplacement != NULL);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001288 ptoappend = PyString_AS_STRING(Zreplacement);
1289 ntoappend = PyString_GET_SIZE(Zreplacement);
Tim Peters2a799bf2002-12-16 20:18:38 +00001290 }
Skip Montanarofc070d22008-03-15 16:04:45 +00001291 else if (ch == 'f') {
1292 /* format microseconds */
1293 if (freplacement == NULL) {
1294 freplacement = make_freplacement(object);
1295 if (freplacement == NULL)
1296 goto Done;
1297 }
1298 assert(freplacement != NULL);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001299 assert(PyString_Check(freplacement));
1300 ptoappend = PyString_AS_STRING(freplacement);
1301 ntoappend = PyString_GET_SIZE(freplacement);
Skip Montanarofc070d22008-03-15 16:04:45 +00001302 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001303 else {
Tim Peters328fff72002-12-20 01:31:27 +00001304 /* percent followed by neither z nor Z */
1305 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001306 ntoappend = 2;
1307 }
1308
1309 /* Append the ntoappend chars starting at ptoappend to
1310 * the new format.
1311 */
Neal Norwitzd5b0c9b2006-03-20 01:58:39 +00001312 assert(ptoappend != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001313 assert(ntoappend >= 0);
1314 if (ntoappend == 0)
1315 continue;
1316 while (usednew + ntoappend > totalnew) {
Gregory P. Smith137d8242008-06-02 04:05:52 +00001317 size_t bigger = totalnew << 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001318 if ((bigger >> 1) != totalnew) { /* overflow */
1319 PyErr_NoMemory();
1320 goto Done;
1321 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001322 if (_PyString_Resize(&newfmt, bigger) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001323 goto Done;
1324 totalnew = bigger;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001325 pnew = PyString_AsString(newfmt) + usednew;
Tim Peters2a799bf2002-12-16 20:18:38 +00001326 }
1327 memcpy(pnew, ptoappend, ntoappend);
1328 pnew += ntoappend;
1329 usednew += ntoappend;
1330 assert(usednew <= totalnew);
1331 } /* end while() */
1332
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001333 if (_PyString_Resize(&newfmt, usednew) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001334 goto Done;
1335 {
Christian Heimes000a0742008-01-03 22:16:32 +00001336 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001337 if (time == NULL)
1338 goto Done;
1339 result = PyObject_CallMethod(time, "strftime", "OO",
1340 newfmt, timetuple);
1341 Py_DECREF(time);
1342 }
1343 Done:
Skip Montanarofc070d22008-03-15 16:04:45 +00001344 Py_XDECREF(freplacement);
Tim Peters2a799bf2002-12-16 20:18:38 +00001345 Py_XDECREF(zreplacement);
1346 Py_XDECREF(Zreplacement);
1347 Py_XDECREF(newfmt);
1348 return result;
1349}
1350
1351static char *
1352isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1353{
1354 int x;
1355 x = PyOS_snprintf(buffer, bufflen,
1356 "%04d-%02d-%02d",
1357 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1358 return buffer + x;
1359}
1360
1361static void
1362isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1363{
1364 int us = DATE_GET_MICROSECOND(dt);
1365
1366 PyOS_snprintf(buffer, bufflen,
1367 "%02d:%02d:%02d", /* 8 characters */
1368 DATE_GET_HOUR(dt),
1369 DATE_GET_MINUTE(dt),
1370 DATE_GET_SECOND(dt));
1371 if (us)
1372 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1373}
1374
1375/* ---------------------------------------------------------------------------
1376 * Wrap functions from the time module. These aren't directly available
1377 * from C. Perhaps they should be.
1378 */
1379
1380/* Call time.time() and return its result (a Python float). */
1381static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001382time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001383{
1384 PyObject *result = NULL;
Christian Heimes000a0742008-01-03 22:16:32 +00001385 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001386
1387 if (time != NULL) {
1388 result = PyObject_CallMethod(time, "time", "()");
1389 Py_DECREF(time);
1390 }
1391 return result;
1392}
1393
1394/* Build a time.struct_time. The weekday and day number are automatically
1395 * computed from the y,m,d args.
1396 */
1397static PyObject *
1398build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1399{
1400 PyObject *time;
1401 PyObject *result = NULL;
1402
Christian Heimes000a0742008-01-03 22:16:32 +00001403 time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001404 if (time != NULL) {
1405 result = PyObject_CallMethod(time, "struct_time",
1406 "((iiiiiiiii))",
1407 y, m, d,
1408 hh, mm, ss,
1409 weekday(y, m, d),
1410 days_before_month(y, m) + d,
1411 dstflag);
1412 Py_DECREF(time);
1413 }
1414 return result;
1415}
1416
1417/* ---------------------------------------------------------------------------
1418 * Miscellaneous helpers.
1419 */
1420
1421/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1422 * The comparisons here all most naturally compute a cmp()-like result.
1423 * This little helper turns that into a bool result for rich comparisons.
1424 */
1425static PyObject *
1426diff_to_bool(int diff, int op)
1427{
1428 PyObject *result;
1429 int istrue;
1430
1431 switch (op) {
1432 case Py_EQ: istrue = diff == 0; break;
1433 case Py_NE: istrue = diff != 0; break;
1434 case Py_LE: istrue = diff <= 0; break;
1435 case Py_GE: istrue = diff >= 0; break;
1436 case Py_LT: istrue = diff < 0; break;
1437 case Py_GT: istrue = diff > 0; break;
1438 default:
1439 assert(! "op unknown");
1440 istrue = 0; /* To shut up compiler */
1441 }
1442 result = istrue ? Py_True : Py_False;
1443 Py_INCREF(result);
1444 return result;
1445}
1446
Tim Peters07534a62003-02-07 22:50:28 +00001447/* Raises a "can't compare" TypeError and returns NULL. */
1448static PyObject *
1449cmperror(PyObject *a, PyObject *b)
1450{
1451 PyErr_Format(PyExc_TypeError,
1452 "can't compare %s to %s",
Christian Heimese93237d2007-12-19 02:37:44 +00001453 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
Tim Peters07534a62003-02-07 22:50:28 +00001454 return NULL;
1455}
1456
Tim Peters2a799bf2002-12-16 20:18:38 +00001457/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001458 * Cached Python objects; these are set by the module init function.
1459 */
1460
1461/* Conversion factors. */
1462static PyObject *us_per_us = NULL; /* 1 */
1463static PyObject *us_per_ms = NULL; /* 1000 */
1464static PyObject *us_per_second = NULL; /* 1000000 */
1465static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1466static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1467static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1468static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1469static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1470
Tim Peters2a799bf2002-12-16 20:18:38 +00001471/* ---------------------------------------------------------------------------
1472 * Class implementations.
1473 */
1474
1475/*
1476 * PyDateTime_Delta implementation.
1477 */
1478
1479/* Convert a timedelta to a number of us,
1480 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1481 * as a Python int or long.
1482 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1483 * due to ubiquitous overflow possibilities.
1484 */
1485static PyObject *
1486delta_to_microseconds(PyDateTime_Delta *self)
1487{
1488 PyObject *x1 = NULL;
1489 PyObject *x2 = NULL;
1490 PyObject *x3 = NULL;
1491 PyObject *result = NULL;
1492
1493 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1494 if (x1 == NULL)
1495 goto Done;
1496 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1497 if (x2 == NULL)
1498 goto Done;
1499 Py_DECREF(x1);
1500 x1 = NULL;
1501
1502 /* x2 has days in seconds */
1503 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1504 if (x1 == NULL)
1505 goto Done;
1506 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1507 if (x3 == NULL)
1508 goto Done;
1509 Py_DECREF(x1);
1510 Py_DECREF(x2);
1511 x1 = x2 = NULL;
1512
1513 /* x3 has days+seconds in seconds */
1514 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1515 if (x1 == NULL)
1516 goto Done;
1517 Py_DECREF(x3);
1518 x3 = NULL;
1519
1520 /* x1 has days+seconds in us */
1521 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1522 if (x2 == NULL)
1523 goto Done;
1524 result = PyNumber_Add(x1, x2);
1525
1526Done:
1527 Py_XDECREF(x1);
1528 Py_XDECREF(x2);
1529 Py_XDECREF(x3);
1530 return result;
1531}
1532
1533/* Convert a number of us (as a Python int or long) to a timedelta.
1534 */
1535static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001536microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001537{
1538 int us;
1539 int s;
1540 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001541 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001542
1543 PyObject *tuple = NULL;
1544 PyObject *num = NULL;
1545 PyObject *result = NULL;
1546
1547 tuple = PyNumber_Divmod(pyus, us_per_second);
1548 if (tuple == NULL)
1549 goto Done;
1550
1551 num = PyTuple_GetItem(tuple, 1); /* us */
1552 if (num == NULL)
1553 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001554 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001555 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001556 if (temp == -1 && PyErr_Occurred())
1557 goto Done;
1558 assert(0 <= temp && temp < 1000000);
1559 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001560 if (us < 0) {
1561 /* The divisor was positive, so this must be an error. */
1562 assert(PyErr_Occurred());
1563 goto Done;
1564 }
1565
1566 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1567 if (num == NULL)
1568 goto Done;
1569 Py_INCREF(num);
1570 Py_DECREF(tuple);
1571
1572 tuple = PyNumber_Divmod(num, seconds_per_day);
1573 if (tuple == NULL)
1574 goto Done;
1575 Py_DECREF(num);
1576
1577 num = PyTuple_GetItem(tuple, 1); /* seconds */
1578 if (num == NULL)
1579 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001580 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001581 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001582 if (temp == -1 && PyErr_Occurred())
1583 goto Done;
1584 assert(0 <= temp && temp < 24*3600);
1585 s = (int)temp;
1586
Tim Peters2a799bf2002-12-16 20:18:38 +00001587 if (s < 0) {
1588 /* The divisor was positive, so this must be an error. */
1589 assert(PyErr_Occurred());
1590 goto Done;
1591 }
1592
1593 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1594 if (num == NULL)
1595 goto Done;
1596 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001597 temp = PyLong_AsLong(num);
1598 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001599 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001600 d = (int)temp;
1601 if ((long)d != temp) {
1602 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1603 "large to fit in a C int");
1604 goto Done;
1605 }
Tim Petersb0c854d2003-05-17 15:57:00 +00001606 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001607
1608Done:
1609 Py_XDECREF(tuple);
1610 Py_XDECREF(num);
1611 return result;
1612}
1613
Tim Petersb0c854d2003-05-17 15:57:00 +00001614#define microseconds_to_delta(pymicros) \
1615 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1616
Tim Peters2a799bf2002-12-16 20:18:38 +00001617static PyObject *
1618multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1619{
1620 PyObject *pyus_in;
1621 PyObject *pyus_out;
1622 PyObject *result;
1623
1624 pyus_in = delta_to_microseconds(delta);
1625 if (pyus_in == NULL)
1626 return NULL;
1627
1628 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1629 Py_DECREF(pyus_in);
1630 if (pyus_out == NULL)
1631 return NULL;
1632
1633 result = microseconds_to_delta(pyus_out);
1634 Py_DECREF(pyus_out);
1635 return result;
1636}
1637
1638static PyObject *
1639divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1640{
1641 PyObject *pyus_in;
1642 PyObject *pyus_out;
1643 PyObject *result;
1644
1645 pyus_in = delta_to_microseconds(delta);
1646 if (pyus_in == NULL)
1647 return NULL;
1648
1649 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1650 Py_DECREF(pyus_in);
1651 if (pyus_out == NULL)
1652 return NULL;
1653
1654 result = microseconds_to_delta(pyus_out);
1655 Py_DECREF(pyus_out);
1656 return result;
1657}
1658
1659static PyObject *
1660delta_add(PyObject *left, PyObject *right)
1661{
1662 PyObject *result = Py_NotImplemented;
1663
1664 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1665 /* delta + delta */
1666 /* The C-level additions can't overflow because of the
1667 * invariant bounds.
1668 */
1669 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1670 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1671 int microseconds = GET_TD_MICROSECONDS(left) +
1672 GET_TD_MICROSECONDS(right);
1673 result = new_delta(days, seconds, microseconds, 1);
1674 }
1675
1676 if (result == Py_NotImplemented)
1677 Py_INCREF(result);
1678 return result;
1679}
1680
1681static PyObject *
1682delta_negative(PyDateTime_Delta *self)
1683{
1684 return new_delta(-GET_TD_DAYS(self),
1685 -GET_TD_SECONDS(self),
1686 -GET_TD_MICROSECONDS(self),
1687 1);
1688}
1689
1690static PyObject *
1691delta_positive(PyDateTime_Delta *self)
1692{
1693 /* Could optimize this (by returning self) if this isn't a
1694 * subclass -- but who uses unary + ? Approximately nobody.
1695 */
1696 return new_delta(GET_TD_DAYS(self),
1697 GET_TD_SECONDS(self),
1698 GET_TD_MICROSECONDS(self),
1699 0);
1700}
1701
1702static PyObject *
1703delta_abs(PyDateTime_Delta *self)
1704{
1705 PyObject *result;
1706
1707 assert(GET_TD_MICROSECONDS(self) >= 0);
1708 assert(GET_TD_SECONDS(self) >= 0);
1709
1710 if (GET_TD_DAYS(self) < 0)
1711 result = delta_negative(self);
1712 else
1713 result = delta_positive(self);
1714
1715 return result;
1716}
1717
1718static PyObject *
1719delta_subtract(PyObject *left, PyObject *right)
1720{
1721 PyObject *result = Py_NotImplemented;
1722
1723 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1724 /* delta - delta */
1725 PyObject *minus_right = PyNumber_Negative(right);
1726 if (minus_right) {
1727 result = delta_add(left, minus_right);
1728 Py_DECREF(minus_right);
1729 }
1730 else
1731 result = NULL;
1732 }
1733
1734 if (result == Py_NotImplemented)
1735 Py_INCREF(result);
1736 return result;
1737}
1738
1739/* This is more natural as a tp_compare, but doesn't work then: for whatever
1740 * reason, Python's try_3way_compare ignores tp_compare unless
1741 * PyInstance_Check returns true, but these aren't old-style classes.
1742 */
1743static PyObject *
1744delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1745{
Tim Peters07534a62003-02-07 22:50:28 +00001746 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001747
Tim Petersaa7d8492003-02-08 03:28:59 +00001748 if (PyDelta_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00001749 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1750 if (diff == 0) {
1751 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1752 if (diff == 0)
1753 diff = GET_TD_MICROSECONDS(self) -
1754 GET_TD_MICROSECONDS(other);
1755 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001756 }
Tim Peters07534a62003-02-07 22:50:28 +00001757 else if (op == Py_EQ || op == Py_NE)
1758 diff = 1; /* any non-zero value will do */
1759
1760 else /* stop this from falling back to address comparison */
1761 return cmperror((PyObject *)self, other);
1762
Tim Peters2a799bf2002-12-16 20:18:38 +00001763 return diff_to_bool(diff, op);
1764}
1765
1766static PyObject *delta_getstate(PyDateTime_Delta *self);
1767
1768static long
1769delta_hash(PyDateTime_Delta *self)
1770{
1771 if (self->hashcode == -1) {
1772 PyObject *temp = delta_getstate(self);
1773 if (temp != NULL) {
1774 self->hashcode = PyObject_Hash(temp);
1775 Py_DECREF(temp);
1776 }
1777 }
1778 return self->hashcode;
1779}
1780
1781static PyObject *
1782delta_multiply(PyObject *left, PyObject *right)
1783{
1784 PyObject *result = Py_NotImplemented;
1785
1786 if (PyDelta_Check(left)) {
1787 /* delta * ??? */
1788 if (PyInt_Check(right) || PyLong_Check(right))
1789 result = multiply_int_timedelta(right,
1790 (PyDateTime_Delta *) left);
1791 }
1792 else if (PyInt_Check(left) || PyLong_Check(left))
1793 result = multiply_int_timedelta(left,
1794 (PyDateTime_Delta *) right);
1795
1796 if (result == Py_NotImplemented)
1797 Py_INCREF(result);
1798 return result;
1799}
1800
1801static PyObject *
1802delta_divide(PyObject *left, PyObject *right)
1803{
1804 PyObject *result = Py_NotImplemented;
1805
1806 if (PyDelta_Check(left)) {
1807 /* delta * ??? */
1808 if (PyInt_Check(right) || PyLong_Check(right))
1809 result = divide_timedelta_int(
1810 (PyDateTime_Delta *)left,
1811 right);
1812 }
1813
1814 if (result == Py_NotImplemented)
1815 Py_INCREF(result);
1816 return result;
1817}
1818
1819/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1820 * timedelta constructor. sofar is the # of microseconds accounted for
1821 * so far, and there are factor microseconds per current unit, the number
1822 * of which is given by num. num * factor is added to sofar in a
1823 * numerically careful way, and that's the result. Any fractional
1824 * microseconds left over (this can happen if num is a float type) are
1825 * added into *leftover.
1826 * Note that there are many ways this can give an error (NULL) return.
1827 */
1828static PyObject *
1829accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1830 double *leftover)
1831{
1832 PyObject *prod;
1833 PyObject *sum;
1834
1835 assert(num != NULL);
1836
1837 if (PyInt_Check(num) || PyLong_Check(num)) {
1838 prod = PyNumber_Multiply(num, factor);
1839 if (prod == NULL)
1840 return NULL;
1841 sum = PyNumber_Add(sofar, prod);
1842 Py_DECREF(prod);
1843 return sum;
1844 }
1845
1846 if (PyFloat_Check(num)) {
1847 double dnum;
1848 double fracpart;
1849 double intpart;
1850 PyObject *x;
1851 PyObject *y;
1852
1853 /* The Plan: decompose num into an integer part and a
1854 * fractional part, num = intpart + fracpart.
1855 * Then num * factor ==
1856 * intpart * factor + fracpart * factor
1857 * and the LHS can be computed exactly in long arithmetic.
1858 * The RHS is again broken into an int part and frac part.
1859 * and the frac part is added into *leftover.
1860 */
1861 dnum = PyFloat_AsDouble(num);
1862 if (dnum == -1.0 && PyErr_Occurred())
1863 return NULL;
1864 fracpart = modf(dnum, &intpart);
1865 x = PyLong_FromDouble(intpart);
1866 if (x == NULL)
1867 return NULL;
1868
1869 prod = PyNumber_Multiply(x, factor);
1870 Py_DECREF(x);
1871 if (prod == NULL)
1872 return NULL;
1873
1874 sum = PyNumber_Add(sofar, prod);
1875 Py_DECREF(prod);
1876 if (sum == NULL)
1877 return NULL;
1878
1879 if (fracpart == 0.0)
1880 return sum;
1881 /* So far we've lost no information. Dealing with the
1882 * fractional part requires float arithmetic, and may
1883 * lose a little info.
1884 */
1885 assert(PyInt_Check(factor) || PyLong_Check(factor));
1886 if (PyInt_Check(factor))
1887 dnum = (double)PyInt_AsLong(factor);
1888 else
1889 dnum = PyLong_AsDouble(factor);
1890
1891 dnum *= fracpart;
1892 fracpart = modf(dnum, &intpart);
1893 x = PyLong_FromDouble(intpart);
1894 if (x == NULL) {
1895 Py_DECREF(sum);
1896 return NULL;
1897 }
1898
1899 y = PyNumber_Add(sum, x);
1900 Py_DECREF(sum);
1901 Py_DECREF(x);
1902 *leftover += fracpart;
1903 return y;
1904 }
1905
1906 PyErr_Format(PyExc_TypeError,
1907 "unsupported type for timedelta %s component: %s",
Christian Heimese93237d2007-12-19 02:37:44 +00001908 tag, Py_TYPE(num)->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00001909 return NULL;
1910}
1911
1912static PyObject *
1913delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1914{
1915 PyObject *self = NULL;
1916
1917 /* Argument objects. */
1918 PyObject *day = NULL;
1919 PyObject *second = NULL;
1920 PyObject *us = NULL;
1921 PyObject *ms = NULL;
1922 PyObject *minute = NULL;
1923 PyObject *hour = NULL;
1924 PyObject *week = NULL;
1925
1926 PyObject *x = NULL; /* running sum of microseconds */
1927 PyObject *y = NULL; /* temp sum of microseconds */
1928 double leftover_us = 0.0;
1929
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001930 static char *keywords[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00001931 "days", "seconds", "microseconds", "milliseconds",
1932 "minutes", "hours", "weeks", NULL
1933 };
1934
1935 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1936 keywords,
1937 &day, &second, &us,
1938 &ms, &minute, &hour, &week) == 0)
1939 goto Done;
1940
1941 x = PyInt_FromLong(0);
1942 if (x == NULL)
1943 goto Done;
1944
1945#define CLEANUP \
1946 Py_DECREF(x); \
1947 x = y; \
1948 if (x == NULL) \
1949 goto Done
1950
1951 if (us) {
1952 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1953 CLEANUP;
1954 }
1955 if (ms) {
1956 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1957 CLEANUP;
1958 }
1959 if (second) {
1960 y = accum("seconds", x, second, us_per_second, &leftover_us);
1961 CLEANUP;
1962 }
1963 if (minute) {
1964 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1965 CLEANUP;
1966 }
1967 if (hour) {
1968 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1969 CLEANUP;
1970 }
1971 if (day) {
1972 y = accum("days", x, day, us_per_day, &leftover_us);
1973 CLEANUP;
1974 }
1975 if (week) {
1976 y = accum("weeks", x, week, us_per_week, &leftover_us);
1977 CLEANUP;
1978 }
1979 if (leftover_us) {
1980 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001981 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001982 if (temp == NULL) {
1983 Py_DECREF(x);
1984 goto Done;
1985 }
1986 y = PyNumber_Add(x, temp);
1987 Py_DECREF(temp);
1988 CLEANUP;
1989 }
1990
Tim Petersb0c854d2003-05-17 15:57:00 +00001991 self = microseconds_to_delta_ex(x, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001992 Py_DECREF(x);
1993Done:
1994 return self;
1995
1996#undef CLEANUP
1997}
1998
1999static int
2000delta_nonzero(PyDateTime_Delta *self)
2001{
2002 return (GET_TD_DAYS(self) != 0
2003 || GET_TD_SECONDS(self) != 0
2004 || GET_TD_MICROSECONDS(self) != 0);
2005}
2006
2007static PyObject *
2008delta_repr(PyDateTime_Delta *self)
2009{
2010 if (GET_TD_MICROSECONDS(self) != 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002011 return PyString_FromFormat("%s(%d, %d, %d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002012 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002013 GET_TD_DAYS(self),
2014 GET_TD_SECONDS(self),
2015 GET_TD_MICROSECONDS(self));
2016 if (GET_TD_SECONDS(self) != 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002017 return PyString_FromFormat("%s(%d, %d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002018 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002019 GET_TD_DAYS(self),
2020 GET_TD_SECONDS(self));
2021
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002022 return PyString_FromFormat("%s(%d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002023 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002024 GET_TD_DAYS(self));
2025}
2026
2027static PyObject *
2028delta_str(PyDateTime_Delta *self)
2029{
2030 int days = GET_TD_DAYS(self);
2031 int seconds = GET_TD_SECONDS(self);
2032 int us = GET_TD_MICROSECONDS(self);
2033 int hours;
2034 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00002035 char buf[100];
2036 char *pbuf = buf;
2037 size_t buflen = sizeof(buf);
2038 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002039
2040 minutes = divmod(seconds, 60, &seconds);
2041 hours = divmod(minutes, 60, &minutes);
2042
2043 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00002044 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2045 (days == 1 || days == -1) ? "" : "s");
2046 if (n < 0 || (size_t)n >= buflen)
2047 goto Fail;
2048 pbuf += n;
2049 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002050 }
2051
Tim Petersba873472002-12-18 20:19:21 +00002052 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2053 hours, minutes, seconds);
2054 if (n < 0 || (size_t)n >= buflen)
2055 goto Fail;
2056 pbuf += n;
2057 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002058
2059 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00002060 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2061 if (n < 0 || (size_t)n >= buflen)
2062 goto Fail;
2063 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002064 }
2065
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002066 return PyString_FromStringAndSize(buf, pbuf - buf);
Tim Petersba873472002-12-18 20:19:21 +00002067
2068 Fail:
2069 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2070 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002071}
2072
Tim Peters371935f2003-02-01 01:52:50 +00002073/* Pickle support, a simple use of __reduce__. */
2074
Tim Petersb57f8f02003-02-01 02:54:15 +00002075/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002076static PyObject *
2077delta_getstate(PyDateTime_Delta *self)
2078{
2079 return Py_BuildValue("iii", GET_TD_DAYS(self),
2080 GET_TD_SECONDS(self),
2081 GET_TD_MICROSECONDS(self));
2082}
2083
Tim Peters2a799bf2002-12-16 20:18:38 +00002084static PyObject *
2085delta_reduce(PyDateTime_Delta* self)
2086{
Christian Heimese93237d2007-12-19 02:37:44 +00002087 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002088}
2089
2090#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2091
2092static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002093
Neal Norwitzdfb80862002-12-19 02:30:56 +00002094 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002095 PyDoc_STR("Number of days.")},
2096
Neal Norwitzdfb80862002-12-19 02:30:56 +00002097 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002098 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2099
Neal Norwitzdfb80862002-12-19 02:30:56 +00002100 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002101 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2102 {NULL}
2103};
2104
2105static PyMethodDef delta_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002106 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2107 PyDoc_STR("__reduce__() -> (cls, state)")},
2108
Tim Peters2a799bf2002-12-16 20:18:38 +00002109 {NULL, NULL},
2110};
2111
2112static char delta_doc[] =
2113PyDoc_STR("Difference between two datetime values.");
2114
2115static PyNumberMethods delta_as_number = {
2116 delta_add, /* nb_add */
2117 delta_subtract, /* nb_subtract */
2118 delta_multiply, /* nb_multiply */
2119 delta_divide, /* nb_divide */
2120 0, /* nb_remainder */
2121 0, /* nb_divmod */
2122 0, /* nb_power */
2123 (unaryfunc)delta_negative, /* nb_negative */
2124 (unaryfunc)delta_positive, /* nb_positive */
2125 (unaryfunc)delta_abs, /* nb_absolute */
2126 (inquiry)delta_nonzero, /* nb_nonzero */
2127 0, /*nb_invert*/
2128 0, /*nb_lshift*/
2129 0, /*nb_rshift*/
2130 0, /*nb_and*/
2131 0, /*nb_xor*/
2132 0, /*nb_or*/
2133 0, /*nb_coerce*/
2134 0, /*nb_int*/
2135 0, /*nb_long*/
2136 0, /*nb_float*/
2137 0, /*nb_oct*/
2138 0, /*nb_hex*/
2139 0, /*nb_inplace_add*/
2140 0, /*nb_inplace_subtract*/
2141 0, /*nb_inplace_multiply*/
2142 0, /*nb_inplace_divide*/
2143 0, /*nb_inplace_remainder*/
2144 0, /*nb_inplace_power*/
2145 0, /*nb_inplace_lshift*/
2146 0, /*nb_inplace_rshift*/
2147 0, /*nb_inplace_and*/
2148 0, /*nb_inplace_xor*/
2149 0, /*nb_inplace_or*/
2150 delta_divide, /* nb_floor_divide */
2151 0, /* nb_true_divide */
2152 0, /* nb_inplace_floor_divide */
2153 0, /* nb_inplace_true_divide */
2154};
2155
2156static PyTypeObject PyDateTime_DeltaType = {
Martin v. Löwis68192102007-07-21 06:55:02 +00002157 PyVarObject_HEAD_INIT(NULL, 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00002158 "datetime.timedelta", /* tp_name */
2159 sizeof(PyDateTime_Delta), /* tp_basicsize */
2160 0, /* tp_itemsize */
2161 0, /* tp_dealloc */
2162 0, /* tp_print */
2163 0, /* tp_getattr */
2164 0, /* tp_setattr */
2165 0, /* tp_compare */
2166 (reprfunc)delta_repr, /* tp_repr */
2167 &delta_as_number, /* tp_as_number */
2168 0, /* tp_as_sequence */
2169 0, /* tp_as_mapping */
2170 (hashfunc)delta_hash, /* tp_hash */
2171 0, /* tp_call */
2172 (reprfunc)delta_str, /* tp_str */
2173 PyObject_GenericGetAttr, /* tp_getattro */
2174 0, /* tp_setattro */
2175 0, /* tp_as_buffer */
Tim Petersb0c854d2003-05-17 15:57:00 +00002176 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2177 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters2a799bf2002-12-16 20:18:38 +00002178 delta_doc, /* tp_doc */
2179 0, /* tp_traverse */
2180 0, /* tp_clear */
2181 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2182 0, /* tp_weaklistoffset */
2183 0, /* tp_iter */
2184 0, /* tp_iternext */
2185 delta_methods, /* tp_methods */
2186 delta_members, /* tp_members */
2187 0, /* tp_getset */
2188 0, /* tp_base */
2189 0, /* tp_dict */
2190 0, /* tp_descr_get */
2191 0, /* tp_descr_set */
2192 0, /* tp_dictoffset */
2193 0, /* tp_init */
2194 0, /* tp_alloc */
2195 delta_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002196 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002197};
2198
2199/*
2200 * PyDateTime_Date implementation.
2201 */
2202
2203/* Accessor properties. */
2204
2205static PyObject *
2206date_year(PyDateTime_Date *self, void *unused)
2207{
2208 return PyInt_FromLong(GET_YEAR(self));
2209}
2210
2211static PyObject *
2212date_month(PyDateTime_Date *self, void *unused)
2213{
2214 return PyInt_FromLong(GET_MONTH(self));
2215}
2216
2217static PyObject *
2218date_day(PyDateTime_Date *self, void *unused)
2219{
2220 return PyInt_FromLong(GET_DAY(self));
2221}
2222
2223static PyGetSetDef date_getset[] = {
2224 {"year", (getter)date_year},
2225 {"month", (getter)date_month},
2226 {"day", (getter)date_day},
2227 {NULL}
2228};
2229
2230/* Constructors. */
2231
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002232static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002233
Tim Peters2a799bf2002-12-16 20:18:38 +00002234static PyObject *
2235date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2236{
2237 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002238 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002239 int year;
2240 int month;
2241 int day;
2242
Guido van Rossum177e41a2003-01-30 22:06:23 +00002243 /* Check for invocation from pickle with __getstate__ state */
2244 if (PyTuple_GET_SIZE(args) == 1 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002245 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2246 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2247 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00002248 {
Tim Peters70533e22003-02-01 04:40:04 +00002249 PyDateTime_Date *me;
2250
Tim Peters604c0132004-06-07 23:04:33 +00002251 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
Tim Peters70533e22003-02-01 04:40:04 +00002252 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002253 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00002254 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2255 me->hashcode = -1;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002256 }
Tim Peters70533e22003-02-01 04:40:04 +00002257 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002258 }
2259
Tim Peters12bf3392002-12-24 05:41:27 +00002260 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002261 &year, &month, &day)) {
2262 if (check_date_args(year, month, day) < 0)
2263 return NULL;
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002264 self = new_date_ex(year, month, day, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00002265 }
2266 return self;
2267}
2268
2269/* Return new date from localtime(t). */
2270static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002271date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002272{
2273 struct tm *tm;
Tim Peters1b6f7a92004-06-20 02:50:16 +00002274 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002275 PyObject *result = NULL;
2276
Tim Peters1b6f7a92004-06-20 02:50:16 +00002277 t = _PyTime_DoubleToTimet(ts);
2278 if (t == (time_t)-1 && PyErr_Occurred())
2279 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002280 tm = localtime(&t);
2281 if (tm)
2282 result = PyObject_CallFunction(cls, "iii",
2283 tm->tm_year + 1900,
2284 tm->tm_mon + 1,
2285 tm->tm_mday);
2286 else
2287 PyErr_SetString(PyExc_ValueError,
2288 "timestamp out of range for "
2289 "platform localtime() function");
2290 return result;
2291}
2292
2293/* Return new date from current time.
2294 * We say this is equivalent to fromtimestamp(time.time()), and the
2295 * only way to be sure of that is to *call* time.time(). That's not
2296 * generally the same as calling C's time.
2297 */
2298static PyObject *
2299date_today(PyObject *cls, PyObject *dummy)
2300{
2301 PyObject *time;
2302 PyObject *result;
2303
2304 time = time_time();
2305 if (time == NULL)
2306 return NULL;
2307
2308 /* Note well: today() is a class method, so this may not call
2309 * date.fromtimestamp. For example, it may call
2310 * datetime.fromtimestamp. That's why we need all the accuracy
2311 * time.time() delivers; if someone were gonzo about optimization,
2312 * date.today() could get away with plain C time().
2313 */
2314 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2315 Py_DECREF(time);
2316 return result;
2317}
2318
2319/* Return new date from given timestamp (Python timestamp -- a double). */
2320static PyObject *
2321date_fromtimestamp(PyObject *cls, PyObject *args)
2322{
2323 double timestamp;
2324 PyObject *result = NULL;
2325
2326 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
Tim Peters1b6f7a92004-06-20 02:50:16 +00002327 result = date_local_from_time_t(cls, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002328 return result;
2329}
2330
2331/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2332 * the ordinal is out of range.
2333 */
2334static PyObject *
2335date_fromordinal(PyObject *cls, PyObject *args)
2336{
2337 PyObject *result = NULL;
2338 int ordinal;
2339
2340 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2341 int year;
2342 int month;
2343 int day;
2344
2345 if (ordinal < 1)
2346 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2347 ">= 1");
2348 else {
2349 ord_to_ymd(ordinal, &year, &month, &day);
2350 result = PyObject_CallFunction(cls, "iii",
2351 year, month, day);
2352 }
2353 }
2354 return result;
2355}
2356
2357/*
2358 * Date arithmetic.
2359 */
2360
2361/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2362 * instead.
2363 */
2364static PyObject *
2365add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2366{
2367 PyObject *result = NULL;
2368 int year = GET_YEAR(date);
2369 int month = GET_MONTH(date);
2370 int deltadays = GET_TD_DAYS(delta);
2371 /* C-level overflow is impossible because |deltadays| < 1e9. */
2372 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2373
2374 if (normalize_date(&year, &month, &day) >= 0)
2375 result = new_date(year, month, day);
2376 return result;
2377}
2378
2379static PyObject *
2380date_add(PyObject *left, PyObject *right)
2381{
2382 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2383 Py_INCREF(Py_NotImplemented);
2384 return Py_NotImplemented;
2385 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002386 if (PyDate_Check(left)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002387 /* date + ??? */
2388 if (PyDelta_Check(right))
2389 /* date + delta */
2390 return add_date_timedelta((PyDateTime_Date *) left,
2391 (PyDateTime_Delta *) right,
2392 0);
2393 }
2394 else {
2395 /* ??? + date
2396 * 'right' must be one of us, or we wouldn't have been called
2397 */
2398 if (PyDelta_Check(left))
2399 /* delta + date */
2400 return add_date_timedelta((PyDateTime_Date *) right,
2401 (PyDateTime_Delta *) left,
2402 0);
2403 }
2404 Py_INCREF(Py_NotImplemented);
2405 return Py_NotImplemented;
2406}
2407
2408static PyObject *
2409date_subtract(PyObject *left, PyObject *right)
2410{
2411 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2412 Py_INCREF(Py_NotImplemented);
2413 return Py_NotImplemented;
2414 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002415 if (PyDate_Check(left)) {
2416 if (PyDate_Check(right)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002417 /* date - date */
2418 int left_ord = ymd_to_ord(GET_YEAR(left),
2419 GET_MONTH(left),
2420 GET_DAY(left));
2421 int right_ord = ymd_to_ord(GET_YEAR(right),
2422 GET_MONTH(right),
2423 GET_DAY(right));
2424 return new_delta(left_ord - right_ord, 0, 0, 0);
2425 }
2426 if (PyDelta_Check(right)) {
2427 /* date - delta */
2428 return add_date_timedelta((PyDateTime_Date *) left,
2429 (PyDateTime_Delta *) right,
2430 1);
2431 }
2432 }
2433 Py_INCREF(Py_NotImplemented);
2434 return Py_NotImplemented;
2435}
2436
2437
2438/* Various ways to turn a date into a string. */
2439
2440static PyObject *
2441date_repr(PyDateTime_Date *self)
2442{
2443 char buffer[1028];
Skip Montanaro14f88992006-04-18 19:35:04 +00002444 const char *type_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002445
Christian Heimese93237d2007-12-19 02:37:44 +00002446 type_name = Py_TYPE(self)->tp_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002447 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00002448 type_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002449 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2450
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002451 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002452}
2453
2454static PyObject *
2455date_isoformat(PyDateTime_Date *self)
2456{
2457 char buffer[128];
2458
2459 isoformat_date(self, buffer, sizeof(buffer));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002460 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002461}
2462
Tim Peterse2df5ff2003-05-02 18:39:55 +00002463/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002464static PyObject *
2465date_str(PyDateTime_Date *self)
2466{
2467 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2468}
2469
2470
2471static PyObject *
2472date_ctime(PyDateTime_Date *self)
2473{
2474 return format_ctime(self, 0, 0, 0);
2475}
2476
2477static PyObject *
2478date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2479{
2480 /* This method can be inherited, and needs to call the
2481 * timetuple() method appropriate to self's class.
2482 */
2483 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002484 PyObject *tuple;
Gregory P. Smith137d8242008-06-02 04:05:52 +00002485 const char *format;
2486 Py_ssize_t format_len;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002487 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002488
Gregory P. Smith137d8242008-06-02 04:05:52 +00002489 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2490 &format, &format_len))
Tim Peters2a799bf2002-12-16 20:18:38 +00002491 return NULL;
2492
2493 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2494 if (tuple == NULL)
2495 return NULL;
Gregory P. Smith137d8242008-06-02 04:05:52 +00002496 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
Tim Petersbad8ff02002-12-30 20:52:32 +00002497 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002498 Py_DECREF(tuple);
2499 return result;
2500}
2501
Eric Smitha9f7d622008-02-17 19:46:49 +00002502static PyObject *
2503date_format(PyDateTime_Date *self, PyObject *args)
2504{
2505 PyObject *format;
2506
2507 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2508 return NULL;
2509
2510 /* Check for str or unicode */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002511 if (PyString_Check(format)) {
Eric Smitha9f7d622008-02-17 19:46:49 +00002512 /* If format is zero length, return str(self) */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002513 if (PyString_GET_SIZE(format) == 0)
Eric Smitha9f7d622008-02-17 19:46:49 +00002514 return PyObject_Str((PyObject *)self);
2515 } else if (PyUnicode_Check(format)) {
2516 /* If format is zero length, return str(self) */
2517 if (PyUnicode_GET_SIZE(format) == 0)
2518 return PyObject_Unicode((PyObject *)self);
2519 } else {
2520 PyErr_Format(PyExc_ValueError,
2521 "__format__ expects str or unicode, not %.200s",
2522 Py_TYPE(format)->tp_name);
2523 return NULL;
2524 }
2525 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2526}
2527
Tim Peters2a799bf2002-12-16 20:18:38 +00002528/* ISO methods. */
2529
2530static PyObject *
2531date_isoweekday(PyDateTime_Date *self)
2532{
2533 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2534
2535 return PyInt_FromLong(dow + 1);
2536}
2537
2538static PyObject *
2539date_isocalendar(PyDateTime_Date *self)
2540{
2541 int year = GET_YEAR(self);
2542 int week1_monday = iso_week1_monday(year);
2543 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2544 int week;
2545 int day;
2546
2547 week = divmod(today - week1_monday, 7, &day);
2548 if (week < 0) {
2549 --year;
2550 week1_monday = iso_week1_monday(year);
2551 week = divmod(today - week1_monday, 7, &day);
2552 }
2553 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2554 ++year;
2555 week = 0;
2556 }
2557 return Py_BuildValue("iii", year, week + 1, day + 1);
2558}
2559
2560/* Miscellaneous methods. */
2561
2562/* This is more natural as a tp_compare, but doesn't work then: for whatever
2563 * reason, Python's try_3way_compare ignores tp_compare unless
2564 * PyInstance_Check returns true, but these aren't old-style classes.
2565 */
2566static PyObject *
2567date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2568{
Tim Peters07534a62003-02-07 22:50:28 +00002569 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002570
Tim Peters07534a62003-02-07 22:50:28 +00002571 if (PyDate_Check(other))
2572 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2573 _PyDateTime_DATE_DATASIZE);
2574
2575 else if (PyObject_HasAttrString(other, "timetuple")) {
2576 /* A hook for other kinds of date objects. */
2577 Py_INCREF(Py_NotImplemented);
2578 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002579 }
Tim Peters07534a62003-02-07 22:50:28 +00002580 else if (op == Py_EQ || op == Py_NE)
2581 diff = 1; /* any non-zero value will do */
2582
2583 else /* stop this from falling back to address comparison */
2584 return cmperror((PyObject *)self, other);
2585
Tim Peters2a799bf2002-12-16 20:18:38 +00002586 return diff_to_bool(diff, op);
2587}
2588
2589static PyObject *
2590date_timetuple(PyDateTime_Date *self)
2591{
2592 return build_struct_time(GET_YEAR(self),
2593 GET_MONTH(self),
2594 GET_DAY(self),
2595 0, 0, 0, -1);
2596}
2597
Tim Peters12bf3392002-12-24 05:41:27 +00002598static PyObject *
2599date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2600{
2601 PyObject *clone;
2602 PyObject *tuple;
2603 int year = GET_YEAR(self);
2604 int month = GET_MONTH(self);
2605 int day = GET_DAY(self);
2606
2607 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2608 &year, &month, &day))
2609 return NULL;
2610 tuple = Py_BuildValue("iii", year, month, day);
2611 if (tuple == NULL)
2612 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00002613 clone = date_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00002614 Py_DECREF(tuple);
2615 return clone;
2616}
2617
Tim Peters2a799bf2002-12-16 20:18:38 +00002618static PyObject *date_getstate(PyDateTime_Date *self);
2619
2620static long
2621date_hash(PyDateTime_Date *self)
2622{
2623 if (self->hashcode == -1) {
2624 PyObject *temp = date_getstate(self);
2625 if (temp != NULL) {
2626 self->hashcode = PyObject_Hash(temp);
2627 Py_DECREF(temp);
2628 }
2629 }
2630 return self->hashcode;
2631}
2632
2633static PyObject *
2634date_toordinal(PyDateTime_Date *self)
2635{
2636 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2637 GET_DAY(self)));
2638}
2639
2640static PyObject *
2641date_weekday(PyDateTime_Date *self)
2642{
2643 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2644
2645 return PyInt_FromLong(dow);
2646}
2647
Tim Peters371935f2003-02-01 01:52:50 +00002648/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002649
Tim Petersb57f8f02003-02-01 02:54:15 +00002650/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002651static PyObject *
2652date_getstate(PyDateTime_Date *self)
2653{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002654 return Py_BuildValue(
2655 "(N)",
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002656 PyString_FromStringAndSize((char *)self->data,
Guido van Rossum177e41a2003-01-30 22:06:23 +00002657 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002658}
2659
2660static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002661date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002662{
Christian Heimese93237d2007-12-19 02:37:44 +00002663 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002664}
2665
2666static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002667
Tim Peters2a799bf2002-12-16 20:18:38 +00002668 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002669
Tim Peters2a799bf2002-12-16 20:18:38 +00002670 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2671 METH_CLASS,
2672 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2673 "time.time()).")},
2674
2675 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2676 METH_CLASS,
2677 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2678 "ordinal.")},
2679
2680 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2681 PyDoc_STR("Current date or datetime: same as "
2682 "self.__class__.fromtimestamp(time.time()).")},
2683
2684 /* Instance methods: */
2685
2686 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2687 PyDoc_STR("Return ctime() style string.")},
2688
Neal Norwitza84dcd72007-05-22 07:16:44 +00002689 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00002690 PyDoc_STR("format -> strftime() style string.")},
2691
Eric Smitha9f7d622008-02-17 19:46:49 +00002692 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2693 PyDoc_STR("Formats self with strftime.")},
2694
Tim Peters2a799bf2002-12-16 20:18:38 +00002695 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2696 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2697
2698 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2699 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2700 "weekday.")},
2701
2702 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2703 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2704
2705 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2706 PyDoc_STR("Return the day of the week represented by the date.\n"
2707 "Monday == 1 ... Sunday == 7")},
2708
2709 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2710 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2711 "1 is day 1.")},
2712
2713 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2714 PyDoc_STR("Return the day of the week represented by the date.\n"
2715 "Monday == 0 ... Sunday == 6")},
2716
Neal Norwitza84dcd72007-05-22 07:16:44 +00002717 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
Tim Peters12bf3392002-12-24 05:41:27 +00002718 PyDoc_STR("Return date with new specified fields.")},
2719
Guido van Rossum177e41a2003-01-30 22:06:23 +00002720 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2721 PyDoc_STR("__reduce__() -> (cls, state)")},
2722
Tim Peters2a799bf2002-12-16 20:18:38 +00002723 {NULL, NULL}
2724};
2725
2726static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002727PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002728
2729static PyNumberMethods date_as_number = {
2730 date_add, /* nb_add */
2731 date_subtract, /* nb_subtract */
2732 0, /* nb_multiply */
2733 0, /* nb_divide */
2734 0, /* nb_remainder */
2735 0, /* nb_divmod */
2736 0, /* nb_power */
2737 0, /* nb_negative */
2738 0, /* nb_positive */
2739 0, /* nb_absolute */
2740 0, /* nb_nonzero */
2741};
2742
2743static PyTypeObject PyDateTime_DateType = {
Martin v. Löwis68192102007-07-21 06:55:02 +00002744 PyVarObject_HEAD_INIT(NULL, 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00002745 "datetime.date", /* tp_name */
2746 sizeof(PyDateTime_Date), /* tp_basicsize */
2747 0, /* tp_itemsize */
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002748 0, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00002749 0, /* tp_print */
2750 0, /* tp_getattr */
2751 0, /* tp_setattr */
2752 0, /* tp_compare */
2753 (reprfunc)date_repr, /* tp_repr */
2754 &date_as_number, /* tp_as_number */
2755 0, /* tp_as_sequence */
2756 0, /* tp_as_mapping */
2757 (hashfunc)date_hash, /* tp_hash */
2758 0, /* tp_call */
2759 (reprfunc)date_str, /* tp_str */
2760 PyObject_GenericGetAttr, /* tp_getattro */
2761 0, /* tp_setattro */
2762 0, /* tp_as_buffer */
2763 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2764 Py_TPFLAGS_BASETYPE, /* tp_flags */
2765 date_doc, /* tp_doc */
2766 0, /* tp_traverse */
2767 0, /* tp_clear */
2768 (richcmpfunc)date_richcompare, /* tp_richcompare */
2769 0, /* tp_weaklistoffset */
2770 0, /* tp_iter */
2771 0, /* tp_iternext */
2772 date_methods, /* tp_methods */
2773 0, /* tp_members */
2774 date_getset, /* tp_getset */
2775 0, /* tp_base */
2776 0, /* tp_dict */
2777 0, /* tp_descr_get */
2778 0, /* tp_descr_set */
2779 0, /* tp_dictoffset */
2780 0, /* tp_init */
2781 0, /* tp_alloc */
2782 date_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002783 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002784};
2785
2786/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002787 * PyDateTime_TZInfo implementation.
2788 */
2789
2790/* This is a pure abstract base class, so doesn't do anything beyond
2791 * raising NotImplemented exceptions. Real tzinfo classes need
2792 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002793 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002794 * be subclasses of this tzinfo class, which is easy and quick to check).
2795 *
2796 * Note: For reasons having to do with pickling of subclasses, we have
2797 * to allow tzinfo objects to be instantiated. This wasn't an issue
2798 * in the Python implementation (__init__() could raise NotImplementedError
2799 * there without ill effect), but doing so in the C implementation hit a
2800 * brick wall.
2801 */
2802
2803static PyObject *
2804tzinfo_nogo(const char* methodname)
2805{
2806 PyErr_Format(PyExc_NotImplementedError,
2807 "a tzinfo subclass must implement %s()",
2808 methodname);
2809 return NULL;
2810}
2811
2812/* Methods. A subclass must implement these. */
2813
Tim Peters52dcce22003-01-23 16:36:11 +00002814static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002815tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2816{
2817 return tzinfo_nogo("tzname");
2818}
2819
Tim Peters52dcce22003-01-23 16:36:11 +00002820static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002821tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2822{
2823 return tzinfo_nogo("utcoffset");
2824}
2825
Tim Peters52dcce22003-01-23 16:36:11 +00002826static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002827tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2828{
2829 return tzinfo_nogo("dst");
2830}
2831
Tim Peters52dcce22003-01-23 16:36:11 +00002832static PyObject *
2833tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2834{
2835 int y, m, d, hh, mm, ss, us;
2836
2837 PyObject *result;
2838 int off, dst;
2839 int none;
2840 int delta;
2841
2842 if (! PyDateTime_Check(dt)) {
2843 PyErr_SetString(PyExc_TypeError,
2844 "fromutc: argument must be a datetime");
2845 return NULL;
2846 }
2847 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2848 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2849 "is not self");
2850 return NULL;
2851 }
2852
2853 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2854 if (off == -1 && PyErr_Occurred())
2855 return NULL;
2856 if (none) {
2857 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2858 "utcoffset() result required");
2859 return NULL;
2860 }
2861
2862 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2863 if (dst == -1 && PyErr_Occurred())
2864 return NULL;
2865 if (none) {
2866 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2867 "dst() result required");
2868 return NULL;
2869 }
2870
2871 y = GET_YEAR(dt);
2872 m = GET_MONTH(dt);
2873 d = GET_DAY(dt);
2874 hh = DATE_GET_HOUR(dt);
2875 mm = DATE_GET_MINUTE(dt);
2876 ss = DATE_GET_SECOND(dt);
2877 us = DATE_GET_MICROSECOND(dt);
2878
2879 delta = off - dst;
2880 mm += delta;
2881 if ((mm < 0 || mm >= 60) &&
2882 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002883 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002884 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2885 if (result == NULL)
2886 return result;
2887
2888 dst = call_dst(dt->tzinfo, result, &none);
2889 if (dst == -1 && PyErr_Occurred())
2890 goto Fail;
2891 if (none)
2892 goto Inconsistent;
2893 if (dst == 0)
2894 return result;
2895
2896 mm += dst;
2897 if ((mm < 0 || mm >= 60) &&
2898 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2899 goto Fail;
2900 Py_DECREF(result);
2901 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2902 return result;
2903
2904Inconsistent:
2905 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2906 "inconsistent results; cannot convert");
2907
2908 /* fall thru to failure */
2909Fail:
2910 Py_DECREF(result);
2911 return NULL;
2912}
2913
Tim Peters2a799bf2002-12-16 20:18:38 +00002914/*
2915 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002916 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002917 */
2918
Guido van Rossum177e41a2003-01-30 22:06:23 +00002919static PyObject *
2920tzinfo_reduce(PyObject *self)
2921{
2922 PyObject *args, *state, *tmp;
2923 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002924
Guido van Rossum177e41a2003-01-30 22:06:23 +00002925 tmp = PyTuple_New(0);
2926 if (tmp == NULL)
2927 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002928
Guido van Rossum177e41a2003-01-30 22:06:23 +00002929 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2930 if (getinitargs != NULL) {
2931 args = PyObject_CallObject(getinitargs, tmp);
2932 Py_DECREF(getinitargs);
2933 if (args == NULL) {
2934 Py_DECREF(tmp);
2935 return NULL;
2936 }
2937 }
2938 else {
2939 PyErr_Clear();
2940 args = tmp;
2941 Py_INCREF(args);
2942 }
2943
2944 getstate = PyObject_GetAttrString(self, "__getstate__");
2945 if (getstate != NULL) {
2946 state = PyObject_CallObject(getstate, tmp);
2947 Py_DECREF(getstate);
2948 if (state == NULL) {
2949 Py_DECREF(args);
2950 Py_DECREF(tmp);
2951 return NULL;
2952 }
2953 }
2954 else {
2955 PyObject **dictptr;
2956 PyErr_Clear();
2957 state = Py_None;
2958 dictptr = _PyObject_GetDictPtr(self);
2959 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2960 state = *dictptr;
2961 Py_INCREF(state);
2962 }
2963
2964 Py_DECREF(tmp);
2965
2966 if (state == Py_None) {
2967 Py_DECREF(state);
Christian Heimese93237d2007-12-19 02:37:44 +00002968 return Py_BuildValue("(ON)", Py_TYPE(self), args);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002969 }
2970 else
Christian Heimese93237d2007-12-19 02:37:44 +00002971 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002972}
Tim Peters2a799bf2002-12-16 20:18:38 +00002973
2974static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002975
Tim Peters2a799bf2002-12-16 20:18:38 +00002976 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2977 PyDoc_STR("datetime -> string name of time zone.")},
2978
2979 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2980 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2981 "west of UTC).")},
2982
2983 {"dst", (PyCFunction)tzinfo_dst, METH_O,
2984 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
2985
Tim Peters52dcce22003-01-23 16:36:11 +00002986 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
2987 PyDoc_STR("datetime in UTC -> datetime in local time.")},
2988
Guido van Rossum177e41a2003-01-30 22:06:23 +00002989 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
2990 PyDoc_STR("-> (cls, state)")},
2991
Tim Peters2a799bf2002-12-16 20:18:38 +00002992 {NULL, NULL}
2993};
2994
2995static char tzinfo_doc[] =
2996PyDoc_STR("Abstract base class for time zone info objects.");
2997
Neal Norwitzce3d34d2003-02-04 20:45:17 +00002998statichere PyTypeObject PyDateTime_TZInfoType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00002999 PyObject_HEAD_INIT(NULL)
3000 0, /* ob_size */
3001 "datetime.tzinfo", /* tp_name */
3002 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3003 0, /* tp_itemsize */
3004 0, /* tp_dealloc */
3005 0, /* tp_print */
3006 0, /* tp_getattr */
3007 0, /* tp_setattr */
3008 0, /* tp_compare */
3009 0, /* tp_repr */
3010 0, /* tp_as_number */
3011 0, /* tp_as_sequence */
3012 0, /* tp_as_mapping */
3013 0, /* tp_hash */
3014 0, /* tp_call */
3015 0, /* tp_str */
3016 PyObject_GenericGetAttr, /* tp_getattro */
3017 0, /* tp_setattro */
3018 0, /* tp_as_buffer */
3019 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3020 Py_TPFLAGS_BASETYPE, /* tp_flags */
3021 tzinfo_doc, /* tp_doc */
3022 0, /* tp_traverse */
3023 0, /* tp_clear */
3024 0, /* tp_richcompare */
3025 0, /* tp_weaklistoffset */
3026 0, /* tp_iter */
3027 0, /* tp_iternext */
3028 tzinfo_methods, /* tp_methods */
3029 0, /* tp_members */
3030 0, /* tp_getset */
3031 0, /* tp_base */
3032 0, /* tp_dict */
3033 0, /* tp_descr_get */
3034 0, /* tp_descr_set */
3035 0, /* tp_dictoffset */
3036 0, /* tp_init */
3037 0, /* tp_alloc */
3038 PyType_GenericNew, /* tp_new */
3039 0, /* tp_free */
3040};
3041
3042/*
Tim Peters37f39822003-01-10 03:49:02 +00003043 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003044 */
3045
Tim Peters37f39822003-01-10 03:49:02 +00003046/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003047 */
3048
3049static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003050time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003051{
Tim Peters37f39822003-01-10 03:49:02 +00003052 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003053}
3054
Tim Peters37f39822003-01-10 03:49:02 +00003055static PyObject *
3056time_minute(PyDateTime_Time *self, void *unused)
3057{
3058 return PyInt_FromLong(TIME_GET_MINUTE(self));
3059}
3060
3061/* The name time_second conflicted with some platform header file. */
3062static PyObject *
3063py_time_second(PyDateTime_Time *self, void *unused)
3064{
3065 return PyInt_FromLong(TIME_GET_SECOND(self));
3066}
3067
3068static PyObject *
3069time_microsecond(PyDateTime_Time *self, void *unused)
3070{
3071 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3072}
3073
3074static PyObject *
3075time_tzinfo(PyDateTime_Time *self, void *unused)
3076{
Tim Petersa032d2e2003-01-11 00:15:54 +00003077 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00003078 Py_INCREF(result);
3079 return result;
3080}
3081
3082static PyGetSetDef time_getset[] = {
3083 {"hour", (getter)time_hour},
3084 {"minute", (getter)time_minute},
3085 {"second", (getter)py_time_second},
3086 {"microsecond", (getter)time_microsecond},
3087 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003088 {NULL}
3089};
3090
3091/*
3092 * Constructors.
3093 */
3094
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003095static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Tim Peters37f39822003-01-10 03:49:02 +00003096 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003097
Tim Peters2a799bf2002-12-16 20:18:38 +00003098static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003099time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003100{
3101 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003102 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003103 int hour = 0;
3104 int minute = 0;
3105 int second = 0;
3106 int usecond = 0;
3107 PyObject *tzinfo = Py_None;
3108
Guido van Rossum177e41a2003-01-30 22:06:23 +00003109 /* Check for invocation from pickle with __getstate__ state */
3110 if (PyTuple_GET_SIZE(args) >= 1 &&
3111 PyTuple_GET_SIZE(args) <= 2 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003112 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3113 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3114 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003115 {
Tim Peters70533e22003-02-01 04:40:04 +00003116 PyDateTime_Time *me;
3117 char aware;
3118
3119 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003120 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003121 if (check_tzinfo_subclass(tzinfo) < 0) {
3122 PyErr_SetString(PyExc_TypeError, "bad "
3123 "tzinfo state arg");
3124 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003125 }
3126 }
Tim Peters70533e22003-02-01 04:40:04 +00003127 aware = (char)(tzinfo != Py_None);
Tim Peters604c0132004-06-07 23:04:33 +00003128 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
Tim Peters70533e22003-02-01 04:40:04 +00003129 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003130 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003131
3132 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3133 me->hashcode = -1;
3134 me->hastzinfo = aware;
3135 if (aware) {
3136 Py_INCREF(tzinfo);
3137 me->tzinfo = tzinfo;
3138 }
3139 }
3140 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003141 }
3142
Tim Peters37f39822003-01-10 03:49:02 +00003143 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003144 &hour, &minute, &second, &usecond,
3145 &tzinfo)) {
3146 if (check_time_args(hour, minute, second, usecond) < 0)
3147 return NULL;
3148 if (check_tzinfo_subclass(tzinfo) < 0)
3149 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003150 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3151 type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003152 }
3153 return self;
3154}
3155
3156/*
3157 * Destructor.
3158 */
3159
3160static void
Tim Peters37f39822003-01-10 03:49:02 +00003161time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003162{
Tim Petersa032d2e2003-01-11 00:15:54 +00003163 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003164 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003165 }
Christian Heimese93237d2007-12-19 02:37:44 +00003166 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003167}
3168
3169/*
Tim Peters855fe882002-12-22 03:43:39 +00003170 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003171 */
3172
Tim Peters2a799bf2002-12-16 20:18:38 +00003173/* These are all METH_NOARGS, so don't need to check the arglist. */
3174static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003175time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003176 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003177 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003178}
3179
3180static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003181time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003182 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003183 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003184}
3185
3186static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003187time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003188 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003189 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003190}
3191
3192/*
Tim Peters37f39822003-01-10 03:49:02 +00003193 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003194 */
3195
3196static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003197time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003198{
Tim Peters37f39822003-01-10 03:49:02 +00003199 char buffer[100];
Christian Heimese93237d2007-12-19 02:37:44 +00003200 const char *type_name = Py_TYPE(self)->tp_name;
Tim Peters37f39822003-01-10 03:49:02 +00003201 int h = TIME_GET_HOUR(self);
3202 int m = TIME_GET_MINUTE(self);
3203 int s = TIME_GET_SECOND(self);
3204 int us = TIME_GET_MICROSECOND(self);
3205 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003206
Tim Peters37f39822003-01-10 03:49:02 +00003207 if (us)
3208 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003209 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
Tim Peters37f39822003-01-10 03:49:02 +00003210 else if (s)
3211 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003212 "%s(%d, %d, %d)", type_name, h, m, s);
Tim Peters37f39822003-01-10 03:49:02 +00003213 else
3214 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003215 "%s(%d, %d)", type_name, h, m);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003216 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003217 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003218 result = append_keyword_tzinfo(result, self->tzinfo);
3219 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003220}
3221
Tim Peters37f39822003-01-10 03:49:02 +00003222static PyObject *
3223time_str(PyDateTime_Time *self)
3224{
3225 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3226}
Tim Peters2a799bf2002-12-16 20:18:38 +00003227
3228static PyObject *
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003229time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003230{
3231 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003232 PyObject *result;
3233 /* Reuse the time format code from the datetime type. */
3234 PyDateTime_DateTime datetime;
3235 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003236
Tim Peters37f39822003-01-10 03:49:02 +00003237 /* Copy over just the time bytes. */
3238 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3239 self->data,
3240 _PyDateTime_TIME_DATASIZE);
3241
3242 isoformat_time(pdatetime, buf, sizeof(buf));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003243 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003244 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003245 return result;
3246
3247 /* We need to append the UTC offset. */
3248 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003249 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003250 Py_DECREF(result);
3251 return NULL;
3252 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003253 PyString_ConcatAndDel(&result, PyString_FromString(buf));
Tim Peters2a799bf2002-12-16 20:18:38 +00003254 return result;
3255}
3256
Tim Peters37f39822003-01-10 03:49:02 +00003257static PyObject *
3258time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3259{
3260 PyObject *result;
Tim Peters37f39822003-01-10 03:49:02 +00003261 PyObject *tuple;
Gregory P. Smith137d8242008-06-02 04:05:52 +00003262 const char *format;
3263 Py_ssize_t format_len;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003264 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003265
Gregory P. Smith137d8242008-06-02 04:05:52 +00003266 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3267 &format, &format_len))
Tim Peters37f39822003-01-10 03:49:02 +00003268 return NULL;
3269
3270 /* Python's strftime does insane things with the year part of the
3271 * timetuple. The year is forced to (the otherwise nonsensical)
3272 * 1900 to worm around that.
3273 */
3274 tuple = Py_BuildValue("iiiiiiiii",
Brett Cannond1080a32004-03-02 04:38:10 +00003275 1900, 1, 1, /* year, month, day */
Tim Peters37f39822003-01-10 03:49:02 +00003276 TIME_GET_HOUR(self),
3277 TIME_GET_MINUTE(self),
3278 TIME_GET_SECOND(self),
Brett Cannond1080a32004-03-02 04:38:10 +00003279 0, 1, -1); /* weekday, daynum, dst */
Tim Peters37f39822003-01-10 03:49:02 +00003280 if (tuple == NULL)
3281 return NULL;
3282 assert(PyTuple_Size(tuple) == 9);
Gregory P. Smith137d8242008-06-02 04:05:52 +00003283 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3284 Py_None);
Tim Peters37f39822003-01-10 03:49:02 +00003285 Py_DECREF(tuple);
3286 return result;
3287}
Tim Peters2a799bf2002-12-16 20:18:38 +00003288
3289/*
3290 * Miscellaneous methods.
3291 */
3292
Tim Peters37f39822003-01-10 03:49:02 +00003293/* This is more natural as a tp_compare, but doesn't work then: for whatever
3294 * reason, Python's try_3way_compare ignores tp_compare unless
3295 * PyInstance_Check returns true, but these aren't old-style classes.
3296 */
3297static PyObject *
3298time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3299{
3300 int diff;
3301 naivety n1, n2;
3302 int offset1, offset2;
3303
3304 if (! PyTime_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00003305 if (op == Py_EQ || op == Py_NE) {
3306 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3307 Py_INCREF(result);
3308 return result;
3309 }
Tim Peters37f39822003-01-10 03:49:02 +00003310 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00003311 return cmperror((PyObject *)self, other);
Tim Peters37f39822003-01-10 03:49:02 +00003312 }
3313 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3314 other, &offset2, &n2, Py_None) < 0)
3315 return NULL;
3316 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3317 /* If they're both naive, or both aware and have the same offsets,
3318 * we get off cheap. Note that if they're both naive, offset1 ==
3319 * offset2 == 0 at this point.
3320 */
3321 if (n1 == n2 && offset1 == offset2) {
3322 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3323 _PyDateTime_TIME_DATASIZE);
3324 return diff_to_bool(diff, op);
3325 }
3326
3327 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3328 assert(offset1 != offset2); /* else last "if" handled it */
3329 /* Convert everything except microseconds to seconds. These
3330 * can't overflow (no more than the # of seconds in 2 days).
3331 */
3332 offset1 = TIME_GET_HOUR(self) * 3600 +
3333 (TIME_GET_MINUTE(self) - offset1) * 60 +
3334 TIME_GET_SECOND(self);
3335 offset2 = TIME_GET_HOUR(other) * 3600 +
3336 (TIME_GET_MINUTE(other) - offset2) * 60 +
3337 TIME_GET_SECOND(other);
3338 diff = offset1 - offset2;
3339 if (diff == 0)
3340 diff = TIME_GET_MICROSECOND(self) -
3341 TIME_GET_MICROSECOND(other);
3342 return diff_to_bool(diff, op);
3343 }
3344
3345 assert(n1 != n2);
3346 PyErr_SetString(PyExc_TypeError,
3347 "can't compare offset-naive and "
3348 "offset-aware times");
3349 return NULL;
3350}
3351
3352static long
3353time_hash(PyDateTime_Time *self)
3354{
3355 if (self->hashcode == -1) {
3356 naivety n;
3357 int offset;
3358 PyObject *temp;
3359
3360 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3361 assert(n != OFFSET_UNKNOWN);
3362 if (n == OFFSET_ERROR)
3363 return -1;
3364
3365 /* Reduce this to a hash of another object. */
3366 if (offset == 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003367 temp = PyString_FromStringAndSize((char *)self->data,
Tim Peters37f39822003-01-10 03:49:02 +00003368 _PyDateTime_TIME_DATASIZE);
3369 else {
3370 int hour;
3371 int minute;
3372
3373 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003374 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003375 hour = divmod(TIME_GET_HOUR(self) * 60 +
3376 TIME_GET_MINUTE(self) - offset,
3377 60,
3378 &minute);
3379 if (0 <= hour && hour < 24)
3380 temp = new_time(hour, minute,
3381 TIME_GET_SECOND(self),
3382 TIME_GET_MICROSECOND(self),
3383 Py_None);
3384 else
3385 temp = Py_BuildValue("iiii",
3386 hour, minute,
3387 TIME_GET_SECOND(self),
3388 TIME_GET_MICROSECOND(self));
3389 }
3390 if (temp != NULL) {
3391 self->hashcode = PyObject_Hash(temp);
3392 Py_DECREF(temp);
3393 }
3394 }
3395 return self->hashcode;
3396}
Tim Peters2a799bf2002-12-16 20:18:38 +00003397
Tim Peters12bf3392002-12-24 05:41:27 +00003398static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003399time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003400{
3401 PyObject *clone;
3402 PyObject *tuple;
3403 int hh = TIME_GET_HOUR(self);
3404 int mm = TIME_GET_MINUTE(self);
3405 int ss = TIME_GET_SECOND(self);
3406 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003407 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003408
3409 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003410 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003411 &hh, &mm, &ss, &us, &tzinfo))
3412 return NULL;
3413 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3414 if (tuple == NULL)
3415 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00003416 clone = time_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003417 Py_DECREF(tuple);
3418 return clone;
3419}
3420
Tim Peters2a799bf2002-12-16 20:18:38 +00003421static int
Tim Peters37f39822003-01-10 03:49:02 +00003422time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003423{
3424 int offset;
3425 int none;
3426
3427 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3428 /* Since utcoffset is in whole minutes, nothing can
3429 * alter the conclusion that this is nonzero.
3430 */
3431 return 1;
3432 }
3433 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003434 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003435 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003436 if (offset == -1 && PyErr_Occurred())
3437 return -1;
3438 }
3439 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3440}
3441
Tim Peters371935f2003-02-01 01:52:50 +00003442/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003443
Tim Peters33e0f382003-01-10 02:05:14 +00003444/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003445 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3446 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003447 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003448 */
3449static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003450time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003451{
3452 PyObject *basestate;
3453 PyObject *result = NULL;
3454
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003455 basestate = PyString_FromStringAndSize((char *)self->data,
Tim Peters33e0f382003-01-10 02:05:14 +00003456 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003457 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003458 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003459 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00003460 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003461 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003462 Py_DECREF(basestate);
3463 }
3464 return result;
3465}
3466
3467static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003468time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003469{
Christian Heimese93237d2007-12-19 02:37:44 +00003470 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003471}
3472
Tim Peters37f39822003-01-10 03:49:02 +00003473static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003474
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003475 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003476 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3477 "[+HH:MM].")},
3478
Neal Norwitza84dcd72007-05-22 07:16:44 +00003479 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
Tim Peters37f39822003-01-10 03:49:02 +00003480 PyDoc_STR("format -> strftime() style string.")},
3481
Eric Smitha9f7d622008-02-17 19:46:49 +00003482 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3483 PyDoc_STR("Formats self with strftime.")},
3484
Tim Peters37f39822003-01-10 03:49:02 +00003485 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003486 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3487
Tim Peters37f39822003-01-10 03:49:02 +00003488 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003489 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3490
Tim Peters37f39822003-01-10 03:49:02 +00003491 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003492 PyDoc_STR("Return self.tzinfo.dst(self).")},
3493
Neal Norwitza84dcd72007-05-22 07:16:44 +00003494 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
Tim Peters37f39822003-01-10 03:49:02 +00003495 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003496
Guido van Rossum177e41a2003-01-30 22:06:23 +00003497 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3498 PyDoc_STR("__reduce__() -> (cls, state)")},
3499
Tim Peters2a799bf2002-12-16 20:18:38 +00003500 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003501};
3502
Tim Peters37f39822003-01-10 03:49:02 +00003503static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003504PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3505\n\
3506All arguments are optional. tzinfo may be None, or an instance of\n\
3507a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003508
Tim Peters37f39822003-01-10 03:49:02 +00003509static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003510 0, /* nb_add */
3511 0, /* nb_subtract */
3512 0, /* nb_multiply */
3513 0, /* nb_divide */
3514 0, /* nb_remainder */
3515 0, /* nb_divmod */
3516 0, /* nb_power */
3517 0, /* nb_negative */
3518 0, /* nb_positive */
3519 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003520 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003521};
3522
Tim Peters37f39822003-01-10 03:49:02 +00003523statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003524 PyObject_HEAD_INIT(NULL)
3525 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003526 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003527 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003528 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003529 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003530 0, /* tp_print */
3531 0, /* tp_getattr */
3532 0, /* tp_setattr */
3533 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003534 (reprfunc)time_repr, /* tp_repr */
3535 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003536 0, /* tp_as_sequence */
3537 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003538 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003539 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003540 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003541 PyObject_GenericGetAttr, /* tp_getattro */
3542 0, /* tp_setattro */
3543 0, /* tp_as_buffer */
3544 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3545 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003546 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003547 0, /* tp_traverse */
3548 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003549 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003550 0, /* tp_weaklistoffset */
3551 0, /* tp_iter */
3552 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003553 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003554 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003555 time_getset, /* tp_getset */
3556 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003557 0, /* tp_dict */
3558 0, /* tp_descr_get */
3559 0, /* tp_descr_set */
3560 0, /* tp_dictoffset */
3561 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00003562 time_alloc, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003563 time_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00003564 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003565};
3566
3567/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003568 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003569 */
3570
Tim Petersa9bc1682003-01-11 03:39:11 +00003571/* Accessor properties. Properties for day, month, and year are inherited
3572 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003573 */
3574
3575static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003576datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003577{
Tim Petersa9bc1682003-01-11 03:39:11 +00003578 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003579}
3580
Tim Petersa9bc1682003-01-11 03:39:11 +00003581static PyObject *
3582datetime_minute(PyDateTime_DateTime *self, void *unused)
3583{
3584 return PyInt_FromLong(DATE_GET_MINUTE(self));
3585}
3586
3587static PyObject *
3588datetime_second(PyDateTime_DateTime *self, void *unused)
3589{
3590 return PyInt_FromLong(DATE_GET_SECOND(self));
3591}
3592
3593static PyObject *
3594datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3595{
3596 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3597}
3598
3599static PyObject *
3600datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3601{
3602 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3603 Py_INCREF(result);
3604 return result;
3605}
3606
3607static PyGetSetDef datetime_getset[] = {
3608 {"hour", (getter)datetime_hour},
3609 {"minute", (getter)datetime_minute},
3610 {"second", (getter)datetime_second},
3611 {"microsecond", (getter)datetime_microsecond},
3612 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003613 {NULL}
3614};
3615
3616/*
3617 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003618 */
3619
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003620static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003621 "year", "month", "day", "hour", "minute", "second",
3622 "microsecond", "tzinfo", NULL
3623};
3624
Tim Peters2a799bf2002-12-16 20:18:38 +00003625static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003626datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003627{
3628 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003629 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003630 int year;
3631 int month;
3632 int day;
3633 int hour = 0;
3634 int minute = 0;
3635 int second = 0;
3636 int usecond = 0;
3637 PyObject *tzinfo = Py_None;
3638
Guido van Rossum177e41a2003-01-30 22:06:23 +00003639 /* Check for invocation from pickle with __getstate__ state */
3640 if (PyTuple_GET_SIZE(args) >= 1 &&
3641 PyTuple_GET_SIZE(args) <= 2 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003642 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3643 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3644 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003645 {
Tim Peters70533e22003-02-01 04:40:04 +00003646 PyDateTime_DateTime *me;
3647 char aware;
3648
3649 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003650 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003651 if (check_tzinfo_subclass(tzinfo) < 0) {
3652 PyErr_SetString(PyExc_TypeError, "bad "
3653 "tzinfo state arg");
3654 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003655 }
3656 }
Tim Peters70533e22003-02-01 04:40:04 +00003657 aware = (char)(tzinfo != Py_None);
Tim Peters604c0132004-06-07 23:04:33 +00003658 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
Tim Peters70533e22003-02-01 04:40:04 +00003659 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003660 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003661
3662 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3663 me->hashcode = -1;
3664 me->hastzinfo = aware;
3665 if (aware) {
3666 Py_INCREF(tzinfo);
3667 me->tzinfo = tzinfo;
3668 }
3669 }
3670 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003671 }
3672
Tim Petersa9bc1682003-01-11 03:39:11 +00003673 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003674 &year, &month, &day, &hour, &minute,
3675 &second, &usecond, &tzinfo)) {
3676 if (check_date_args(year, month, day) < 0)
3677 return NULL;
3678 if (check_time_args(hour, minute, second, usecond) < 0)
3679 return NULL;
3680 if (check_tzinfo_subclass(tzinfo) < 0)
3681 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003682 self = new_datetime_ex(year, month, day,
3683 hour, minute, second, usecond,
3684 tzinfo, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003685 }
3686 return self;
3687}
3688
Tim Petersa9bc1682003-01-11 03:39:11 +00003689/* TM_FUNC is the shared type of localtime() and gmtime(). */
3690typedef struct tm *(*TM_FUNC)(const time_t *timer);
3691
3692/* Internal helper.
3693 * Build datetime from a time_t and a distinct count of microseconds.
3694 * Pass localtime or gmtime for f, to control the interpretation of timet.
3695 */
3696static PyObject *
3697datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3698 PyObject *tzinfo)
3699{
3700 struct tm *tm;
3701 PyObject *result = NULL;
3702
3703 tm = f(&timet);
3704 if (tm) {
3705 /* The platform localtime/gmtime may insert leap seconds,
3706 * indicated by tm->tm_sec > 59. We don't care about them,
3707 * except to the extent that passing them on to the datetime
3708 * constructor would raise ValueError for a reason that
3709 * made no sense to the user.
3710 */
3711 if (tm->tm_sec > 59)
3712 tm->tm_sec = 59;
3713 result = PyObject_CallFunction(cls, "iiiiiiiO",
3714 tm->tm_year + 1900,
3715 tm->tm_mon + 1,
3716 tm->tm_mday,
3717 tm->tm_hour,
3718 tm->tm_min,
3719 tm->tm_sec,
3720 us,
3721 tzinfo);
3722 }
3723 else
3724 PyErr_SetString(PyExc_ValueError,
3725 "timestamp out of range for "
3726 "platform localtime()/gmtime() function");
3727 return result;
3728}
3729
3730/* Internal helper.
3731 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3732 * to control the interpretation of the timestamp. Since a double doesn't
3733 * have enough bits to cover a datetime's full range of precision, it's
3734 * better to call datetime_from_timet_and_us provided you have a way
3735 * to get that much precision (e.g., C time() isn't good enough).
3736 */
3737static PyObject *
3738datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3739 PyObject *tzinfo)
3740{
Tim Peters1b6f7a92004-06-20 02:50:16 +00003741 time_t timet;
3742 double fraction;
3743 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00003744
Tim Peters1b6f7a92004-06-20 02:50:16 +00003745 timet = _PyTime_DoubleToTimet(timestamp);
3746 if (timet == (time_t)-1 && PyErr_Occurred())
3747 return NULL;
3748 fraction = timestamp - (double)timet;
3749 us = (int)round_to_long(fraction * 1e6);
Guido van Rossum2054ee92007-03-06 15:50:01 +00003750 if (us < 0) {
3751 /* Truncation towards zero is not what we wanted
3752 for negative numbers (Python's mod semantics) */
3753 timet -= 1;
3754 us += 1000000;
3755 }
Georg Brandl6d78a582006-04-28 19:09:24 +00003756 /* If timestamp is less than one microsecond smaller than a
3757 * full second, round up. Otherwise, ValueErrors are raised
3758 * for some floats. */
3759 if (us == 1000000) {
3760 timet += 1;
3761 us = 0;
3762 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003763 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3764}
3765
3766/* Internal helper.
3767 * Build most accurate possible datetime for current time. Pass localtime or
3768 * gmtime for f as appropriate.
3769 */
3770static PyObject *
3771datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3772{
3773#ifdef HAVE_GETTIMEOFDAY
3774 struct timeval t;
3775
3776#ifdef GETTIMEOFDAY_NO_TZ
3777 gettimeofday(&t);
3778#else
3779 gettimeofday(&t, (struct timezone *)NULL);
3780#endif
3781 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3782 tzinfo);
3783
3784#else /* ! HAVE_GETTIMEOFDAY */
3785 /* No flavor of gettimeofday exists on this platform. Python's
3786 * time.time() does a lot of other platform tricks to get the
3787 * best time it can on the platform, and we're not going to do
3788 * better than that (if we could, the better code would belong
3789 * in time.time()!) We're limited by the precision of a double,
3790 * though.
3791 */
3792 PyObject *time;
3793 double dtime;
3794
3795 time = time_time();
3796 if (time == NULL)
3797 return NULL;
3798 dtime = PyFloat_AsDouble(time);
3799 Py_DECREF(time);
3800 if (dtime == -1.0 && PyErr_Occurred())
3801 return NULL;
3802 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3803#endif /* ! HAVE_GETTIMEOFDAY */
3804}
3805
Tim Peters2a799bf2002-12-16 20:18:38 +00003806/* Return best possible local time -- this isn't constrained by the
3807 * precision of a timestamp.
3808 */
3809static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003810datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003811{
Tim Peters10cadce2003-01-23 19:58:02 +00003812 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003813 PyObject *tzinfo = Py_None;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003814 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003815
Tim Peters10cadce2003-01-23 19:58:02 +00003816 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3817 &tzinfo))
3818 return NULL;
3819 if (check_tzinfo_subclass(tzinfo) < 0)
3820 return NULL;
3821
3822 self = datetime_best_possible(cls,
3823 tzinfo == Py_None ? localtime : gmtime,
3824 tzinfo);
3825 if (self != NULL && tzinfo != Py_None) {
3826 /* Convert UTC to tzinfo's zone. */
3827 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003828 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003829 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003830 }
3831 return self;
3832}
3833
Tim Petersa9bc1682003-01-11 03:39:11 +00003834/* Return best possible UTC time -- this isn't constrained by the
3835 * precision of a timestamp.
3836 */
3837static PyObject *
3838datetime_utcnow(PyObject *cls, PyObject *dummy)
3839{
3840 return datetime_best_possible(cls, gmtime, Py_None);
3841}
3842
Tim Peters2a799bf2002-12-16 20:18:38 +00003843/* Return new local datetime from timestamp (Python timestamp -- a double). */
3844static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003845datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003846{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003847 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003848 double timestamp;
3849 PyObject *tzinfo = Py_None;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003850 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003851
Tim Peters2a44a8d2003-01-23 20:53:10 +00003852 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3853 keywords, &timestamp, &tzinfo))
3854 return NULL;
3855 if (check_tzinfo_subclass(tzinfo) < 0)
3856 return NULL;
3857
3858 self = datetime_from_timestamp(cls,
3859 tzinfo == Py_None ? localtime : gmtime,
3860 timestamp,
3861 tzinfo);
3862 if (self != NULL && tzinfo != Py_None) {
3863 /* Convert UTC to tzinfo's zone. */
3864 PyObject *temp = self;
3865 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3866 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003867 }
3868 return self;
3869}
3870
Tim Petersa9bc1682003-01-11 03:39:11 +00003871/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3872static PyObject *
3873datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3874{
3875 double timestamp;
3876 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003877
Tim Petersa9bc1682003-01-11 03:39:11 +00003878 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3879 result = datetime_from_timestamp(cls, gmtime, timestamp,
3880 Py_None);
3881 return result;
3882}
3883
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003884/* Return new datetime from time.strptime(). */
3885static PyObject *
3886datetime_strptime(PyObject *cls, PyObject *args)
3887{
Skip Montanarofc070d22008-03-15 16:04:45 +00003888 static PyObject *module = NULL;
3889 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003890 const char *string, *format;
3891
3892 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3893 return NULL;
3894
Skip Montanarofc070d22008-03-15 16:04:45 +00003895 if (module == NULL &&
3896 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003897 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003898
Skip Montanarofc070d22008-03-15 16:04:45 +00003899 /* _strptime._strptime returns a two-element tuple. The first
3900 element is a time.struct_time object. The second is the
3901 microseconds (which are not defined for time.struct_time). */
3902 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003903 if (obj != NULL) {
3904 int i, good_timetuple = 1;
Skip Montanarofc070d22008-03-15 16:04:45 +00003905 long int ia[7];
3906 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3907 st = PySequence_GetItem(obj, 0);
3908 frac = PySequence_GetItem(obj, 1);
3909 if (st == NULL || frac == NULL)
3910 good_timetuple = 0;
3911 /* copy y/m/d/h/m/s values out of the
3912 time.struct_time */
3913 if (good_timetuple &&
3914 PySequence_Check(st) &&
3915 PySequence_Size(st) >= 6) {
3916 for (i=0; i < 6; i++) {
3917 PyObject *p = PySequence_GetItem(st, i);
3918 if (p == NULL) {
3919 good_timetuple = 0;
3920 break;
3921 }
3922 if (PyInt_Check(p))
3923 ia[i] = PyInt_AsLong(p);
3924 else
3925 good_timetuple = 0;
3926 Py_DECREF(p);
Thomas Wouters3cfea2d2006-04-14 21:23:42 +00003927 }
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003928 }
Skip Montanarofc070d22008-03-15 16:04:45 +00003929 else
3930 good_timetuple = 0;
3931 /* follow that up with a little dose of microseconds */
3932 if (PyInt_Check(frac))
3933 ia[6] = PyInt_AsLong(frac);
3934 else
3935 good_timetuple = 0;
3936 }
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003937 else
3938 good_timetuple = 0;
3939 if (good_timetuple)
Skip Montanarofc070d22008-03-15 16:04:45 +00003940 result = PyObject_CallFunction(cls, "iiiiiii",
3941 ia[0], ia[1], ia[2],
3942 ia[3], ia[4], ia[5],
3943 ia[6]);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003944 else
3945 PyErr_SetString(PyExc_ValueError,
Skip Montanarofc070d22008-03-15 16:04:45 +00003946 "unexpected value from _strptime._strptime");
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003947 }
Skip Montanarofc070d22008-03-15 16:04:45 +00003948 Py_XDECREF(obj);
3949 Py_XDECREF(st);
3950 Py_XDECREF(frac);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003951 return result;
3952}
3953
Tim Petersa9bc1682003-01-11 03:39:11 +00003954/* Return new datetime from date/datetime and time arguments. */
3955static PyObject *
3956datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3957{
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003958 static char *keywords[] = {"date", "time", NULL};
Tim Petersa9bc1682003-01-11 03:39:11 +00003959 PyObject *date;
3960 PyObject *time;
3961 PyObject *result = NULL;
3962
3963 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3964 &PyDateTime_DateType, &date,
3965 &PyDateTime_TimeType, &time)) {
3966 PyObject *tzinfo = Py_None;
3967
3968 if (HASTZINFO(time))
3969 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3970 result = PyObject_CallFunction(cls, "iiiiiiiO",
3971 GET_YEAR(date),
3972 GET_MONTH(date),
3973 GET_DAY(date),
3974 TIME_GET_HOUR(time),
3975 TIME_GET_MINUTE(time),
3976 TIME_GET_SECOND(time),
3977 TIME_GET_MICROSECOND(time),
3978 tzinfo);
3979 }
3980 return result;
3981}
Tim Peters2a799bf2002-12-16 20:18:38 +00003982
3983/*
3984 * Destructor.
3985 */
3986
3987static void
Tim Petersa9bc1682003-01-11 03:39:11 +00003988datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003989{
Tim Petersa9bc1682003-01-11 03:39:11 +00003990 if (HASTZINFO(self)) {
3991 Py_XDECREF(self->tzinfo);
3992 }
Christian Heimese93237d2007-12-19 02:37:44 +00003993 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003994}
3995
3996/*
3997 * Indirect access to tzinfo methods.
3998 */
3999
Tim Peters2a799bf2002-12-16 20:18:38 +00004000/* These are all METH_NOARGS, so don't need to check the arglist. */
4001static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004002datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
4003 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4004 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004005}
4006
4007static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004008datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
4009 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4010 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004011}
4012
4013static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004014datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
4015 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4016 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004017}
4018
4019/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004020 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004021 */
4022
Tim Petersa9bc1682003-01-11 03:39:11 +00004023/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4024 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004025 */
4026static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004027add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4028 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004029{
Tim Petersa9bc1682003-01-11 03:39:11 +00004030 /* Note that the C-level additions can't overflow, because of
4031 * invariant bounds on the member values.
4032 */
4033 int year = GET_YEAR(date);
4034 int month = GET_MONTH(date);
4035 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4036 int hour = DATE_GET_HOUR(date);
4037 int minute = DATE_GET_MINUTE(date);
4038 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4039 int microsecond = DATE_GET_MICROSECOND(date) +
4040 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004041
Tim Petersa9bc1682003-01-11 03:39:11 +00004042 assert(factor == 1 || factor == -1);
4043 if (normalize_datetime(&year, &month, &day,
4044 &hour, &minute, &second, &microsecond) < 0)
4045 return NULL;
4046 else
4047 return new_datetime(year, month, day,
4048 hour, minute, second, microsecond,
4049 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004050}
4051
4052static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004053datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004054{
Tim Petersa9bc1682003-01-11 03:39:11 +00004055 if (PyDateTime_Check(left)) {
4056 /* datetime + ??? */
4057 if (PyDelta_Check(right))
4058 /* datetime + delta */
4059 return add_datetime_timedelta(
4060 (PyDateTime_DateTime *)left,
4061 (PyDateTime_Delta *)right,
4062 1);
4063 }
4064 else if (PyDelta_Check(left)) {
4065 /* delta + datetime */
4066 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4067 (PyDateTime_Delta *) left,
4068 1);
4069 }
4070 Py_INCREF(Py_NotImplemented);
4071 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004072}
4073
4074static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004075datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004076{
4077 PyObject *result = Py_NotImplemented;
4078
4079 if (PyDateTime_Check(left)) {
4080 /* datetime - ??? */
4081 if (PyDateTime_Check(right)) {
4082 /* datetime - datetime */
4083 naivety n1, n2;
4084 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004085 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004086
Tim Peterse39a80c2002-12-30 21:28:52 +00004087 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4088 right, &offset2, &n2,
4089 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00004090 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00004091 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00004092 if (n1 != n2) {
4093 PyErr_SetString(PyExc_TypeError,
4094 "can't subtract offset-naive and "
4095 "offset-aware datetimes");
4096 return NULL;
4097 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004098 delta_d = ymd_to_ord(GET_YEAR(left),
4099 GET_MONTH(left),
4100 GET_DAY(left)) -
4101 ymd_to_ord(GET_YEAR(right),
4102 GET_MONTH(right),
4103 GET_DAY(right));
4104 /* These can't overflow, since the values are
4105 * normalized. At most this gives the number of
4106 * seconds in one day.
4107 */
4108 delta_s = (DATE_GET_HOUR(left) -
4109 DATE_GET_HOUR(right)) * 3600 +
4110 (DATE_GET_MINUTE(left) -
4111 DATE_GET_MINUTE(right)) * 60 +
4112 (DATE_GET_SECOND(left) -
4113 DATE_GET_SECOND(right));
4114 delta_us = DATE_GET_MICROSECOND(left) -
4115 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00004116 /* (left - offset1) - (right - offset2) =
4117 * (left - right) + (offset2 - offset1)
4118 */
Tim Petersa9bc1682003-01-11 03:39:11 +00004119 delta_s += (offset2 - offset1) * 60;
4120 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004121 }
4122 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004123 /* datetime - delta */
4124 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00004125 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00004126 (PyDateTime_Delta *)right,
4127 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004128 }
4129 }
4130
4131 if (result == Py_NotImplemented)
4132 Py_INCREF(result);
4133 return result;
4134}
4135
4136/* Various ways to turn a datetime into a string. */
4137
4138static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004139datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004140{
Tim Petersa9bc1682003-01-11 03:39:11 +00004141 char buffer[1000];
Christian Heimese93237d2007-12-19 02:37:44 +00004142 const char *type_name = Py_TYPE(self)->tp_name;
Tim Petersa9bc1682003-01-11 03:39:11 +00004143 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004144
Tim Petersa9bc1682003-01-11 03:39:11 +00004145 if (DATE_GET_MICROSECOND(self)) {
4146 PyOS_snprintf(buffer, sizeof(buffer),
4147 "%s(%d, %d, %d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004148 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004149 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4150 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4151 DATE_GET_SECOND(self),
4152 DATE_GET_MICROSECOND(self));
4153 }
4154 else if (DATE_GET_SECOND(self)) {
4155 PyOS_snprintf(buffer, sizeof(buffer),
4156 "%s(%d, %d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004157 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004158 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4159 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4160 DATE_GET_SECOND(self));
4161 }
4162 else {
4163 PyOS_snprintf(buffer, sizeof(buffer),
4164 "%s(%d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004165 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004166 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4167 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4168 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004169 baserepr = PyString_FromString(buffer);
Tim Petersa9bc1682003-01-11 03:39:11 +00004170 if (baserepr == NULL || ! HASTZINFO(self))
4171 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004172 return append_keyword_tzinfo(baserepr, self->tzinfo);
4173}
4174
Tim Petersa9bc1682003-01-11 03:39:11 +00004175static PyObject *
4176datetime_str(PyDateTime_DateTime *self)
4177{
4178 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4179}
Tim Peters2a799bf2002-12-16 20:18:38 +00004180
4181static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004182datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004183{
Tim Petersa9bc1682003-01-11 03:39:11 +00004184 char sep = 'T';
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004185 static char *keywords[] = {"sep", NULL};
Tim Petersa9bc1682003-01-11 03:39:11 +00004186 char buffer[100];
4187 char *cp;
4188 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004189
Tim Petersa9bc1682003-01-11 03:39:11 +00004190 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4191 &sep))
4192 return NULL;
4193 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4194 assert(cp != NULL);
4195 *cp++ = sep;
4196 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004197 result = PyString_FromString(buffer);
Tim Petersa9bc1682003-01-11 03:39:11 +00004198 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00004199 return result;
4200
4201 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00004202 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00004203 (PyObject *)self) < 0) {
4204 Py_DECREF(result);
4205 return NULL;
4206 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004207 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00004208 return result;
4209}
4210
Tim Petersa9bc1682003-01-11 03:39:11 +00004211static PyObject *
4212datetime_ctime(PyDateTime_DateTime *self)
4213{
4214 return format_ctime((PyDateTime_Date *)self,
4215 DATE_GET_HOUR(self),
4216 DATE_GET_MINUTE(self),
4217 DATE_GET_SECOND(self));
4218}
4219
Tim Peters2a799bf2002-12-16 20:18:38 +00004220/* Miscellaneous methods. */
4221
Tim Petersa9bc1682003-01-11 03:39:11 +00004222/* This is more natural as a tp_compare, but doesn't work then: for whatever
4223 * reason, Python's try_3way_compare ignores tp_compare unless
4224 * PyInstance_Check returns true, but these aren't old-style classes.
4225 */
4226static PyObject *
4227datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4228{
4229 int diff;
4230 naivety n1, n2;
4231 int offset1, offset2;
4232
4233 if (! PyDateTime_Check(other)) {
Tim Peters528ca532004-09-16 01:30:50 +00004234 /* If other has a "timetuple" attr, that's an advertised
4235 * hook for other classes to ask to get comparison control.
4236 * However, date instances have a timetuple attr, and we
4237 * don't want to allow that comparison. Because datetime
4238 * is a subclass of date, when mixing date and datetime
4239 * in a comparison, Python gives datetime the first shot
4240 * (it's the more specific subtype). So we can stop that
4241 * combination here reliably.
4242 */
4243 if (PyObject_HasAttrString(other, "timetuple") &&
4244 ! PyDate_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004245 /* A hook for other kinds of datetime objects. */
4246 Py_INCREF(Py_NotImplemented);
4247 return Py_NotImplemented;
4248 }
Tim Peters07534a62003-02-07 22:50:28 +00004249 if (op == Py_EQ || op == Py_NE) {
4250 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4251 Py_INCREF(result);
4252 return result;
4253 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004254 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00004255 return cmperror((PyObject *)self, other);
Tim Petersa9bc1682003-01-11 03:39:11 +00004256 }
4257
4258 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4259 (PyObject *)self,
4260 other, &offset2, &n2,
4261 other) < 0)
4262 return NULL;
4263 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4264 /* If they're both naive, or both aware and have the same offsets,
4265 * we get off cheap. Note that if they're both naive, offset1 ==
4266 * offset2 == 0 at this point.
4267 */
4268 if (n1 == n2 && offset1 == offset2) {
4269 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4270 _PyDateTime_DATETIME_DATASIZE);
4271 return diff_to_bool(diff, op);
4272 }
4273
4274 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4275 PyDateTime_Delta *delta;
4276
4277 assert(offset1 != offset2); /* else last "if" handled it */
4278 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4279 other);
4280 if (delta == NULL)
4281 return NULL;
4282 diff = GET_TD_DAYS(delta);
4283 if (diff == 0)
4284 diff = GET_TD_SECONDS(delta) |
4285 GET_TD_MICROSECONDS(delta);
4286 Py_DECREF(delta);
4287 return diff_to_bool(diff, op);
4288 }
4289
4290 assert(n1 != n2);
4291 PyErr_SetString(PyExc_TypeError,
4292 "can't compare offset-naive and "
4293 "offset-aware datetimes");
4294 return NULL;
4295}
4296
4297static long
4298datetime_hash(PyDateTime_DateTime *self)
4299{
4300 if (self->hashcode == -1) {
4301 naivety n;
4302 int offset;
4303 PyObject *temp;
4304
4305 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4306 &offset);
4307 assert(n != OFFSET_UNKNOWN);
4308 if (n == OFFSET_ERROR)
4309 return -1;
4310
4311 /* Reduce this to a hash of another object. */
4312 if (n == OFFSET_NAIVE)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004313 temp = PyString_FromStringAndSize(
Tim Petersa9bc1682003-01-11 03:39:11 +00004314 (char *)self->data,
4315 _PyDateTime_DATETIME_DATASIZE);
4316 else {
4317 int days;
4318 int seconds;
4319
4320 assert(n == OFFSET_AWARE);
4321 assert(HASTZINFO(self));
4322 days = ymd_to_ord(GET_YEAR(self),
4323 GET_MONTH(self),
4324 GET_DAY(self));
4325 seconds = DATE_GET_HOUR(self) * 3600 +
4326 (DATE_GET_MINUTE(self) - offset) * 60 +
4327 DATE_GET_SECOND(self);
4328 temp = new_delta(days,
4329 seconds,
4330 DATE_GET_MICROSECOND(self),
4331 1);
4332 }
4333 if (temp != NULL) {
4334 self->hashcode = PyObject_Hash(temp);
4335 Py_DECREF(temp);
4336 }
4337 }
4338 return self->hashcode;
4339}
Tim Peters2a799bf2002-12-16 20:18:38 +00004340
4341static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004342datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004343{
4344 PyObject *clone;
4345 PyObject *tuple;
4346 int y = GET_YEAR(self);
4347 int m = GET_MONTH(self);
4348 int d = GET_DAY(self);
4349 int hh = DATE_GET_HOUR(self);
4350 int mm = DATE_GET_MINUTE(self);
4351 int ss = DATE_GET_SECOND(self);
4352 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004353 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004354
4355 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004356 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004357 &y, &m, &d, &hh, &mm, &ss, &us,
4358 &tzinfo))
4359 return NULL;
4360 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4361 if (tuple == NULL)
4362 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00004363 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004364 Py_DECREF(tuple);
4365 return clone;
4366}
4367
4368static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004369datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004370{
Tim Peters52dcce22003-01-23 16:36:11 +00004371 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004372 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004373 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004374
Tim Peters80475bb2002-12-25 07:40:55 +00004375 PyObject *tzinfo;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004376 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004377
Tim Peters52dcce22003-01-23 16:36:11 +00004378 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4379 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004380 return NULL;
4381
Tim Peters52dcce22003-01-23 16:36:11 +00004382 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4383 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004384
Tim Peters52dcce22003-01-23 16:36:11 +00004385 /* Conversion to self's own time zone is a NOP. */
4386 if (self->tzinfo == tzinfo) {
4387 Py_INCREF(self);
4388 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004389 }
Tim Peters521fc152002-12-31 17:36:56 +00004390
Tim Peters52dcce22003-01-23 16:36:11 +00004391 /* Convert self to UTC. */
4392 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4393 if (offset == -1 && PyErr_Occurred())
4394 return NULL;
4395 if (none)
4396 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004397
Tim Peters52dcce22003-01-23 16:36:11 +00004398 y = GET_YEAR(self);
4399 m = GET_MONTH(self);
4400 d = GET_DAY(self);
4401 hh = DATE_GET_HOUR(self);
4402 mm = DATE_GET_MINUTE(self);
4403 ss = DATE_GET_SECOND(self);
4404 us = DATE_GET_MICROSECOND(self);
4405
4406 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004407 if ((mm < 0 || mm >= 60) &&
4408 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004409 return NULL;
4410
4411 /* Attach new tzinfo and let fromutc() do the rest. */
4412 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4413 if (result != NULL) {
4414 PyObject *temp = result;
4415
4416 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4417 Py_DECREF(temp);
4418 }
Tim Petersadf64202003-01-04 06:03:15 +00004419 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004420
Tim Peters52dcce22003-01-23 16:36:11 +00004421NeedAware:
4422 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4423 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004424 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004425}
4426
4427static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004428datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004429{
4430 int dstflag = -1;
4431
Tim Petersa9bc1682003-01-11 03:39:11 +00004432 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004433 int none;
4434
4435 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4436 if (dstflag == -1 && PyErr_Occurred())
4437 return NULL;
4438
4439 if (none)
4440 dstflag = -1;
4441 else if (dstflag != 0)
4442 dstflag = 1;
4443
4444 }
4445 return build_struct_time(GET_YEAR(self),
4446 GET_MONTH(self),
4447 GET_DAY(self),
4448 DATE_GET_HOUR(self),
4449 DATE_GET_MINUTE(self),
4450 DATE_GET_SECOND(self),
4451 dstflag);
4452}
4453
4454static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004455datetime_getdate(PyDateTime_DateTime *self)
4456{
4457 return new_date(GET_YEAR(self),
4458 GET_MONTH(self),
4459 GET_DAY(self));
4460}
4461
4462static PyObject *
4463datetime_gettime(PyDateTime_DateTime *self)
4464{
4465 return new_time(DATE_GET_HOUR(self),
4466 DATE_GET_MINUTE(self),
4467 DATE_GET_SECOND(self),
4468 DATE_GET_MICROSECOND(self),
4469 Py_None);
4470}
4471
4472static PyObject *
4473datetime_gettimetz(PyDateTime_DateTime *self)
4474{
4475 return new_time(DATE_GET_HOUR(self),
4476 DATE_GET_MINUTE(self),
4477 DATE_GET_SECOND(self),
4478 DATE_GET_MICROSECOND(self),
4479 HASTZINFO(self) ? self->tzinfo : Py_None);
4480}
4481
4482static PyObject *
4483datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004484{
4485 int y = GET_YEAR(self);
4486 int m = GET_MONTH(self);
4487 int d = GET_DAY(self);
4488 int hh = DATE_GET_HOUR(self);
4489 int mm = DATE_GET_MINUTE(self);
4490 int ss = DATE_GET_SECOND(self);
4491 int us = 0; /* microseconds are ignored in a timetuple */
4492 int offset = 0;
4493
Tim Petersa9bc1682003-01-11 03:39:11 +00004494 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004495 int none;
4496
4497 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4498 if (offset == -1 && PyErr_Occurred())
4499 return NULL;
4500 }
4501 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4502 * 0 in a UTC timetuple regardless of what dst() says.
4503 */
4504 if (offset) {
4505 /* Subtract offset minutes & normalize. */
4506 int stat;
4507
4508 mm -= offset;
4509 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4510 if (stat < 0) {
4511 /* At the edges, it's possible we overflowed
4512 * beyond MINYEAR or MAXYEAR.
4513 */
4514 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4515 PyErr_Clear();
4516 else
4517 return NULL;
4518 }
4519 }
4520 return build_struct_time(y, m, d, hh, mm, ss, 0);
4521}
4522
Tim Peters371935f2003-02-01 01:52:50 +00004523/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004524
Tim Petersa9bc1682003-01-11 03:39:11 +00004525/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004526 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4527 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004528 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004529 */
4530static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004531datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004532{
4533 PyObject *basestate;
4534 PyObject *result = NULL;
4535
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004536 basestate = PyString_FromStringAndSize((char *)self->data,
Tim Peters33e0f382003-01-10 02:05:14 +00004537 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004538 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004539 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004540 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00004541 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004542 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004543 Py_DECREF(basestate);
4544 }
4545 return result;
4546}
4547
4548static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004549datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004550{
Christian Heimese93237d2007-12-19 02:37:44 +00004551 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004552}
4553
Tim Petersa9bc1682003-01-11 03:39:11 +00004554static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004555
Tim Peters2a799bf2002-12-16 20:18:38 +00004556 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004557
Tim Petersa9bc1682003-01-11 03:39:11 +00004558 {"now", (PyCFunction)datetime_now,
Neal Norwitza84dcd72007-05-22 07:16:44 +00004559 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004560 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004561
Tim Petersa9bc1682003-01-11 03:39:11 +00004562 {"utcnow", (PyCFunction)datetime_utcnow,
4563 METH_NOARGS | METH_CLASS,
4564 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4565
4566 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Neal Norwitza84dcd72007-05-22 07:16:44 +00004567 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004568 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004569
Tim Petersa9bc1682003-01-11 03:39:11 +00004570 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4571 METH_VARARGS | METH_CLASS,
4572 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4573 "(like time.time()).")},
4574
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004575 {"strptime", (PyCFunction)datetime_strptime,
4576 METH_VARARGS | METH_CLASS,
4577 PyDoc_STR("string, format -> new datetime parsed from a string "
4578 "(like time.strptime()).")},
4579
Tim Petersa9bc1682003-01-11 03:39:11 +00004580 {"combine", (PyCFunction)datetime_combine,
4581 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4582 PyDoc_STR("date, time -> datetime with same date and time fields")},
4583
Tim Peters2a799bf2002-12-16 20:18:38 +00004584 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004585
Tim Petersa9bc1682003-01-11 03:39:11 +00004586 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4587 PyDoc_STR("Return date object with same year, month and day.")},
4588
4589 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4590 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4591
4592 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4593 PyDoc_STR("Return time object with same time and tzinfo.")},
4594
4595 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4596 PyDoc_STR("Return ctime() style string.")},
4597
4598 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004599 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4600
Tim Petersa9bc1682003-01-11 03:39:11 +00004601 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004602 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4603
Neal Norwitza84dcd72007-05-22 07:16:44 +00004604 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004605 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4606 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4607 "sep is used to separate the year from the time, and "
4608 "defaults to 'T'.")},
4609
Tim Petersa9bc1682003-01-11 03:39:11 +00004610 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004611 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4612
Tim Petersa9bc1682003-01-11 03:39:11 +00004613 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004614 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4615
Tim Petersa9bc1682003-01-11 03:39:11 +00004616 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004617 PyDoc_STR("Return self.tzinfo.dst(self).")},
4618
Neal Norwitza84dcd72007-05-22 07:16:44 +00004619 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
Tim Petersa9bc1682003-01-11 03:39:11 +00004620 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004621
Neal Norwitza84dcd72007-05-22 07:16:44 +00004622 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004623 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4624
Guido van Rossum177e41a2003-01-30 22:06:23 +00004625 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4626 PyDoc_STR("__reduce__() -> (cls, state)")},
4627
Tim Peters2a799bf2002-12-16 20:18:38 +00004628 {NULL, NULL}
4629};
4630
Tim Petersa9bc1682003-01-11 03:39:11 +00004631static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004632PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4633\n\
4634The year, month and day arguments are required. tzinfo may be None, or an\n\
4635instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004636
Tim Petersa9bc1682003-01-11 03:39:11 +00004637static PyNumberMethods datetime_as_number = {
4638 datetime_add, /* nb_add */
4639 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004640 0, /* nb_multiply */
4641 0, /* nb_divide */
4642 0, /* nb_remainder */
4643 0, /* nb_divmod */
4644 0, /* nb_power */
4645 0, /* nb_negative */
4646 0, /* nb_positive */
4647 0, /* nb_absolute */
4648 0, /* nb_nonzero */
4649};
4650
Tim Petersa9bc1682003-01-11 03:39:11 +00004651statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004652 PyObject_HEAD_INIT(NULL)
4653 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004654 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004655 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004656 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004657 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004658 0, /* tp_print */
4659 0, /* tp_getattr */
4660 0, /* tp_setattr */
4661 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004662 (reprfunc)datetime_repr, /* tp_repr */
4663 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004664 0, /* tp_as_sequence */
4665 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004666 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004667 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004668 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004669 PyObject_GenericGetAttr, /* tp_getattro */
4670 0, /* tp_setattro */
4671 0, /* tp_as_buffer */
4672 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4673 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004674 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004675 0, /* tp_traverse */
4676 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004677 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004678 0, /* tp_weaklistoffset */
4679 0, /* tp_iter */
4680 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004681 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004682 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004683 datetime_getset, /* tp_getset */
4684 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004685 0, /* tp_dict */
4686 0, /* tp_descr_get */
4687 0, /* tp_descr_set */
4688 0, /* tp_dictoffset */
4689 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00004690 datetime_alloc, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004691 datetime_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00004692 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004693};
4694
4695/* ---------------------------------------------------------------------------
4696 * Module methods and initialization.
4697 */
4698
4699static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004700 {NULL, NULL}
4701};
4702
Tim Peters9ddf40b2004-06-20 22:41:32 +00004703/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4704 * datetime.h.
4705 */
4706static PyDateTime_CAPI CAPI = {
4707 &PyDateTime_DateType,
4708 &PyDateTime_DateTimeType,
4709 &PyDateTime_TimeType,
4710 &PyDateTime_DeltaType,
4711 &PyDateTime_TZInfoType,
4712 new_date_ex,
4713 new_datetime_ex,
4714 new_time_ex,
4715 new_delta_ex,
4716 datetime_fromtimestamp,
4717 date_fromtimestamp
4718};
4719
4720
Tim Peters2a799bf2002-12-16 20:18:38 +00004721PyMODINIT_FUNC
4722initdatetime(void)
4723{
4724 PyObject *m; /* a module object */
4725 PyObject *d; /* its dict */
4726 PyObject *x;
4727
Tim Peters2a799bf2002-12-16 20:18:38 +00004728 m = Py_InitModule3("datetime", module_methods,
4729 "Fast implementation of the datetime type.");
Neal Norwitz1ac754f2006-01-19 06:09:39 +00004730 if (m == NULL)
4731 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004732
4733 if (PyType_Ready(&PyDateTime_DateType) < 0)
4734 return;
4735 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4736 return;
4737 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4738 return;
4739 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4740 return;
4741 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4742 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004743
Tim Peters2a799bf2002-12-16 20:18:38 +00004744 /* timedelta values */
4745 d = PyDateTime_DeltaType.tp_dict;
4746
Tim Peters2a799bf2002-12-16 20:18:38 +00004747 x = new_delta(0, 0, 1, 0);
4748 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4749 return;
4750 Py_DECREF(x);
4751
4752 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4753 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4754 return;
4755 Py_DECREF(x);
4756
4757 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4758 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4759 return;
4760 Py_DECREF(x);
4761
4762 /* date values */
4763 d = PyDateTime_DateType.tp_dict;
4764
4765 x = new_date(1, 1, 1);
4766 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4767 return;
4768 Py_DECREF(x);
4769
4770 x = new_date(MAXYEAR, 12, 31);
4771 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4772 return;
4773 Py_DECREF(x);
4774
4775 x = new_delta(1, 0, 0, 0);
4776 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4777 return;
4778 Py_DECREF(x);
4779
Tim Peters37f39822003-01-10 03:49:02 +00004780 /* time values */
4781 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004782
Tim Peters37f39822003-01-10 03:49:02 +00004783 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004784 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4785 return;
4786 Py_DECREF(x);
4787
Tim Peters37f39822003-01-10 03:49:02 +00004788 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004789 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4790 return;
4791 Py_DECREF(x);
4792
4793 x = new_delta(0, 0, 1, 0);
4794 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4795 return;
4796 Py_DECREF(x);
4797
Tim Petersa9bc1682003-01-11 03:39:11 +00004798 /* datetime values */
4799 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004800
Tim Petersa9bc1682003-01-11 03:39:11 +00004801 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004802 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4803 return;
4804 Py_DECREF(x);
4805
Tim Petersa9bc1682003-01-11 03:39:11 +00004806 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004807 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4808 return;
4809 Py_DECREF(x);
4810
4811 x = new_delta(0, 0, 1, 0);
4812 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4813 return;
4814 Py_DECREF(x);
4815
Tim Peters2a799bf2002-12-16 20:18:38 +00004816 /* module initialization */
4817 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4818 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4819
4820 Py_INCREF(&PyDateTime_DateType);
4821 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4822
Tim Petersa9bc1682003-01-11 03:39:11 +00004823 Py_INCREF(&PyDateTime_DateTimeType);
4824 PyModule_AddObject(m, "datetime",
4825 (PyObject *)&PyDateTime_DateTimeType);
4826
4827 Py_INCREF(&PyDateTime_TimeType);
4828 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4829
Tim Peters2a799bf2002-12-16 20:18:38 +00004830 Py_INCREF(&PyDateTime_DeltaType);
4831 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4832
Tim Peters2a799bf2002-12-16 20:18:38 +00004833 Py_INCREF(&PyDateTime_TZInfoType);
4834 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4835
Tim Peters9ddf40b2004-06-20 22:41:32 +00004836 x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
4837 NULL);
4838 if (x == NULL)
4839 return;
4840 PyModule_AddObject(m, "datetime_CAPI", x);
4841
Tim Peters2a799bf2002-12-16 20:18:38 +00004842 /* A 4-year cycle has an extra leap day over what we'd get from
4843 * pasting together 4 single years.
4844 */
4845 assert(DI4Y == 4 * 365 + 1);
4846 assert(DI4Y == days_before_year(4+1));
4847
4848 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4849 * get from pasting together 4 100-year cycles.
4850 */
4851 assert(DI400Y == 4 * DI100Y + 1);
4852 assert(DI400Y == days_before_year(400+1));
4853
4854 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4855 * pasting together 25 4-year cycles.
4856 */
4857 assert(DI100Y == 25 * DI4Y - 1);
4858 assert(DI100Y == days_before_year(100+1));
4859
4860 us_per_us = PyInt_FromLong(1);
4861 us_per_ms = PyInt_FromLong(1000);
4862 us_per_second = PyInt_FromLong(1000000);
4863 us_per_minute = PyInt_FromLong(60000000);
4864 seconds_per_day = PyInt_FromLong(24 * 3600);
4865 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4866 us_per_minute == NULL || seconds_per_day == NULL)
4867 return;
4868
4869 /* The rest are too big for 32-bit ints, but even
4870 * us_per_week fits in 40 bits, so doubles should be exact.
4871 */
4872 us_per_hour = PyLong_FromDouble(3600000000.0);
4873 us_per_day = PyLong_FromDouble(86400000000.0);
4874 us_per_week = PyLong_FromDouble(604800000000.0);
4875 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4876 return;
4877}
Tim Petersf3615152003-01-01 21:51:37 +00004878
4879/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004880Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004881 x.n = x stripped of its timezone -- its naive time.
4882 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4883 return None
4884 x.d = x.dst(), and assuming that doesn't raise an exception or
4885 return None
4886 x.s = x's standard offset, x.o - x.d
4887
4888Now some derived rules, where k is a duration (timedelta).
4889
48901. x.o = x.s + x.d
4891 This follows from the definition of x.s.
4892
Tim Petersc5dc4da2003-01-02 17:55:03 +000048932. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004894 This is actually a requirement, an assumption we need to make about
4895 sane tzinfo classes.
4896
48973. The naive UTC time corresponding to x is x.n - x.o.
4898 This is again a requirement for a sane tzinfo class.
4899
49004. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004901 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004902
Tim Petersc5dc4da2003-01-02 17:55:03 +000049035. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004904 Again follows from how arithmetic is defined.
4905
Tim Peters8bb5ad22003-01-24 02:44:45 +00004906Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004907(meaning that the various tzinfo methods exist, and don't blow up or return
4908None when called).
4909
Tim Petersa9bc1682003-01-11 03:39:11 +00004910The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004911x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004912
4913By #3, we want
4914
Tim Peters8bb5ad22003-01-24 02:44:45 +00004915 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004916
4917The algorithm starts by attaching tz to x.n, and calling that y. So
4918x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4919becomes true; in effect, we want to solve [2] for k:
4920
Tim Peters8bb5ad22003-01-24 02:44:45 +00004921 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004922
4923By #1, this is the same as
4924
Tim Peters8bb5ad22003-01-24 02:44:45 +00004925 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004926
4927By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4928Substituting that into [3],
4929
Tim Peters8bb5ad22003-01-24 02:44:45 +00004930 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4931 k - (y+k).s - (y+k).d = 0; rearranging,
4932 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4933 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004934
Tim Peters8bb5ad22003-01-24 02:44:45 +00004935On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4936approximate k by ignoring the (y+k).d term at first. Note that k can't be
4937very large, since all offset-returning methods return a duration of magnitude
4938less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4939be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004940
4941In any case, the new value is
4942
Tim Peters8bb5ad22003-01-24 02:44:45 +00004943 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004944
Tim Peters8bb5ad22003-01-24 02:44:45 +00004945It's helpful to step back at look at [4] from a higher level: it's simply
4946mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004947
4948At this point, if
4949
Tim Peters8bb5ad22003-01-24 02:44:45 +00004950 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004951
4952we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004953at the start of daylight time. Picture US Eastern for concreteness. The wall
4954time 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 +00004955sense then. The docs ask that an Eastern tzinfo class consider such a time to
4956be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4957on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004958the only spelling that makes sense on the local wall clock.
4959
Tim Petersc5dc4da2003-01-02 17:55:03 +00004960In fact, if [5] holds at this point, we do have the standard-time spelling,
4961but that takes a bit of proof. We first prove a stronger result. What's the
4962difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004963
Tim Peters8bb5ad22003-01-24 02:44:45 +00004964 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004965
Tim Petersc5dc4da2003-01-02 17:55:03 +00004966Now
4967 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004968 (y + y.s).n = by #5
4969 y.n + y.s = since y.n = x.n
4970 x.n + y.s = since z and y are have the same tzinfo member,
4971 y.s = z.s by #2
4972 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004973
Tim Petersc5dc4da2003-01-02 17:55:03 +00004974Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004975
Tim Petersc5dc4da2003-01-02 17:55:03 +00004976 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004977 x.n - ((x.n + z.s) - z.o) = expanding
4978 x.n - x.n - z.s + z.o = cancelling
4979 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004980 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004981
Tim Petersc5dc4da2003-01-02 17:55:03 +00004982So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00004983
Tim Petersc5dc4da2003-01-02 17:55:03 +00004984If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00004985spelling we wanted in the endcase described above. We're done. Contrarily,
4986if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00004987
Tim Petersc5dc4da2003-01-02 17:55:03 +00004988If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
4989add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00004990local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00004991
Tim Petersc5dc4da2003-01-02 17:55:03 +00004992Let
Tim Petersf3615152003-01-01 21:51:37 +00004993
Tim Peters4fede1a2003-01-04 00:26:59 +00004994 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004995
Tim Peters4fede1a2003-01-04 00:26:59 +00004996and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00004997
Tim Peters8bb5ad22003-01-24 02:44:45 +00004998 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00004999
Tim Peters8bb5ad22003-01-24 02:44:45 +00005000If so, we're done. If not, the tzinfo class is insane, according to the
5001assumptions we've made. This also requires a bit of proof. As before, let's
5002compute the difference between the LHS and RHS of [8] (and skipping some of
5003the justifications for the kinds of substitutions we've done several times
5004already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005005
Tim Peters8bb5ad22003-01-24 02:44:45 +00005006 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5007 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5008 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5009 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5010 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00005011 - z.o + z'.o = #1 twice
5012 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5013 z'.d - z.d
5014
5015So 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 +00005016we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5017return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005018
Tim Peters8bb5ad22003-01-24 02:44:45 +00005019How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5020a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5021would have to change the result dst() returns: we start in DST, and moving
5022a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005023
Tim Peters8bb5ad22003-01-24 02:44:45 +00005024There isn't a sane case where this can happen. The closest it gets is at
5025the end of DST, where there's an hour in UTC with no spelling in a hybrid
5026tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5027that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5028UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5029time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5030clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5031standard time. Since that's what the local clock *does*, we want to map both
5032UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005033in local time, but so it goes -- it's the way the local clock works.
5034
Tim Peters8bb5ad22003-01-24 02:44:45 +00005035When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5036so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5037z' = 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 +00005038(correctly) concludes that z' is not UTC-equivalent to x.
5039
5040Because we know z.d said z was in daylight time (else [5] would have held and
5041we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005042and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005043return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5044but the reasoning doesn't depend on the example -- it depends on there being
5045two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005046z' must be in standard time, and is the spelling we want in this case.
5047
5048Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5049concerned (because it takes z' as being in standard time rather than the
5050daylight time we intend here), but returning it gives the real-life "local
5051clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5052tz.
5053
5054When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5055the 1:MM standard time spelling we want.
5056
5057So how can this break? One of the assumptions must be violated. Two
5058possibilities:
5059
50601) [2] effectively says that y.s is invariant across all y belong to a given
5061 time zone. This isn't true if, for political reasons or continental drift,
5062 a region decides to change its base offset from UTC.
5063
50642) There may be versions of "double daylight" time where the tail end of
5065 the analysis gives up a step too early. I haven't thought about that
5066 enough to say.
5067
5068In any case, it's clear that the default fromutc() is strong enough to handle
5069"almost all" time zones: so long as the standard offset is invariant, it
5070doesn't matter if daylight time transition points change from year to year, or
5071if daylight time is skipped in some years; it doesn't matter how large or
5072small dst() may get within its bounds; and it doesn't even matter if some
5073perverse time zone returns a negative dst()). So a breaking case must be
5074pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005075--------------------------------------------------------------------------- */