blob: 181883661913fd1a47e4525ebf4b6b98d2eaf2ea [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
Gregory P. Smith9d534572008-06-11 07:41:16 +00001118 assert(buflen >= 1);
1119
Tim Peters2a799bf2002-12-16 20:18:38 +00001120 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1121 if (offset == -1 && PyErr_Occurred())
1122 return -1;
1123 if (none) {
1124 *buf = '\0';
1125 return 0;
1126 }
1127 sign = '+';
1128 if (offset < 0) {
1129 sign = '-';
1130 offset = - offset;
1131 }
1132 hours = divmod(offset, 60, &minutes);
1133 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1134 return 0;
1135}
1136
Skip Montanarofc070d22008-03-15 16:04:45 +00001137static PyObject *
1138make_freplacement(PyObject *object)
1139{
Neal Norwitzf13572d2008-03-17 19:02:45 +00001140 char freplacement[64];
Skip Montanarofc070d22008-03-15 16:04:45 +00001141 if (PyTime_Check(object))
1142 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1143 else if (PyDateTime_Check(object))
1144 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1145 else
1146 sprintf(freplacement, "%06d", 0);
1147
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001148 return PyString_FromStringAndSize(freplacement, strlen(freplacement));
Skip Montanarofc070d22008-03-15 16:04:45 +00001149}
1150
Tim Peters2a799bf2002-12-16 20:18:38 +00001151/* I sure don't want to reproduce the strftime code from the time module,
1152 * so this imports the module and calls it. All the hair is due to
Skip Montanarofc070d22008-03-15 16:04:45 +00001153 * giving special meanings to the %z, %Z and %f format codes via a
1154 * preprocessing step on the format string.
Tim Petersbad8ff02002-12-30 20:52:32 +00001155 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1156 * needed.
Tim Peters2a799bf2002-12-16 20:18:38 +00001157 */
1158static PyObject *
Gregory P. Smith137d8242008-06-02 04:05:52 +00001159wrap_strftime(PyObject *object, const char *format, size_t format_len,
1160 PyObject *timetuple, PyObject *tzinfoarg)
Tim Peters2a799bf2002-12-16 20:18:38 +00001161{
1162 PyObject *result = NULL; /* guilty until proved innocent */
1163
1164 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1165 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
Skip Montanarofc070d22008-03-15 16:04:45 +00001166 PyObject *freplacement = NULL; /* py string, replacement for %f */
Tim Peters2a799bf2002-12-16 20:18:38 +00001167
Gregory P. Smith137d8242008-06-02 04:05:52 +00001168 const char *pin; /* pointer to next char in input format */
1169 char ch; /* next char in input format */
Tim Peters2a799bf2002-12-16 20:18:38 +00001170
1171 PyObject *newfmt = NULL; /* py string, the output format */
1172 char *pnew; /* pointer to available byte in output format */
Gregory P. Smith137d8242008-06-02 04:05:52 +00001173 size_t totalnew; /* number bytes total in output format buffer,
1174 exclusive of trailing \0 */
1175 size_t usednew; /* number bytes used so far in output format buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001176
Gregory P. Smith137d8242008-06-02 04:05:52 +00001177 const char *ptoappend; /* ptr to string to append to output buffer */
1178 size_t ntoappend; /* # of bytes to append to output buffer */
Tim Peters2a799bf2002-12-16 20:18:38 +00001179
Tim Peters2a799bf2002-12-16 20:18:38 +00001180 assert(object && format && timetuple);
Tim Peters2a799bf2002-12-16 20:18:38 +00001181
Tim Petersd6844152002-12-22 20:58:42 +00001182 /* Give up if the year is before 1900.
1183 * Python strftime() plays games with the year, and different
1184 * games depending on whether envar PYTHON2K is set. This makes
1185 * years before 1900 a nightmare, even if the platform strftime
1186 * supports them (and not all do).
1187 * We could get a lot farther here by avoiding Python's strftime
1188 * wrapper and calling the C strftime() directly, but that isn't
1189 * an option in the Python implementation of this module.
1190 */
1191 {
1192 long year;
1193 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1194 if (pyyear == NULL) return NULL;
1195 assert(PyInt_Check(pyyear));
1196 year = PyInt_AsLong(pyyear);
1197 Py_DECREF(pyyear);
1198 if (year < 1900) {
1199 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1200 "1900; the datetime strftime() "
1201 "methods require year >= 1900",
1202 year);
1203 return NULL;
1204 }
1205 }
1206
Skip Montanarofc070d22008-03-15 16:04:45 +00001207 /* Scan the input format, looking for %z/%Z/%f escapes, building
Tim Peters328fff72002-12-20 01:31:27 +00001208 * a new format. Since computing the replacements for those codes
1209 * is expensive, don't unless they're actually used.
Tim Peters2a799bf2002-12-16 20:18:38 +00001210 */
Gregory P. Smith9d534572008-06-11 07:41:16 +00001211 if (format_len > INT_MAX - 1) {
1212 PyErr_NoMemory();
1213 goto Done;
1214 }
1215
Gregory P. Smith137d8242008-06-02 04:05:52 +00001216 totalnew = format_len + 1; /* realistic if no %z/%Z/%f */
Gregory P. Smith99a3dce2008-06-10 17:42:36 +00001217 newfmt = PyString_FromStringAndSize(NULL, totalnew);
Tim Peters2a799bf2002-12-16 20:18:38 +00001218 if (newfmt == NULL) goto Done;
Gregory P. Smith99a3dce2008-06-10 17:42:36 +00001219 pnew = PyString_AsString(newfmt);
Tim Peters2a799bf2002-12-16 20:18:38 +00001220 usednew = 0;
1221
Gregory P. Smith137d8242008-06-02 04:05:52 +00001222 pin = format;
Tim Peters2a799bf2002-12-16 20:18:38 +00001223 while ((ch = *pin++) != '\0') {
1224 if (ch != '%') {
Tim Peters328fff72002-12-20 01:31:27 +00001225 ptoappend = pin - 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001226 ntoappend = 1;
1227 }
1228 else if ((ch = *pin++) == '\0') {
1229 /* There's a lone trailing %; doesn't make sense. */
1230 PyErr_SetString(PyExc_ValueError, "strftime format "
1231 "ends with raw %");
1232 goto Done;
1233 }
1234 /* A % has been seen and ch is the character after it. */
1235 else if (ch == 'z') {
1236 if (zreplacement == NULL) {
1237 /* format utcoffset */
Tim Peters328fff72002-12-20 01:31:27 +00001238 char buf[100];
Tim Peters2a799bf2002-12-16 20:18:38 +00001239 PyObject *tzinfo = get_tzinfo_member(object);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001240 zreplacement = PyString_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00001241 if (zreplacement == NULL) goto Done;
1242 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001243 assert(tzinfoarg != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001244 if (format_utcoffset(buf,
Tim Peters328fff72002-12-20 01:31:27 +00001245 sizeof(buf),
Tim Peters2a799bf2002-12-16 20:18:38 +00001246 "",
1247 tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00001248 tzinfoarg) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001249 goto Done;
1250 Py_DECREF(zreplacement);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001251 zreplacement = PyString_FromString(buf);
Tim Peters2a799bf2002-12-16 20:18:38 +00001252 if (zreplacement == NULL) goto Done;
1253 }
1254 }
1255 assert(zreplacement != NULL);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001256 ptoappend = PyString_AS_STRING(zreplacement);
1257 ntoappend = PyString_GET_SIZE(zreplacement);
Tim Peters2a799bf2002-12-16 20:18:38 +00001258 }
1259 else if (ch == 'Z') {
1260 /* format tzname */
1261 if (Zreplacement == NULL) {
1262 PyObject *tzinfo = get_tzinfo_member(object);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001263 Zreplacement = PyString_FromString("");
Tim Peters2a799bf2002-12-16 20:18:38 +00001264 if (Zreplacement == NULL) goto Done;
1265 if (tzinfo != Py_None && tzinfo != NULL) {
Tim Petersbad8ff02002-12-30 20:52:32 +00001266 PyObject *temp;
1267 assert(tzinfoarg != NULL);
1268 temp = call_tzname(tzinfo, tzinfoarg);
Tim Peters2a799bf2002-12-16 20:18:38 +00001269 if (temp == NULL) goto Done;
1270 if (temp != Py_None) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001271 assert(PyString_Check(temp));
Tim Peters2a799bf2002-12-16 20:18:38 +00001272 /* Since the tzname is getting
1273 * stuffed into the format, we
1274 * have to double any % signs
1275 * so that strftime doesn't
1276 * treat them as format codes.
1277 */
1278 Py_DECREF(Zreplacement);
1279 Zreplacement = PyObject_CallMethod(
1280 temp, "replace",
1281 "ss", "%", "%%");
1282 Py_DECREF(temp);
1283 if (Zreplacement == NULL)
1284 goto Done;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001285 if (!PyString_Check(Zreplacement)) {
Neal Norwitzd5b0c9b2006-03-20 01:58:39 +00001286 PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
1287 goto Done;
1288 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001289 }
1290 else
1291 Py_DECREF(temp);
1292 }
1293 }
1294 assert(Zreplacement != NULL);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001295 ptoappend = PyString_AS_STRING(Zreplacement);
1296 ntoappend = PyString_GET_SIZE(Zreplacement);
Tim Peters2a799bf2002-12-16 20:18:38 +00001297 }
Skip Montanarofc070d22008-03-15 16:04:45 +00001298 else if (ch == 'f') {
1299 /* format microseconds */
1300 if (freplacement == NULL) {
1301 freplacement = make_freplacement(object);
1302 if (freplacement == NULL)
1303 goto Done;
1304 }
1305 assert(freplacement != NULL);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001306 assert(PyString_Check(freplacement));
1307 ptoappend = PyString_AS_STRING(freplacement);
1308 ntoappend = PyString_GET_SIZE(freplacement);
Skip Montanarofc070d22008-03-15 16:04:45 +00001309 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001310 else {
Tim Peters328fff72002-12-20 01:31:27 +00001311 /* percent followed by neither z nor Z */
1312 ptoappend = pin - 2;
Tim Peters2a799bf2002-12-16 20:18:38 +00001313 ntoappend = 2;
1314 }
1315
1316 /* Append the ntoappend chars starting at ptoappend to
1317 * the new format.
1318 */
Neal Norwitzd5b0c9b2006-03-20 01:58:39 +00001319 assert(ptoappend != NULL);
Tim Peters2a799bf2002-12-16 20:18:38 +00001320 assert(ntoappend >= 0);
1321 if (ntoappend == 0)
1322 continue;
1323 while (usednew + ntoappend > totalnew) {
Gregory P. Smith137d8242008-06-02 04:05:52 +00001324 size_t bigger = totalnew << 1;
Tim Peters2a799bf2002-12-16 20:18:38 +00001325 if ((bigger >> 1) != totalnew) { /* overflow */
1326 PyErr_NoMemory();
1327 goto Done;
1328 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001329 if (_PyString_Resize(&newfmt, bigger) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001330 goto Done;
1331 totalnew = bigger;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001332 pnew = PyString_AsString(newfmt) + usednew;
Tim Peters2a799bf2002-12-16 20:18:38 +00001333 }
1334 memcpy(pnew, ptoappend, ntoappend);
1335 pnew += ntoappend;
1336 usednew += ntoappend;
1337 assert(usednew <= totalnew);
1338 } /* end while() */
1339
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001340 if (_PyString_Resize(&newfmt, usednew) < 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00001341 goto Done;
1342 {
Christian Heimes000a0742008-01-03 22:16:32 +00001343 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001344 if (time == NULL)
1345 goto Done;
1346 result = PyObject_CallMethod(time, "strftime", "OO",
1347 newfmt, timetuple);
1348 Py_DECREF(time);
1349 }
1350 Done:
Skip Montanarofc070d22008-03-15 16:04:45 +00001351 Py_XDECREF(freplacement);
Tim Peters2a799bf2002-12-16 20:18:38 +00001352 Py_XDECREF(zreplacement);
1353 Py_XDECREF(Zreplacement);
1354 Py_XDECREF(newfmt);
1355 return result;
1356}
1357
1358static char *
1359isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1360{
1361 int x;
1362 x = PyOS_snprintf(buffer, bufflen,
1363 "%04d-%02d-%02d",
1364 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1365 return buffer + x;
1366}
1367
1368static void
1369isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1370{
1371 int us = DATE_GET_MICROSECOND(dt);
1372
1373 PyOS_snprintf(buffer, bufflen,
1374 "%02d:%02d:%02d", /* 8 characters */
1375 DATE_GET_HOUR(dt),
1376 DATE_GET_MINUTE(dt),
1377 DATE_GET_SECOND(dt));
1378 if (us)
1379 PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
1380}
1381
1382/* ---------------------------------------------------------------------------
1383 * Wrap functions from the time module. These aren't directly available
1384 * from C. Perhaps they should be.
1385 */
1386
1387/* Call time.time() and return its result (a Python float). */
1388static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001389time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001390{
1391 PyObject *result = NULL;
Christian Heimes000a0742008-01-03 22:16:32 +00001392 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001393
1394 if (time != NULL) {
1395 result = PyObject_CallMethod(time, "time", "()");
1396 Py_DECREF(time);
1397 }
1398 return result;
1399}
1400
1401/* Build a time.struct_time. The weekday and day number are automatically
1402 * computed from the y,m,d args.
1403 */
1404static PyObject *
1405build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1406{
1407 PyObject *time;
1408 PyObject *result = NULL;
1409
Christian Heimes000a0742008-01-03 22:16:32 +00001410 time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001411 if (time != NULL) {
1412 result = PyObject_CallMethod(time, "struct_time",
1413 "((iiiiiiiii))",
1414 y, m, d,
1415 hh, mm, ss,
1416 weekday(y, m, d),
1417 days_before_month(y, m) + d,
1418 dstflag);
1419 Py_DECREF(time);
1420 }
1421 return result;
1422}
1423
1424/* ---------------------------------------------------------------------------
1425 * Miscellaneous helpers.
1426 */
1427
1428/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1429 * The comparisons here all most naturally compute a cmp()-like result.
1430 * This little helper turns that into a bool result for rich comparisons.
1431 */
1432static PyObject *
1433diff_to_bool(int diff, int op)
1434{
1435 PyObject *result;
1436 int istrue;
1437
1438 switch (op) {
1439 case Py_EQ: istrue = diff == 0; break;
1440 case Py_NE: istrue = diff != 0; break;
1441 case Py_LE: istrue = diff <= 0; break;
1442 case Py_GE: istrue = diff >= 0; break;
1443 case Py_LT: istrue = diff < 0; break;
1444 case Py_GT: istrue = diff > 0; break;
1445 default:
1446 assert(! "op unknown");
1447 istrue = 0; /* To shut up compiler */
1448 }
1449 result = istrue ? Py_True : Py_False;
1450 Py_INCREF(result);
1451 return result;
1452}
1453
Tim Peters07534a62003-02-07 22:50:28 +00001454/* Raises a "can't compare" TypeError and returns NULL. */
1455static PyObject *
1456cmperror(PyObject *a, PyObject *b)
1457{
1458 PyErr_Format(PyExc_TypeError,
1459 "can't compare %s to %s",
Christian Heimese93237d2007-12-19 02:37:44 +00001460 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
Tim Peters07534a62003-02-07 22:50:28 +00001461 return NULL;
1462}
1463
Tim Peters2a799bf2002-12-16 20:18:38 +00001464/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001465 * Cached Python objects; these are set by the module init function.
1466 */
1467
1468/* Conversion factors. */
1469static PyObject *us_per_us = NULL; /* 1 */
1470static PyObject *us_per_ms = NULL; /* 1000 */
1471static PyObject *us_per_second = NULL; /* 1000000 */
1472static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1473static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1474static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1475static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1476static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1477
Tim Peters2a799bf2002-12-16 20:18:38 +00001478/* ---------------------------------------------------------------------------
1479 * Class implementations.
1480 */
1481
1482/*
1483 * PyDateTime_Delta implementation.
1484 */
1485
1486/* Convert a timedelta to a number of us,
1487 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1488 * as a Python int or long.
1489 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1490 * due to ubiquitous overflow possibilities.
1491 */
1492static PyObject *
1493delta_to_microseconds(PyDateTime_Delta *self)
1494{
1495 PyObject *x1 = NULL;
1496 PyObject *x2 = NULL;
1497 PyObject *x3 = NULL;
1498 PyObject *result = NULL;
1499
1500 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1501 if (x1 == NULL)
1502 goto Done;
1503 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1504 if (x2 == NULL)
1505 goto Done;
1506 Py_DECREF(x1);
1507 x1 = NULL;
1508
1509 /* x2 has days in seconds */
1510 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1511 if (x1 == NULL)
1512 goto Done;
1513 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1514 if (x3 == NULL)
1515 goto Done;
1516 Py_DECREF(x1);
1517 Py_DECREF(x2);
1518 x1 = x2 = NULL;
1519
1520 /* x3 has days+seconds in seconds */
1521 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1522 if (x1 == NULL)
1523 goto Done;
1524 Py_DECREF(x3);
1525 x3 = NULL;
1526
1527 /* x1 has days+seconds in us */
1528 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1529 if (x2 == NULL)
1530 goto Done;
1531 result = PyNumber_Add(x1, x2);
1532
1533Done:
1534 Py_XDECREF(x1);
1535 Py_XDECREF(x2);
1536 Py_XDECREF(x3);
1537 return result;
1538}
1539
1540/* Convert a number of us (as a Python int or long) to a timedelta.
1541 */
1542static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001543microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001544{
1545 int us;
1546 int s;
1547 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001548 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001549
1550 PyObject *tuple = NULL;
1551 PyObject *num = NULL;
1552 PyObject *result = NULL;
1553
1554 tuple = PyNumber_Divmod(pyus, us_per_second);
1555 if (tuple == NULL)
1556 goto Done;
1557
1558 num = PyTuple_GetItem(tuple, 1); /* us */
1559 if (num == NULL)
1560 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001561 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001562 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001563 if (temp == -1 && PyErr_Occurred())
1564 goto Done;
1565 assert(0 <= temp && temp < 1000000);
1566 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001567 if (us < 0) {
1568 /* The divisor was positive, so this must be an error. */
1569 assert(PyErr_Occurred());
1570 goto Done;
1571 }
1572
1573 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1574 if (num == NULL)
1575 goto Done;
1576 Py_INCREF(num);
1577 Py_DECREF(tuple);
1578
1579 tuple = PyNumber_Divmod(num, seconds_per_day);
1580 if (tuple == NULL)
1581 goto Done;
1582 Py_DECREF(num);
1583
1584 num = PyTuple_GetItem(tuple, 1); /* seconds */
1585 if (num == NULL)
1586 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001587 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001588 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001589 if (temp == -1 && PyErr_Occurred())
1590 goto Done;
1591 assert(0 <= temp && temp < 24*3600);
1592 s = (int)temp;
1593
Tim Peters2a799bf2002-12-16 20:18:38 +00001594 if (s < 0) {
1595 /* The divisor was positive, so this must be an error. */
1596 assert(PyErr_Occurred());
1597 goto Done;
1598 }
1599
1600 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1601 if (num == NULL)
1602 goto Done;
1603 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001604 temp = PyLong_AsLong(num);
1605 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001606 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001607 d = (int)temp;
1608 if ((long)d != temp) {
1609 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1610 "large to fit in a C int");
1611 goto Done;
1612 }
Tim Petersb0c854d2003-05-17 15:57:00 +00001613 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001614
1615Done:
1616 Py_XDECREF(tuple);
1617 Py_XDECREF(num);
1618 return result;
1619}
1620
Tim Petersb0c854d2003-05-17 15:57:00 +00001621#define microseconds_to_delta(pymicros) \
1622 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1623
Tim Peters2a799bf2002-12-16 20:18:38 +00001624static PyObject *
1625multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1626{
1627 PyObject *pyus_in;
1628 PyObject *pyus_out;
1629 PyObject *result;
1630
1631 pyus_in = delta_to_microseconds(delta);
1632 if (pyus_in == NULL)
1633 return NULL;
1634
1635 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1636 Py_DECREF(pyus_in);
1637 if (pyus_out == NULL)
1638 return NULL;
1639
1640 result = microseconds_to_delta(pyus_out);
1641 Py_DECREF(pyus_out);
1642 return result;
1643}
1644
1645static PyObject *
1646divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1647{
1648 PyObject *pyus_in;
1649 PyObject *pyus_out;
1650 PyObject *result;
1651
1652 pyus_in = delta_to_microseconds(delta);
1653 if (pyus_in == NULL)
1654 return NULL;
1655
1656 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1657 Py_DECREF(pyus_in);
1658 if (pyus_out == NULL)
1659 return NULL;
1660
1661 result = microseconds_to_delta(pyus_out);
1662 Py_DECREF(pyus_out);
1663 return result;
1664}
1665
1666static PyObject *
1667delta_add(PyObject *left, PyObject *right)
1668{
1669 PyObject *result = Py_NotImplemented;
1670
1671 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1672 /* delta + delta */
1673 /* The C-level additions can't overflow because of the
1674 * invariant bounds.
1675 */
1676 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1677 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1678 int microseconds = GET_TD_MICROSECONDS(left) +
1679 GET_TD_MICROSECONDS(right);
1680 result = new_delta(days, seconds, microseconds, 1);
1681 }
1682
1683 if (result == Py_NotImplemented)
1684 Py_INCREF(result);
1685 return result;
1686}
1687
1688static PyObject *
1689delta_negative(PyDateTime_Delta *self)
1690{
1691 return new_delta(-GET_TD_DAYS(self),
1692 -GET_TD_SECONDS(self),
1693 -GET_TD_MICROSECONDS(self),
1694 1);
1695}
1696
1697static PyObject *
1698delta_positive(PyDateTime_Delta *self)
1699{
1700 /* Could optimize this (by returning self) if this isn't a
1701 * subclass -- but who uses unary + ? Approximately nobody.
1702 */
1703 return new_delta(GET_TD_DAYS(self),
1704 GET_TD_SECONDS(self),
1705 GET_TD_MICROSECONDS(self),
1706 0);
1707}
1708
1709static PyObject *
1710delta_abs(PyDateTime_Delta *self)
1711{
1712 PyObject *result;
1713
1714 assert(GET_TD_MICROSECONDS(self) >= 0);
1715 assert(GET_TD_SECONDS(self) >= 0);
1716
1717 if (GET_TD_DAYS(self) < 0)
1718 result = delta_negative(self);
1719 else
1720 result = delta_positive(self);
1721
1722 return result;
1723}
1724
1725static PyObject *
1726delta_subtract(PyObject *left, PyObject *right)
1727{
1728 PyObject *result = Py_NotImplemented;
1729
1730 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1731 /* delta - delta */
1732 PyObject *minus_right = PyNumber_Negative(right);
1733 if (minus_right) {
1734 result = delta_add(left, minus_right);
1735 Py_DECREF(minus_right);
1736 }
1737 else
1738 result = NULL;
1739 }
1740
1741 if (result == Py_NotImplemented)
1742 Py_INCREF(result);
1743 return result;
1744}
1745
1746/* This is more natural as a tp_compare, but doesn't work then: for whatever
1747 * reason, Python's try_3way_compare ignores tp_compare unless
1748 * PyInstance_Check returns true, but these aren't old-style classes.
1749 */
1750static PyObject *
1751delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1752{
Tim Peters07534a62003-02-07 22:50:28 +00001753 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001754
Tim Petersaa7d8492003-02-08 03:28:59 +00001755 if (PyDelta_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00001756 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1757 if (diff == 0) {
1758 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1759 if (diff == 0)
1760 diff = GET_TD_MICROSECONDS(self) -
1761 GET_TD_MICROSECONDS(other);
1762 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001763 }
Tim Peters07534a62003-02-07 22:50:28 +00001764 else if (op == Py_EQ || op == Py_NE)
1765 diff = 1; /* any non-zero value will do */
1766
1767 else /* stop this from falling back to address comparison */
1768 return cmperror((PyObject *)self, other);
1769
Tim Peters2a799bf2002-12-16 20:18:38 +00001770 return diff_to_bool(diff, op);
1771}
1772
1773static PyObject *delta_getstate(PyDateTime_Delta *self);
1774
1775static long
1776delta_hash(PyDateTime_Delta *self)
1777{
1778 if (self->hashcode == -1) {
1779 PyObject *temp = delta_getstate(self);
1780 if (temp != NULL) {
1781 self->hashcode = PyObject_Hash(temp);
1782 Py_DECREF(temp);
1783 }
1784 }
1785 return self->hashcode;
1786}
1787
1788static PyObject *
1789delta_multiply(PyObject *left, PyObject *right)
1790{
1791 PyObject *result = Py_NotImplemented;
1792
1793 if (PyDelta_Check(left)) {
1794 /* delta * ??? */
1795 if (PyInt_Check(right) || PyLong_Check(right))
1796 result = multiply_int_timedelta(right,
1797 (PyDateTime_Delta *) left);
1798 }
1799 else if (PyInt_Check(left) || PyLong_Check(left))
1800 result = multiply_int_timedelta(left,
1801 (PyDateTime_Delta *) right);
1802
1803 if (result == Py_NotImplemented)
1804 Py_INCREF(result);
1805 return result;
1806}
1807
1808static PyObject *
1809delta_divide(PyObject *left, PyObject *right)
1810{
1811 PyObject *result = Py_NotImplemented;
1812
1813 if (PyDelta_Check(left)) {
1814 /* delta * ??? */
1815 if (PyInt_Check(right) || PyLong_Check(right))
1816 result = divide_timedelta_int(
1817 (PyDateTime_Delta *)left,
1818 right);
1819 }
1820
1821 if (result == Py_NotImplemented)
1822 Py_INCREF(result);
1823 return result;
1824}
1825
1826/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1827 * timedelta constructor. sofar is the # of microseconds accounted for
1828 * so far, and there are factor microseconds per current unit, the number
1829 * of which is given by num. num * factor is added to sofar in a
1830 * numerically careful way, and that's the result. Any fractional
1831 * microseconds left over (this can happen if num is a float type) are
1832 * added into *leftover.
1833 * Note that there are many ways this can give an error (NULL) return.
1834 */
1835static PyObject *
1836accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1837 double *leftover)
1838{
1839 PyObject *prod;
1840 PyObject *sum;
1841
1842 assert(num != NULL);
1843
1844 if (PyInt_Check(num) || PyLong_Check(num)) {
1845 prod = PyNumber_Multiply(num, factor);
1846 if (prod == NULL)
1847 return NULL;
1848 sum = PyNumber_Add(sofar, prod);
1849 Py_DECREF(prod);
1850 return sum;
1851 }
1852
1853 if (PyFloat_Check(num)) {
1854 double dnum;
1855 double fracpart;
1856 double intpart;
1857 PyObject *x;
1858 PyObject *y;
1859
1860 /* The Plan: decompose num into an integer part and a
1861 * fractional part, num = intpart + fracpart.
1862 * Then num * factor ==
1863 * intpart * factor + fracpart * factor
1864 * and the LHS can be computed exactly in long arithmetic.
1865 * The RHS is again broken into an int part and frac part.
1866 * and the frac part is added into *leftover.
1867 */
1868 dnum = PyFloat_AsDouble(num);
1869 if (dnum == -1.0 && PyErr_Occurred())
1870 return NULL;
1871 fracpart = modf(dnum, &intpart);
1872 x = PyLong_FromDouble(intpart);
1873 if (x == NULL)
1874 return NULL;
1875
1876 prod = PyNumber_Multiply(x, factor);
1877 Py_DECREF(x);
1878 if (prod == NULL)
1879 return NULL;
1880
1881 sum = PyNumber_Add(sofar, prod);
1882 Py_DECREF(prod);
1883 if (sum == NULL)
1884 return NULL;
1885
1886 if (fracpart == 0.0)
1887 return sum;
1888 /* So far we've lost no information. Dealing with the
1889 * fractional part requires float arithmetic, and may
1890 * lose a little info.
1891 */
1892 assert(PyInt_Check(factor) || PyLong_Check(factor));
1893 if (PyInt_Check(factor))
1894 dnum = (double)PyInt_AsLong(factor);
1895 else
1896 dnum = PyLong_AsDouble(factor);
1897
1898 dnum *= fracpart;
1899 fracpart = modf(dnum, &intpart);
1900 x = PyLong_FromDouble(intpart);
1901 if (x == NULL) {
1902 Py_DECREF(sum);
1903 return NULL;
1904 }
1905
1906 y = PyNumber_Add(sum, x);
1907 Py_DECREF(sum);
1908 Py_DECREF(x);
1909 *leftover += fracpart;
1910 return y;
1911 }
1912
1913 PyErr_Format(PyExc_TypeError,
1914 "unsupported type for timedelta %s component: %s",
Christian Heimese93237d2007-12-19 02:37:44 +00001915 tag, Py_TYPE(num)->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00001916 return NULL;
1917}
1918
1919static PyObject *
1920delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1921{
1922 PyObject *self = NULL;
1923
1924 /* Argument objects. */
1925 PyObject *day = NULL;
1926 PyObject *second = NULL;
1927 PyObject *us = NULL;
1928 PyObject *ms = NULL;
1929 PyObject *minute = NULL;
1930 PyObject *hour = NULL;
1931 PyObject *week = NULL;
1932
1933 PyObject *x = NULL; /* running sum of microseconds */
1934 PyObject *y = NULL; /* temp sum of microseconds */
1935 double leftover_us = 0.0;
1936
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001937 static char *keywords[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00001938 "days", "seconds", "microseconds", "milliseconds",
1939 "minutes", "hours", "weeks", NULL
1940 };
1941
1942 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1943 keywords,
1944 &day, &second, &us,
1945 &ms, &minute, &hour, &week) == 0)
1946 goto Done;
1947
1948 x = PyInt_FromLong(0);
1949 if (x == NULL)
1950 goto Done;
1951
1952#define CLEANUP \
1953 Py_DECREF(x); \
1954 x = y; \
1955 if (x == NULL) \
1956 goto Done
1957
1958 if (us) {
1959 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1960 CLEANUP;
1961 }
1962 if (ms) {
1963 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1964 CLEANUP;
1965 }
1966 if (second) {
1967 y = accum("seconds", x, second, us_per_second, &leftover_us);
1968 CLEANUP;
1969 }
1970 if (minute) {
1971 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1972 CLEANUP;
1973 }
1974 if (hour) {
1975 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1976 CLEANUP;
1977 }
1978 if (day) {
1979 y = accum("days", x, day, us_per_day, &leftover_us);
1980 CLEANUP;
1981 }
1982 if (week) {
1983 y = accum("weeks", x, week, us_per_week, &leftover_us);
1984 CLEANUP;
1985 }
1986 if (leftover_us) {
1987 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001988 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001989 if (temp == NULL) {
1990 Py_DECREF(x);
1991 goto Done;
1992 }
1993 y = PyNumber_Add(x, temp);
1994 Py_DECREF(temp);
1995 CLEANUP;
1996 }
1997
Tim Petersb0c854d2003-05-17 15:57:00 +00001998 self = microseconds_to_delta_ex(x, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001999 Py_DECREF(x);
2000Done:
2001 return self;
2002
2003#undef CLEANUP
2004}
2005
2006static int
2007delta_nonzero(PyDateTime_Delta *self)
2008{
2009 return (GET_TD_DAYS(self) != 0
2010 || GET_TD_SECONDS(self) != 0
2011 || GET_TD_MICROSECONDS(self) != 0);
2012}
2013
2014static PyObject *
2015delta_repr(PyDateTime_Delta *self)
2016{
2017 if (GET_TD_MICROSECONDS(self) != 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002018 return PyString_FromFormat("%s(%d, %d, %d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002019 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002020 GET_TD_DAYS(self),
2021 GET_TD_SECONDS(self),
2022 GET_TD_MICROSECONDS(self));
2023 if (GET_TD_SECONDS(self) != 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002024 return PyString_FromFormat("%s(%d, %d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002025 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002026 GET_TD_DAYS(self),
2027 GET_TD_SECONDS(self));
2028
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002029 return PyString_FromFormat("%s(%d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002030 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002031 GET_TD_DAYS(self));
2032}
2033
2034static PyObject *
2035delta_str(PyDateTime_Delta *self)
2036{
2037 int days = GET_TD_DAYS(self);
2038 int seconds = GET_TD_SECONDS(self);
2039 int us = GET_TD_MICROSECONDS(self);
2040 int hours;
2041 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00002042 char buf[100];
2043 char *pbuf = buf;
2044 size_t buflen = sizeof(buf);
2045 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002046
2047 minutes = divmod(seconds, 60, &seconds);
2048 hours = divmod(minutes, 60, &minutes);
2049
2050 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00002051 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2052 (days == 1 || days == -1) ? "" : "s");
2053 if (n < 0 || (size_t)n >= buflen)
2054 goto Fail;
2055 pbuf += n;
2056 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002057 }
2058
Tim Petersba873472002-12-18 20:19:21 +00002059 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2060 hours, minutes, seconds);
2061 if (n < 0 || (size_t)n >= buflen)
2062 goto Fail;
2063 pbuf += n;
2064 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002065
2066 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00002067 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2068 if (n < 0 || (size_t)n >= buflen)
2069 goto Fail;
2070 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002071 }
2072
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002073 return PyString_FromStringAndSize(buf, pbuf - buf);
Tim Petersba873472002-12-18 20:19:21 +00002074
2075 Fail:
2076 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2077 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002078}
2079
Tim Peters371935f2003-02-01 01:52:50 +00002080/* Pickle support, a simple use of __reduce__. */
2081
Tim Petersb57f8f02003-02-01 02:54:15 +00002082/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002083static PyObject *
2084delta_getstate(PyDateTime_Delta *self)
2085{
2086 return Py_BuildValue("iii", GET_TD_DAYS(self),
2087 GET_TD_SECONDS(self),
2088 GET_TD_MICROSECONDS(self));
2089}
2090
Tim Peters2a799bf2002-12-16 20:18:38 +00002091static PyObject *
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002092delta_total_seconds(PyObject *self)
2093{
2094 return PyFloat_FromDouble(GET_TD_MICROSECONDS(self) / 1000000.0 +
2095 GET_TD_SECONDS(self) +
2096 GET_TD_DAYS(self) * 24.0 * 3600.0);
2097}
2098
2099static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002100delta_reduce(PyDateTime_Delta* self)
2101{
Christian Heimese93237d2007-12-19 02:37:44 +00002102 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002103}
2104
2105#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2106
2107static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002108
Neal Norwitzdfb80862002-12-19 02:30:56 +00002109 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002110 PyDoc_STR("Number of days.")},
2111
Neal Norwitzdfb80862002-12-19 02:30:56 +00002112 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002113 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2114
Neal Norwitzdfb80862002-12-19 02:30:56 +00002115 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002116 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2117 {NULL}
2118};
2119
2120static PyMethodDef delta_methods[] = {
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002121 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2122 PyDoc_STR("Total seconds in the duration.")},
2123
2124 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
Guido van Rossum177e41a2003-01-30 22:06:23 +00002125 PyDoc_STR("__reduce__() -> (cls, state)")},
2126
Tim Peters2a799bf2002-12-16 20:18:38 +00002127 {NULL, NULL},
2128};
2129
2130static char delta_doc[] =
2131PyDoc_STR("Difference between two datetime values.");
2132
2133static PyNumberMethods delta_as_number = {
2134 delta_add, /* nb_add */
2135 delta_subtract, /* nb_subtract */
2136 delta_multiply, /* nb_multiply */
2137 delta_divide, /* nb_divide */
2138 0, /* nb_remainder */
2139 0, /* nb_divmod */
2140 0, /* nb_power */
2141 (unaryfunc)delta_negative, /* nb_negative */
2142 (unaryfunc)delta_positive, /* nb_positive */
2143 (unaryfunc)delta_abs, /* nb_absolute */
2144 (inquiry)delta_nonzero, /* nb_nonzero */
2145 0, /*nb_invert*/
2146 0, /*nb_lshift*/
2147 0, /*nb_rshift*/
2148 0, /*nb_and*/
2149 0, /*nb_xor*/
2150 0, /*nb_or*/
2151 0, /*nb_coerce*/
2152 0, /*nb_int*/
2153 0, /*nb_long*/
2154 0, /*nb_float*/
2155 0, /*nb_oct*/
2156 0, /*nb_hex*/
2157 0, /*nb_inplace_add*/
2158 0, /*nb_inplace_subtract*/
2159 0, /*nb_inplace_multiply*/
2160 0, /*nb_inplace_divide*/
2161 0, /*nb_inplace_remainder*/
2162 0, /*nb_inplace_power*/
2163 0, /*nb_inplace_lshift*/
2164 0, /*nb_inplace_rshift*/
2165 0, /*nb_inplace_and*/
2166 0, /*nb_inplace_xor*/
2167 0, /*nb_inplace_or*/
2168 delta_divide, /* nb_floor_divide */
2169 0, /* nb_true_divide */
2170 0, /* nb_inplace_floor_divide */
2171 0, /* nb_inplace_true_divide */
2172};
2173
2174static PyTypeObject PyDateTime_DeltaType = {
Martin v. Löwis68192102007-07-21 06:55:02 +00002175 PyVarObject_HEAD_INIT(NULL, 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00002176 "datetime.timedelta", /* tp_name */
2177 sizeof(PyDateTime_Delta), /* tp_basicsize */
2178 0, /* tp_itemsize */
2179 0, /* tp_dealloc */
2180 0, /* tp_print */
2181 0, /* tp_getattr */
2182 0, /* tp_setattr */
2183 0, /* tp_compare */
2184 (reprfunc)delta_repr, /* tp_repr */
2185 &delta_as_number, /* tp_as_number */
2186 0, /* tp_as_sequence */
2187 0, /* tp_as_mapping */
2188 (hashfunc)delta_hash, /* tp_hash */
2189 0, /* tp_call */
2190 (reprfunc)delta_str, /* tp_str */
2191 PyObject_GenericGetAttr, /* tp_getattro */
2192 0, /* tp_setattro */
2193 0, /* tp_as_buffer */
Tim Petersb0c854d2003-05-17 15:57:00 +00002194 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2195 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters2a799bf2002-12-16 20:18:38 +00002196 delta_doc, /* tp_doc */
2197 0, /* tp_traverse */
2198 0, /* tp_clear */
2199 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2200 0, /* tp_weaklistoffset */
2201 0, /* tp_iter */
2202 0, /* tp_iternext */
2203 delta_methods, /* tp_methods */
2204 delta_members, /* tp_members */
2205 0, /* tp_getset */
2206 0, /* tp_base */
2207 0, /* tp_dict */
2208 0, /* tp_descr_get */
2209 0, /* tp_descr_set */
2210 0, /* tp_dictoffset */
2211 0, /* tp_init */
2212 0, /* tp_alloc */
2213 delta_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002214 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002215};
2216
2217/*
2218 * PyDateTime_Date implementation.
2219 */
2220
2221/* Accessor properties. */
2222
2223static PyObject *
2224date_year(PyDateTime_Date *self, void *unused)
2225{
2226 return PyInt_FromLong(GET_YEAR(self));
2227}
2228
2229static PyObject *
2230date_month(PyDateTime_Date *self, void *unused)
2231{
2232 return PyInt_FromLong(GET_MONTH(self));
2233}
2234
2235static PyObject *
2236date_day(PyDateTime_Date *self, void *unused)
2237{
2238 return PyInt_FromLong(GET_DAY(self));
2239}
2240
2241static PyGetSetDef date_getset[] = {
2242 {"year", (getter)date_year},
2243 {"month", (getter)date_month},
2244 {"day", (getter)date_day},
2245 {NULL}
2246};
2247
2248/* Constructors. */
2249
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002250static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002251
Tim Peters2a799bf2002-12-16 20:18:38 +00002252static PyObject *
2253date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2254{
2255 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002256 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002257 int year;
2258 int month;
2259 int day;
2260
Guido van Rossum177e41a2003-01-30 22:06:23 +00002261 /* Check for invocation from pickle with __getstate__ state */
2262 if (PyTuple_GET_SIZE(args) == 1 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002263 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2264 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2265 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00002266 {
Tim Peters70533e22003-02-01 04:40:04 +00002267 PyDateTime_Date *me;
2268
Tim Peters604c0132004-06-07 23:04:33 +00002269 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
Tim Peters70533e22003-02-01 04:40:04 +00002270 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002271 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00002272 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2273 me->hashcode = -1;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002274 }
Tim Peters70533e22003-02-01 04:40:04 +00002275 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002276 }
2277
Tim Peters12bf3392002-12-24 05:41:27 +00002278 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002279 &year, &month, &day)) {
2280 if (check_date_args(year, month, day) < 0)
2281 return NULL;
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002282 self = new_date_ex(year, month, day, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00002283 }
2284 return self;
2285}
2286
2287/* Return new date from localtime(t). */
2288static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002289date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002290{
2291 struct tm *tm;
Tim Peters1b6f7a92004-06-20 02:50:16 +00002292 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002293 PyObject *result = NULL;
2294
Tim Peters1b6f7a92004-06-20 02:50:16 +00002295 t = _PyTime_DoubleToTimet(ts);
2296 if (t == (time_t)-1 && PyErr_Occurred())
2297 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002298 tm = localtime(&t);
2299 if (tm)
2300 result = PyObject_CallFunction(cls, "iii",
2301 tm->tm_year + 1900,
2302 tm->tm_mon + 1,
2303 tm->tm_mday);
2304 else
2305 PyErr_SetString(PyExc_ValueError,
2306 "timestamp out of range for "
2307 "platform localtime() function");
2308 return result;
2309}
2310
2311/* Return new date from current time.
2312 * We say this is equivalent to fromtimestamp(time.time()), and the
2313 * only way to be sure of that is to *call* time.time(). That's not
2314 * generally the same as calling C's time.
2315 */
2316static PyObject *
2317date_today(PyObject *cls, PyObject *dummy)
2318{
2319 PyObject *time;
2320 PyObject *result;
2321
2322 time = time_time();
2323 if (time == NULL)
2324 return NULL;
2325
2326 /* Note well: today() is a class method, so this may not call
2327 * date.fromtimestamp. For example, it may call
2328 * datetime.fromtimestamp. That's why we need all the accuracy
2329 * time.time() delivers; if someone were gonzo about optimization,
2330 * date.today() could get away with plain C time().
2331 */
2332 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2333 Py_DECREF(time);
2334 return result;
2335}
2336
2337/* Return new date from given timestamp (Python timestamp -- a double). */
2338static PyObject *
2339date_fromtimestamp(PyObject *cls, PyObject *args)
2340{
2341 double timestamp;
2342 PyObject *result = NULL;
2343
2344 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
Tim Peters1b6f7a92004-06-20 02:50:16 +00002345 result = date_local_from_time_t(cls, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002346 return result;
2347}
2348
2349/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2350 * the ordinal is out of range.
2351 */
2352static PyObject *
2353date_fromordinal(PyObject *cls, PyObject *args)
2354{
2355 PyObject *result = NULL;
2356 int ordinal;
2357
2358 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2359 int year;
2360 int month;
2361 int day;
2362
2363 if (ordinal < 1)
2364 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2365 ">= 1");
2366 else {
2367 ord_to_ymd(ordinal, &year, &month, &day);
2368 result = PyObject_CallFunction(cls, "iii",
2369 year, month, day);
2370 }
2371 }
2372 return result;
2373}
2374
2375/*
2376 * Date arithmetic.
2377 */
2378
2379/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2380 * instead.
2381 */
2382static PyObject *
2383add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2384{
2385 PyObject *result = NULL;
2386 int year = GET_YEAR(date);
2387 int month = GET_MONTH(date);
2388 int deltadays = GET_TD_DAYS(delta);
2389 /* C-level overflow is impossible because |deltadays| < 1e9. */
2390 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2391
2392 if (normalize_date(&year, &month, &day) >= 0)
2393 result = new_date(year, month, day);
2394 return result;
2395}
2396
2397static PyObject *
2398date_add(PyObject *left, PyObject *right)
2399{
2400 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2401 Py_INCREF(Py_NotImplemented);
2402 return Py_NotImplemented;
2403 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002404 if (PyDate_Check(left)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002405 /* date + ??? */
2406 if (PyDelta_Check(right))
2407 /* date + delta */
2408 return add_date_timedelta((PyDateTime_Date *) left,
2409 (PyDateTime_Delta *) right,
2410 0);
2411 }
2412 else {
2413 /* ??? + date
2414 * 'right' must be one of us, or we wouldn't have been called
2415 */
2416 if (PyDelta_Check(left))
2417 /* delta + date */
2418 return add_date_timedelta((PyDateTime_Date *) right,
2419 (PyDateTime_Delta *) left,
2420 0);
2421 }
2422 Py_INCREF(Py_NotImplemented);
2423 return Py_NotImplemented;
2424}
2425
2426static PyObject *
2427date_subtract(PyObject *left, PyObject *right)
2428{
2429 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2430 Py_INCREF(Py_NotImplemented);
2431 return Py_NotImplemented;
2432 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002433 if (PyDate_Check(left)) {
2434 if (PyDate_Check(right)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002435 /* date - date */
2436 int left_ord = ymd_to_ord(GET_YEAR(left),
2437 GET_MONTH(left),
2438 GET_DAY(left));
2439 int right_ord = ymd_to_ord(GET_YEAR(right),
2440 GET_MONTH(right),
2441 GET_DAY(right));
2442 return new_delta(left_ord - right_ord, 0, 0, 0);
2443 }
2444 if (PyDelta_Check(right)) {
2445 /* date - delta */
2446 return add_date_timedelta((PyDateTime_Date *) left,
2447 (PyDateTime_Delta *) right,
2448 1);
2449 }
2450 }
2451 Py_INCREF(Py_NotImplemented);
2452 return Py_NotImplemented;
2453}
2454
2455
2456/* Various ways to turn a date into a string. */
2457
2458static PyObject *
2459date_repr(PyDateTime_Date *self)
2460{
2461 char buffer[1028];
Skip Montanaro14f88992006-04-18 19:35:04 +00002462 const char *type_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002463
Christian Heimese93237d2007-12-19 02:37:44 +00002464 type_name = Py_TYPE(self)->tp_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002465 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00002466 type_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002467 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2468
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002469 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002470}
2471
2472static PyObject *
2473date_isoformat(PyDateTime_Date *self)
2474{
2475 char buffer[128];
2476
2477 isoformat_date(self, buffer, sizeof(buffer));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002478 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002479}
2480
Tim Peterse2df5ff2003-05-02 18:39:55 +00002481/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002482static PyObject *
2483date_str(PyDateTime_Date *self)
2484{
2485 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2486}
2487
2488
2489static PyObject *
2490date_ctime(PyDateTime_Date *self)
2491{
2492 return format_ctime(self, 0, 0, 0);
2493}
2494
2495static PyObject *
2496date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2497{
2498 /* This method can be inherited, and needs to call the
2499 * timetuple() method appropriate to self's class.
2500 */
2501 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002502 PyObject *tuple;
Gregory P. Smith137d8242008-06-02 04:05:52 +00002503 const char *format;
2504 Py_ssize_t format_len;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002505 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002506
Gregory P. Smith137d8242008-06-02 04:05:52 +00002507 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2508 &format, &format_len))
Tim Peters2a799bf2002-12-16 20:18:38 +00002509 return NULL;
2510
2511 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2512 if (tuple == NULL)
2513 return NULL;
Gregory P. Smith137d8242008-06-02 04:05:52 +00002514 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
Tim Petersbad8ff02002-12-30 20:52:32 +00002515 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002516 Py_DECREF(tuple);
2517 return result;
2518}
2519
Eric Smitha9f7d622008-02-17 19:46:49 +00002520static PyObject *
2521date_format(PyDateTime_Date *self, PyObject *args)
2522{
2523 PyObject *format;
2524
2525 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2526 return NULL;
2527
2528 /* Check for str or unicode */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002529 if (PyString_Check(format)) {
Eric Smitha9f7d622008-02-17 19:46:49 +00002530 /* If format is zero length, return str(self) */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002531 if (PyString_GET_SIZE(format) == 0)
Eric Smitha9f7d622008-02-17 19:46:49 +00002532 return PyObject_Str((PyObject *)self);
2533 } else if (PyUnicode_Check(format)) {
2534 /* If format is zero length, return str(self) */
2535 if (PyUnicode_GET_SIZE(format) == 0)
2536 return PyObject_Unicode((PyObject *)self);
2537 } else {
2538 PyErr_Format(PyExc_ValueError,
2539 "__format__ expects str or unicode, not %.200s",
2540 Py_TYPE(format)->tp_name);
2541 return NULL;
2542 }
2543 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2544}
2545
Tim Peters2a799bf2002-12-16 20:18:38 +00002546/* ISO methods. */
2547
2548static PyObject *
2549date_isoweekday(PyDateTime_Date *self)
2550{
2551 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2552
2553 return PyInt_FromLong(dow + 1);
2554}
2555
2556static PyObject *
2557date_isocalendar(PyDateTime_Date *self)
2558{
2559 int year = GET_YEAR(self);
2560 int week1_monday = iso_week1_monday(year);
2561 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2562 int week;
2563 int day;
2564
2565 week = divmod(today - week1_monday, 7, &day);
2566 if (week < 0) {
2567 --year;
2568 week1_monday = iso_week1_monday(year);
2569 week = divmod(today - week1_monday, 7, &day);
2570 }
2571 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2572 ++year;
2573 week = 0;
2574 }
2575 return Py_BuildValue("iii", year, week + 1, day + 1);
2576}
2577
2578/* Miscellaneous methods. */
2579
2580/* This is more natural as a tp_compare, but doesn't work then: for whatever
2581 * reason, Python's try_3way_compare ignores tp_compare unless
2582 * PyInstance_Check returns true, but these aren't old-style classes.
2583 */
2584static PyObject *
2585date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2586{
Tim Peters07534a62003-02-07 22:50:28 +00002587 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002588
Tim Peters07534a62003-02-07 22:50:28 +00002589 if (PyDate_Check(other))
2590 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2591 _PyDateTime_DATE_DATASIZE);
2592
2593 else if (PyObject_HasAttrString(other, "timetuple")) {
2594 /* A hook for other kinds of date objects. */
2595 Py_INCREF(Py_NotImplemented);
2596 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002597 }
Tim Peters07534a62003-02-07 22:50:28 +00002598 else if (op == Py_EQ || op == Py_NE)
2599 diff = 1; /* any non-zero value will do */
2600
2601 else /* stop this from falling back to address comparison */
2602 return cmperror((PyObject *)self, other);
2603
Tim Peters2a799bf2002-12-16 20:18:38 +00002604 return diff_to_bool(diff, op);
2605}
2606
2607static PyObject *
2608date_timetuple(PyDateTime_Date *self)
2609{
2610 return build_struct_time(GET_YEAR(self),
2611 GET_MONTH(self),
2612 GET_DAY(self),
2613 0, 0, 0, -1);
2614}
2615
Tim Peters12bf3392002-12-24 05:41:27 +00002616static PyObject *
2617date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2618{
2619 PyObject *clone;
2620 PyObject *tuple;
2621 int year = GET_YEAR(self);
2622 int month = GET_MONTH(self);
2623 int day = GET_DAY(self);
2624
2625 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2626 &year, &month, &day))
2627 return NULL;
2628 tuple = Py_BuildValue("iii", year, month, day);
2629 if (tuple == NULL)
2630 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00002631 clone = date_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00002632 Py_DECREF(tuple);
2633 return clone;
2634}
2635
Tim Peters2a799bf2002-12-16 20:18:38 +00002636static PyObject *date_getstate(PyDateTime_Date *self);
2637
2638static long
2639date_hash(PyDateTime_Date *self)
2640{
2641 if (self->hashcode == -1) {
2642 PyObject *temp = date_getstate(self);
2643 if (temp != NULL) {
2644 self->hashcode = PyObject_Hash(temp);
2645 Py_DECREF(temp);
2646 }
2647 }
2648 return self->hashcode;
2649}
2650
2651static PyObject *
2652date_toordinal(PyDateTime_Date *self)
2653{
2654 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2655 GET_DAY(self)));
2656}
2657
2658static PyObject *
2659date_weekday(PyDateTime_Date *self)
2660{
2661 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2662
2663 return PyInt_FromLong(dow);
2664}
2665
Tim Peters371935f2003-02-01 01:52:50 +00002666/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002667
Tim Petersb57f8f02003-02-01 02:54:15 +00002668/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002669static PyObject *
2670date_getstate(PyDateTime_Date *self)
2671{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002672 return Py_BuildValue(
2673 "(N)",
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002674 PyString_FromStringAndSize((char *)self->data,
Guido van Rossum177e41a2003-01-30 22:06:23 +00002675 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002676}
2677
2678static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002679date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002680{
Christian Heimese93237d2007-12-19 02:37:44 +00002681 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002682}
2683
2684static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002685
Tim Peters2a799bf2002-12-16 20:18:38 +00002686 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002687
Tim Peters2a799bf2002-12-16 20:18:38 +00002688 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2689 METH_CLASS,
2690 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2691 "time.time()).")},
2692
2693 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2694 METH_CLASS,
2695 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2696 "ordinal.")},
2697
2698 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2699 PyDoc_STR("Current date or datetime: same as "
2700 "self.__class__.fromtimestamp(time.time()).")},
2701
2702 /* Instance methods: */
2703
2704 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2705 PyDoc_STR("Return ctime() style string.")},
2706
Neal Norwitza84dcd72007-05-22 07:16:44 +00002707 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00002708 PyDoc_STR("format -> strftime() style string.")},
2709
Eric Smitha9f7d622008-02-17 19:46:49 +00002710 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2711 PyDoc_STR("Formats self with strftime.")},
2712
Tim Peters2a799bf2002-12-16 20:18:38 +00002713 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2714 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2715
2716 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2717 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2718 "weekday.")},
2719
2720 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2721 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2722
2723 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2724 PyDoc_STR("Return the day of the week represented by the date.\n"
2725 "Monday == 1 ... Sunday == 7")},
2726
2727 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2728 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2729 "1 is day 1.")},
2730
2731 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2732 PyDoc_STR("Return the day of the week represented by the date.\n"
2733 "Monday == 0 ... Sunday == 6")},
2734
Neal Norwitza84dcd72007-05-22 07:16:44 +00002735 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
Tim Peters12bf3392002-12-24 05:41:27 +00002736 PyDoc_STR("Return date with new specified fields.")},
2737
Guido van Rossum177e41a2003-01-30 22:06:23 +00002738 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2739 PyDoc_STR("__reduce__() -> (cls, state)")},
2740
Tim Peters2a799bf2002-12-16 20:18:38 +00002741 {NULL, NULL}
2742};
2743
2744static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002745PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002746
2747static PyNumberMethods date_as_number = {
2748 date_add, /* nb_add */
2749 date_subtract, /* nb_subtract */
2750 0, /* nb_multiply */
2751 0, /* nb_divide */
2752 0, /* nb_remainder */
2753 0, /* nb_divmod */
2754 0, /* nb_power */
2755 0, /* nb_negative */
2756 0, /* nb_positive */
2757 0, /* nb_absolute */
2758 0, /* nb_nonzero */
2759};
2760
2761static PyTypeObject PyDateTime_DateType = {
Martin v. Löwis68192102007-07-21 06:55:02 +00002762 PyVarObject_HEAD_INIT(NULL, 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00002763 "datetime.date", /* tp_name */
2764 sizeof(PyDateTime_Date), /* tp_basicsize */
2765 0, /* tp_itemsize */
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002766 0, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00002767 0, /* tp_print */
2768 0, /* tp_getattr */
2769 0, /* tp_setattr */
2770 0, /* tp_compare */
2771 (reprfunc)date_repr, /* tp_repr */
2772 &date_as_number, /* tp_as_number */
2773 0, /* tp_as_sequence */
2774 0, /* tp_as_mapping */
2775 (hashfunc)date_hash, /* tp_hash */
2776 0, /* tp_call */
2777 (reprfunc)date_str, /* tp_str */
2778 PyObject_GenericGetAttr, /* tp_getattro */
2779 0, /* tp_setattro */
2780 0, /* tp_as_buffer */
2781 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2782 Py_TPFLAGS_BASETYPE, /* tp_flags */
2783 date_doc, /* tp_doc */
2784 0, /* tp_traverse */
2785 0, /* tp_clear */
2786 (richcmpfunc)date_richcompare, /* tp_richcompare */
2787 0, /* tp_weaklistoffset */
2788 0, /* tp_iter */
2789 0, /* tp_iternext */
2790 date_methods, /* tp_methods */
2791 0, /* tp_members */
2792 date_getset, /* tp_getset */
2793 0, /* tp_base */
2794 0, /* tp_dict */
2795 0, /* tp_descr_get */
2796 0, /* tp_descr_set */
2797 0, /* tp_dictoffset */
2798 0, /* tp_init */
2799 0, /* tp_alloc */
2800 date_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002801 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002802};
2803
2804/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002805 * PyDateTime_TZInfo implementation.
2806 */
2807
2808/* This is a pure abstract base class, so doesn't do anything beyond
2809 * raising NotImplemented exceptions. Real tzinfo classes need
2810 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002811 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002812 * be subclasses of this tzinfo class, which is easy and quick to check).
2813 *
2814 * Note: For reasons having to do with pickling of subclasses, we have
2815 * to allow tzinfo objects to be instantiated. This wasn't an issue
2816 * in the Python implementation (__init__() could raise NotImplementedError
2817 * there without ill effect), but doing so in the C implementation hit a
2818 * brick wall.
2819 */
2820
2821static PyObject *
2822tzinfo_nogo(const char* methodname)
2823{
2824 PyErr_Format(PyExc_NotImplementedError,
2825 "a tzinfo subclass must implement %s()",
2826 methodname);
2827 return NULL;
2828}
2829
2830/* Methods. A subclass must implement these. */
2831
Tim Peters52dcce22003-01-23 16:36:11 +00002832static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002833tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2834{
2835 return tzinfo_nogo("tzname");
2836}
2837
Tim Peters52dcce22003-01-23 16:36:11 +00002838static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002839tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2840{
2841 return tzinfo_nogo("utcoffset");
2842}
2843
Tim Peters52dcce22003-01-23 16:36:11 +00002844static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002845tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2846{
2847 return tzinfo_nogo("dst");
2848}
2849
Tim Peters52dcce22003-01-23 16:36:11 +00002850static PyObject *
2851tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2852{
2853 int y, m, d, hh, mm, ss, us;
2854
2855 PyObject *result;
2856 int off, dst;
2857 int none;
2858 int delta;
2859
2860 if (! PyDateTime_Check(dt)) {
2861 PyErr_SetString(PyExc_TypeError,
2862 "fromutc: argument must be a datetime");
2863 return NULL;
2864 }
2865 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2866 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2867 "is not self");
2868 return NULL;
2869 }
2870
2871 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2872 if (off == -1 && PyErr_Occurred())
2873 return NULL;
2874 if (none) {
2875 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2876 "utcoffset() result required");
2877 return NULL;
2878 }
2879
2880 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2881 if (dst == -1 && PyErr_Occurred())
2882 return NULL;
2883 if (none) {
2884 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2885 "dst() result required");
2886 return NULL;
2887 }
2888
2889 y = GET_YEAR(dt);
2890 m = GET_MONTH(dt);
2891 d = GET_DAY(dt);
2892 hh = DATE_GET_HOUR(dt);
2893 mm = DATE_GET_MINUTE(dt);
2894 ss = DATE_GET_SECOND(dt);
2895 us = DATE_GET_MICROSECOND(dt);
2896
2897 delta = off - dst;
2898 mm += delta;
2899 if ((mm < 0 || mm >= 60) &&
2900 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002901 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002902 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2903 if (result == NULL)
2904 return result;
2905
2906 dst = call_dst(dt->tzinfo, result, &none);
2907 if (dst == -1 && PyErr_Occurred())
2908 goto Fail;
2909 if (none)
2910 goto Inconsistent;
2911 if (dst == 0)
2912 return result;
2913
2914 mm += dst;
2915 if ((mm < 0 || mm >= 60) &&
2916 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2917 goto Fail;
2918 Py_DECREF(result);
2919 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2920 return result;
2921
2922Inconsistent:
2923 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2924 "inconsistent results; cannot convert");
2925
2926 /* fall thru to failure */
2927Fail:
2928 Py_DECREF(result);
2929 return NULL;
2930}
2931
Tim Peters2a799bf2002-12-16 20:18:38 +00002932/*
2933 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002934 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002935 */
2936
Guido van Rossum177e41a2003-01-30 22:06:23 +00002937static PyObject *
2938tzinfo_reduce(PyObject *self)
2939{
2940 PyObject *args, *state, *tmp;
2941 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002942
Guido van Rossum177e41a2003-01-30 22:06:23 +00002943 tmp = PyTuple_New(0);
2944 if (tmp == NULL)
2945 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002946
Guido van Rossum177e41a2003-01-30 22:06:23 +00002947 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2948 if (getinitargs != NULL) {
2949 args = PyObject_CallObject(getinitargs, tmp);
2950 Py_DECREF(getinitargs);
2951 if (args == NULL) {
2952 Py_DECREF(tmp);
2953 return NULL;
2954 }
2955 }
2956 else {
2957 PyErr_Clear();
2958 args = tmp;
2959 Py_INCREF(args);
2960 }
2961
2962 getstate = PyObject_GetAttrString(self, "__getstate__");
2963 if (getstate != NULL) {
2964 state = PyObject_CallObject(getstate, tmp);
2965 Py_DECREF(getstate);
2966 if (state == NULL) {
2967 Py_DECREF(args);
2968 Py_DECREF(tmp);
2969 return NULL;
2970 }
2971 }
2972 else {
2973 PyObject **dictptr;
2974 PyErr_Clear();
2975 state = Py_None;
2976 dictptr = _PyObject_GetDictPtr(self);
2977 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2978 state = *dictptr;
2979 Py_INCREF(state);
2980 }
2981
2982 Py_DECREF(tmp);
2983
2984 if (state == Py_None) {
2985 Py_DECREF(state);
Christian Heimese93237d2007-12-19 02:37:44 +00002986 return Py_BuildValue("(ON)", Py_TYPE(self), args);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002987 }
2988 else
Christian Heimese93237d2007-12-19 02:37:44 +00002989 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002990}
Tim Peters2a799bf2002-12-16 20:18:38 +00002991
2992static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002993
Tim Peters2a799bf2002-12-16 20:18:38 +00002994 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
2995 PyDoc_STR("datetime -> string name of time zone.")},
2996
2997 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
2998 PyDoc_STR("datetime -> minutes east of UTC (negative for "
2999 "west of UTC).")},
3000
3001 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3002 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3003
Tim Peters52dcce22003-01-23 16:36:11 +00003004 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
3005 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3006
Guido van Rossum177e41a2003-01-30 22:06:23 +00003007 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3008 PyDoc_STR("-> (cls, state)")},
3009
Tim Peters2a799bf2002-12-16 20:18:38 +00003010 {NULL, NULL}
3011};
3012
3013static char tzinfo_doc[] =
3014PyDoc_STR("Abstract base class for time zone info objects.");
3015
Neal Norwitzce3d34d2003-02-04 20:45:17 +00003016statichere PyTypeObject PyDateTime_TZInfoType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003017 PyObject_HEAD_INIT(NULL)
3018 0, /* ob_size */
3019 "datetime.tzinfo", /* tp_name */
3020 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3021 0, /* tp_itemsize */
3022 0, /* tp_dealloc */
3023 0, /* tp_print */
3024 0, /* tp_getattr */
3025 0, /* tp_setattr */
3026 0, /* tp_compare */
3027 0, /* tp_repr */
3028 0, /* tp_as_number */
3029 0, /* tp_as_sequence */
3030 0, /* tp_as_mapping */
3031 0, /* tp_hash */
3032 0, /* tp_call */
3033 0, /* tp_str */
3034 PyObject_GenericGetAttr, /* tp_getattro */
3035 0, /* tp_setattro */
3036 0, /* tp_as_buffer */
3037 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3038 Py_TPFLAGS_BASETYPE, /* tp_flags */
3039 tzinfo_doc, /* tp_doc */
3040 0, /* tp_traverse */
3041 0, /* tp_clear */
3042 0, /* tp_richcompare */
3043 0, /* tp_weaklistoffset */
3044 0, /* tp_iter */
3045 0, /* tp_iternext */
3046 tzinfo_methods, /* tp_methods */
3047 0, /* tp_members */
3048 0, /* tp_getset */
3049 0, /* tp_base */
3050 0, /* tp_dict */
3051 0, /* tp_descr_get */
3052 0, /* tp_descr_set */
3053 0, /* tp_dictoffset */
3054 0, /* tp_init */
3055 0, /* tp_alloc */
3056 PyType_GenericNew, /* tp_new */
3057 0, /* tp_free */
3058};
3059
3060/*
Tim Peters37f39822003-01-10 03:49:02 +00003061 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003062 */
3063
Tim Peters37f39822003-01-10 03:49:02 +00003064/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003065 */
3066
3067static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003068time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003069{
Tim Peters37f39822003-01-10 03:49:02 +00003070 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003071}
3072
Tim Peters37f39822003-01-10 03:49:02 +00003073static PyObject *
3074time_minute(PyDateTime_Time *self, void *unused)
3075{
3076 return PyInt_FromLong(TIME_GET_MINUTE(self));
3077}
3078
3079/* The name time_second conflicted with some platform header file. */
3080static PyObject *
3081py_time_second(PyDateTime_Time *self, void *unused)
3082{
3083 return PyInt_FromLong(TIME_GET_SECOND(self));
3084}
3085
3086static PyObject *
3087time_microsecond(PyDateTime_Time *self, void *unused)
3088{
3089 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3090}
3091
3092static PyObject *
3093time_tzinfo(PyDateTime_Time *self, void *unused)
3094{
Tim Petersa032d2e2003-01-11 00:15:54 +00003095 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00003096 Py_INCREF(result);
3097 return result;
3098}
3099
3100static PyGetSetDef time_getset[] = {
3101 {"hour", (getter)time_hour},
3102 {"minute", (getter)time_minute},
3103 {"second", (getter)py_time_second},
3104 {"microsecond", (getter)time_microsecond},
3105 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003106 {NULL}
3107};
3108
3109/*
3110 * Constructors.
3111 */
3112
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003113static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Tim Peters37f39822003-01-10 03:49:02 +00003114 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003115
Tim Peters2a799bf2002-12-16 20:18:38 +00003116static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003117time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003118{
3119 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003120 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003121 int hour = 0;
3122 int minute = 0;
3123 int second = 0;
3124 int usecond = 0;
3125 PyObject *tzinfo = Py_None;
3126
Guido van Rossum177e41a2003-01-30 22:06:23 +00003127 /* Check for invocation from pickle with __getstate__ state */
3128 if (PyTuple_GET_SIZE(args) >= 1 &&
3129 PyTuple_GET_SIZE(args) <= 2 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003130 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3131 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3132 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003133 {
Tim Peters70533e22003-02-01 04:40:04 +00003134 PyDateTime_Time *me;
3135 char aware;
3136
3137 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003138 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003139 if (check_tzinfo_subclass(tzinfo) < 0) {
3140 PyErr_SetString(PyExc_TypeError, "bad "
3141 "tzinfo state arg");
3142 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003143 }
3144 }
Tim Peters70533e22003-02-01 04:40:04 +00003145 aware = (char)(tzinfo != Py_None);
Tim Peters604c0132004-06-07 23:04:33 +00003146 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
Tim Peters70533e22003-02-01 04:40:04 +00003147 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003148 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003149
3150 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3151 me->hashcode = -1;
3152 me->hastzinfo = aware;
3153 if (aware) {
3154 Py_INCREF(tzinfo);
3155 me->tzinfo = tzinfo;
3156 }
3157 }
3158 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003159 }
3160
Tim Peters37f39822003-01-10 03:49:02 +00003161 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003162 &hour, &minute, &second, &usecond,
3163 &tzinfo)) {
3164 if (check_time_args(hour, minute, second, usecond) < 0)
3165 return NULL;
3166 if (check_tzinfo_subclass(tzinfo) < 0)
3167 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003168 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3169 type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003170 }
3171 return self;
3172}
3173
3174/*
3175 * Destructor.
3176 */
3177
3178static void
Tim Peters37f39822003-01-10 03:49:02 +00003179time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003180{
Tim Petersa032d2e2003-01-11 00:15:54 +00003181 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003182 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003183 }
Christian Heimese93237d2007-12-19 02:37:44 +00003184 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003185}
3186
3187/*
Tim Peters855fe882002-12-22 03:43:39 +00003188 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003189 */
3190
Tim Peters2a799bf2002-12-16 20:18:38 +00003191/* These are all METH_NOARGS, so don't need to check the arglist. */
3192static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003193time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003194 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003195 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003196}
3197
3198static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003199time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003200 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003201 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003202}
3203
3204static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003205time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003206 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003207 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003208}
3209
3210/*
Tim Peters37f39822003-01-10 03:49:02 +00003211 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003212 */
3213
3214static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003215time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003216{
Tim Peters37f39822003-01-10 03:49:02 +00003217 char buffer[100];
Christian Heimese93237d2007-12-19 02:37:44 +00003218 const char *type_name = Py_TYPE(self)->tp_name;
Tim Peters37f39822003-01-10 03:49:02 +00003219 int h = TIME_GET_HOUR(self);
3220 int m = TIME_GET_MINUTE(self);
3221 int s = TIME_GET_SECOND(self);
3222 int us = TIME_GET_MICROSECOND(self);
3223 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003224
Tim Peters37f39822003-01-10 03:49:02 +00003225 if (us)
3226 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003227 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
Tim Peters37f39822003-01-10 03:49:02 +00003228 else if (s)
3229 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003230 "%s(%d, %d, %d)", type_name, h, m, s);
Tim Peters37f39822003-01-10 03:49:02 +00003231 else
3232 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003233 "%s(%d, %d)", type_name, h, m);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003234 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003235 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003236 result = append_keyword_tzinfo(result, self->tzinfo);
3237 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003238}
3239
Tim Peters37f39822003-01-10 03:49:02 +00003240static PyObject *
3241time_str(PyDateTime_Time *self)
3242{
3243 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3244}
Tim Peters2a799bf2002-12-16 20:18:38 +00003245
3246static PyObject *
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003247time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003248{
3249 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003250 PyObject *result;
3251 /* Reuse the time format code from the datetime type. */
3252 PyDateTime_DateTime datetime;
3253 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003254
Tim Peters37f39822003-01-10 03:49:02 +00003255 /* Copy over just the time bytes. */
3256 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3257 self->data,
3258 _PyDateTime_TIME_DATASIZE);
3259
3260 isoformat_time(pdatetime, buf, sizeof(buf));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003261 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003262 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003263 return result;
3264
3265 /* We need to append the UTC offset. */
3266 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003267 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003268 Py_DECREF(result);
3269 return NULL;
3270 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003271 PyString_ConcatAndDel(&result, PyString_FromString(buf));
Tim Peters2a799bf2002-12-16 20:18:38 +00003272 return result;
3273}
3274
Tim Peters37f39822003-01-10 03:49:02 +00003275static PyObject *
3276time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3277{
3278 PyObject *result;
Tim Peters37f39822003-01-10 03:49:02 +00003279 PyObject *tuple;
Gregory P. Smith137d8242008-06-02 04:05:52 +00003280 const char *format;
3281 Py_ssize_t format_len;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003282 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003283
Gregory P. Smith137d8242008-06-02 04:05:52 +00003284 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3285 &format, &format_len))
Tim Peters37f39822003-01-10 03:49:02 +00003286 return NULL;
3287
3288 /* Python's strftime does insane things with the year part of the
3289 * timetuple. The year is forced to (the otherwise nonsensical)
3290 * 1900 to worm around that.
3291 */
3292 tuple = Py_BuildValue("iiiiiiiii",
Brett Cannond1080a32004-03-02 04:38:10 +00003293 1900, 1, 1, /* year, month, day */
Tim Peters37f39822003-01-10 03:49:02 +00003294 TIME_GET_HOUR(self),
3295 TIME_GET_MINUTE(self),
3296 TIME_GET_SECOND(self),
Brett Cannond1080a32004-03-02 04:38:10 +00003297 0, 1, -1); /* weekday, daynum, dst */
Tim Peters37f39822003-01-10 03:49:02 +00003298 if (tuple == NULL)
3299 return NULL;
3300 assert(PyTuple_Size(tuple) == 9);
Gregory P. Smith137d8242008-06-02 04:05:52 +00003301 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3302 Py_None);
Tim Peters37f39822003-01-10 03:49:02 +00003303 Py_DECREF(tuple);
3304 return result;
3305}
Tim Peters2a799bf2002-12-16 20:18:38 +00003306
3307/*
3308 * Miscellaneous methods.
3309 */
3310
Tim Peters37f39822003-01-10 03:49:02 +00003311/* This is more natural as a tp_compare, but doesn't work then: for whatever
3312 * reason, Python's try_3way_compare ignores tp_compare unless
3313 * PyInstance_Check returns true, but these aren't old-style classes.
3314 */
3315static PyObject *
3316time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3317{
3318 int diff;
3319 naivety n1, n2;
3320 int offset1, offset2;
3321
3322 if (! PyTime_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00003323 if (op == Py_EQ || op == Py_NE) {
3324 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3325 Py_INCREF(result);
3326 return result;
3327 }
Tim Peters37f39822003-01-10 03:49:02 +00003328 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00003329 return cmperror((PyObject *)self, other);
Tim Peters37f39822003-01-10 03:49:02 +00003330 }
3331 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3332 other, &offset2, &n2, Py_None) < 0)
3333 return NULL;
3334 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3335 /* If they're both naive, or both aware and have the same offsets,
3336 * we get off cheap. Note that if they're both naive, offset1 ==
3337 * offset2 == 0 at this point.
3338 */
3339 if (n1 == n2 && offset1 == offset2) {
3340 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3341 _PyDateTime_TIME_DATASIZE);
3342 return diff_to_bool(diff, op);
3343 }
3344
3345 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3346 assert(offset1 != offset2); /* else last "if" handled it */
3347 /* Convert everything except microseconds to seconds. These
3348 * can't overflow (no more than the # of seconds in 2 days).
3349 */
3350 offset1 = TIME_GET_HOUR(self) * 3600 +
3351 (TIME_GET_MINUTE(self) - offset1) * 60 +
3352 TIME_GET_SECOND(self);
3353 offset2 = TIME_GET_HOUR(other) * 3600 +
3354 (TIME_GET_MINUTE(other) - offset2) * 60 +
3355 TIME_GET_SECOND(other);
3356 diff = offset1 - offset2;
3357 if (diff == 0)
3358 diff = TIME_GET_MICROSECOND(self) -
3359 TIME_GET_MICROSECOND(other);
3360 return diff_to_bool(diff, op);
3361 }
3362
3363 assert(n1 != n2);
3364 PyErr_SetString(PyExc_TypeError,
3365 "can't compare offset-naive and "
3366 "offset-aware times");
3367 return NULL;
3368}
3369
3370static long
3371time_hash(PyDateTime_Time *self)
3372{
3373 if (self->hashcode == -1) {
3374 naivety n;
3375 int offset;
3376 PyObject *temp;
3377
3378 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3379 assert(n != OFFSET_UNKNOWN);
3380 if (n == OFFSET_ERROR)
3381 return -1;
3382
3383 /* Reduce this to a hash of another object. */
3384 if (offset == 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003385 temp = PyString_FromStringAndSize((char *)self->data,
Tim Peters37f39822003-01-10 03:49:02 +00003386 _PyDateTime_TIME_DATASIZE);
3387 else {
3388 int hour;
3389 int minute;
3390
3391 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003392 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003393 hour = divmod(TIME_GET_HOUR(self) * 60 +
3394 TIME_GET_MINUTE(self) - offset,
3395 60,
3396 &minute);
3397 if (0 <= hour && hour < 24)
3398 temp = new_time(hour, minute,
3399 TIME_GET_SECOND(self),
3400 TIME_GET_MICROSECOND(self),
3401 Py_None);
3402 else
3403 temp = Py_BuildValue("iiii",
3404 hour, minute,
3405 TIME_GET_SECOND(self),
3406 TIME_GET_MICROSECOND(self));
3407 }
3408 if (temp != NULL) {
3409 self->hashcode = PyObject_Hash(temp);
3410 Py_DECREF(temp);
3411 }
3412 }
3413 return self->hashcode;
3414}
Tim Peters2a799bf2002-12-16 20:18:38 +00003415
Tim Peters12bf3392002-12-24 05:41:27 +00003416static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003417time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003418{
3419 PyObject *clone;
3420 PyObject *tuple;
3421 int hh = TIME_GET_HOUR(self);
3422 int mm = TIME_GET_MINUTE(self);
3423 int ss = TIME_GET_SECOND(self);
3424 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003425 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003426
3427 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003428 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003429 &hh, &mm, &ss, &us, &tzinfo))
3430 return NULL;
3431 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3432 if (tuple == NULL)
3433 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00003434 clone = time_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003435 Py_DECREF(tuple);
3436 return clone;
3437}
3438
Tim Peters2a799bf2002-12-16 20:18:38 +00003439static int
Tim Peters37f39822003-01-10 03:49:02 +00003440time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003441{
3442 int offset;
3443 int none;
3444
3445 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3446 /* Since utcoffset is in whole minutes, nothing can
3447 * alter the conclusion that this is nonzero.
3448 */
3449 return 1;
3450 }
3451 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003452 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003453 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003454 if (offset == -1 && PyErr_Occurred())
3455 return -1;
3456 }
3457 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3458}
3459
Tim Peters371935f2003-02-01 01:52:50 +00003460/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003461
Tim Peters33e0f382003-01-10 02:05:14 +00003462/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003463 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3464 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003465 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003466 */
3467static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003468time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003469{
3470 PyObject *basestate;
3471 PyObject *result = NULL;
3472
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003473 basestate = PyString_FromStringAndSize((char *)self->data,
Tim Peters33e0f382003-01-10 02:05:14 +00003474 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003475 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003476 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003477 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00003478 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003479 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003480 Py_DECREF(basestate);
3481 }
3482 return result;
3483}
3484
3485static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003486time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003487{
Christian Heimese93237d2007-12-19 02:37:44 +00003488 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003489}
3490
Tim Peters37f39822003-01-10 03:49:02 +00003491static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003492
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003493 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003494 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3495 "[+HH:MM].")},
3496
Neal Norwitza84dcd72007-05-22 07:16:44 +00003497 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
Tim Peters37f39822003-01-10 03:49:02 +00003498 PyDoc_STR("format -> strftime() style string.")},
3499
Eric Smitha9f7d622008-02-17 19:46:49 +00003500 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3501 PyDoc_STR("Formats self with strftime.")},
3502
Tim Peters37f39822003-01-10 03:49:02 +00003503 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003504 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3505
Tim Peters37f39822003-01-10 03:49:02 +00003506 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003507 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3508
Tim Peters37f39822003-01-10 03:49:02 +00003509 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003510 PyDoc_STR("Return self.tzinfo.dst(self).")},
3511
Neal Norwitza84dcd72007-05-22 07:16:44 +00003512 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
Tim Peters37f39822003-01-10 03:49:02 +00003513 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003514
Guido van Rossum177e41a2003-01-30 22:06:23 +00003515 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3516 PyDoc_STR("__reduce__() -> (cls, state)")},
3517
Tim Peters2a799bf2002-12-16 20:18:38 +00003518 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003519};
3520
Tim Peters37f39822003-01-10 03:49:02 +00003521static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003522PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3523\n\
3524All arguments are optional. tzinfo may be None, or an instance of\n\
3525a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003526
Tim Peters37f39822003-01-10 03:49:02 +00003527static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003528 0, /* nb_add */
3529 0, /* nb_subtract */
3530 0, /* nb_multiply */
3531 0, /* nb_divide */
3532 0, /* nb_remainder */
3533 0, /* nb_divmod */
3534 0, /* nb_power */
3535 0, /* nb_negative */
3536 0, /* nb_positive */
3537 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003538 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003539};
3540
Tim Peters37f39822003-01-10 03:49:02 +00003541statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003542 PyObject_HEAD_INIT(NULL)
3543 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003544 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003545 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003546 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003547 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003548 0, /* tp_print */
3549 0, /* tp_getattr */
3550 0, /* tp_setattr */
3551 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003552 (reprfunc)time_repr, /* tp_repr */
3553 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003554 0, /* tp_as_sequence */
3555 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003556 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003557 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003558 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003559 PyObject_GenericGetAttr, /* tp_getattro */
3560 0, /* tp_setattro */
3561 0, /* tp_as_buffer */
3562 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3563 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003564 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003565 0, /* tp_traverse */
3566 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003567 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003568 0, /* tp_weaklistoffset */
3569 0, /* tp_iter */
3570 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003571 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003572 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003573 time_getset, /* tp_getset */
3574 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003575 0, /* tp_dict */
3576 0, /* tp_descr_get */
3577 0, /* tp_descr_set */
3578 0, /* tp_dictoffset */
3579 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00003580 time_alloc, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003581 time_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00003582 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003583};
3584
3585/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003586 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003587 */
3588
Tim Petersa9bc1682003-01-11 03:39:11 +00003589/* Accessor properties. Properties for day, month, and year are inherited
3590 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003591 */
3592
3593static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003594datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003595{
Tim Petersa9bc1682003-01-11 03:39:11 +00003596 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003597}
3598
Tim Petersa9bc1682003-01-11 03:39:11 +00003599static PyObject *
3600datetime_minute(PyDateTime_DateTime *self, void *unused)
3601{
3602 return PyInt_FromLong(DATE_GET_MINUTE(self));
3603}
3604
3605static PyObject *
3606datetime_second(PyDateTime_DateTime *self, void *unused)
3607{
3608 return PyInt_FromLong(DATE_GET_SECOND(self));
3609}
3610
3611static PyObject *
3612datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3613{
3614 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3615}
3616
3617static PyObject *
3618datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3619{
3620 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3621 Py_INCREF(result);
3622 return result;
3623}
3624
3625static PyGetSetDef datetime_getset[] = {
3626 {"hour", (getter)datetime_hour},
3627 {"minute", (getter)datetime_minute},
3628 {"second", (getter)datetime_second},
3629 {"microsecond", (getter)datetime_microsecond},
3630 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003631 {NULL}
3632};
3633
3634/*
3635 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003636 */
3637
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003638static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003639 "year", "month", "day", "hour", "minute", "second",
3640 "microsecond", "tzinfo", NULL
3641};
3642
Tim Peters2a799bf2002-12-16 20:18:38 +00003643static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003644datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003645{
3646 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003647 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003648 int year;
3649 int month;
3650 int day;
3651 int hour = 0;
3652 int minute = 0;
3653 int second = 0;
3654 int usecond = 0;
3655 PyObject *tzinfo = Py_None;
3656
Guido van Rossum177e41a2003-01-30 22:06:23 +00003657 /* Check for invocation from pickle with __getstate__ state */
3658 if (PyTuple_GET_SIZE(args) >= 1 &&
3659 PyTuple_GET_SIZE(args) <= 2 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003660 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3661 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3662 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003663 {
Tim Peters70533e22003-02-01 04:40:04 +00003664 PyDateTime_DateTime *me;
3665 char aware;
3666
3667 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003668 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003669 if (check_tzinfo_subclass(tzinfo) < 0) {
3670 PyErr_SetString(PyExc_TypeError, "bad "
3671 "tzinfo state arg");
3672 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003673 }
3674 }
Tim Peters70533e22003-02-01 04:40:04 +00003675 aware = (char)(tzinfo != Py_None);
Tim Peters604c0132004-06-07 23:04:33 +00003676 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
Tim Peters70533e22003-02-01 04:40:04 +00003677 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003678 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003679
3680 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3681 me->hashcode = -1;
3682 me->hastzinfo = aware;
3683 if (aware) {
3684 Py_INCREF(tzinfo);
3685 me->tzinfo = tzinfo;
3686 }
3687 }
3688 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003689 }
3690
Tim Petersa9bc1682003-01-11 03:39:11 +00003691 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003692 &year, &month, &day, &hour, &minute,
3693 &second, &usecond, &tzinfo)) {
3694 if (check_date_args(year, month, day) < 0)
3695 return NULL;
3696 if (check_time_args(hour, minute, second, usecond) < 0)
3697 return NULL;
3698 if (check_tzinfo_subclass(tzinfo) < 0)
3699 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003700 self = new_datetime_ex(year, month, day,
3701 hour, minute, second, usecond,
3702 tzinfo, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003703 }
3704 return self;
3705}
3706
Tim Petersa9bc1682003-01-11 03:39:11 +00003707/* TM_FUNC is the shared type of localtime() and gmtime(). */
3708typedef struct tm *(*TM_FUNC)(const time_t *timer);
3709
3710/* Internal helper.
3711 * Build datetime from a time_t and a distinct count of microseconds.
3712 * Pass localtime or gmtime for f, to control the interpretation of timet.
3713 */
3714static PyObject *
3715datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3716 PyObject *tzinfo)
3717{
3718 struct tm *tm;
3719 PyObject *result = NULL;
3720
3721 tm = f(&timet);
3722 if (tm) {
3723 /* The platform localtime/gmtime may insert leap seconds,
3724 * indicated by tm->tm_sec > 59. We don't care about them,
3725 * except to the extent that passing them on to the datetime
3726 * constructor would raise ValueError for a reason that
3727 * made no sense to the user.
3728 */
3729 if (tm->tm_sec > 59)
3730 tm->tm_sec = 59;
3731 result = PyObject_CallFunction(cls, "iiiiiiiO",
3732 tm->tm_year + 1900,
3733 tm->tm_mon + 1,
3734 tm->tm_mday,
3735 tm->tm_hour,
3736 tm->tm_min,
3737 tm->tm_sec,
3738 us,
3739 tzinfo);
3740 }
3741 else
3742 PyErr_SetString(PyExc_ValueError,
3743 "timestamp out of range for "
3744 "platform localtime()/gmtime() function");
3745 return result;
3746}
3747
3748/* Internal helper.
3749 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3750 * to control the interpretation of the timestamp. Since a double doesn't
3751 * have enough bits to cover a datetime's full range of precision, it's
3752 * better to call datetime_from_timet_and_us provided you have a way
3753 * to get that much precision (e.g., C time() isn't good enough).
3754 */
3755static PyObject *
3756datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3757 PyObject *tzinfo)
3758{
Tim Peters1b6f7a92004-06-20 02:50:16 +00003759 time_t timet;
3760 double fraction;
3761 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00003762
Tim Peters1b6f7a92004-06-20 02:50:16 +00003763 timet = _PyTime_DoubleToTimet(timestamp);
3764 if (timet == (time_t)-1 && PyErr_Occurred())
3765 return NULL;
3766 fraction = timestamp - (double)timet;
3767 us = (int)round_to_long(fraction * 1e6);
Guido van Rossum2054ee92007-03-06 15:50:01 +00003768 if (us < 0) {
3769 /* Truncation towards zero is not what we wanted
3770 for negative numbers (Python's mod semantics) */
3771 timet -= 1;
3772 us += 1000000;
3773 }
Georg Brandl6d78a582006-04-28 19:09:24 +00003774 /* If timestamp is less than one microsecond smaller than a
3775 * full second, round up. Otherwise, ValueErrors are raised
3776 * for some floats. */
3777 if (us == 1000000) {
3778 timet += 1;
3779 us = 0;
3780 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003781 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3782}
3783
3784/* Internal helper.
3785 * Build most accurate possible datetime for current time. Pass localtime or
3786 * gmtime for f as appropriate.
3787 */
3788static PyObject *
3789datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3790{
3791#ifdef HAVE_GETTIMEOFDAY
3792 struct timeval t;
3793
3794#ifdef GETTIMEOFDAY_NO_TZ
3795 gettimeofday(&t);
3796#else
3797 gettimeofday(&t, (struct timezone *)NULL);
3798#endif
3799 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3800 tzinfo);
3801
3802#else /* ! HAVE_GETTIMEOFDAY */
3803 /* No flavor of gettimeofday exists on this platform. Python's
3804 * time.time() does a lot of other platform tricks to get the
3805 * best time it can on the platform, and we're not going to do
3806 * better than that (if we could, the better code would belong
3807 * in time.time()!) We're limited by the precision of a double,
3808 * though.
3809 */
3810 PyObject *time;
3811 double dtime;
3812
3813 time = time_time();
3814 if (time == NULL)
3815 return NULL;
3816 dtime = PyFloat_AsDouble(time);
3817 Py_DECREF(time);
3818 if (dtime == -1.0 && PyErr_Occurred())
3819 return NULL;
3820 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3821#endif /* ! HAVE_GETTIMEOFDAY */
3822}
3823
Tim Peters2a799bf2002-12-16 20:18:38 +00003824/* Return best possible local time -- this isn't constrained by the
3825 * precision of a timestamp.
3826 */
3827static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003828datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003829{
Tim Peters10cadce2003-01-23 19:58:02 +00003830 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003831 PyObject *tzinfo = Py_None;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003832 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003833
Tim Peters10cadce2003-01-23 19:58:02 +00003834 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3835 &tzinfo))
3836 return NULL;
3837 if (check_tzinfo_subclass(tzinfo) < 0)
3838 return NULL;
3839
3840 self = datetime_best_possible(cls,
3841 tzinfo == Py_None ? localtime : gmtime,
3842 tzinfo);
3843 if (self != NULL && tzinfo != Py_None) {
3844 /* Convert UTC to tzinfo's zone. */
3845 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003846 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003847 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003848 }
3849 return self;
3850}
3851
Tim Petersa9bc1682003-01-11 03:39:11 +00003852/* Return best possible UTC time -- this isn't constrained by the
3853 * precision of a timestamp.
3854 */
3855static PyObject *
3856datetime_utcnow(PyObject *cls, PyObject *dummy)
3857{
3858 return datetime_best_possible(cls, gmtime, Py_None);
3859}
3860
Tim Peters2a799bf2002-12-16 20:18:38 +00003861/* Return new local datetime from timestamp (Python timestamp -- a double). */
3862static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003863datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003864{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003865 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003866 double timestamp;
3867 PyObject *tzinfo = Py_None;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003868 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003869
Tim Peters2a44a8d2003-01-23 20:53:10 +00003870 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3871 keywords, &timestamp, &tzinfo))
3872 return NULL;
3873 if (check_tzinfo_subclass(tzinfo) < 0)
3874 return NULL;
3875
3876 self = datetime_from_timestamp(cls,
3877 tzinfo == Py_None ? localtime : gmtime,
3878 timestamp,
3879 tzinfo);
3880 if (self != NULL && tzinfo != Py_None) {
3881 /* Convert UTC to tzinfo's zone. */
3882 PyObject *temp = self;
3883 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3884 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003885 }
3886 return self;
3887}
3888
Tim Petersa9bc1682003-01-11 03:39:11 +00003889/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3890static PyObject *
3891datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3892{
3893 double timestamp;
3894 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003895
Tim Petersa9bc1682003-01-11 03:39:11 +00003896 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3897 result = datetime_from_timestamp(cls, gmtime, timestamp,
3898 Py_None);
3899 return result;
3900}
3901
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003902/* Return new datetime from time.strptime(). */
3903static PyObject *
3904datetime_strptime(PyObject *cls, PyObject *args)
3905{
Skip Montanarofc070d22008-03-15 16:04:45 +00003906 static PyObject *module = NULL;
3907 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003908 const char *string, *format;
3909
3910 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3911 return NULL;
3912
Skip Montanarofc070d22008-03-15 16:04:45 +00003913 if (module == NULL &&
3914 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003915 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003916
Skip Montanarofc070d22008-03-15 16:04:45 +00003917 /* _strptime._strptime returns a two-element tuple. The first
3918 element is a time.struct_time object. The second is the
3919 microseconds (which are not defined for time.struct_time). */
3920 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003921 if (obj != NULL) {
3922 int i, good_timetuple = 1;
Skip Montanarofc070d22008-03-15 16:04:45 +00003923 long int ia[7];
3924 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3925 st = PySequence_GetItem(obj, 0);
3926 frac = PySequence_GetItem(obj, 1);
3927 if (st == NULL || frac == NULL)
3928 good_timetuple = 0;
3929 /* copy y/m/d/h/m/s values out of the
3930 time.struct_time */
3931 if (good_timetuple &&
3932 PySequence_Check(st) &&
3933 PySequence_Size(st) >= 6) {
3934 for (i=0; i < 6; i++) {
3935 PyObject *p = PySequence_GetItem(st, i);
3936 if (p == NULL) {
3937 good_timetuple = 0;
3938 break;
3939 }
3940 if (PyInt_Check(p))
3941 ia[i] = PyInt_AsLong(p);
3942 else
3943 good_timetuple = 0;
3944 Py_DECREF(p);
Thomas Wouters3cfea2d2006-04-14 21:23:42 +00003945 }
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003946 }
Skip Montanarofc070d22008-03-15 16:04:45 +00003947 else
3948 good_timetuple = 0;
3949 /* follow that up with a little dose of microseconds */
3950 if (PyInt_Check(frac))
3951 ia[6] = PyInt_AsLong(frac);
3952 else
3953 good_timetuple = 0;
3954 }
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003955 else
3956 good_timetuple = 0;
3957 if (good_timetuple)
Skip Montanarofc070d22008-03-15 16:04:45 +00003958 result = PyObject_CallFunction(cls, "iiiiiii",
3959 ia[0], ia[1], ia[2],
3960 ia[3], ia[4], ia[5],
3961 ia[6]);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003962 else
3963 PyErr_SetString(PyExc_ValueError,
Skip Montanarofc070d22008-03-15 16:04:45 +00003964 "unexpected value from _strptime._strptime");
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003965 }
Skip Montanarofc070d22008-03-15 16:04:45 +00003966 Py_XDECREF(obj);
3967 Py_XDECREF(st);
3968 Py_XDECREF(frac);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003969 return result;
3970}
3971
Tim Petersa9bc1682003-01-11 03:39:11 +00003972/* Return new datetime from date/datetime and time arguments. */
3973static PyObject *
3974datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3975{
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003976 static char *keywords[] = {"date", "time", NULL};
Tim Petersa9bc1682003-01-11 03:39:11 +00003977 PyObject *date;
3978 PyObject *time;
3979 PyObject *result = NULL;
3980
3981 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3982 &PyDateTime_DateType, &date,
3983 &PyDateTime_TimeType, &time)) {
3984 PyObject *tzinfo = Py_None;
3985
3986 if (HASTZINFO(time))
3987 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3988 result = PyObject_CallFunction(cls, "iiiiiiiO",
3989 GET_YEAR(date),
3990 GET_MONTH(date),
3991 GET_DAY(date),
3992 TIME_GET_HOUR(time),
3993 TIME_GET_MINUTE(time),
3994 TIME_GET_SECOND(time),
3995 TIME_GET_MICROSECOND(time),
3996 tzinfo);
3997 }
3998 return result;
3999}
Tim Peters2a799bf2002-12-16 20:18:38 +00004000
4001/*
4002 * Destructor.
4003 */
4004
4005static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004006datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004007{
Tim Petersa9bc1682003-01-11 03:39:11 +00004008 if (HASTZINFO(self)) {
4009 Py_XDECREF(self->tzinfo);
4010 }
Christian Heimese93237d2007-12-19 02:37:44 +00004011 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004012}
4013
4014/*
4015 * Indirect access to tzinfo methods.
4016 */
4017
Tim Peters2a799bf2002-12-16 20:18:38 +00004018/* These are all METH_NOARGS, so don't need to check the arglist. */
4019static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004020datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
4021 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4022 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004023}
4024
4025static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004026datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
4027 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4028 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004029}
4030
4031static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004032datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
4033 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4034 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004035}
4036
4037/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004038 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004039 */
4040
Tim Petersa9bc1682003-01-11 03:39:11 +00004041/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4042 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004043 */
4044static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004045add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4046 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004047{
Tim Petersa9bc1682003-01-11 03:39:11 +00004048 /* Note that the C-level additions can't overflow, because of
4049 * invariant bounds on the member values.
4050 */
4051 int year = GET_YEAR(date);
4052 int month = GET_MONTH(date);
4053 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4054 int hour = DATE_GET_HOUR(date);
4055 int minute = DATE_GET_MINUTE(date);
4056 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4057 int microsecond = DATE_GET_MICROSECOND(date) +
4058 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004059
Tim Petersa9bc1682003-01-11 03:39:11 +00004060 assert(factor == 1 || factor == -1);
4061 if (normalize_datetime(&year, &month, &day,
4062 &hour, &minute, &second, &microsecond) < 0)
4063 return NULL;
4064 else
4065 return new_datetime(year, month, day,
4066 hour, minute, second, microsecond,
4067 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004068}
4069
4070static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004071datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004072{
Tim Petersa9bc1682003-01-11 03:39:11 +00004073 if (PyDateTime_Check(left)) {
4074 /* datetime + ??? */
4075 if (PyDelta_Check(right))
4076 /* datetime + delta */
4077 return add_datetime_timedelta(
4078 (PyDateTime_DateTime *)left,
4079 (PyDateTime_Delta *)right,
4080 1);
4081 }
4082 else if (PyDelta_Check(left)) {
4083 /* delta + datetime */
4084 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4085 (PyDateTime_Delta *) left,
4086 1);
4087 }
4088 Py_INCREF(Py_NotImplemented);
4089 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004090}
4091
4092static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004093datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004094{
4095 PyObject *result = Py_NotImplemented;
4096
4097 if (PyDateTime_Check(left)) {
4098 /* datetime - ??? */
4099 if (PyDateTime_Check(right)) {
4100 /* datetime - datetime */
4101 naivety n1, n2;
4102 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004103 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004104
Tim Peterse39a80c2002-12-30 21:28:52 +00004105 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4106 right, &offset2, &n2,
4107 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00004108 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00004109 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00004110 if (n1 != n2) {
4111 PyErr_SetString(PyExc_TypeError,
4112 "can't subtract offset-naive and "
4113 "offset-aware datetimes");
4114 return NULL;
4115 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004116 delta_d = ymd_to_ord(GET_YEAR(left),
4117 GET_MONTH(left),
4118 GET_DAY(left)) -
4119 ymd_to_ord(GET_YEAR(right),
4120 GET_MONTH(right),
4121 GET_DAY(right));
4122 /* These can't overflow, since the values are
4123 * normalized. At most this gives the number of
4124 * seconds in one day.
4125 */
4126 delta_s = (DATE_GET_HOUR(left) -
4127 DATE_GET_HOUR(right)) * 3600 +
4128 (DATE_GET_MINUTE(left) -
4129 DATE_GET_MINUTE(right)) * 60 +
4130 (DATE_GET_SECOND(left) -
4131 DATE_GET_SECOND(right));
4132 delta_us = DATE_GET_MICROSECOND(left) -
4133 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00004134 /* (left - offset1) - (right - offset2) =
4135 * (left - right) + (offset2 - offset1)
4136 */
Tim Petersa9bc1682003-01-11 03:39:11 +00004137 delta_s += (offset2 - offset1) * 60;
4138 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004139 }
4140 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004141 /* datetime - delta */
4142 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00004143 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00004144 (PyDateTime_Delta *)right,
4145 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004146 }
4147 }
4148
4149 if (result == Py_NotImplemented)
4150 Py_INCREF(result);
4151 return result;
4152}
4153
4154/* Various ways to turn a datetime into a string. */
4155
4156static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004157datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004158{
Tim Petersa9bc1682003-01-11 03:39:11 +00004159 char buffer[1000];
Christian Heimese93237d2007-12-19 02:37:44 +00004160 const char *type_name = Py_TYPE(self)->tp_name;
Tim Petersa9bc1682003-01-11 03:39:11 +00004161 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004162
Tim Petersa9bc1682003-01-11 03:39:11 +00004163 if (DATE_GET_MICROSECOND(self)) {
4164 PyOS_snprintf(buffer, sizeof(buffer),
4165 "%s(%d, %d, %d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004166 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004167 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4168 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4169 DATE_GET_SECOND(self),
4170 DATE_GET_MICROSECOND(self));
4171 }
4172 else if (DATE_GET_SECOND(self)) {
4173 PyOS_snprintf(buffer, sizeof(buffer),
4174 "%s(%d, %d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004175 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004176 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4177 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4178 DATE_GET_SECOND(self));
4179 }
4180 else {
4181 PyOS_snprintf(buffer, sizeof(buffer),
4182 "%s(%d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004183 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004184 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4185 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4186 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004187 baserepr = PyString_FromString(buffer);
Tim Petersa9bc1682003-01-11 03:39:11 +00004188 if (baserepr == NULL || ! HASTZINFO(self))
4189 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004190 return append_keyword_tzinfo(baserepr, self->tzinfo);
4191}
4192
Tim Petersa9bc1682003-01-11 03:39:11 +00004193static PyObject *
4194datetime_str(PyDateTime_DateTime *self)
4195{
4196 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4197}
Tim Peters2a799bf2002-12-16 20:18:38 +00004198
4199static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004200datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004201{
Tim Petersa9bc1682003-01-11 03:39:11 +00004202 char sep = 'T';
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004203 static char *keywords[] = {"sep", NULL};
Tim Petersa9bc1682003-01-11 03:39:11 +00004204 char buffer[100];
4205 char *cp;
4206 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004207
Tim Petersa9bc1682003-01-11 03:39:11 +00004208 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4209 &sep))
4210 return NULL;
4211 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4212 assert(cp != NULL);
4213 *cp++ = sep;
4214 isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004215 result = PyString_FromString(buffer);
Tim Petersa9bc1682003-01-11 03:39:11 +00004216 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00004217 return result;
4218
4219 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00004220 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00004221 (PyObject *)self) < 0) {
4222 Py_DECREF(result);
4223 return NULL;
4224 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004225 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00004226 return result;
4227}
4228
Tim Petersa9bc1682003-01-11 03:39:11 +00004229static PyObject *
4230datetime_ctime(PyDateTime_DateTime *self)
4231{
4232 return format_ctime((PyDateTime_Date *)self,
4233 DATE_GET_HOUR(self),
4234 DATE_GET_MINUTE(self),
4235 DATE_GET_SECOND(self));
4236}
4237
Tim Peters2a799bf2002-12-16 20:18:38 +00004238/* Miscellaneous methods. */
4239
Tim Petersa9bc1682003-01-11 03:39:11 +00004240/* This is more natural as a tp_compare, but doesn't work then: for whatever
4241 * reason, Python's try_3way_compare ignores tp_compare unless
4242 * PyInstance_Check returns true, but these aren't old-style classes.
4243 */
4244static PyObject *
4245datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4246{
4247 int diff;
4248 naivety n1, n2;
4249 int offset1, offset2;
4250
4251 if (! PyDateTime_Check(other)) {
Tim Peters528ca532004-09-16 01:30:50 +00004252 /* If other has a "timetuple" attr, that's an advertised
4253 * hook for other classes to ask to get comparison control.
4254 * However, date instances have a timetuple attr, and we
4255 * don't want to allow that comparison. Because datetime
4256 * is a subclass of date, when mixing date and datetime
4257 * in a comparison, Python gives datetime the first shot
4258 * (it's the more specific subtype). So we can stop that
4259 * combination here reliably.
4260 */
4261 if (PyObject_HasAttrString(other, "timetuple") &&
4262 ! PyDate_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004263 /* A hook for other kinds of datetime objects. */
4264 Py_INCREF(Py_NotImplemented);
4265 return Py_NotImplemented;
4266 }
Tim Peters07534a62003-02-07 22:50:28 +00004267 if (op == Py_EQ || op == Py_NE) {
4268 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4269 Py_INCREF(result);
4270 return result;
4271 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004272 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00004273 return cmperror((PyObject *)self, other);
Tim Petersa9bc1682003-01-11 03:39:11 +00004274 }
4275
4276 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4277 (PyObject *)self,
4278 other, &offset2, &n2,
4279 other) < 0)
4280 return NULL;
4281 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4282 /* If they're both naive, or both aware and have the same offsets,
4283 * we get off cheap. Note that if they're both naive, offset1 ==
4284 * offset2 == 0 at this point.
4285 */
4286 if (n1 == n2 && offset1 == offset2) {
4287 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4288 _PyDateTime_DATETIME_DATASIZE);
4289 return diff_to_bool(diff, op);
4290 }
4291
4292 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4293 PyDateTime_Delta *delta;
4294
4295 assert(offset1 != offset2); /* else last "if" handled it */
4296 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4297 other);
4298 if (delta == NULL)
4299 return NULL;
4300 diff = GET_TD_DAYS(delta);
4301 if (diff == 0)
4302 diff = GET_TD_SECONDS(delta) |
4303 GET_TD_MICROSECONDS(delta);
4304 Py_DECREF(delta);
4305 return diff_to_bool(diff, op);
4306 }
4307
4308 assert(n1 != n2);
4309 PyErr_SetString(PyExc_TypeError,
4310 "can't compare offset-naive and "
4311 "offset-aware datetimes");
4312 return NULL;
4313}
4314
4315static long
4316datetime_hash(PyDateTime_DateTime *self)
4317{
4318 if (self->hashcode == -1) {
4319 naivety n;
4320 int offset;
4321 PyObject *temp;
4322
4323 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4324 &offset);
4325 assert(n != OFFSET_UNKNOWN);
4326 if (n == OFFSET_ERROR)
4327 return -1;
4328
4329 /* Reduce this to a hash of another object. */
4330 if (n == OFFSET_NAIVE)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004331 temp = PyString_FromStringAndSize(
Tim Petersa9bc1682003-01-11 03:39:11 +00004332 (char *)self->data,
4333 _PyDateTime_DATETIME_DATASIZE);
4334 else {
4335 int days;
4336 int seconds;
4337
4338 assert(n == OFFSET_AWARE);
4339 assert(HASTZINFO(self));
4340 days = ymd_to_ord(GET_YEAR(self),
4341 GET_MONTH(self),
4342 GET_DAY(self));
4343 seconds = DATE_GET_HOUR(self) * 3600 +
4344 (DATE_GET_MINUTE(self) - offset) * 60 +
4345 DATE_GET_SECOND(self);
4346 temp = new_delta(days,
4347 seconds,
4348 DATE_GET_MICROSECOND(self),
4349 1);
4350 }
4351 if (temp != NULL) {
4352 self->hashcode = PyObject_Hash(temp);
4353 Py_DECREF(temp);
4354 }
4355 }
4356 return self->hashcode;
4357}
Tim Peters2a799bf2002-12-16 20:18:38 +00004358
4359static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004360datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004361{
4362 PyObject *clone;
4363 PyObject *tuple;
4364 int y = GET_YEAR(self);
4365 int m = GET_MONTH(self);
4366 int d = GET_DAY(self);
4367 int hh = DATE_GET_HOUR(self);
4368 int mm = DATE_GET_MINUTE(self);
4369 int ss = DATE_GET_SECOND(self);
4370 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004371 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004372
4373 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004374 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004375 &y, &m, &d, &hh, &mm, &ss, &us,
4376 &tzinfo))
4377 return NULL;
4378 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4379 if (tuple == NULL)
4380 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00004381 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004382 Py_DECREF(tuple);
4383 return clone;
4384}
4385
4386static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004387datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004388{
Tim Peters52dcce22003-01-23 16:36:11 +00004389 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004390 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004391 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004392
Tim Peters80475bb2002-12-25 07:40:55 +00004393 PyObject *tzinfo;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004394 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004395
Tim Peters52dcce22003-01-23 16:36:11 +00004396 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4397 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004398 return NULL;
4399
Tim Peters52dcce22003-01-23 16:36:11 +00004400 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4401 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004402
Tim Peters52dcce22003-01-23 16:36:11 +00004403 /* Conversion to self's own time zone is a NOP. */
4404 if (self->tzinfo == tzinfo) {
4405 Py_INCREF(self);
4406 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004407 }
Tim Peters521fc152002-12-31 17:36:56 +00004408
Tim Peters52dcce22003-01-23 16:36:11 +00004409 /* Convert self to UTC. */
4410 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4411 if (offset == -1 && PyErr_Occurred())
4412 return NULL;
4413 if (none)
4414 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004415
Tim Peters52dcce22003-01-23 16:36:11 +00004416 y = GET_YEAR(self);
4417 m = GET_MONTH(self);
4418 d = GET_DAY(self);
4419 hh = DATE_GET_HOUR(self);
4420 mm = DATE_GET_MINUTE(self);
4421 ss = DATE_GET_SECOND(self);
4422 us = DATE_GET_MICROSECOND(self);
4423
4424 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004425 if ((mm < 0 || mm >= 60) &&
4426 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004427 return NULL;
4428
4429 /* Attach new tzinfo and let fromutc() do the rest. */
4430 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4431 if (result != NULL) {
4432 PyObject *temp = result;
4433
4434 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4435 Py_DECREF(temp);
4436 }
Tim Petersadf64202003-01-04 06:03:15 +00004437 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004438
Tim Peters52dcce22003-01-23 16:36:11 +00004439NeedAware:
4440 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4441 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004442 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004443}
4444
4445static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004446datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004447{
4448 int dstflag = -1;
4449
Tim Petersa9bc1682003-01-11 03:39:11 +00004450 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004451 int none;
4452
4453 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4454 if (dstflag == -1 && PyErr_Occurred())
4455 return NULL;
4456
4457 if (none)
4458 dstflag = -1;
4459 else if (dstflag != 0)
4460 dstflag = 1;
4461
4462 }
4463 return build_struct_time(GET_YEAR(self),
4464 GET_MONTH(self),
4465 GET_DAY(self),
4466 DATE_GET_HOUR(self),
4467 DATE_GET_MINUTE(self),
4468 DATE_GET_SECOND(self),
4469 dstflag);
4470}
4471
4472static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004473datetime_getdate(PyDateTime_DateTime *self)
4474{
4475 return new_date(GET_YEAR(self),
4476 GET_MONTH(self),
4477 GET_DAY(self));
4478}
4479
4480static PyObject *
4481datetime_gettime(PyDateTime_DateTime *self)
4482{
4483 return new_time(DATE_GET_HOUR(self),
4484 DATE_GET_MINUTE(self),
4485 DATE_GET_SECOND(self),
4486 DATE_GET_MICROSECOND(self),
4487 Py_None);
4488}
4489
4490static PyObject *
4491datetime_gettimetz(PyDateTime_DateTime *self)
4492{
4493 return new_time(DATE_GET_HOUR(self),
4494 DATE_GET_MINUTE(self),
4495 DATE_GET_SECOND(self),
4496 DATE_GET_MICROSECOND(self),
4497 HASTZINFO(self) ? self->tzinfo : Py_None);
4498}
4499
4500static PyObject *
4501datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004502{
4503 int y = GET_YEAR(self);
4504 int m = GET_MONTH(self);
4505 int d = GET_DAY(self);
4506 int hh = DATE_GET_HOUR(self);
4507 int mm = DATE_GET_MINUTE(self);
4508 int ss = DATE_GET_SECOND(self);
4509 int us = 0; /* microseconds are ignored in a timetuple */
4510 int offset = 0;
4511
Tim Petersa9bc1682003-01-11 03:39:11 +00004512 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004513 int none;
4514
4515 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4516 if (offset == -1 && PyErr_Occurred())
4517 return NULL;
4518 }
4519 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4520 * 0 in a UTC timetuple regardless of what dst() says.
4521 */
4522 if (offset) {
4523 /* Subtract offset minutes & normalize. */
4524 int stat;
4525
4526 mm -= offset;
4527 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4528 if (stat < 0) {
4529 /* At the edges, it's possible we overflowed
4530 * beyond MINYEAR or MAXYEAR.
4531 */
4532 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4533 PyErr_Clear();
4534 else
4535 return NULL;
4536 }
4537 }
4538 return build_struct_time(y, m, d, hh, mm, ss, 0);
4539}
4540
Tim Peters371935f2003-02-01 01:52:50 +00004541/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004542
Tim Petersa9bc1682003-01-11 03:39:11 +00004543/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004544 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4545 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004546 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004547 */
4548static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004549datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004550{
4551 PyObject *basestate;
4552 PyObject *result = NULL;
4553
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004554 basestate = PyString_FromStringAndSize((char *)self->data,
Tim Peters33e0f382003-01-10 02:05:14 +00004555 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004556 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004557 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004558 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00004559 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004560 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004561 Py_DECREF(basestate);
4562 }
4563 return result;
4564}
4565
4566static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004567datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004568{
Christian Heimese93237d2007-12-19 02:37:44 +00004569 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004570}
4571
Tim Petersa9bc1682003-01-11 03:39:11 +00004572static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004573
Tim Peters2a799bf2002-12-16 20:18:38 +00004574 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004575
Tim Petersa9bc1682003-01-11 03:39:11 +00004576 {"now", (PyCFunction)datetime_now,
Neal Norwitza84dcd72007-05-22 07:16:44 +00004577 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004578 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004579
Tim Petersa9bc1682003-01-11 03:39:11 +00004580 {"utcnow", (PyCFunction)datetime_utcnow,
4581 METH_NOARGS | METH_CLASS,
4582 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4583
4584 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Neal Norwitza84dcd72007-05-22 07:16:44 +00004585 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004586 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004587
Tim Petersa9bc1682003-01-11 03:39:11 +00004588 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4589 METH_VARARGS | METH_CLASS,
4590 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4591 "(like time.time()).")},
4592
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004593 {"strptime", (PyCFunction)datetime_strptime,
4594 METH_VARARGS | METH_CLASS,
4595 PyDoc_STR("string, format -> new datetime parsed from a string "
4596 "(like time.strptime()).")},
4597
Tim Petersa9bc1682003-01-11 03:39:11 +00004598 {"combine", (PyCFunction)datetime_combine,
4599 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4600 PyDoc_STR("date, time -> datetime with same date and time fields")},
4601
Tim Peters2a799bf2002-12-16 20:18:38 +00004602 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004603
Tim Petersa9bc1682003-01-11 03:39:11 +00004604 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4605 PyDoc_STR("Return date object with same year, month and day.")},
4606
4607 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4608 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4609
4610 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4611 PyDoc_STR("Return time object with same time and tzinfo.")},
4612
4613 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4614 PyDoc_STR("Return ctime() style string.")},
4615
4616 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004617 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4618
Tim Petersa9bc1682003-01-11 03:39:11 +00004619 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004620 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4621
Neal Norwitza84dcd72007-05-22 07:16:44 +00004622 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004623 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4624 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4625 "sep is used to separate the year from the time, and "
4626 "defaults to 'T'.")},
4627
Tim Petersa9bc1682003-01-11 03:39:11 +00004628 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004629 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4630
Tim Petersa9bc1682003-01-11 03:39:11 +00004631 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004632 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4633
Tim Petersa9bc1682003-01-11 03:39:11 +00004634 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004635 PyDoc_STR("Return self.tzinfo.dst(self).")},
4636
Neal Norwitza84dcd72007-05-22 07:16:44 +00004637 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
Tim Petersa9bc1682003-01-11 03:39:11 +00004638 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004639
Neal Norwitza84dcd72007-05-22 07:16:44 +00004640 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004641 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4642
Guido van Rossum177e41a2003-01-30 22:06:23 +00004643 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4644 PyDoc_STR("__reduce__() -> (cls, state)")},
4645
Tim Peters2a799bf2002-12-16 20:18:38 +00004646 {NULL, NULL}
4647};
4648
Tim Petersa9bc1682003-01-11 03:39:11 +00004649static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004650PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4651\n\
4652The year, month and day arguments are required. tzinfo may be None, or an\n\
4653instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004654
Tim Petersa9bc1682003-01-11 03:39:11 +00004655static PyNumberMethods datetime_as_number = {
4656 datetime_add, /* nb_add */
4657 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004658 0, /* nb_multiply */
4659 0, /* nb_divide */
4660 0, /* nb_remainder */
4661 0, /* nb_divmod */
4662 0, /* nb_power */
4663 0, /* nb_negative */
4664 0, /* nb_positive */
4665 0, /* nb_absolute */
4666 0, /* nb_nonzero */
4667};
4668
Tim Petersa9bc1682003-01-11 03:39:11 +00004669statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004670 PyObject_HEAD_INIT(NULL)
4671 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004672 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004673 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004674 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004675 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004676 0, /* tp_print */
4677 0, /* tp_getattr */
4678 0, /* tp_setattr */
4679 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004680 (reprfunc)datetime_repr, /* tp_repr */
4681 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004682 0, /* tp_as_sequence */
4683 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004684 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004685 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004686 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004687 PyObject_GenericGetAttr, /* tp_getattro */
4688 0, /* tp_setattro */
4689 0, /* tp_as_buffer */
4690 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4691 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004692 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004693 0, /* tp_traverse */
4694 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004695 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004696 0, /* tp_weaklistoffset */
4697 0, /* tp_iter */
4698 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004699 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004700 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004701 datetime_getset, /* tp_getset */
4702 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004703 0, /* tp_dict */
4704 0, /* tp_descr_get */
4705 0, /* tp_descr_set */
4706 0, /* tp_dictoffset */
4707 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00004708 datetime_alloc, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004709 datetime_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00004710 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004711};
4712
4713/* ---------------------------------------------------------------------------
4714 * Module methods and initialization.
4715 */
4716
4717static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004718 {NULL, NULL}
4719};
4720
Tim Peters9ddf40b2004-06-20 22:41:32 +00004721/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4722 * datetime.h.
4723 */
4724static PyDateTime_CAPI CAPI = {
4725 &PyDateTime_DateType,
4726 &PyDateTime_DateTimeType,
4727 &PyDateTime_TimeType,
4728 &PyDateTime_DeltaType,
4729 &PyDateTime_TZInfoType,
4730 new_date_ex,
4731 new_datetime_ex,
4732 new_time_ex,
4733 new_delta_ex,
4734 datetime_fromtimestamp,
4735 date_fromtimestamp
4736};
4737
4738
Tim Peters2a799bf2002-12-16 20:18:38 +00004739PyMODINIT_FUNC
4740initdatetime(void)
4741{
4742 PyObject *m; /* a module object */
4743 PyObject *d; /* its dict */
4744 PyObject *x;
4745
Tim Peters2a799bf2002-12-16 20:18:38 +00004746 m = Py_InitModule3("datetime", module_methods,
4747 "Fast implementation of the datetime type.");
Neal Norwitz1ac754f2006-01-19 06:09:39 +00004748 if (m == NULL)
4749 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004750
4751 if (PyType_Ready(&PyDateTime_DateType) < 0)
4752 return;
4753 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4754 return;
4755 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4756 return;
4757 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4758 return;
4759 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4760 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004761
Tim Peters2a799bf2002-12-16 20:18:38 +00004762 /* timedelta values */
4763 d = PyDateTime_DeltaType.tp_dict;
4764
Tim Peters2a799bf2002-12-16 20:18:38 +00004765 x = new_delta(0, 0, 1, 0);
4766 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4767 return;
4768 Py_DECREF(x);
4769
4770 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4771 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4772 return;
4773 Py_DECREF(x);
4774
4775 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4776 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4777 return;
4778 Py_DECREF(x);
4779
4780 /* date values */
4781 d = PyDateTime_DateType.tp_dict;
4782
4783 x = new_date(1, 1, 1);
4784 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4785 return;
4786 Py_DECREF(x);
4787
4788 x = new_date(MAXYEAR, 12, 31);
4789 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4790 return;
4791 Py_DECREF(x);
4792
4793 x = new_delta(1, 0, 0, 0);
4794 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4795 return;
4796 Py_DECREF(x);
4797
Tim Peters37f39822003-01-10 03:49:02 +00004798 /* time values */
4799 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004800
Tim Peters37f39822003-01-10 03:49:02 +00004801 x = new_time(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 Peters37f39822003-01-10 03:49:02 +00004806 x = new_time(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 Petersa9bc1682003-01-11 03:39:11 +00004816 /* datetime values */
4817 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004818
Tim Petersa9bc1682003-01-11 03:39:11 +00004819 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004820 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4821 return;
4822 Py_DECREF(x);
4823
Tim Petersa9bc1682003-01-11 03:39:11 +00004824 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004825 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4826 return;
4827 Py_DECREF(x);
4828
4829 x = new_delta(0, 0, 1, 0);
4830 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4831 return;
4832 Py_DECREF(x);
4833
Tim Peters2a799bf2002-12-16 20:18:38 +00004834 /* module initialization */
4835 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4836 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4837
4838 Py_INCREF(&PyDateTime_DateType);
4839 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4840
Tim Petersa9bc1682003-01-11 03:39:11 +00004841 Py_INCREF(&PyDateTime_DateTimeType);
4842 PyModule_AddObject(m, "datetime",
4843 (PyObject *)&PyDateTime_DateTimeType);
4844
4845 Py_INCREF(&PyDateTime_TimeType);
4846 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4847
Tim Peters2a799bf2002-12-16 20:18:38 +00004848 Py_INCREF(&PyDateTime_DeltaType);
4849 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4850
Tim Peters2a799bf2002-12-16 20:18:38 +00004851 Py_INCREF(&PyDateTime_TZInfoType);
4852 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4853
Tim Peters9ddf40b2004-06-20 22:41:32 +00004854 x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
4855 NULL);
4856 if (x == NULL)
4857 return;
4858 PyModule_AddObject(m, "datetime_CAPI", x);
4859
Tim Peters2a799bf2002-12-16 20:18:38 +00004860 /* A 4-year cycle has an extra leap day over what we'd get from
4861 * pasting together 4 single years.
4862 */
4863 assert(DI4Y == 4 * 365 + 1);
4864 assert(DI4Y == days_before_year(4+1));
4865
4866 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4867 * get from pasting together 4 100-year cycles.
4868 */
4869 assert(DI400Y == 4 * DI100Y + 1);
4870 assert(DI400Y == days_before_year(400+1));
4871
4872 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4873 * pasting together 25 4-year cycles.
4874 */
4875 assert(DI100Y == 25 * DI4Y - 1);
4876 assert(DI100Y == days_before_year(100+1));
4877
4878 us_per_us = PyInt_FromLong(1);
4879 us_per_ms = PyInt_FromLong(1000);
4880 us_per_second = PyInt_FromLong(1000000);
4881 us_per_minute = PyInt_FromLong(60000000);
4882 seconds_per_day = PyInt_FromLong(24 * 3600);
4883 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4884 us_per_minute == NULL || seconds_per_day == NULL)
4885 return;
4886
4887 /* The rest are too big for 32-bit ints, but even
4888 * us_per_week fits in 40 bits, so doubles should be exact.
4889 */
4890 us_per_hour = PyLong_FromDouble(3600000000.0);
4891 us_per_day = PyLong_FromDouble(86400000000.0);
4892 us_per_week = PyLong_FromDouble(604800000000.0);
4893 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4894 return;
4895}
Tim Petersf3615152003-01-01 21:51:37 +00004896
4897/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004898Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004899 x.n = x stripped of its timezone -- its naive time.
4900 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4901 return None
4902 x.d = x.dst(), and assuming that doesn't raise an exception or
4903 return None
4904 x.s = x's standard offset, x.o - x.d
4905
4906Now some derived rules, where k is a duration (timedelta).
4907
49081. x.o = x.s + x.d
4909 This follows from the definition of x.s.
4910
Tim Petersc5dc4da2003-01-02 17:55:03 +000049112. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004912 This is actually a requirement, an assumption we need to make about
4913 sane tzinfo classes.
4914
49153. The naive UTC time corresponding to x is x.n - x.o.
4916 This is again a requirement for a sane tzinfo class.
4917
49184. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004919 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004920
Tim Petersc5dc4da2003-01-02 17:55:03 +000049215. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004922 Again follows from how arithmetic is defined.
4923
Tim Peters8bb5ad22003-01-24 02:44:45 +00004924Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004925(meaning that the various tzinfo methods exist, and don't blow up or return
4926None when called).
4927
Tim Petersa9bc1682003-01-11 03:39:11 +00004928The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004929x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004930
4931By #3, we want
4932
Tim Peters8bb5ad22003-01-24 02:44:45 +00004933 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004934
4935The algorithm starts by attaching tz to x.n, and calling that y. So
4936x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4937becomes true; in effect, we want to solve [2] for k:
4938
Tim Peters8bb5ad22003-01-24 02:44:45 +00004939 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004940
4941By #1, this is the same as
4942
Tim Peters8bb5ad22003-01-24 02:44:45 +00004943 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004944
4945By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4946Substituting that into [3],
4947
Tim Peters8bb5ad22003-01-24 02:44:45 +00004948 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4949 k - (y+k).s - (y+k).d = 0; rearranging,
4950 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4951 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004952
Tim Peters8bb5ad22003-01-24 02:44:45 +00004953On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4954approximate k by ignoring the (y+k).d term at first. Note that k can't be
4955very large, since all offset-returning methods return a duration of magnitude
4956less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4957be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004958
4959In any case, the new value is
4960
Tim Peters8bb5ad22003-01-24 02:44:45 +00004961 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004962
Tim Peters8bb5ad22003-01-24 02:44:45 +00004963It's helpful to step back at look at [4] from a higher level: it's simply
4964mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004965
4966At this point, if
4967
Tim Peters8bb5ad22003-01-24 02:44:45 +00004968 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004969
4970we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004971at the start of daylight time. Picture US Eastern for concreteness. The wall
4972time 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 +00004973sense then. The docs ask that an Eastern tzinfo class consider such a time to
4974be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4975on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004976the only spelling that makes sense on the local wall clock.
4977
Tim Petersc5dc4da2003-01-02 17:55:03 +00004978In fact, if [5] holds at this point, we do have the standard-time spelling,
4979but that takes a bit of proof. We first prove a stronger result. What's the
4980difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004981
Tim Peters8bb5ad22003-01-24 02:44:45 +00004982 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004983
Tim Petersc5dc4da2003-01-02 17:55:03 +00004984Now
4985 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004986 (y + y.s).n = by #5
4987 y.n + y.s = since y.n = x.n
4988 x.n + y.s = since z and y are have the same tzinfo member,
4989 y.s = z.s by #2
4990 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004991
Tim Petersc5dc4da2003-01-02 17:55:03 +00004992Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004993
Tim Petersc5dc4da2003-01-02 17:55:03 +00004994 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004995 x.n - ((x.n + z.s) - z.o) = expanding
4996 x.n - x.n - z.s + z.o = cancelling
4997 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00004998 z.d
Tim Petersf3615152003-01-01 21:51:37 +00004999
Tim Petersc5dc4da2003-01-02 17:55:03 +00005000So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005001
Tim Petersc5dc4da2003-01-02 17:55:03 +00005002If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005003spelling we wanted in the endcase described above. We're done. Contrarily,
5004if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005005
Tim Petersc5dc4da2003-01-02 17:55:03 +00005006If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5007add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005008local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005009
Tim Petersc5dc4da2003-01-02 17:55:03 +00005010Let
Tim Petersf3615152003-01-01 21:51:37 +00005011
Tim Peters4fede1a2003-01-04 00:26:59 +00005012 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005013
Tim Peters4fede1a2003-01-04 00:26:59 +00005014and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005015
Tim Peters8bb5ad22003-01-24 02:44:45 +00005016 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005017
Tim Peters8bb5ad22003-01-24 02:44:45 +00005018If so, we're done. If not, the tzinfo class is insane, according to the
5019assumptions we've made. This also requires a bit of proof. As before, let's
5020compute the difference between the LHS and RHS of [8] (and skipping some of
5021the justifications for the kinds of substitutions we've done several times
5022already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005023
Tim Peters8bb5ad22003-01-24 02:44:45 +00005024 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5025 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5026 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5027 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5028 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00005029 - z.o + z'.o = #1 twice
5030 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5031 z'.d - z.d
5032
5033So 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 +00005034we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5035return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005036
Tim Peters8bb5ad22003-01-24 02:44:45 +00005037How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5038a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5039would have to change the result dst() returns: we start in DST, and moving
5040a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005041
Tim Peters8bb5ad22003-01-24 02:44:45 +00005042There isn't a sane case where this can happen. The closest it gets is at
5043the end of DST, where there's an hour in UTC with no spelling in a hybrid
5044tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5045that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5046UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5047time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5048clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5049standard time. Since that's what the local clock *does*, we want to map both
5050UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005051in local time, but so it goes -- it's the way the local clock works.
5052
Tim Peters8bb5ad22003-01-24 02:44:45 +00005053When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5054so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5055z' = 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 +00005056(correctly) concludes that z' is not UTC-equivalent to x.
5057
5058Because we know z.d said z was in daylight time (else [5] would have held and
5059we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005060and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005061return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5062but the reasoning doesn't depend on the example -- it depends on there being
5063two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005064z' must be in standard time, and is the spelling we want in this case.
5065
5066Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5067concerned (because it takes z' as being in standard time rather than the
5068daylight time we intend here), but returning it gives the real-life "local
5069clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5070tz.
5071
5072When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5073the 1:MM standard time spelling we want.
5074
5075So how can this break? One of the assumptions must be violated. Two
5076possibilities:
5077
50781) [2] effectively says that y.s is invariant across all y belong to a given
5079 time zone. This isn't true if, for political reasons or continental drift,
5080 a region decides to change its base offset from UTC.
5081
50822) There may be versions of "double daylight" time where the tail end of
5083 the analysis gives up a step too early. I haven't thought about that
5084 enough to say.
5085
5086In any case, it's clear that the default fromutc() is strong enough to handle
5087"almost all" time zones: so long as the standard offset is invariant, it
5088doesn't matter if daylight time transition points change from year to year, or
5089if daylight time is skipped in some years; it doesn't matter how large or
5090small dst() may get within its bounds; and it doesn't even matter if some
5091perverse time zone returns a negative dst()). So a breaking case must be
5092pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005093--------------------------------------------------------------------------- */