blob: 402dae9cd95d5404a66be61c8b9685e9ac687281 [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));
Amaury Forgeot d'Arc8645a5c2009-12-29 22:03:38 +00001365 assert(bufflen >= x);
Tim Peters2a799bf2002-12-16 20:18:38 +00001366 return buffer + x;
1367}
1368
Amaury Forgeot d'Arc8645a5c2009-12-29 22:03:38 +00001369static char *
Tim Peters2a799bf2002-12-16 20:18:38 +00001370isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1371{
Amaury Forgeot d'Arc8645a5c2009-12-29 22:03:38 +00001372 int x;
Tim Peters2a799bf2002-12-16 20:18:38 +00001373 int us = DATE_GET_MICROSECOND(dt);
1374
Amaury Forgeot d'Arc8645a5c2009-12-29 22:03:38 +00001375 x = PyOS_snprintf(buffer, bufflen,
1376 "%02d:%02d:%02d",
1377 DATE_GET_HOUR(dt),
1378 DATE_GET_MINUTE(dt),
1379 DATE_GET_SECOND(dt));
1380 assert(bufflen >= x);
Tim Peters2a799bf2002-12-16 20:18:38 +00001381 if (us)
Amaury Forgeot d'Arc8645a5c2009-12-29 22:03:38 +00001382 x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us);
1383 assert(bufflen >= x);
1384 return buffer + x;
Tim Peters2a799bf2002-12-16 20:18:38 +00001385}
1386
1387/* ---------------------------------------------------------------------------
1388 * Wrap functions from the time module. These aren't directly available
1389 * from C. Perhaps they should be.
1390 */
1391
1392/* Call time.time() and return its result (a Python float). */
1393static PyObject *
Guido van Rossumbd43e912002-12-16 20:34:55 +00001394time_time(void)
Tim Peters2a799bf2002-12-16 20:18:38 +00001395{
1396 PyObject *result = NULL;
Christian Heimes000a0742008-01-03 22:16:32 +00001397 PyObject *time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001398
1399 if (time != NULL) {
1400 result = PyObject_CallMethod(time, "time", "()");
1401 Py_DECREF(time);
1402 }
1403 return result;
1404}
1405
1406/* Build a time.struct_time. The weekday and day number are automatically
1407 * computed from the y,m,d args.
1408 */
1409static PyObject *
1410build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1411{
1412 PyObject *time;
1413 PyObject *result = NULL;
1414
Christian Heimes000a0742008-01-03 22:16:32 +00001415 time = PyImport_ImportModuleNoBlock("time");
Tim Peters2a799bf2002-12-16 20:18:38 +00001416 if (time != NULL) {
1417 result = PyObject_CallMethod(time, "struct_time",
1418 "((iiiiiiiii))",
1419 y, m, d,
1420 hh, mm, ss,
1421 weekday(y, m, d),
1422 days_before_month(y, m) + d,
1423 dstflag);
1424 Py_DECREF(time);
1425 }
1426 return result;
1427}
1428
1429/* ---------------------------------------------------------------------------
1430 * Miscellaneous helpers.
1431 */
1432
1433/* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1434 * The comparisons here all most naturally compute a cmp()-like result.
1435 * This little helper turns that into a bool result for rich comparisons.
1436 */
1437static PyObject *
1438diff_to_bool(int diff, int op)
1439{
1440 PyObject *result;
1441 int istrue;
1442
1443 switch (op) {
1444 case Py_EQ: istrue = diff == 0; break;
1445 case Py_NE: istrue = diff != 0; break;
1446 case Py_LE: istrue = diff <= 0; break;
1447 case Py_GE: istrue = diff >= 0; break;
1448 case Py_LT: istrue = diff < 0; break;
1449 case Py_GT: istrue = diff > 0; break;
1450 default:
1451 assert(! "op unknown");
1452 istrue = 0; /* To shut up compiler */
1453 }
1454 result = istrue ? Py_True : Py_False;
1455 Py_INCREF(result);
1456 return result;
1457}
1458
Tim Peters07534a62003-02-07 22:50:28 +00001459/* Raises a "can't compare" TypeError and returns NULL. */
1460static PyObject *
1461cmperror(PyObject *a, PyObject *b)
1462{
1463 PyErr_Format(PyExc_TypeError,
1464 "can't compare %s to %s",
Christian Heimese93237d2007-12-19 02:37:44 +00001465 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
Tim Peters07534a62003-02-07 22:50:28 +00001466 return NULL;
1467}
1468
Tim Peters2a799bf2002-12-16 20:18:38 +00001469/* ---------------------------------------------------------------------------
Tim Peters2a799bf2002-12-16 20:18:38 +00001470 * Cached Python objects; these are set by the module init function.
1471 */
1472
1473/* Conversion factors. */
1474static PyObject *us_per_us = NULL; /* 1 */
1475static PyObject *us_per_ms = NULL; /* 1000 */
1476static PyObject *us_per_second = NULL; /* 1000000 */
1477static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1478static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1479static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1480static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1481static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1482
Tim Peters2a799bf2002-12-16 20:18:38 +00001483/* ---------------------------------------------------------------------------
1484 * Class implementations.
1485 */
1486
1487/*
1488 * PyDateTime_Delta implementation.
1489 */
1490
1491/* Convert a timedelta to a number of us,
1492 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1493 * as a Python int or long.
1494 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1495 * due to ubiquitous overflow possibilities.
1496 */
1497static PyObject *
1498delta_to_microseconds(PyDateTime_Delta *self)
1499{
1500 PyObject *x1 = NULL;
1501 PyObject *x2 = NULL;
1502 PyObject *x3 = NULL;
1503 PyObject *result = NULL;
1504
1505 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1506 if (x1 == NULL)
1507 goto Done;
1508 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1509 if (x2 == NULL)
1510 goto Done;
1511 Py_DECREF(x1);
1512 x1 = NULL;
1513
1514 /* x2 has days in seconds */
1515 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1516 if (x1 == NULL)
1517 goto Done;
1518 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1519 if (x3 == NULL)
1520 goto Done;
1521 Py_DECREF(x1);
1522 Py_DECREF(x2);
1523 x1 = x2 = NULL;
1524
1525 /* x3 has days+seconds in seconds */
1526 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1527 if (x1 == NULL)
1528 goto Done;
1529 Py_DECREF(x3);
1530 x3 = NULL;
1531
1532 /* x1 has days+seconds in us */
1533 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1534 if (x2 == NULL)
1535 goto Done;
1536 result = PyNumber_Add(x1, x2);
1537
1538Done:
1539 Py_XDECREF(x1);
1540 Py_XDECREF(x2);
1541 Py_XDECREF(x3);
1542 return result;
1543}
1544
1545/* Convert a number of us (as a Python int or long) to a timedelta.
1546 */
1547static PyObject *
Tim Petersb0c854d2003-05-17 15:57:00 +00001548microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
Tim Peters2a799bf2002-12-16 20:18:38 +00001549{
1550 int us;
1551 int s;
1552 int d;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001553 long temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001554
1555 PyObject *tuple = NULL;
1556 PyObject *num = NULL;
1557 PyObject *result = NULL;
1558
1559 tuple = PyNumber_Divmod(pyus, us_per_second);
1560 if (tuple == NULL)
1561 goto Done;
1562
1563 num = PyTuple_GetItem(tuple, 1); /* us */
1564 if (num == NULL)
1565 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001566 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001567 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001568 if (temp == -1 && PyErr_Occurred())
1569 goto Done;
1570 assert(0 <= temp && temp < 1000000);
1571 us = (int)temp;
Tim Peters2a799bf2002-12-16 20:18:38 +00001572 if (us < 0) {
1573 /* The divisor was positive, so this must be an error. */
1574 assert(PyErr_Occurred());
1575 goto Done;
1576 }
1577
1578 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1579 if (num == NULL)
1580 goto Done;
1581 Py_INCREF(num);
1582 Py_DECREF(tuple);
1583
1584 tuple = PyNumber_Divmod(num, seconds_per_day);
1585 if (tuple == NULL)
1586 goto Done;
1587 Py_DECREF(num);
1588
1589 num = PyTuple_GetItem(tuple, 1); /* seconds */
1590 if (num == NULL)
1591 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001592 temp = PyLong_AsLong(num);
Tim Peters2a799bf2002-12-16 20:18:38 +00001593 num = NULL;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001594 if (temp == -1 && PyErr_Occurred())
1595 goto Done;
1596 assert(0 <= temp && temp < 24*3600);
1597 s = (int)temp;
1598
Tim Peters2a799bf2002-12-16 20:18:38 +00001599 if (s < 0) {
1600 /* The divisor was positive, so this must be an error. */
1601 assert(PyErr_Occurred());
1602 goto Done;
1603 }
1604
1605 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1606 if (num == NULL)
1607 goto Done;
1608 Py_INCREF(num);
Tim Peters0b0f41c2002-12-19 01:44:38 +00001609 temp = PyLong_AsLong(num);
1610 if (temp == -1 && PyErr_Occurred())
Tim Peters2a799bf2002-12-16 20:18:38 +00001611 goto Done;
Tim Peters0b0f41c2002-12-19 01:44:38 +00001612 d = (int)temp;
1613 if ((long)d != temp) {
1614 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1615 "large to fit in a C int");
1616 goto Done;
1617 }
Tim Petersb0c854d2003-05-17 15:57:00 +00001618 result = new_delta_ex(d, s, us, 0, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00001619
1620Done:
1621 Py_XDECREF(tuple);
1622 Py_XDECREF(num);
1623 return result;
1624}
1625
Tim Petersb0c854d2003-05-17 15:57:00 +00001626#define microseconds_to_delta(pymicros) \
1627 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1628
Tim Peters2a799bf2002-12-16 20:18:38 +00001629static PyObject *
1630multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1631{
1632 PyObject *pyus_in;
1633 PyObject *pyus_out;
1634 PyObject *result;
1635
1636 pyus_in = delta_to_microseconds(delta);
1637 if (pyus_in == NULL)
1638 return NULL;
1639
1640 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1641 Py_DECREF(pyus_in);
1642 if (pyus_out == NULL)
1643 return NULL;
1644
1645 result = microseconds_to_delta(pyus_out);
1646 Py_DECREF(pyus_out);
1647 return result;
1648}
1649
1650static PyObject *
1651divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1652{
1653 PyObject *pyus_in;
1654 PyObject *pyus_out;
1655 PyObject *result;
1656
1657 pyus_in = delta_to_microseconds(delta);
1658 if (pyus_in == NULL)
1659 return NULL;
1660
1661 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1662 Py_DECREF(pyus_in);
1663 if (pyus_out == NULL)
1664 return NULL;
1665
1666 result = microseconds_to_delta(pyus_out);
1667 Py_DECREF(pyus_out);
1668 return result;
1669}
1670
1671static PyObject *
1672delta_add(PyObject *left, PyObject *right)
1673{
1674 PyObject *result = Py_NotImplemented;
1675
1676 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1677 /* delta + delta */
1678 /* The C-level additions can't overflow because of the
1679 * invariant bounds.
1680 */
1681 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1682 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1683 int microseconds = GET_TD_MICROSECONDS(left) +
1684 GET_TD_MICROSECONDS(right);
1685 result = new_delta(days, seconds, microseconds, 1);
1686 }
1687
1688 if (result == Py_NotImplemented)
1689 Py_INCREF(result);
1690 return result;
1691}
1692
1693static PyObject *
1694delta_negative(PyDateTime_Delta *self)
1695{
1696 return new_delta(-GET_TD_DAYS(self),
1697 -GET_TD_SECONDS(self),
1698 -GET_TD_MICROSECONDS(self),
1699 1);
1700}
1701
1702static PyObject *
1703delta_positive(PyDateTime_Delta *self)
1704{
1705 /* Could optimize this (by returning self) if this isn't a
1706 * subclass -- but who uses unary + ? Approximately nobody.
1707 */
1708 return new_delta(GET_TD_DAYS(self),
1709 GET_TD_SECONDS(self),
1710 GET_TD_MICROSECONDS(self),
1711 0);
1712}
1713
1714static PyObject *
1715delta_abs(PyDateTime_Delta *self)
1716{
1717 PyObject *result;
1718
1719 assert(GET_TD_MICROSECONDS(self) >= 0);
1720 assert(GET_TD_SECONDS(self) >= 0);
1721
1722 if (GET_TD_DAYS(self) < 0)
1723 result = delta_negative(self);
1724 else
1725 result = delta_positive(self);
1726
1727 return result;
1728}
1729
1730static PyObject *
1731delta_subtract(PyObject *left, PyObject *right)
1732{
1733 PyObject *result = Py_NotImplemented;
1734
1735 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1736 /* delta - delta */
1737 PyObject *minus_right = PyNumber_Negative(right);
1738 if (minus_right) {
1739 result = delta_add(left, minus_right);
1740 Py_DECREF(minus_right);
1741 }
1742 else
1743 result = NULL;
1744 }
1745
1746 if (result == Py_NotImplemented)
1747 Py_INCREF(result);
1748 return result;
1749}
1750
1751/* This is more natural as a tp_compare, but doesn't work then: for whatever
1752 * reason, Python's try_3way_compare ignores tp_compare unless
1753 * PyInstance_Check returns true, but these aren't old-style classes.
1754 */
1755static PyObject *
1756delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1757{
Tim Peters07534a62003-02-07 22:50:28 +00001758 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00001759
Tim Petersaa7d8492003-02-08 03:28:59 +00001760 if (PyDelta_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00001761 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1762 if (diff == 0) {
1763 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1764 if (diff == 0)
1765 diff = GET_TD_MICROSECONDS(self) -
1766 GET_TD_MICROSECONDS(other);
1767 }
Tim Peters2a799bf2002-12-16 20:18:38 +00001768 }
Tim Peters07534a62003-02-07 22:50:28 +00001769 else if (op == Py_EQ || op == Py_NE)
1770 diff = 1; /* any non-zero value will do */
1771
1772 else /* stop this from falling back to address comparison */
1773 return cmperror((PyObject *)self, other);
1774
Tim Peters2a799bf2002-12-16 20:18:38 +00001775 return diff_to_bool(diff, op);
1776}
1777
1778static PyObject *delta_getstate(PyDateTime_Delta *self);
1779
1780static long
1781delta_hash(PyDateTime_Delta *self)
1782{
1783 if (self->hashcode == -1) {
1784 PyObject *temp = delta_getstate(self);
1785 if (temp != NULL) {
1786 self->hashcode = PyObject_Hash(temp);
1787 Py_DECREF(temp);
1788 }
1789 }
1790 return self->hashcode;
1791}
1792
1793static PyObject *
1794delta_multiply(PyObject *left, PyObject *right)
1795{
1796 PyObject *result = Py_NotImplemented;
1797
1798 if (PyDelta_Check(left)) {
1799 /* delta * ??? */
1800 if (PyInt_Check(right) || PyLong_Check(right))
1801 result = multiply_int_timedelta(right,
1802 (PyDateTime_Delta *) left);
1803 }
1804 else if (PyInt_Check(left) || PyLong_Check(left))
1805 result = multiply_int_timedelta(left,
1806 (PyDateTime_Delta *) right);
1807
1808 if (result == Py_NotImplemented)
1809 Py_INCREF(result);
1810 return result;
1811}
1812
1813static PyObject *
1814delta_divide(PyObject *left, PyObject *right)
1815{
1816 PyObject *result = Py_NotImplemented;
1817
1818 if (PyDelta_Check(left)) {
1819 /* delta * ??? */
1820 if (PyInt_Check(right) || PyLong_Check(right))
1821 result = divide_timedelta_int(
1822 (PyDateTime_Delta *)left,
1823 right);
1824 }
1825
1826 if (result == Py_NotImplemented)
1827 Py_INCREF(result);
1828 return result;
1829}
1830
1831/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1832 * timedelta constructor. sofar is the # of microseconds accounted for
1833 * so far, and there are factor microseconds per current unit, the number
1834 * of which is given by num. num * factor is added to sofar in a
1835 * numerically careful way, and that's the result. Any fractional
1836 * microseconds left over (this can happen if num is a float type) are
1837 * added into *leftover.
1838 * Note that there are many ways this can give an error (NULL) return.
1839 */
1840static PyObject *
1841accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1842 double *leftover)
1843{
1844 PyObject *prod;
1845 PyObject *sum;
1846
1847 assert(num != NULL);
1848
1849 if (PyInt_Check(num) || PyLong_Check(num)) {
1850 prod = PyNumber_Multiply(num, factor);
1851 if (prod == NULL)
1852 return NULL;
1853 sum = PyNumber_Add(sofar, prod);
1854 Py_DECREF(prod);
1855 return sum;
1856 }
1857
1858 if (PyFloat_Check(num)) {
1859 double dnum;
1860 double fracpart;
1861 double intpart;
1862 PyObject *x;
1863 PyObject *y;
1864
1865 /* The Plan: decompose num into an integer part and a
1866 * fractional part, num = intpart + fracpart.
1867 * Then num * factor ==
1868 * intpart * factor + fracpart * factor
1869 * and the LHS can be computed exactly in long arithmetic.
1870 * The RHS is again broken into an int part and frac part.
1871 * and the frac part is added into *leftover.
1872 */
1873 dnum = PyFloat_AsDouble(num);
1874 if (dnum == -1.0 && PyErr_Occurred())
1875 return NULL;
1876 fracpart = modf(dnum, &intpart);
1877 x = PyLong_FromDouble(intpart);
1878 if (x == NULL)
1879 return NULL;
1880
1881 prod = PyNumber_Multiply(x, factor);
1882 Py_DECREF(x);
1883 if (prod == NULL)
1884 return NULL;
1885
1886 sum = PyNumber_Add(sofar, prod);
1887 Py_DECREF(prod);
1888 if (sum == NULL)
1889 return NULL;
1890
1891 if (fracpart == 0.0)
1892 return sum;
1893 /* So far we've lost no information. Dealing with the
1894 * fractional part requires float arithmetic, and may
1895 * lose a little info.
1896 */
1897 assert(PyInt_Check(factor) || PyLong_Check(factor));
1898 if (PyInt_Check(factor))
1899 dnum = (double)PyInt_AsLong(factor);
1900 else
1901 dnum = PyLong_AsDouble(factor);
1902
1903 dnum *= fracpart;
1904 fracpart = modf(dnum, &intpart);
1905 x = PyLong_FromDouble(intpart);
1906 if (x == NULL) {
1907 Py_DECREF(sum);
1908 return NULL;
1909 }
1910
1911 y = PyNumber_Add(sum, x);
1912 Py_DECREF(sum);
1913 Py_DECREF(x);
1914 *leftover += fracpart;
1915 return y;
1916 }
1917
1918 PyErr_Format(PyExc_TypeError,
1919 "unsupported type for timedelta %s component: %s",
Christian Heimese93237d2007-12-19 02:37:44 +00001920 tag, Py_TYPE(num)->tp_name);
Tim Peters2a799bf2002-12-16 20:18:38 +00001921 return NULL;
1922}
1923
1924static PyObject *
1925delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1926{
1927 PyObject *self = NULL;
1928
1929 /* Argument objects. */
1930 PyObject *day = NULL;
1931 PyObject *second = NULL;
1932 PyObject *us = NULL;
1933 PyObject *ms = NULL;
1934 PyObject *minute = NULL;
1935 PyObject *hour = NULL;
1936 PyObject *week = NULL;
1937
1938 PyObject *x = NULL; /* running sum of microseconds */
1939 PyObject *y = NULL; /* temp sum of microseconds */
1940 double leftover_us = 0.0;
1941
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001942 static char *keywords[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00001943 "days", "seconds", "microseconds", "milliseconds",
1944 "minutes", "hours", "weeks", NULL
1945 };
1946
1947 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1948 keywords,
1949 &day, &second, &us,
1950 &ms, &minute, &hour, &week) == 0)
1951 goto Done;
1952
1953 x = PyInt_FromLong(0);
1954 if (x == NULL)
1955 goto Done;
1956
1957#define CLEANUP \
1958 Py_DECREF(x); \
1959 x = y; \
1960 if (x == NULL) \
1961 goto Done
1962
1963 if (us) {
1964 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1965 CLEANUP;
1966 }
1967 if (ms) {
1968 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1969 CLEANUP;
1970 }
1971 if (second) {
1972 y = accum("seconds", x, second, us_per_second, &leftover_us);
1973 CLEANUP;
1974 }
1975 if (minute) {
1976 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1977 CLEANUP;
1978 }
1979 if (hour) {
1980 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1981 CLEANUP;
1982 }
1983 if (day) {
1984 y = accum("days", x, day, us_per_day, &leftover_us);
1985 CLEANUP;
1986 }
1987 if (week) {
1988 y = accum("weeks", x, week, us_per_week, &leftover_us);
1989 CLEANUP;
1990 }
1991 if (leftover_us) {
1992 /* Round to nearest whole # of us, and add into x. */
Tim Peters5d644dd2003-01-02 16:32:54 +00001993 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
Tim Peters2a799bf2002-12-16 20:18:38 +00001994 if (temp == NULL) {
1995 Py_DECREF(x);
1996 goto Done;
1997 }
1998 y = PyNumber_Add(x, temp);
1999 Py_DECREF(temp);
2000 CLEANUP;
2001 }
2002
Tim Petersb0c854d2003-05-17 15:57:00 +00002003 self = microseconds_to_delta_ex(x, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00002004 Py_DECREF(x);
2005Done:
2006 return self;
2007
2008#undef CLEANUP
2009}
2010
2011static int
2012delta_nonzero(PyDateTime_Delta *self)
2013{
2014 return (GET_TD_DAYS(self) != 0
2015 || GET_TD_SECONDS(self) != 0
2016 || GET_TD_MICROSECONDS(self) != 0);
2017}
2018
2019static PyObject *
2020delta_repr(PyDateTime_Delta *self)
2021{
2022 if (GET_TD_MICROSECONDS(self) != 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002023 return PyString_FromFormat("%s(%d, %d, %d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002024 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002025 GET_TD_DAYS(self),
2026 GET_TD_SECONDS(self),
2027 GET_TD_MICROSECONDS(self));
2028 if (GET_TD_SECONDS(self) != 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002029 return PyString_FromFormat("%s(%d, %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 GET_TD_SECONDS(self));
2033
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002034 return PyString_FromFormat("%s(%d)",
Christian Heimese93237d2007-12-19 02:37:44 +00002035 Py_TYPE(self)->tp_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002036 GET_TD_DAYS(self));
2037}
2038
2039static PyObject *
2040delta_str(PyDateTime_Delta *self)
2041{
2042 int days = GET_TD_DAYS(self);
2043 int seconds = GET_TD_SECONDS(self);
2044 int us = GET_TD_MICROSECONDS(self);
2045 int hours;
2046 int minutes;
Tim Petersba873472002-12-18 20:19:21 +00002047 char buf[100];
2048 char *pbuf = buf;
2049 size_t buflen = sizeof(buf);
2050 int n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002051
2052 minutes = divmod(seconds, 60, &seconds);
2053 hours = divmod(minutes, 60, &minutes);
2054
2055 if (days) {
Tim Petersba873472002-12-18 20:19:21 +00002056 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2057 (days == 1 || days == -1) ? "" : "s");
2058 if (n < 0 || (size_t)n >= buflen)
2059 goto Fail;
2060 pbuf += n;
2061 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002062 }
2063
Tim Petersba873472002-12-18 20:19:21 +00002064 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2065 hours, minutes, seconds);
2066 if (n < 0 || (size_t)n >= buflen)
2067 goto Fail;
2068 pbuf += n;
2069 buflen -= (size_t)n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002070
2071 if (us) {
Tim Petersba873472002-12-18 20:19:21 +00002072 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2073 if (n < 0 || (size_t)n >= buflen)
2074 goto Fail;
2075 pbuf += n;
Tim Peters2a799bf2002-12-16 20:18:38 +00002076 }
2077
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002078 return PyString_FromStringAndSize(buf, pbuf - buf);
Tim Petersba873472002-12-18 20:19:21 +00002079
2080 Fail:
2081 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2082 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002083}
2084
Tim Peters371935f2003-02-01 01:52:50 +00002085/* Pickle support, a simple use of __reduce__. */
2086
Tim Petersb57f8f02003-02-01 02:54:15 +00002087/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002088static PyObject *
2089delta_getstate(PyDateTime_Delta *self)
2090{
2091 return Py_BuildValue("iii", GET_TD_DAYS(self),
2092 GET_TD_SECONDS(self),
2093 GET_TD_MICROSECONDS(self));
2094}
2095
Tim Peters2a799bf2002-12-16 20:18:38 +00002096static PyObject *
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002097delta_total_seconds(PyObject *self)
2098{
2099 return PyFloat_FromDouble(GET_TD_MICROSECONDS(self) / 1000000.0 +
2100 GET_TD_SECONDS(self) +
2101 GET_TD_DAYS(self) * 24.0 * 3600.0);
2102}
2103
2104static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002105delta_reduce(PyDateTime_Delta* self)
2106{
Christian Heimese93237d2007-12-19 02:37:44 +00002107 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002108}
2109
2110#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2111
2112static PyMemberDef delta_members[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002113
Neal Norwitzdfb80862002-12-19 02:30:56 +00002114 {"days", T_INT, OFFSET(days), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002115 PyDoc_STR("Number of days.")},
2116
Neal Norwitzdfb80862002-12-19 02:30:56 +00002117 {"seconds", T_INT, OFFSET(seconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002118 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2119
Neal Norwitzdfb80862002-12-19 02:30:56 +00002120 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
Tim Peters2a799bf2002-12-16 20:18:38 +00002121 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2122 {NULL}
2123};
2124
2125static PyMethodDef delta_methods[] = {
Antoine Pitroubcfaf802009-11-25 22:59:36 +00002126 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2127 PyDoc_STR("Total seconds in the duration.")},
2128
2129 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
Guido van Rossum177e41a2003-01-30 22:06:23 +00002130 PyDoc_STR("__reduce__() -> (cls, state)")},
2131
Tim Peters2a799bf2002-12-16 20:18:38 +00002132 {NULL, NULL},
2133};
2134
2135static char delta_doc[] =
2136PyDoc_STR("Difference between two datetime values.");
2137
2138static PyNumberMethods delta_as_number = {
2139 delta_add, /* nb_add */
2140 delta_subtract, /* nb_subtract */
2141 delta_multiply, /* nb_multiply */
2142 delta_divide, /* nb_divide */
2143 0, /* nb_remainder */
2144 0, /* nb_divmod */
2145 0, /* nb_power */
2146 (unaryfunc)delta_negative, /* nb_negative */
2147 (unaryfunc)delta_positive, /* nb_positive */
2148 (unaryfunc)delta_abs, /* nb_absolute */
2149 (inquiry)delta_nonzero, /* nb_nonzero */
2150 0, /*nb_invert*/
2151 0, /*nb_lshift*/
2152 0, /*nb_rshift*/
2153 0, /*nb_and*/
2154 0, /*nb_xor*/
2155 0, /*nb_or*/
2156 0, /*nb_coerce*/
2157 0, /*nb_int*/
2158 0, /*nb_long*/
2159 0, /*nb_float*/
2160 0, /*nb_oct*/
2161 0, /*nb_hex*/
2162 0, /*nb_inplace_add*/
2163 0, /*nb_inplace_subtract*/
2164 0, /*nb_inplace_multiply*/
2165 0, /*nb_inplace_divide*/
2166 0, /*nb_inplace_remainder*/
2167 0, /*nb_inplace_power*/
2168 0, /*nb_inplace_lshift*/
2169 0, /*nb_inplace_rshift*/
2170 0, /*nb_inplace_and*/
2171 0, /*nb_inplace_xor*/
2172 0, /*nb_inplace_or*/
2173 delta_divide, /* nb_floor_divide */
2174 0, /* nb_true_divide */
2175 0, /* nb_inplace_floor_divide */
2176 0, /* nb_inplace_true_divide */
2177};
2178
2179static PyTypeObject PyDateTime_DeltaType = {
Martin v. Löwis68192102007-07-21 06:55:02 +00002180 PyVarObject_HEAD_INIT(NULL, 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00002181 "datetime.timedelta", /* tp_name */
2182 sizeof(PyDateTime_Delta), /* tp_basicsize */
2183 0, /* tp_itemsize */
2184 0, /* tp_dealloc */
2185 0, /* tp_print */
2186 0, /* tp_getattr */
2187 0, /* tp_setattr */
2188 0, /* tp_compare */
2189 (reprfunc)delta_repr, /* tp_repr */
2190 &delta_as_number, /* tp_as_number */
2191 0, /* tp_as_sequence */
2192 0, /* tp_as_mapping */
2193 (hashfunc)delta_hash, /* tp_hash */
2194 0, /* tp_call */
2195 (reprfunc)delta_str, /* tp_str */
2196 PyObject_GenericGetAttr, /* tp_getattro */
2197 0, /* tp_setattro */
2198 0, /* tp_as_buffer */
Tim Petersb0c854d2003-05-17 15:57:00 +00002199 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2200 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters2a799bf2002-12-16 20:18:38 +00002201 delta_doc, /* tp_doc */
2202 0, /* tp_traverse */
2203 0, /* tp_clear */
2204 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2205 0, /* tp_weaklistoffset */
2206 0, /* tp_iter */
2207 0, /* tp_iternext */
2208 delta_methods, /* tp_methods */
2209 delta_members, /* tp_members */
2210 0, /* tp_getset */
2211 0, /* tp_base */
2212 0, /* tp_dict */
2213 0, /* tp_descr_get */
2214 0, /* tp_descr_set */
2215 0, /* tp_dictoffset */
2216 0, /* tp_init */
2217 0, /* tp_alloc */
2218 delta_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002219 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002220};
2221
2222/*
2223 * PyDateTime_Date implementation.
2224 */
2225
2226/* Accessor properties. */
2227
2228static PyObject *
2229date_year(PyDateTime_Date *self, void *unused)
2230{
2231 return PyInt_FromLong(GET_YEAR(self));
2232}
2233
2234static PyObject *
2235date_month(PyDateTime_Date *self, void *unused)
2236{
2237 return PyInt_FromLong(GET_MONTH(self));
2238}
2239
2240static PyObject *
2241date_day(PyDateTime_Date *self, void *unused)
2242{
2243 return PyInt_FromLong(GET_DAY(self));
2244}
2245
2246static PyGetSetDef date_getset[] = {
2247 {"year", (getter)date_year},
2248 {"month", (getter)date_month},
2249 {"day", (getter)date_day},
2250 {NULL}
2251};
2252
2253/* Constructors. */
2254
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002255static char *date_kws[] = {"year", "month", "day", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00002256
Tim Peters2a799bf2002-12-16 20:18:38 +00002257static PyObject *
2258date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2259{
2260 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00002261 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00002262 int year;
2263 int month;
2264 int day;
2265
Guido van Rossum177e41a2003-01-30 22:06:23 +00002266 /* Check for invocation from pickle with __getstate__ state */
2267 if (PyTuple_GET_SIZE(args) == 1 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002268 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2269 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2270 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00002271 {
Tim Peters70533e22003-02-01 04:40:04 +00002272 PyDateTime_Date *me;
2273
Tim Peters604c0132004-06-07 23:04:33 +00002274 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
Tim Peters70533e22003-02-01 04:40:04 +00002275 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002276 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00002277 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2278 me->hashcode = -1;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002279 }
Tim Peters70533e22003-02-01 04:40:04 +00002280 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00002281 }
2282
Tim Peters12bf3392002-12-24 05:41:27 +00002283 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00002284 &year, &month, &day)) {
2285 if (check_date_args(year, month, day) < 0)
2286 return NULL;
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002287 self = new_date_ex(year, month, day, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00002288 }
2289 return self;
2290}
2291
2292/* Return new date from localtime(t). */
2293static PyObject *
Tim Peters1b6f7a92004-06-20 02:50:16 +00002294date_local_from_time_t(PyObject *cls, double ts)
Tim Peters2a799bf2002-12-16 20:18:38 +00002295{
2296 struct tm *tm;
Tim Peters1b6f7a92004-06-20 02:50:16 +00002297 time_t t;
Tim Peters2a799bf2002-12-16 20:18:38 +00002298 PyObject *result = NULL;
2299
Tim Peters1b6f7a92004-06-20 02:50:16 +00002300 t = _PyTime_DoubleToTimet(ts);
2301 if (t == (time_t)-1 && PyErr_Occurred())
2302 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002303 tm = localtime(&t);
2304 if (tm)
2305 result = PyObject_CallFunction(cls, "iii",
2306 tm->tm_year + 1900,
2307 tm->tm_mon + 1,
2308 tm->tm_mday);
2309 else
2310 PyErr_SetString(PyExc_ValueError,
2311 "timestamp out of range for "
2312 "platform localtime() function");
2313 return result;
2314}
2315
2316/* Return new date from current time.
2317 * We say this is equivalent to fromtimestamp(time.time()), and the
2318 * only way to be sure of that is to *call* time.time(). That's not
2319 * generally the same as calling C's time.
2320 */
2321static PyObject *
2322date_today(PyObject *cls, PyObject *dummy)
2323{
2324 PyObject *time;
2325 PyObject *result;
2326
2327 time = time_time();
2328 if (time == NULL)
2329 return NULL;
2330
2331 /* Note well: today() is a class method, so this may not call
2332 * date.fromtimestamp. For example, it may call
2333 * datetime.fromtimestamp. That's why we need all the accuracy
2334 * time.time() delivers; if someone were gonzo about optimization,
2335 * date.today() could get away with plain C time().
2336 */
2337 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2338 Py_DECREF(time);
2339 return result;
2340}
2341
2342/* Return new date from given timestamp (Python timestamp -- a double). */
2343static PyObject *
2344date_fromtimestamp(PyObject *cls, PyObject *args)
2345{
2346 double timestamp;
2347 PyObject *result = NULL;
2348
2349 if (PyArg_ParseTuple(args, "d:fromtimestamp", &timestamp))
Tim Peters1b6f7a92004-06-20 02:50:16 +00002350 result = date_local_from_time_t(cls, timestamp);
Tim Peters2a799bf2002-12-16 20:18:38 +00002351 return result;
2352}
2353
2354/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2355 * the ordinal is out of range.
2356 */
2357static PyObject *
2358date_fromordinal(PyObject *cls, PyObject *args)
2359{
2360 PyObject *result = NULL;
2361 int ordinal;
2362
2363 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2364 int year;
2365 int month;
2366 int day;
2367
2368 if (ordinal < 1)
2369 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2370 ">= 1");
2371 else {
2372 ord_to_ymd(ordinal, &year, &month, &day);
2373 result = PyObject_CallFunction(cls, "iii",
2374 year, month, day);
2375 }
2376 }
2377 return result;
2378}
2379
2380/*
2381 * Date arithmetic.
2382 */
2383
2384/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2385 * instead.
2386 */
2387static PyObject *
2388add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2389{
2390 PyObject *result = NULL;
2391 int year = GET_YEAR(date);
2392 int month = GET_MONTH(date);
2393 int deltadays = GET_TD_DAYS(delta);
2394 /* C-level overflow is impossible because |deltadays| < 1e9. */
2395 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2396
2397 if (normalize_date(&year, &month, &day) >= 0)
2398 result = new_date(year, month, day);
2399 return result;
2400}
2401
2402static PyObject *
2403date_add(PyObject *left, PyObject *right)
2404{
2405 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2406 Py_INCREF(Py_NotImplemented);
2407 return Py_NotImplemented;
2408 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002409 if (PyDate_Check(left)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002410 /* date + ??? */
2411 if (PyDelta_Check(right))
2412 /* date + delta */
2413 return add_date_timedelta((PyDateTime_Date *) left,
2414 (PyDateTime_Delta *) right,
2415 0);
2416 }
2417 else {
2418 /* ??? + date
2419 * 'right' must be one of us, or we wouldn't have been called
2420 */
2421 if (PyDelta_Check(left))
2422 /* delta + date */
2423 return add_date_timedelta((PyDateTime_Date *) right,
2424 (PyDateTime_Delta *) left,
2425 0);
2426 }
2427 Py_INCREF(Py_NotImplemented);
2428 return Py_NotImplemented;
2429}
2430
2431static PyObject *
2432date_subtract(PyObject *left, PyObject *right)
2433{
2434 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2435 Py_INCREF(Py_NotImplemented);
2436 return Py_NotImplemented;
2437 }
Tim Petersaa7d8492003-02-08 03:28:59 +00002438 if (PyDate_Check(left)) {
2439 if (PyDate_Check(right)) {
Tim Peters2a799bf2002-12-16 20:18:38 +00002440 /* date - date */
2441 int left_ord = ymd_to_ord(GET_YEAR(left),
2442 GET_MONTH(left),
2443 GET_DAY(left));
2444 int right_ord = ymd_to_ord(GET_YEAR(right),
2445 GET_MONTH(right),
2446 GET_DAY(right));
2447 return new_delta(left_ord - right_ord, 0, 0, 0);
2448 }
2449 if (PyDelta_Check(right)) {
2450 /* date - delta */
2451 return add_date_timedelta((PyDateTime_Date *) left,
2452 (PyDateTime_Delta *) right,
2453 1);
2454 }
2455 }
2456 Py_INCREF(Py_NotImplemented);
2457 return Py_NotImplemented;
2458}
2459
2460
2461/* Various ways to turn a date into a string. */
2462
2463static PyObject *
2464date_repr(PyDateTime_Date *self)
2465{
2466 char buffer[1028];
Skip Montanaro14f88992006-04-18 19:35:04 +00002467 const char *type_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002468
Christian Heimese93237d2007-12-19 02:37:44 +00002469 type_name = Py_TYPE(self)->tp_name;
Tim Peters2a799bf2002-12-16 20:18:38 +00002470 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00002471 type_name,
Tim Peters2a799bf2002-12-16 20:18:38 +00002472 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2473
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002474 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002475}
2476
2477static PyObject *
2478date_isoformat(PyDateTime_Date *self)
2479{
2480 char buffer[128];
2481
2482 isoformat_date(self, buffer, sizeof(buffer));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002483 return PyString_FromString(buffer);
Tim Peters2a799bf2002-12-16 20:18:38 +00002484}
2485
Tim Peterse2df5ff2003-05-02 18:39:55 +00002486/* str() calls the appropriate isoformat() method. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002487static PyObject *
2488date_str(PyDateTime_Date *self)
2489{
2490 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2491}
2492
2493
2494static PyObject *
2495date_ctime(PyDateTime_Date *self)
2496{
2497 return format_ctime(self, 0, 0, 0);
2498}
2499
2500static PyObject *
2501date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2502{
2503 /* This method can be inherited, and needs to call the
2504 * timetuple() method appropriate to self's class.
2505 */
2506 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00002507 PyObject *tuple;
Gregory P. Smith137d8242008-06-02 04:05:52 +00002508 const char *format;
2509 Py_ssize_t format_len;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002510 static char *keywords[] = {"format", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00002511
Gregory P. Smith137d8242008-06-02 04:05:52 +00002512 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2513 &format, &format_len))
Tim Peters2a799bf2002-12-16 20:18:38 +00002514 return NULL;
2515
2516 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2517 if (tuple == NULL)
2518 return NULL;
Gregory P. Smith137d8242008-06-02 04:05:52 +00002519 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
Tim Petersbad8ff02002-12-30 20:52:32 +00002520 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00002521 Py_DECREF(tuple);
2522 return result;
2523}
2524
Eric Smitha9f7d622008-02-17 19:46:49 +00002525static PyObject *
2526date_format(PyDateTime_Date *self, PyObject *args)
2527{
2528 PyObject *format;
2529
2530 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2531 return NULL;
2532
2533 /* Check for str or unicode */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002534 if (PyString_Check(format)) {
Eric Smitha9f7d622008-02-17 19:46:49 +00002535 /* If format is zero length, return str(self) */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002536 if (PyString_GET_SIZE(format) == 0)
Eric Smitha9f7d622008-02-17 19:46:49 +00002537 return PyObject_Str((PyObject *)self);
2538 } else if (PyUnicode_Check(format)) {
2539 /* If format is zero length, return str(self) */
2540 if (PyUnicode_GET_SIZE(format) == 0)
2541 return PyObject_Unicode((PyObject *)self);
2542 } else {
2543 PyErr_Format(PyExc_ValueError,
2544 "__format__ expects str or unicode, not %.200s",
2545 Py_TYPE(format)->tp_name);
2546 return NULL;
2547 }
2548 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2549}
2550
Tim Peters2a799bf2002-12-16 20:18:38 +00002551/* ISO methods. */
2552
2553static PyObject *
2554date_isoweekday(PyDateTime_Date *self)
2555{
2556 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2557
2558 return PyInt_FromLong(dow + 1);
2559}
2560
2561static PyObject *
2562date_isocalendar(PyDateTime_Date *self)
2563{
2564 int year = GET_YEAR(self);
2565 int week1_monday = iso_week1_monday(year);
2566 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2567 int week;
2568 int day;
2569
2570 week = divmod(today - week1_monday, 7, &day);
2571 if (week < 0) {
2572 --year;
2573 week1_monday = iso_week1_monday(year);
2574 week = divmod(today - week1_monday, 7, &day);
2575 }
2576 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2577 ++year;
2578 week = 0;
2579 }
2580 return Py_BuildValue("iii", year, week + 1, day + 1);
2581}
2582
2583/* Miscellaneous methods. */
2584
2585/* This is more natural as a tp_compare, but doesn't work then: for whatever
2586 * reason, Python's try_3way_compare ignores tp_compare unless
2587 * PyInstance_Check returns true, but these aren't old-style classes.
2588 */
2589static PyObject *
2590date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2591{
Tim Peters07534a62003-02-07 22:50:28 +00002592 int diff = 42; /* nonsense */
Tim Peters2a799bf2002-12-16 20:18:38 +00002593
Tim Peters07534a62003-02-07 22:50:28 +00002594 if (PyDate_Check(other))
2595 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2596 _PyDateTime_DATE_DATASIZE);
2597
2598 else if (PyObject_HasAttrString(other, "timetuple")) {
2599 /* A hook for other kinds of date objects. */
2600 Py_INCREF(Py_NotImplemented);
2601 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00002602 }
Tim Peters07534a62003-02-07 22:50:28 +00002603 else if (op == Py_EQ || op == Py_NE)
2604 diff = 1; /* any non-zero value will do */
2605
2606 else /* stop this from falling back to address comparison */
2607 return cmperror((PyObject *)self, other);
2608
Tim Peters2a799bf2002-12-16 20:18:38 +00002609 return diff_to_bool(diff, op);
2610}
2611
2612static PyObject *
2613date_timetuple(PyDateTime_Date *self)
2614{
2615 return build_struct_time(GET_YEAR(self),
2616 GET_MONTH(self),
2617 GET_DAY(self),
2618 0, 0, 0, -1);
2619}
2620
Tim Peters12bf3392002-12-24 05:41:27 +00002621static PyObject *
2622date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2623{
2624 PyObject *clone;
2625 PyObject *tuple;
2626 int year = GET_YEAR(self);
2627 int month = GET_MONTH(self);
2628 int day = GET_DAY(self);
2629
2630 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2631 &year, &month, &day))
2632 return NULL;
2633 tuple = Py_BuildValue("iii", year, month, day);
2634 if (tuple == NULL)
2635 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00002636 clone = date_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00002637 Py_DECREF(tuple);
2638 return clone;
2639}
2640
Tim Peters2a799bf2002-12-16 20:18:38 +00002641static PyObject *date_getstate(PyDateTime_Date *self);
2642
2643static long
2644date_hash(PyDateTime_Date *self)
2645{
2646 if (self->hashcode == -1) {
2647 PyObject *temp = date_getstate(self);
2648 if (temp != NULL) {
2649 self->hashcode = PyObject_Hash(temp);
2650 Py_DECREF(temp);
2651 }
2652 }
2653 return self->hashcode;
2654}
2655
2656static PyObject *
2657date_toordinal(PyDateTime_Date *self)
2658{
2659 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2660 GET_DAY(self)));
2661}
2662
2663static PyObject *
2664date_weekday(PyDateTime_Date *self)
2665{
2666 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2667
2668 return PyInt_FromLong(dow);
2669}
2670
Tim Peters371935f2003-02-01 01:52:50 +00002671/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00002672
Tim Petersb57f8f02003-02-01 02:54:15 +00002673/* __getstate__ isn't exposed */
Tim Peters2a799bf2002-12-16 20:18:38 +00002674static PyObject *
2675date_getstate(PyDateTime_Date *self)
2676{
Guido van Rossum177e41a2003-01-30 22:06:23 +00002677 return Py_BuildValue(
2678 "(N)",
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002679 PyString_FromStringAndSize((char *)self->data,
Guido van Rossum177e41a2003-01-30 22:06:23 +00002680 _PyDateTime_DATE_DATASIZE));
Tim Peters2a799bf2002-12-16 20:18:38 +00002681}
2682
2683static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00002684date_reduce(PyDateTime_Date *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00002685{
Christian Heimese93237d2007-12-19 02:37:44 +00002686 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00002687}
2688
2689static PyMethodDef date_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002690
Tim Peters2a799bf2002-12-16 20:18:38 +00002691 /* Class methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00002692
Tim Peters2a799bf2002-12-16 20:18:38 +00002693 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2694 METH_CLASS,
2695 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2696 "time.time()).")},
2697
2698 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2699 METH_CLASS,
2700 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2701 "ordinal.")},
2702
2703 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2704 PyDoc_STR("Current date or datetime: same as "
2705 "self.__class__.fromtimestamp(time.time()).")},
2706
2707 /* Instance methods: */
2708
2709 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2710 PyDoc_STR("Return ctime() style string.")},
2711
Neal Norwitza84dcd72007-05-22 07:16:44 +00002712 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00002713 PyDoc_STR("format -> strftime() style string.")},
2714
Eric Smitha9f7d622008-02-17 19:46:49 +00002715 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2716 PyDoc_STR("Formats self with strftime.")},
2717
Tim Peters2a799bf2002-12-16 20:18:38 +00002718 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2719 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2720
2721 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2722 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2723 "weekday.")},
2724
2725 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2726 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2727
2728 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2729 PyDoc_STR("Return the day of the week represented by the date.\n"
2730 "Monday == 1 ... Sunday == 7")},
2731
2732 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2733 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2734 "1 is day 1.")},
2735
2736 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2737 PyDoc_STR("Return the day of the week represented by the date.\n"
2738 "Monday == 0 ... Sunday == 6")},
2739
Neal Norwitza84dcd72007-05-22 07:16:44 +00002740 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
Tim Peters12bf3392002-12-24 05:41:27 +00002741 PyDoc_STR("Return date with new specified fields.")},
2742
Guido van Rossum177e41a2003-01-30 22:06:23 +00002743 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2744 PyDoc_STR("__reduce__() -> (cls, state)")},
2745
Tim Peters2a799bf2002-12-16 20:18:38 +00002746 {NULL, NULL}
2747};
2748
2749static char date_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00002750PyDoc_STR("date(year, month, day) --> date object");
Tim Peters2a799bf2002-12-16 20:18:38 +00002751
2752static PyNumberMethods date_as_number = {
2753 date_add, /* nb_add */
2754 date_subtract, /* nb_subtract */
2755 0, /* nb_multiply */
2756 0, /* nb_divide */
2757 0, /* nb_remainder */
2758 0, /* nb_divmod */
2759 0, /* nb_power */
2760 0, /* nb_negative */
2761 0, /* nb_positive */
2762 0, /* nb_absolute */
2763 0, /* nb_nonzero */
2764};
2765
2766static PyTypeObject PyDateTime_DateType = {
Martin v. Löwis68192102007-07-21 06:55:02 +00002767 PyVarObject_HEAD_INIT(NULL, 0)
Tim Peters2a799bf2002-12-16 20:18:38 +00002768 "datetime.date", /* tp_name */
2769 sizeof(PyDateTime_Date), /* tp_basicsize */
2770 0, /* tp_itemsize */
Guido van Rossum8b7a9a32003-04-14 22:01:58 +00002771 0, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00002772 0, /* tp_print */
2773 0, /* tp_getattr */
2774 0, /* tp_setattr */
2775 0, /* tp_compare */
2776 (reprfunc)date_repr, /* tp_repr */
2777 &date_as_number, /* tp_as_number */
2778 0, /* tp_as_sequence */
2779 0, /* tp_as_mapping */
2780 (hashfunc)date_hash, /* tp_hash */
2781 0, /* tp_call */
2782 (reprfunc)date_str, /* tp_str */
2783 PyObject_GenericGetAttr, /* tp_getattro */
2784 0, /* tp_setattro */
2785 0, /* tp_as_buffer */
2786 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2787 Py_TPFLAGS_BASETYPE, /* tp_flags */
2788 date_doc, /* tp_doc */
2789 0, /* tp_traverse */
2790 0, /* tp_clear */
2791 (richcmpfunc)date_richcompare, /* tp_richcompare */
2792 0, /* tp_weaklistoffset */
2793 0, /* tp_iter */
2794 0, /* tp_iternext */
2795 date_methods, /* tp_methods */
2796 0, /* tp_members */
2797 date_getset, /* tp_getset */
2798 0, /* tp_base */
2799 0, /* tp_dict */
2800 0, /* tp_descr_get */
2801 0, /* tp_descr_set */
2802 0, /* tp_dictoffset */
2803 0, /* tp_init */
2804 0, /* tp_alloc */
2805 date_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00002806 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00002807};
2808
2809/*
Tim Peters2a799bf2002-12-16 20:18:38 +00002810 * PyDateTime_TZInfo implementation.
2811 */
2812
2813/* This is a pure abstract base class, so doesn't do anything beyond
2814 * raising NotImplemented exceptions. Real tzinfo classes need
2815 * to derive from this. This is mostly for clarity, and for efficiency in
Tim Petersa9bc1682003-01-11 03:39:11 +00002816 * datetime and time constructors (their tzinfo arguments need to
Tim Peters2a799bf2002-12-16 20:18:38 +00002817 * be subclasses of this tzinfo class, which is easy and quick to check).
2818 *
2819 * Note: For reasons having to do with pickling of subclasses, we have
2820 * to allow tzinfo objects to be instantiated. This wasn't an issue
2821 * in the Python implementation (__init__() could raise NotImplementedError
2822 * there without ill effect), but doing so in the C implementation hit a
2823 * brick wall.
2824 */
2825
2826static PyObject *
2827tzinfo_nogo(const char* methodname)
2828{
2829 PyErr_Format(PyExc_NotImplementedError,
2830 "a tzinfo subclass must implement %s()",
2831 methodname);
2832 return NULL;
2833}
2834
2835/* Methods. A subclass must implement these. */
2836
Tim Peters52dcce22003-01-23 16:36:11 +00002837static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002838tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2839{
2840 return tzinfo_nogo("tzname");
2841}
2842
Tim Peters52dcce22003-01-23 16:36:11 +00002843static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002844tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2845{
2846 return tzinfo_nogo("utcoffset");
2847}
2848
Tim Peters52dcce22003-01-23 16:36:11 +00002849static PyObject *
Tim Peters2a799bf2002-12-16 20:18:38 +00002850tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2851{
2852 return tzinfo_nogo("dst");
2853}
2854
Tim Peters52dcce22003-01-23 16:36:11 +00002855static PyObject *
2856tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2857{
2858 int y, m, d, hh, mm, ss, us;
2859
2860 PyObject *result;
2861 int off, dst;
2862 int none;
2863 int delta;
2864
2865 if (! PyDateTime_Check(dt)) {
2866 PyErr_SetString(PyExc_TypeError,
2867 "fromutc: argument must be a datetime");
2868 return NULL;
2869 }
2870 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2871 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2872 "is not self");
2873 return NULL;
2874 }
2875
2876 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2877 if (off == -1 && PyErr_Occurred())
2878 return NULL;
2879 if (none) {
2880 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2881 "utcoffset() result required");
2882 return NULL;
2883 }
2884
2885 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2886 if (dst == -1 && PyErr_Occurred())
2887 return NULL;
2888 if (none) {
2889 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2890 "dst() result required");
2891 return NULL;
2892 }
2893
2894 y = GET_YEAR(dt);
2895 m = GET_MONTH(dt);
2896 d = GET_DAY(dt);
2897 hh = DATE_GET_HOUR(dt);
2898 mm = DATE_GET_MINUTE(dt);
2899 ss = DATE_GET_SECOND(dt);
2900 us = DATE_GET_MICROSECOND(dt);
2901
2902 delta = off - dst;
2903 mm += delta;
2904 if ((mm < 0 || mm >= 60) &&
2905 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Petersb1049e82003-01-23 17:20:36 +00002906 return NULL;
Tim Peters52dcce22003-01-23 16:36:11 +00002907 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2908 if (result == NULL)
2909 return result;
2910
2911 dst = call_dst(dt->tzinfo, result, &none);
2912 if (dst == -1 && PyErr_Occurred())
2913 goto Fail;
2914 if (none)
2915 goto Inconsistent;
2916 if (dst == 0)
2917 return result;
2918
2919 mm += dst;
2920 if ((mm < 0 || mm >= 60) &&
2921 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2922 goto Fail;
2923 Py_DECREF(result);
2924 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2925 return result;
2926
2927Inconsistent:
2928 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2929 "inconsistent results; cannot convert");
2930
2931 /* fall thru to failure */
2932Fail:
2933 Py_DECREF(result);
2934 return NULL;
2935}
2936
Tim Peters2a799bf2002-12-16 20:18:38 +00002937/*
2938 * Pickle support. This is solely so that tzinfo subclasses can use
Guido van Rossum177e41a2003-01-30 22:06:23 +00002939 * pickling -- tzinfo itself is supposed to be uninstantiable.
Tim Peters2a799bf2002-12-16 20:18:38 +00002940 */
2941
Guido van Rossum177e41a2003-01-30 22:06:23 +00002942static PyObject *
2943tzinfo_reduce(PyObject *self)
2944{
2945 PyObject *args, *state, *tmp;
2946 PyObject *getinitargs, *getstate;
Tim Peters2a799bf2002-12-16 20:18:38 +00002947
Guido van Rossum177e41a2003-01-30 22:06:23 +00002948 tmp = PyTuple_New(0);
2949 if (tmp == NULL)
2950 return NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00002951
Guido van Rossum177e41a2003-01-30 22:06:23 +00002952 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2953 if (getinitargs != NULL) {
2954 args = PyObject_CallObject(getinitargs, tmp);
2955 Py_DECREF(getinitargs);
2956 if (args == NULL) {
2957 Py_DECREF(tmp);
2958 return NULL;
2959 }
2960 }
2961 else {
2962 PyErr_Clear();
2963 args = tmp;
2964 Py_INCREF(args);
2965 }
2966
2967 getstate = PyObject_GetAttrString(self, "__getstate__");
2968 if (getstate != NULL) {
2969 state = PyObject_CallObject(getstate, tmp);
2970 Py_DECREF(getstate);
2971 if (state == NULL) {
2972 Py_DECREF(args);
2973 Py_DECREF(tmp);
2974 return NULL;
2975 }
2976 }
2977 else {
2978 PyObject **dictptr;
2979 PyErr_Clear();
2980 state = Py_None;
2981 dictptr = _PyObject_GetDictPtr(self);
2982 if (dictptr && *dictptr && PyDict_Size(*dictptr))
2983 state = *dictptr;
2984 Py_INCREF(state);
2985 }
2986
2987 Py_DECREF(tmp);
2988
2989 if (state == Py_None) {
2990 Py_DECREF(state);
Christian Heimese93237d2007-12-19 02:37:44 +00002991 return Py_BuildValue("(ON)", Py_TYPE(self), args);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002992 }
2993 else
Christian Heimese93237d2007-12-19 02:37:44 +00002994 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
Guido van Rossum177e41a2003-01-30 22:06:23 +00002995}
Tim Peters2a799bf2002-12-16 20:18:38 +00002996
2997static PyMethodDef tzinfo_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00002998
Tim Peters2a799bf2002-12-16 20:18:38 +00002999 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3000 PyDoc_STR("datetime -> string name of time zone.")},
3001
3002 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
3003 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3004 "west of UTC).")},
3005
3006 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3007 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3008
Tim Peters52dcce22003-01-23 16:36:11 +00003009 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
3010 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3011
Guido van Rossum177e41a2003-01-30 22:06:23 +00003012 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3013 PyDoc_STR("-> (cls, state)")},
3014
Tim Peters2a799bf2002-12-16 20:18:38 +00003015 {NULL, NULL}
3016};
3017
3018static char tzinfo_doc[] =
3019PyDoc_STR("Abstract base class for time zone info objects.");
3020
Neal Norwitzce3d34d2003-02-04 20:45:17 +00003021statichere PyTypeObject PyDateTime_TZInfoType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003022 PyObject_HEAD_INIT(NULL)
3023 0, /* ob_size */
3024 "datetime.tzinfo", /* tp_name */
3025 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3026 0, /* tp_itemsize */
3027 0, /* tp_dealloc */
3028 0, /* tp_print */
3029 0, /* tp_getattr */
3030 0, /* tp_setattr */
3031 0, /* tp_compare */
3032 0, /* tp_repr */
3033 0, /* tp_as_number */
3034 0, /* tp_as_sequence */
3035 0, /* tp_as_mapping */
3036 0, /* tp_hash */
3037 0, /* tp_call */
3038 0, /* tp_str */
3039 PyObject_GenericGetAttr, /* tp_getattro */
3040 0, /* tp_setattro */
3041 0, /* tp_as_buffer */
3042 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3043 Py_TPFLAGS_BASETYPE, /* tp_flags */
3044 tzinfo_doc, /* tp_doc */
3045 0, /* tp_traverse */
3046 0, /* tp_clear */
3047 0, /* tp_richcompare */
3048 0, /* tp_weaklistoffset */
3049 0, /* tp_iter */
3050 0, /* tp_iternext */
3051 tzinfo_methods, /* tp_methods */
3052 0, /* tp_members */
3053 0, /* tp_getset */
3054 0, /* tp_base */
3055 0, /* tp_dict */
3056 0, /* tp_descr_get */
3057 0, /* tp_descr_set */
3058 0, /* tp_dictoffset */
3059 0, /* tp_init */
3060 0, /* tp_alloc */
3061 PyType_GenericNew, /* tp_new */
3062 0, /* tp_free */
3063};
3064
3065/*
Tim Peters37f39822003-01-10 03:49:02 +00003066 * PyDateTime_Time implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003067 */
3068
Tim Peters37f39822003-01-10 03:49:02 +00003069/* Accessor properties.
Tim Peters2a799bf2002-12-16 20:18:38 +00003070 */
3071
3072static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003073time_hour(PyDateTime_Time *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003074{
Tim Peters37f39822003-01-10 03:49:02 +00003075 return PyInt_FromLong(TIME_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003076}
3077
Tim Peters37f39822003-01-10 03:49:02 +00003078static PyObject *
3079time_minute(PyDateTime_Time *self, void *unused)
3080{
3081 return PyInt_FromLong(TIME_GET_MINUTE(self));
3082}
3083
3084/* The name time_second conflicted with some platform header file. */
3085static PyObject *
3086py_time_second(PyDateTime_Time *self, void *unused)
3087{
3088 return PyInt_FromLong(TIME_GET_SECOND(self));
3089}
3090
3091static PyObject *
3092time_microsecond(PyDateTime_Time *self, void *unused)
3093{
3094 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3095}
3096
3097static PyObject *
3098time_tzinfo(PyDateTime_Time *self, void *unused)
3099{
Tim Petersa032d2e2003-01-11 00:15:54 +00003100 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters37f39822003-01-10 03:49:02 +00003101 Py_INCREF(result);
3102 return result;
3103}
3104
3105static PyGetSetDef time_getset[] = {
3106 {"hour", (getter)time_hour},
3107 {"minute", (getter)time_minute},
3108 {"second", (getter)py_time_second},
3109 {"microsecond", (getter)time_microsecond},
3110 {"tzinfo", (getter)time_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003111 {NULL}
3112};
3113
3114/*
3115 * Constructors.
3116 */
3117
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003118static char *time_kws[] = {"hour", "minute", "second", "microsecond",
Tim Peters37f39822003-01-10 03:49:02 +00003119 "tzinfo", NULL};
Tim Peters12bf3392002-12-24 05:41:27 +00003120
Tim Peters2a799bf2002-12-16 20:18:38 +00003121static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003122time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003123{
3124 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003125 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003126 int hour = 0;
3127 int minute = 0;
3128 int second = 0;
3129 int usecond = 0;
3130 PyObject *tzinfo = Py_None;
3131
Guido van Rossum177e41a2003-01-30 22:06:23 +00003132 /* Check for invocation from pickle with __getstate__ state */
3133 if (PyTuple_GET_SIZE(args) >= 1 &&
3134 PyTuple_GET_SIZE(args) <= 2 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003135 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3136 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3137 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
Guido van Rossum177e41a2003-01-30 22:06:23 +00003138 {
Tim Peters70533e22003-02-01 04:40:04 +00003139 PyDateTime_Time *me;
3140 char aware;
3141
3142 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003143 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003144 if (check_tzinfo_subclass(tzinfo) < 0) {
3145 PyErr_SetString(PyExc_TypeError, "bad "
3146 "tzinfo state arg");
3147 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003148 }
3149 }
Tim Peters70533e22003-02-01 04:40:04 +00003150 aware = (char)(tzinfo != Py_None);
Tim Peters604c0132004-06-07 23:04:33 +00003151 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
Tim Peters70533e22003-02-01 04:40:04 +00003152 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003153 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003154
3155 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3156 me->hashcode = -1;
3157 me->hastzinfo = aware;
3158 if (aware) {
3159 Py_INCREF(tzinfo);
3160 me->tzinfo = tzinfo;
3161 }
3162 }
3163 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003164 }
3165
Tim Peters37f39822003-01-10 03:49:02 +00003166 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003167 &hour, &minute, &second, &usecond,
3168 &tzinfo)) {
3169 if (check_time_args(hour, minute, second, usecond) < 0)
3170 return NULL;
3171 if (check_tzinfo_subclass(tzinfo) < 0)
3172 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003173 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3174 type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003175 }
3176 return self;
3177}
3178
3179/*
3180 * Destructor.
3181 */
3182
3183static void
Tim Peters37f39822003-01-10 03:49:02 +00003184time_dealloc(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003185{
Tim Petersa032d2e2003-01-11 00:15:54 +00003186 if (HASTZINFO(self)) {
Tim Peters37f39822003-01-10 03:49:02 +00003187 Py_XDECREF(self->tzinfo);
Neal Norwitz8e914d92003-01-10 15:29:16 +00003188 }
Christian Heimese93237d2007-12-19 02:37:44 +00003189 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00003190}
3191
3192/*
Tim Peters855fe882002-12-22 03:43:39 +00003193 * Indirect access to tzinfo methods.
Tim Peters2a799bf2002-12-16 20:18:38 +00003194 */
3195
Tim Peters2a799bf2002-12-16 20:18:38 +00003196/* These are all METH_NOARGS, so don't need to check the arglist. */
3197static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003198time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003199 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003200 "utcoffset", Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003201}
3202
3203static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003204time_dst(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003205 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003206 "dst", Py_None);
Tim Peters855fe882002-12-22 03:43:39 +00003207}
3208
3209static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003210time_tzname(PyDateTime_Time *self, PyObject *unused) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003211 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
Tim Peters37f39822003-01-10 03:49:02 +00003212 Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00003213}
3214
3215/*
Tim Peters37f39822003-01-10 03:49:02 +00003216 * Various ways to turn a time into a string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003217 */
3218
3219static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003220time_repr(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003221{
Tim Peters37f39822003-01-10 03:49:02 +00003222 char buffer[100];
Christian Heimese93237d2007-12-19 02:37:44 +00003223 const char *type_name = Py_TYPE(self)->tp_name;
Tim Peters37f39822003-01-10 03:49:02 +00003224 int h = TIME_GET_HOUR(self);
3225 int m = TIME_GET_MINUTE(self);
3226 int s = TIME_GET_SECOND(self);
3227 int us = TIME_GET_MICROSECOND(self);
3228 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003229
Tim Peters37f39822003-01-10 03:49:02 +00003230 if (us)
3231 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003232 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
Tim Peters37f39822003-01-10 03:49:02 +00003233 else if (s)
3234 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003235 "%s(%d, %d, %d)", type_name, h, m, s);
Tim Peters37f39822003-01-10 03:49:02 +00003236 else
3237 PyOS_snprintf(buffer, sizeof(buffer),
Skip Montanaro14f88992006-04-18 19:35:04 +00003238 "%s(%d, %d)", type_name, h, m);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003239 result = PyString_FromString(buffer);
Tim Petersa032d2e2003-01-11 00:15:54 +00003240 if (result != NULL && HASTZINFO(self))
Tim Peters37f39822003-01-10 03:49:02 +00003241 result = append_keyword_tzinfo(result, self->tzinfo);
3242 return result;
Tim Peters2a799bf2002-12-16 20:18:38 +00003243}
3244
Tim Peters37f39822003-01-10 03:49:02 +00003245static PyObject *
3246time_str(PyDateTime_Time *self)
3247{
3248 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3249}
Tim Peters2a799bf2002-12-16 20:18:38 +00003250
3251static PyObject *
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003252time_isoformat(PyDateTime_Time *self, PyObject *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003253{
3254 char buf[100];
Tim Peters37f39822003-01-10 03:49:02 +00003255 PyObject *result;
3256 /* Reuse the time format code from the datetime type. */
3257 PyDateTime_DateTime datetime;
3258 PyDateTime_DateTime *pdatetime = &datetime;
Tim Peters2a799bf2002-12-16 20:18:38 +00003259
Tim Peters37f39822003-01-10 03:49:02 +00003260 /* Copy over just the time bytes. */
3261 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3262 self->data,
3263 _PyDateTime_TIME_DATASIZE);
3264
3265 isoformat_time(pdatetime, buf, sizeof(buf));
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003266 result = PyString_FromString(buf);
Tim Petersa032d2e2003-01-11 00:15:54 +00003267 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
Tim Peters2a799bf2002-12-16 20:18:38 +00003268 return result;
3269
3270 /* We need to append the UTC offset. */
3271 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
Tim Petersbad8ff02002-12-30 20:52:32 +00003272 Py_None) < 0) {
Tim Peters2a799bf2002-12-16 20:18:38 +00003273 Py_DECREF(result);
3274 return NULL;
3275 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003276 PyString_ConcatAndDel(&result, PyString_FromString(buf));
Tim Peters2a799bf2002-12-16 20:18:38 +00003277 return result;
3278}
3279
Tim Peters37f39822003-01-10 03:49:02 +00003280static PyObject *
3281time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3282{
3283 PyObject *result;
Tim Peters37f39822003-01-10 03:49:02 +00003284 PyObject *tuple;
Gregory P. Smith137d8242008-06-02 04:05:52 +00003285 const char *format;
3286 Py_ssize_t format_len;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003287 static char *keywords[] = {"format", NULL};
Tim Peters37f39822003-01-10 03:49:02 +00003288
Gregory P. Smith137d8242008-06-02 04:05:52 +00003289 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3290 &format, &format_len))
Tim Peters37f39822003-01-10 03:49:02 +00003291 return NULL;
3292
3293 /* Python's strftime does insane things with the year part of the
3294 * timetuple. The year is forced to (the otherwise nonsensical)
3295 * 1900 to worm around that.
3296 */
3297 tuple = Py_BuildValue("iiiiiiiii",
Brett Cannond1080a32004-03-02 04:38:10 +00003298 1900, 1, 1, /* year, month, day */
Tim Peters37f39822003-01-10 03:49:02 +00003299 TIME_GET_HOUR(self),
3300 TIME_GET_MINUTE(self),
3301 TIME_GET_SECOND(self),
Brett Cannond1080a32004-03-02 04:38:10 +00003302 0, 1, -1); /* weekday, daynum, dst */
Tim Peters37f39822003-01-10 03:49:02 +00003303 if (tuple == NULL)
3304 return NULL;
3305 assert(PyTuple_Size(tuple) == 9);
Gregory P. Smith137d8242008-06-02 04:05:52 +00003306 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3307 Py_None);
Tim Peters37f39822003-01-10 03:49:02 +00003308 Py_DECREF(tuple);
3309 return result;
3310}
Tim Peters2a799bf2002-12-16 20:18:38 +00003311
3312/*
3313 * Miscellaneous methods.
3314 */
3315
Tim Peters37f39822003-01-10 03:49:02 +00003316/* This is more natural as a tp_compare, but doesn't work then: for whatever
3317 * reason, Python's try_3way_compare ignores tp_compare unless
3318 * PyInstance_Check returns true, but these aren't old-style classes.
3319 */
3320static PyObject *
3321time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3322{
3323 int diff;
3324 naivety n1, n2;
3325 int offset1, offset2;
3326
3327 if (! PyTime_Check(other)) {
Tim Peters07534a62003-02-07 22:50:28 +00003328 if (op == Py_EQ || op == Py_NE) {
3329 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3330 Py_INCREF(result);
3331 return result;
3332 }
Tim Peters37f39822003-01-10 03:49:02 +00003333 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00003334 return cmperror((PyObject *)self, other);
Tim Peters37f39822003-01-10 03:49:02 +00003335 }
3336 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3337 other, &offset2, &n2, Py_None) < 0)
3338 return NULL;
3339 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3340 /* If they're both naive, or both aware and have the same offsets,
3341 * we get off cheap. Note that if they're both naive, offset1 ==
3342 * offset2 == 0 at this point.
3343 */
3344 if (n1 == n2 && offset1 == offset2) {
3345 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3346 _PyDateTime_TIME_DATASIZE);
3347 return diff_to_bool(diff, op);
3348 }
3349
3350 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3351 assert(offset1 != offset2); /* else last "if" handled it */
3352 /* Convert everything except microseconds to seconds. These
3353 * can't overflow (no more than the # of seconds in 2 days).
3354 */
3355 offset1 = TIME_GET_HOUR(self) * 3600 +
3356 (TIME_GET_MINUTE(self) - offset1) * 60 +
3357 TIME_GET_SECOND(self);
3358 offset2 = TIME_GET_HOUR(other) * 3600 +
3359 (TIME_GET_MINUTE(other) - offset2) * 60 +
3360 TIME_GET_SECOND(other);
3361 diff = offset1 - offset2;
3362 if (diff == 0)
3363 diff = TIME_GET_MICROSECOND(self) -
3364 TIME_GET_MICROSECOND(other);
3365 return diff_to_bool(diff, op);
3366 }
3367
3368 assert(n1 != n2);
3369 PyErr_SetString(PyExc_TypeError,
3370 "can't compare offset-naive and "
3371 "offset-aware times");
3372 return NULL;
3373}
3374
3375static long
3376time_hash(PyDateTime_Time *self)
3377{
3378 if (self->hashcode == -1) {
3379 naivety n;
3380 int offset;
3381 PyObject *temp;
3382
3383 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3384 assert(n != OFFSET_UNKNOWN);
3385 if (n == OFFSET_ERROR)
3386 return -1;
3387
3388 /* Reduce this to a hash of another object. */
3389 if (offset == 0)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003390 temp = PyString_FromStringAndSize((char *)self->data,
Tim Peters37f39822003-01-10 03:49:02 +00003391 _PyDateTime_TIME_DATASIZE);
3392 else {
3393 int hour;
3394 int minute;
3395
3396 assert(n == OFFSET_AWARE);
Tim Petersa032d2e2003-01-11 00:15:54 +00003397 assert(HASTZINFO(self));
Tim Peters37f39822003-01-10 03:49:02 +00003398 hour = divmod(TIME_GET_HOUR(self) * 60 +
3399 TIME_GET_MINUTE(self) - offset,
3400 60,
3401 &minute);
3402 if (0 <= hour && hour < 24)
3403 temp = new_time(hour, minute,
3404 TIME_GET_SECOND(self),
3405 TIME_GET_MICROSECOND(self),
3406 Py_None);
3407 else
3408 temp = Py_BuildValue("iiii",
3409 hour, minute,
3410 TIME_GET_SECOND(self),
3411 TIME_GET_MICROSECOND(self));
3412 }
3413 if (temp != NULL) {
3414 self->hashcode = PyObject_Hash(temp);
3415 Py_DECREF(temp);
3416 }
3417 }
3418 return self->hashcode;
3419}
Tim Peters2a799bf2002-12-16 20:18:38 +00003420
Tim Peters12bf3392002-12-24 05:41:27 +00003421static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003422time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00003423{
3424 PyObject *clone;
3425 PyObject *tuple;
3426 int hh = TIME_GET_HOUR(self);
3427 int mm = TIME_GET_MINUTE(self);
3428 int ss = TIME_GET_SECOND(self);
3429 int us = TIME_GET_MICROSECOND(self);
Tim Petersa032d2e2003-01-11 00:15:54 +00003430 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00003431
3432 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
Tim Peters37f39822003-01-10 03:49:02 +00003433 time_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00003434 &hh, &mm, &ss, &us, &tzinfo))
3435 return NULL;
3436 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3437 if (tuple == NULL)
3438 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00003439 clone = time_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00003440 Py_DECREF(tuple);
3441 return clone;
3442}
3443
Tim Peters2a799bf2002-12-16 20:18:38 +00003444static int
Tim Peters37f39822003-01-10 03:49:02 +00003445time_nonzero(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003446{
3447 int offset;
3448 int none;
3449
3450 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3451 /* Since utcoffset is in whole minutes, nothing can
3452 * alter the conclusion that this is nonzero.
3453 */
3454 return 1;
3455 }
3456 offset = 0;
Tim Petersa032d2e2003-01-11 00:15:54 +00003457 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Petersbad8ff02002-12-30 20:52:32 +00003458 offset = call_utcoffset(self->tzinfo, Py_None, &none);
Tim Peters2a799bf2002-12-16 20:18:38 +00003459 if (offset == -1 && PyErr_Occurred())
3460 return -1;
3461 }
3462 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3463}
3464
Tim Peters371935f2003-02-01 01:52:50 +00003465/* Pickle support, a simple use of __reduce__. */
Tim Peters2a799bf2002-12-16 20:18:38 +00003466
Tim Peters33e0f382003-01-10 02:05:14 +00003467/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00003468 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3469 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00003470 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00003471 */
3472static PyObject *
Tim Peters37f39822003-01-10 03:49:02 +00003473time_getstate(PyDateTime_Time *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00003474{
3475 PyObject *basestate;
3476 PyObject *result = NULL;
3477
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003478 basestate = PyString_FromStringAndSize((char *)self->data,
Tim Peters33e0f382003-01-10 02:05:14 +00003479 _PyDateTime_TIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00003480 if (basestate != NULL) {
Tim Petersa032d2e2003-01-11 00:15:54 +00003481 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003482 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00003483 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003484 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00003485 Py_DECREF(basestate);
3486 }
3487 return result;
3488}
3489
3490static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00003491time_reduce(PyDateTime_Time *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00003492{
Christian Heimese93237d2007-12-19 02:37:44 +00003493 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003494}
3495
Tim Peters37f39822003-01-10 03:49:02 +00003496static PyMethodDef time_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003497
Martin v. Löwis4c11a922007-02-08 09:13:36 +00003498 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003499 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3500 "[+HH:MM].")},
3501
Neal Norwitza84dcd72007-05-22 07:16:44 +00003502 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
Tim Peters37f39822003-01-10 03:49:02 +00003503 PyDoc_STR("format -> strftime() style string.")},
3504
Eric Smitha9f7d622008-02-17 19:46:49 +00003505 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3506 PyDoc_STR("Formats self with strftime.")},
3507
Tim Peters37f39822003-01-10 03:49:02 +00003508 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003509 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3510
Tim Peters37f39822003-01-10 03:49:02 +00003511 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003512 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3513
Tim Peters37f39822003-01-10 03:49:02 +00003514 {"dst", (PyCFunction)time_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00003515 PyDoc_STR("Return self.tzinfo.dst(self).")},
3516
Neal Norwitza84dcd72007-05-22 07:16:44 +00003517 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
Tim Peters37f39822003-01-10 03:49:02 +00003518 PyDoc_STR("Return time with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00003519
Guido van Rossum177e41a2003-01-30 22:06:23 +00003520 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3521 PyDoc_STR("__reduce__() -> (cls, state)")},
3522
Tim Peters2a799bf2002-12-16 20:18:38 +00003523 {NULL, NULL}
Tim Peters2a799bf2002-12-16 20:18:38 +00003524};
3525
Tim Peters37f39822003-01-10 03:49:02 +00003526static char time_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00003527PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3528\n\
3529All arguments are optional. tzinfo may be None, or an instance of\n\
3530a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00003531
Tim Peters37f39822003-01-10 03:49:02 +00003532static PyNumberMethods time_as_number = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003533 0, /* nb_add */
3534 0, /* nb_subtract */
3535 0, /* nb_multiply */
3536 0, /* nb_divide */
3537 0, /* nb_remainder */
3538 0, /* nb_divmod */
3539 0, /* nb_power */
3540 0, /* nb_negative */
3541 0, /* nb_positive */
3542 0, /* nb_absolute */
Tim Peters37f39822003-01-10 03:49:02 +00003543 (inquiry)time_nonzero, /* nb_nonzero */
Tim Peters2a799bf2002-12-16 20:18:38 +00003544};
3545
Tim Peters37f39822003-01-10 03:49:02 +00003546statichere PyTypeObject PyDateTime_TimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00003547 PyObject_HEAD_INIT(NULL)
3548 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00003549 "datetime.time", /* tp_name */
Tim Peters37f39822003-01-10 03:49:02 +00003550 sizeof(PyDateTime_Time), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00003551 0, /* tp_itemsize */
Tim Peters37f39822003-01-10 03:49:02 +00003552 (destructor)time_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003553 0, /* tp_print */
3554 0, /* tp_getattr */
3555 0, /* tp_setattr */
3556 0, /* tp_compare */
Tim Peters37f39822003-01-10 03:49:02 +00003557 (reprfunc)time_repr, /* tp_repr */
3558 &time_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00003559 0, /* tp_as_sequence */
3560 0, /* tp_as_mapping */
Tim Peters37f39822003-01-10 03:49:02 +00003561 (hashfunc)time_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00003562 0, /* tp_call */
Tim Peters37f39822003-01-10 03:49:02 +00003563 (reprfunc)time_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00003564 PyObject_GenericGetAttr, /* tp_getattro */
3565 0, /* tp_setattro */
3566 0, /* tp_as_buffer */
3567 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3568 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Peters37f39822003-01-10 03:49:02 +00003569 time_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00003570 0, /* tp_traverse */
3571 0, /* tp_clear */
Tim Peters37f39822003-01-10 03:49:02 +00003572 (richcmpfunc)time_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00003573 0, /* tp_weaklistoffset */
3574 0, /* tp_iter */
3575 0, /* tp_iternext */
Tim Peters37f39822003-01-10 03:49:02 +00003576 time_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00003577 0, /* tp_members */
Tim Peters37f39822003-01-10 03:49:02 +00003578 time_getset, /* tp_getset */
3579 0, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00003580 0, /* tp_dict */
3581 0, /* tp_descr_get */
3582 0, /* tp_descr_set */
3583 0, /* tp_dictoffset */
3584 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00003585 time_alloc, /* tp_alloc */
Tim Peters37f39822003-01-10 03:49:02 +00003586 time_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00003587 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00003588};
3589
3590/*
Tim Petersa9bc1682003-01-11 03:39:11 +00003591 * PyDateTime_DateTime implementation.
Tim Peters2a799bf2002-12-16 20:18:38 +00003592 */
3593
Tim Petersa9bc1682003-01-11 03:39:11 +00003594/* Accessor properties. Properties for day, month, and year are inherited
3595 * from date.
Tim Peters2a799bf2002-12-16 20:18:38 +00003596 */
3597
3598static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003599datetime_hour(PyDateTime_DateTime *self, void *unused)
Tim Peters2a799bf2002-12-16 20:18:38 +00003600{
Tim Petersa9bc1682003-01-11 03:39:11 +00003601 return PyInt_FromLong(DATE_GET_HOUR(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00003602}
3603
Tim Petersa9bc1682003-01-11 03:39:11 +00003604static PyObject *
3605datetime_minute(PyDateTime_DateTime *self, void *unused)
3606{
3607 return PyInt_FromLong(DATE_GET_MINUTE(self));
3608}
3609
3610static PyObject *
3611datetime_second(PyDateTime_DateTime *self, void *unused)
3612{
3613 return PyInt_FromLong(DATE_GET_SECOND(self));
3614}
3615
3616static PyObject *
3617datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3618{
3619 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3620}
3621
3622static PyObject *
3623datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3624{
3625 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3626 Py_INCREF(result);
3627 return result;
3628}
3629
3630static PyGetSetDef datetime_getset[] = {
3631 {"hour", (getter)datetime_hour},
3632 {"minute", (getter)datetime_minute},
3633 {"second", (getter)datetime_second},
3634 {"microsecond", (getter)datetime_microsecond},
3635 {"tzinfo", (getter)datetime_tzinfo},
Tim Peters2a799bf2002-12-16 20:18:38 +00003636 {NULL}
3637};
3638
3639/*
3640 * Constructors.
Tim Peters2a799bf2002-12-16 20:18:38 +00003641 */
3642
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003643static char *datetime_kws[] = {
Tim Peters12bf3392002-12-24 05:41:27 +00003644 "year", "month", "day", "hour", "minute", "second",
3645 "microsecond", "tzinfo", NULL
3646};
3647
Tim Peters2a799bf2002-12-16 20:18:38 +00003648static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003649datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003650{
3651 PyObject *self = NULL;
Tim Peters70533e22003-02-01 04:40:04 +00003652 PyObject *state;
Tim Peters2a799bf2002-12-16 20:18:38 +00003653 int year;
3654 int month;
3655 int day;
3656 int hour = 0;
3657 int minute = 0;
3658 int second = 0;
3659 int usecond = 0;
3660 PyObject *tzinfo = Py_None;
3661
Guido van Rossum177e41a2003-01-30 22:06:23 +00003662 /* Check for invocation from pickle with __getstate__ state */
3663 if (PyTuple_GET_SIZE(args) >= 1 &&
3664 PyTuple_GET_SIZE(args) <= 2 &&
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003665 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3666 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3667 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
Guido van Rossum177e41a2003-01-30 22:06:23 +00003668 {
Tim Peters70533e22003-02-01 04:40:04 +00003669 PyDateTime_DateTime *me;
3670 char aware;
3671
3672 if (PyTuple_GET_SIZE(args) == 2) {
Guido van Rossum177e41a2003-01-30 22:06:23 +00003673 tzinfo = PyTuple_GET_ITEM(args, 1);
Tim Peters70533e22003-02-01 04:40:04 +00003674 if (check_tzinfo_subclass(tzinfo) < 0) {
3675 PyErr_SetString(PyExc_TypeError, "bad "
3676 "tzinfo state arg");
3677 return NULL;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003678 }
3679 }
Tim Peters70533e22003-02-01 04:40:04 +00003680 aware = (char)(tzinfo != Py_None);
Tim Peters604c0132004-06-07 23:04:33 +00003681 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
Tim Peters70533e22003-02-01 04:40:04 +00003682 if (me != NULL) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003683 char *pdata = PyString_AS_STRING(state);
Tim Peters70533e22003-02-01 04:40:04 +00003684
3685 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3686 me->hashcode = -1;
3687 me->hastzinfo = aware;
3688 if (aware) {
3689 Py_INCREF(tzinfo);
3690 me->tzinfo = tzinfo;
3691 }
3692 }
3693 return (PyObject *)me;
Guido van Rossum177e41a2003-01-30 22:06:23 +00003694 }
3695
Tim Petersa9bc1682003-01-11 03:39:11 +00003696 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
Tim Peters2a799bf2002-12-16 20:18:38 +00003697 &year, &month, &day, &hour, &minute,
3698 &second, &usecond, &tzinfo)) {
3699 if (check_date_args(year, month, day) < 0)
3700 return NULL;
3701 if (check_time_args(hour, minute, second, usecond) < 0)
3702 return NULL;
3703 if (check_tzinfo_subclass(tzinfo) < 0)
3704 return NULL;
Tim Petersa98924a2003-05-17 05:55:19 +00003705 self = new_datetime_ex(year, month, day,
3706 hour, minute, second, usecond,
3707 tzinfo, type);
Tim Peters2a799bf2002-12-16 20:18:38 +00003708 }
3709 return self;
3710}
3711
Tim Petersa9bc1682003-01-11 03:39:11 +00003712/* TM_FUNC is the shared type of localtime() and gmtime(). */
3713typedef struct tm *(*TM_FUNC)(const time_t *timer);
3714
3715/* Internal helper.
3716 * Build datetime from a time_t and a distinct count of microseconds.
3717 * Pass localtime or gmtime for f, to control the interpretation of timet.
3718 */
3719static PyObject *
3720datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3721 PyObject *tzinfo)
3722{
3723 struct tm *tm;
3724 PyObject *result = NULL;
3725
3726 tm = f(&timet);
3727 if (tm) {
3728 /* The platform localtime/gmtime may insert leap seconds,
3729 * indicated by tm->tm_sec > 59. We don't care about them,
3730 * except to the extent that passing them on to the datetime
3731 * constructor would raise ValueError for a reason that
3732 * made no sense to the user.
3733 */
3734 if (tm->tm_sec > 59)
3735 tm->tm_sec = 59;
3736 result = PyObject_CallFunction(cls, "iiiiiiiO",
3737 tm->tm_year + 1900,
3738 tm->tm_mon + 1,
3739 tm->tm_mday,
3740 tm->tm_hour,
3741 tm->tm_min,
3742 tm->tm_sec,
3743 us,
3744 tzinfo);
3745 }
3746 else
3747 PyErr_SetString(PyExc_ValueError,
3748 "timestamp out of range for "
3749 "platform localtime()/gmtime() function");
3750 return result;
3751}
3752
3753/* Internal helper.
3754 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3755 * to control the interpretation of the timestamp. Since a double doesn't
3756 * have enough bits to cover a datetime's full range of precision, it's
3757 * better to call datetime_from_timet_and_us provided you have a way
3758 * to get that much precision (e.g., C time() isn't good enough).
3759 */
3760static PyObject *
3761datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3762 PyObject *tzinfo)
3763{
Tim Peters1b6f7a92004-06-20 02:50:16 +00003764 time_t timet;
3765 double fraction;
3766 int us;
Tim Petersa9bc1682003-01-11 03:39:11 +00003767
Tim Peters1b6f7a92004-06-20 02:50:16 +00003768 timet = _PyTime_DoubleToTimet(timestamp);
3769 if (timet == (time_t)-1 && PyErr_Occurred())
3770 return NULL;
3771 fraction = timestamp - (double)timet;
3772 us = (int)round_to_long(fraction * 1e6);
Guido van Rossum2054ee92007-03-06 15:50:01 +00003773 if (us < 0) {
3774 /* Truncation towards zero is not what we wanted
3775 for negative numbers (Python's mod semantics) */
3776 timet -= 1;
3777 us += 1000000;
3778 }
Georg Brandl6d78a582006-04-28 19:09:24 +00003779 /* If timestamp is less than one microsecond smaller than a
3780 * full second, round up. Otherwise, ValueErrors are raised
3781 * for some floats. */
3782 if (us == 1000000) {
3783 timet += 1;
3784 us = 0;
3785 }
Tim Petersa9bc1682003-01-11 03:39:11 +00003786 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3787}
3788
3789/* Internal helper.
3790 * Build most accurate possible datetime for current time. Pass localtime or
3791 * gmtime for f as appropriate.
3792 */
3793static PyObject *
3794datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3795{
3796#ifdef HAVE_GETTIMEOFDAY
3797 struct timeval t;
3798
3799#ifdef GETTIMEOFDAY_NO_TZ
3800 gettimeofday(&t);
3801#else
3802 gettimeofday(&t, (struct timezone *)NULL);
3803#endif
3804 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3805 tzinfo);
3806
3807#else /* ! HAVE_GETTIMEOFDAY */
3808 /* No flavor of gettimeofday exists on this platform. Python's
3809 * time.time() does a lot of other platform tricks to get the
3810 * best time it can on the platform, and we're not going to do
3811 * better than that (if we could, the better code would belong
3812 * in time.time()!) We're limited by the precision of a double,
3813 * though.
3814 */
3815 PyObject *time;
3816 double dtime;
3817
3818 time = time_time();
3819 if (time == NULL)
3820 return NULL;
3821 dtime = PyFloat_AsDouble(time);
3822 Py_DECREF(time);
3823 if (dtime == -1.0 && PyErr_Occurred())
3824 return NULL;
3825 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3826#endif /* ! HAVE_GETTIMEOFDAY */
3827}
3828
Tim Peters2a799bf2002-12-16 20:18:38 +00003829/* Return best possible local time -- this isn't constrained by the
3830 * precision of a timestamp.
3831 */
3832static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003833datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003834{
Tim Peters10cadce2003-01-23 19:58:02 +00003835 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003836 PyObject *tzinfo = Py_None;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003837 static char *keywords[] = {"tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003838
Tim Peters10cadce2003-01-23 19:58:02 +00003839 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3840 &tzinfo))
3841 return NULL;
3842 if (check_tzinfo_subclass(tzinfo) < 0)
3843 return NULL;
3844
3845 self = datetime_best_possible(cls,
3846 tzinfo == Py_None ? localtime : gmtime,
3847 tzinfo);
3848 if (self != NULL && tzinfo != Py_None) {
3849 /* Convert UTC to tzinfo's zone. */
3850 PyObject *temp = self;
Tim Peters2a44a8d2003-01-23 20:53:10 +00003851 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Tim Peters10cadce2003-01-23 19:58:02 +00003852 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003853 }
3854 return self;
3855}
3856
Tim Petersa9bc1682003-01-11 03:39:11 +00003857/* Return best possible UTC time -- this isn't constrained by the
3858 * precision of a timestamp.
3859 */
3860static PyObject *
3861datetime_utcnow(PyObject *cls, PyObject *dummy)
3862{
3863 return datetime_best_possible(cls, gmtime, Py_None);
3864}
3865
Tim Peters2a799bf2002-12-16 20:18:38 +00003866/* Return new local datetime from timestamp (Python timestamp -- a double). */
3867static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00003868datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00003869{
Tim Peters2a44a8d2003-01-23 20:53:10 +00003870 PyObject *self;
Tim Peters2a799bf2002-12-16 20:18:38 +00003871 double timestamp;
3872 PyObject *tzinfo = Py_None;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003873 static char *keywords[] = {"timestamp", "tz", NULL};
Tim Peters2a799bf2002-12-16 20:18:38 +00003874
Tim Peters2a44a8d2003-01-23 20:53:10 +00003875 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3876 keywords, &timestamp, &tzinfo))
3877 return NULL;
3878 if (check_tzinfo_subclass(tzinfo) < 0)
3879 return NULL;
3880
3881 self = datetime_from_timestamp(cls,
3882 tzinfo == Py_None ? localtime : gmtime,
3883 timestamp,
3884 tzinfo);
3885 if (self != NULL && tzinfo != Py_None) {
3886 /* Convert UTC to tzinfo's zone. */
3887 PyObject *temp = self;
3888 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3889 Py_DECREF(temp);
Tim Peters2a799bf2002-12-16 20:18:38 +00003890 }
3891 return self;
3892}
3893
Tim Petersa9bc1682003-01-11 03:39:11 +00003894/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3895static PyObject *
3896datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3897{
3898 double timestamp;
3899 PyObject *result = NULL;
Tim Peters2a799bf2002-12-16 20:18:38 +00003900
Tim Petersa9bc1682003-01-11 03:39:11 +00003901 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", &timestamp))
3902 result = datetime_from_timestamp(cls, gmtime, timestamp,
3903 Py_None);
3904 return result;
3905}
3906
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003907/* Return new datetime from time.strptime(). */
3908static PyObject *
3909datetime_strptime(PyObject *cls, PyObject *args)
3910{
Skip Montanarofc070d22008-03-15 16:04:45 +00003911 static PyObject *module = NULL;
3912 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003913 const char *string, *format;
3914
3915 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3916 return NULL;
3917
Skip Montanarofc070d22008-03-15 16:04:45 +00003918 if (module == NULL &&
3919 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003920 return NULL;
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003921
Skip Montanarofc070d22008-03-15 16:04:45 +00003922 /* _strptime._strptime returns a two-element tuple. The first
3923 element is a time.struct_time object. The second is the
3924 microseconds (which are not defined for time.struct_time). */
3925 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003926 if (obj != NULL) {
3927 int i, good_timetuple = 1;
Skip Montanarofc070d22008-03-15 16:04:45 +00003928 long int ia[7];
3929 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3930 st = PySequence_GetItem(obj, 0);
3931 frac = PySequence_GetItem(obj, 1);
3932 if (st == NULL || frac == NULL)
3933 good_timetuple = 0;
3934 /* copy y/m/d/h/m/s values out of the
3935 time.struct_time */
3936 if (good_timetuple &&
3937 PySequence_Check(st) &&
3938 PySequence_Size(st) >= 6) {
3939 for (i=0; i < 6; i++) {
3940 PyObject *p = PySequence_GetItem(st, i);
3941 if (p == NULL) {
3942 good_timetuple = 0;
3943 break;
3944 }
3945 if (PyInt_Check(p))
3946 ia[i] = PyInt_AsLong(p);
3947 else
3948 good_timetuple = 0;
3949 Py_DECREF(p);
Thomas Wouters3cfea2d2006-04-14 21:23:42 +00003950 }
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003951 }
Skip Montanarofc070d22008-03-15 16:04:45 +00003952 else
3953 good_timetuple = 0;
3954 /* follow that up with a little dose of microseconds */
3955 if (PyInt_Check(frac))
3956 ia[6] = PyInt_AsLong(frac);
3957 else
3958 good_timetuple = 0;
3959 }
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003960 else
3961 good_timetuple = 0;
3962 if (good_timetuple)
Skip Montanarofc070d22008-03-15 16:04:45 +00003963 result = PyObject_CallFunction(cls, "iiiiiii",
3964 ia[0], ia[1], ia[2],
3965 ia[3], ia[4], ia[5],
3966 ia[6]);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003967 else
3968 PyErr_SetString(PyExc_ValueError,
Skip Montanarofc070d22008-03-15 16:04:45 +00003969 "unexpected value from _strptime._strptime");
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003970 }
Skip Montanarofc070d22008-03-15 16:04:45 +00003971 Py_XDECREF(obj);
3972 Py_XDECREF(st);
3973 Py_XDECREF(frac);
Skip Montanaro0af3ade2005-01-13 04:12:31 +00003974 return result;
3975}
3976
Tim Petersa9bc1682003-01-11 03:39:11 +00003977/* Return new datetime from date/datetime and time arguments. */
3978static PyObject *
3979datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
3980{
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003981 static char *keywords[] = {"date", "time", NULL};
Tim Petersa9bc1682003-01-11 03:39:11 +00003982 PyObject *date;
3983 PyObject *time;
3984 PyObject *result = NULL;
3985
3986 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
3987 &PyDateTime_DateType, &date,
3988 &PyDateTime_TimeType, &time)) {
3989 PyObject *tzinfo = Py_None;
3990
3991 if (HASTZINFO(time))
3992 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
3993 result = PyObject_CallFunction(cls, "iiiiiiiO",
3994 GET_YEAR(date),
3995 GET_MONTH(date),
3996 GET_DAY(date),
3997 TIME_GET_HOUR(time),
3998 TIME_GET_MINUTE(time),
3999 TIME_GET_SECOND(time),
4000 TIME_GET_MICROSECOND(time),
4001 tzinfo);
4002 }
4003 return result;
4004}
Tim Peters2a799bf2002-12-16 20:18:38 +00004005
4006/*
4007 * Destructor.
4008 */
4009
4010static void
Tim Petersa9bc1682003-01-11 03:39:11 +00004011datetime_dealloc(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004012{
Tim Petersa9bc1682003-01-11 03:39:11 +00004013 if (HASTZINFO(self)) {
4014 Py_XDECREF(self->tzinfo);
4015 }
Christian Heimese93237d2007-12-19 02:37:44 +00004016 Py_TYPE(self)->tp_free((PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004017}
4018
4019/*
4020 * Indirect access to tzinfo methods.
4021 */
4022
Tim Peters2a799bf2002-12-16 20:18:38 +00004023/* These are all METH_NOARGS, so don't need to check the arglist. */
4024static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004025datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
4026 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4027 "utcoffset", (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004028}
4029
4030static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004031datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
4032 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4033 "dst", (PyObject *)self);
Tim Peters855fe882002-12-22 03:43:39 +00004034}
4035
4036static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004037datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
4038 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4039 (PyObject *)self);
Tim Peters2a799bf2002-12-16 20:18:38 +00004040}
4041
4042/*
Tim Petersa9bc1682003-01-11 03:39:11 +00004043 * datetime arithmetic.
Tim Peters2a799bf2002-12-16 20:18:38 +00004044 */
4045
Tim Petersa9bc1682003-01-11 03:39:11 +00004046/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4047 * the tzinfo state of date.
Tim Peters2a799bf2002-12-16 20:18:38 +00004048 */
4049static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004050add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4051 int factor)
Tim Peters2a799bf2002-12-16 20:18:38 +00004052{
Tim Petersa9bc1682003-01-11 03:39:11 +00004053 /* Note that the C-level additions can't overflow, because of
4054 * invariant bounds on the member values.
4055 */
4056 int year = GET_YEAR(date);
4057 int month = GET_MONTH(date);
4058 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4059 int hour = DATE_GET_HOUR(date);
4060 int minute = DATE_GET_MINUTE(date);
4061 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4062 int microsecond = DATE_GET_MICROSECOND(date) +
4063 GET_TD_MICROSECONDS(delta) * factor;
Tim Peters2a799bf2002-12-16 20:18:38 +00004064
Tim Petersa9bc1682003-01-11 03:39:11 +00004065 assert(factor == 1 || factor == -1);
4066 if (normalize_datetime(&year, &month, &day,
4067 &hour, &minute, &second, &microsecond) < 0)
4068 return NULL;
4069 else
4070 return new_datetime(year, month, day,
4071 hour, minute, second, microsecond,
4072 HASTZINFO(date) ? date->tzinfo : Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004073}
4074
4075static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004076datetime_add(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004077{
Tim Petersa9bc1682003-01-11 03:39:11 +00004078 if (PyDateTime_Check(left)) {
4079 /* datetime + ??? */
4080 if (PyDelta_Check(right))
4081 /* datetime + delta */
4082 return add_datetime_timedelta(
4083 (PyDateTime_DateTime *)left,
4084 (PyDateTime_Delta *)right,
4085 1);
4086 }
4087 else if (PyDelta_Check(left)) {
4088 /* delta + datetime */
4089 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4090 (PyDateTime_Delta *) left,
4091 1);
4092 }
4093 Py_INCREF(Py_NotImplemented);
4094 return Py_NotImplemented;
Tim Peters2a799bf2002-12-16 20:18:38 +00004095}
4096
4097static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004098datetime_subtract(PyObject *left, PyObject *right)
Tim Peters2a799bf2002-12-16 20:18:38 +00004099{
4100 PyObject *result = Py_NotImplemented;
4101
4102 if (PyDateTime_Check(left)) {
4103 /* datetime - ??? */
4104 if (PyDateTime_Check(right)) {
4105 /* datetime - datetime */
4106 naivety n1, n2;
4107 int offset1, offset2;
Tim Petersa9bc1682003-01-11 03:39:11 +00004108 int delta_d, delta_s, delta_us;
Tim Peters2a799bf2002-12-16 20:18:38 +00004109
Tim Peterse39a80c2002-12-30 21:28:52 +00004110 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4111 right, &offset2, &n2,
4112 right) < 0)
Tim Peters00237032002-12-27 02:21:51 +00004113 return NULL;
Tim Peters8702d5f2002-12-27 02:26:16 +00004114 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
Tim Peters2a799bf2002-12-16 20:18:38 +00004115 if (n1 != n2) {
4116 PyErr_SetString(PyExc_TypeError,
4117 "can't subtract offset-naive and "
4118 "offset-aware datetimes");
4119 return NULL;
4120 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004121 delta_d = ymd_to_ord(GET_YEAR(left),
4122 GET_MONTH(left),
4123 GET_DAY(left)) -
4124 ymd_to_ord(GET_YEAR(right),
4125 GET_MONTH(right),
4126 GET_DAY(right));
4127 /* These can't overflow, since the values are
4128 * normalized. At most this gives the number of
4129 * seconds in one day.
4130 */
4131 delta_s = (DATE_GET_HOUR(left) -
4132 DATE_GET_HOUR(right)) * 3600 +
4133 (DATE_GET_MINUTE(left) -
4134 DATE_GET_MINUTE(right)) * 60 +
4135 (DATE_GET_SECOND(left) -
4136 DATE_GET_SECOND(right));
4137 delta_us = DATE_GET_MICROSECOND(left) -
4138 DATE_GET_MICROSECOND(right);
Tim Peters2a799bf2002-12-16 20:18:38 +00004139 /* (left - offset1) - (right - offset2) =
4140 * (left - right) + (offset2 - offset1)
4141 */
Tim Petersa9bc1682003-01-11 03:39:11 +00004142 delta_s += (offset2 - offset1) * 60;
4143 result = new_delta(delta_d, delta_s, delta_us, 1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004144 }
4145 else if (PyDelta_Check(right)) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004146 /* datetime - delta */
4147 result = add_datetime_timedelta(
Tim Peters2a799bf2002-12-16 20:18:38 +00004148 (PyDateTime_DateTime *)left,
Tim Petersa9bc1682003-01-11 03:39:11 +00004149 (PyDateTime_Delta *)right,
4150 -1);
Tim Peters2a799bf2002-12-16 20:18:38 +00004151 }
4152 }
4153
4154 if (result == Py_NotImplemented)
4155 Py_INCREF(result);
4156 return result;
4157}
4158
4159/* Various ways to turn a datetime into a string. */
4160
4161static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004162datetime_repr(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004163{
Tim Petersa9bc1682003-01-11 03:39:11 +00004164 char buffer[1000];
Christian Heimese93237d2007-12-19 02:37:44 +00004165 const char *type_name = Py_TYPE(self)->tp_name;
Tim Petersa9bc1682003-01-11 03:39:11 +00004166 PyObject *baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004167
Tim Petersa9bc1682003-01-11 03:39:11 +00004168 if (DATE_GET_MICROSECOND(self)) {
4169 PyOS_snprintf(buffer, sizeof(buffer),
4170 "%s(%d, %d, %d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004171 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004172 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4173 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4174 DATE_GET_SECOND(self),
4175 DATE_GET_MICROSECOND(self));
4176 }
4177 else if (DATE_GET_SECOND(self)) {
4178 PyOS_snprintf(buffer, sizeof(buffer),
4179 "%s(%d, %d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004180 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004181 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4182 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4183 DATE_GET_SECOND(self));
4184 }
4185 else {
4186 PyOS_snprintf(buffer, sizeof(buffer),
4187 "%s(%d, %d, %d, %d, %d)",
Skip Montanaro14f88992006-04-18 19:35:04 +00004188 type_name,
Tim Petersa9bc1682003-01-11 03:39:11 +00004189 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4190 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4191 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004192 baserepr = PyString_FromString(buffer);
Tim Petersa9bc1682003-01-11 03:39:11 +00004193 if (baserepr == NULL || ! HASTZINFO(self))
4194 return baserepr;
Tim Peters2a799bf2002-12-16 20:18:38 +00004195 return append_keyword_tzinfo(baserepr, self->tzinfo);
4196}
4197
Tim Petersa9bc1682003-01-11 03:39:11 +00004198static PyObject *
4199datetime_str(PyDateTime_DateTime *self)
4200{
4201 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4202}
Tim Peters2a799bf2002-12-16 20:18:38 +00004203
4204static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004205datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters2a799bf2002-12-16 20:18:38 +00004206{
Tim Petersa9bc1682003-01-11 03:39:11 +00004207 char sep = 'T';
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004208 static char *keywords[] = {"sep", NULL};
Tim Petersa9bc1682003-01-11 03:39:11 +00004209 char buffer[100];
4210 char *cp;
4211 PyObject *result;
Tim Peters2a799bf2002-12-16 20:18:38 +00004212
Tim Petersa9bc1682003-01-11 03:39:11 +00004213 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4214 &sep))
4215 return NULL;
4216 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4217 assert(cp != NULL);
4218 *cp++ = sep;
Amaury Forgeot d'Arc8645a5c2009-12-29 22:03:38 +00004219 cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4220 result = PyString_FromStringAndSize(buffer, cp - buffer);
Tim Petersa9bc1682003-01-11 03:39:11 +00004221 if (result == NULL || ! HASTZINFO(self))
Tim Peters2a799bf2002-12-16 20:18:38 +00004222 return result;
4223
4224 /* We need to append the UTC offset. */
Tim Petersa9bc1682003-01-11 03:39:11 +00004225 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
Tim Peters2a799bf2002-12-16 20:18:38 +00004226 (PyObject *)self) < 0) {
4227 Py_DECREF(result);
4228 return NULL;
4229 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004230 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
Tim Peters2a799bf2002-12-16 20:18:38 +00004231 return result;
4232}
4233
Tim Petersa9bc1682003-01-11 03:39:11 +00004234static PyObject *
4235datetime_ctime(PyDateTime_DateTime *self)
4236{
4237 return format_ctime((PyDateTime_Date *)self,
4238 DATE_GET_HOUR(self),
4239 DATE_GET_MINUTE(self),
4240 DATE_GET_SECOND(self));
4241}
4242
Tim Peters2a799bf2002-12-16 20:18:38 +00004243/* Miscellaneous methods. */
4244
Tim Petersa9bc1682003-01-11 03:39:11 +00004245/* This is more natural as a tp_compare, but doesn't work then: for whatever
4246 * reason, Python's try_3way_compare ignores tp_compare unless
4247 * PyInstance_Check returns true, but these aren't old-style classes.
4248 */
4249static PyObject *
4250datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4251{
4252 int diff;
4253 naivety n1, n2;
4254 int offset1, offset2;
4255
4256 if (! PyDateTime_Check(other)) {
Tim Peters528ca532004-09-16 01:30:50 +00004257 /* If other has a "timetuple" attr, that's an advertised
4258 * hook for other classes to ask to get comparison control.
4259 * However, date instances have a timetuple attr, and we
4260 * don't want to allow that comparison. Because datetime
4261 * is a subclass of date, when mixing date and datetime
4262 * in a comparison, Python gives datetime the first shot
4263 * (it's the more specific subtype). So we can stop that
4264 * combination here reliably.
4265 */
4266 if (PyObject_HasAttrString(other, "timetuple") &&
4267 ! PyDate_Check(other)) {
Tim Peters8d81a012003-01-24 22:36:34 +00004268 /* A hook for other kinds of datetime objects. */
4269 Py_INCREF(Py_NotImplemented);
4270 return Py_NotImplemented;
4271 }
Tim Peters07534a62003-02-07 22:50:28 +00004272 if (op == Py_EQ || op == Py_NE) {
4273 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4274 Py_INCREF(result);
4275 return result;
4276 }
Tim Petersa9bc1682003-01-11 03:39:11 +00004277 /* Stop this from falling back to address comparison. */
Tim Peters07534a62003-02-07 22:50:28 +00004278 return cmperror((PyObject *)self, other);
Tim Petersa9bc1682003-01-11 03:39:11 +00004279 }
4280
4281 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4282 (PyObject *)self,
4283 other, &offset2, &n2,
4284 other) < 0)
4285 return NULL;
4286 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4287 /* If they're both naive, or both aware and have the same offsets,
4288 * we get off cheap. Note that if they're both naive, offset1 ==
4289 * offset2 == 0 at this point.
4290 */
4291 if (n1 == n2 && offset1 == offset2) {
4292 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4293 _PyDateTime_DATETIME_DATASIZE);
4294 return diff_to_bool(diff, op);
4295 }
4296
4297 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4298 PyDateTime_Delta *delta;
4299
4300 assert(offset1 != offset2); /* else last "if" handled it */
4301 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4302 other);
4303 if (delta == NULL)
4304 return NULL;
4305 diff = GET_TD_DAYS(delta);
4306 if (diff == 0)
4307 diff = GET_TD_SECONDS(delta) |
4308 GET_TD_MICROSECONDS(delta);
4309 Py_DECREF(delta);
4310 return diff_to_bool(diff, op);
4311 }
4312
4313 assert(n1 != n2);
4314 PyErr_SetString(PyExc_TypeError,
4315 "can't compare offset-naive and "
4316 "offset-aware datetimes");
4317 return NULL;
4318}
4319
4320static long
4321datetime_hash(PyDateTime_DateTime *self)
4322{
4323 if (self->hashcode == -1) {
4324 naivety n;
4325 int offset;
4326 PyObject *temp;
4327
4328 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4329 &offset);
4330 assert(n != OFFSET_UNKNOWN);
4331 if (n == OFFSET_ERROR)
4332 return -1;
4333
4334 /* Reduce this to a hash of another object. */
4335 if (n == OFFSET_NAIVE)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004336 temp = PyString_FromStringAndSize(
Tim Petersa9bc1682003-01-11 03:39:11 +00004337 (char *)self->data,
4338 _PyDateTime_DATETIME_DATASIZE);
4339 else {
4340 int days;
4341 int seconds;
4342
4343 assert(n == OFFSET_AWARE);
4344 assert(HASTZINFO(self));
4345 days = ymd_to_ord(GET_YEAR(self),
4346 GET_MONTH(self),
4347 GET_DAY(self));
4348 seconds = DATE_GET_HOUR(self) * 3600 +
4349 (DATE_GET_MINUTE(self) - offset) * 60 +
4350 DATE_GET_SECOND(self);
4351 temp = new_delta(days,
4352 seconds,
4353 DATE_GET_MICROSECOND(self),
4354 1);
4355 }
4356 if (temp != NULL) {
4357 self->hashcode = PyObject_Hash(temp);
4358 Py_DECREF(temp);
4359 }
4360 }
4361 return self->hashcode;
4362}
Tim Peters2a799bf2002-12-16 20:18:38 +00004363
4364static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004365datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters12bf3392002-12-24 05:41:27 +00004366{
4367 PyObject *clone;
4368 PyObject *tuple;
4369 int y = GET_YEAR(self);
4370 int m = GET_MONTH(self);
4371 int d = GET_DAY(self);
4372 int hh = DATE_GET_HOUR(self);
4373 int mm = DATE_GET_MINUTE(self);
4374 int ss = DATE_GET_SECOND(self);
4375 int us = DATE_GET_MICROSECOND(self);
Tim Petersa9bc1682003-01-11 03:39:11 +00004376 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
Tim Peters12bf3392002-12-24 05:41:27 +00004377
4378 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
Tim Petersa9bc1682003-01-11 03:39:11 +00004379 datetime_kws,
Tim Peters12bf3392002-12-24 05:41:27 +00004380 &y, &m, &d, &hh, &mm, &ss, &us,
4381 &tzinfo))
4382 return NULL;
4383 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4384 if (tuple == NULL)
4385 return NULL;
Christian Heimese93237d2007-12-19 02:37:44 +00004386 clone = datetime_new(Py_TYPE(self), tuple, NULL);
Tim Peters12bf3392002-12-24 05:41:27 +00004387 Py_DECREF(tuple);
4388 return clone;
4389}
4390
4391static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004392datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
Tim Peters80475bb2002-12-25 07:40:55 +00004393{
Tim Peters52dcce22003-01-23 16:36:11 +00004394 int y, m, d, hh, mm, ss, us;
Tim Peters521fc152002-12-31 17:36:56 +00004395 PyObject *result;
Tim Peters52dcce22003-01-23 16:36:11 +00004396 int offset, none;
Tim Peters521fc152002-12-31 17:36:56 +00004397
Tim Peters80475bb2002-12-25 07:40:55 +00004398 PyObject *tzinfo;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004399 static char *keywords[] = {"tz", NULL};
Tim Peters80475bb2002-12-25 07:40:55 +00004400
Tim Peters52dcce22003-01-23 16:36:11 +00004401 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4402 &PyDateTime_TZInfoType, &tzinfo))
Tim Peters80475bb2002-12-25 07:40:55 +00004403 return NULL;
4404
Tim Peters52dcce22003-01-23 16:36:11 +00004405 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4406 goto NeedAware;
Tim Peters521fc152002-12-31 17:36:56 +00004407
Tim Peters52dcce22003-01-23 16:36:11 +00004408 /* Conversion to self's own time zone is a NOP. */
4409 if (self->tzinfo == tzinfo) {
4410 Py_INCREF(self);
4411 return (PyObject *)self;
Tim Peters710fb152003-01-02 19:35:54 +00004412 }
Tim Peters521fc152002-12-31 17:36:56 +00004413
Tim Peters52dcce22003-01-23 16:36:11 +00004414 /* Convert self to UTC. */
4415 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4416 if (offset == -1 && PyErr_Occurred())
4417 return NULL;
4418 if (none)
4419 goto NeedAware;
Tim Petersf3615152003-01-01 21:51:37 +00004420
Tim Peters52dcce22003-01-23 16:36:11 +00004421 y = GET_YEAR(self);
4422 m = GET_MONTH(self);
4423 d = GET_DAY(self);
4424 hh = DATE_GET_HOUR(self);
4425 mm = DATE_GET_MINUTE(self);
4426 ss = DATE_GET_SECOND(self);
4427 us = DATE_GET_MICROSECOND(self);
4428
4429 mm -= offset;
Tim Petersf3615152003-01-01 21:51:37 +00004430 if ((mm < 0 || mm >= 60) &&
4431 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
Tim Peters52dcce22003-01-23 16:36:11 +00004432 return NULL;
4433
4434 /* Attach new tzinfo and let fromutc() do the rest. */
4435 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4436 if (result != NULL) {
4437 PyObject *temp = result;
4438
4439 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4440 Py_DECREF(temp);
4441 }
Tim Petersadf64202003-01-04 06:03:15 +00004442 return result;
Tim Peters521fc152002-12-31 17:36:56 +00004443
Tim Peters52dcce22003-01-23 16:36:11 +00004444NeedAware:
4445 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4446 "a naive datetime");
Tim Peters521fc152002-12-31 17:36:56 +00004447 return NULL;
Tim Peters80475bb2002-12-25 07:40:55 +00004448}
4449
4450static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004451datetime_timetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004452{
4453 int dstflag = -1;
4454
Tim Petersa9bc1682003-01-11 03:39:11 +00004455 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004456 int none;
4457
4458 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4459 if (dstflag == -1 && PyErr_Occurred())
4460 return NULL;
4461
4462 if (none)
4463 dstflag = -1;
4464 else if (dstflag != 0)
4465 dstflag = 1;
4466
4467 }
4468 return build_struct_time(GET_YEAR(self),
4469 GET_MONTH(self),
4470 GET_DAY(self),
4471 DATE_GET_HOUR(self),
4472 DATE_GET_MINUTE(self),
4473 DATE_GET_SECOND(self),
4474 dstflag);
4475}
4476
4477static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004478datetime_getdate(PyDateTime_DateTime *self)
4479{
4480 return new_date(GET_YEAR(self),
4481 GET_MONTH(self),
4482 GET_DAY(self));
4483}
4484
4485static PyObject *
4486datetime_gettime(PyDateTime_DateTime *self)
4487{
4488 return new_time(DATE_GET_HOUR(self),
4489 DATE_GET_MINUTE(self),
4490 DATE_GET_SECOND(self),
4491 DATE_GET_MICROSECOND(self),
4492 Py_None);
4493}
4494
4495static PyObject *
4496datetime_gettimetz(PyDateTime_DateTime *self)
4497{
4498 return new_time(DATE_GET_HOUR(self),
4499 DATE_GET_MINUTE(self),
4500 DATE_GET_SECOND(self),
4501 DATE_GET_MICROSECOND(self),
4502 HASTZINFO(self) ? self->tzinfo : Py_None);
4503}
4504
4505static PyObject *
4506datetime_utctimetuple(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004507{
4508 int y = GET_YEAR(self);
4509 int m = GET_MONTH(self);
4510 int d = GET_DAY(self);
4511 int hh = DATE_GET_HOUR(self);
4512 int mm = DATE_GET_MINUTE(self);
4513 int ss = DATE_GET_SECOND(self);
4514 int us = 0; /* microseconds are ignored in a timetuple */
4515 int offset = 0;
4516
Tim Petersa9bc1682003-01-11 03:39:11 +00004517 if (HASTZINFO(self) && self->tzinfo != Py_None) {
Tim Peters2a799bf2002-12-16 20:18:38 +00004518 int none;
4519
4520 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4521 if (offset == -1 && PyErr_Occurred())
4522 return NULL;
4523 }
4524 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4525 * 0 in a UTC timetuple regardless of what dst() says.
4526 */
4527 if (offset) {
4528 /* Subtract offset minutes & normalize. */
4529 int stat;
4530
4531 mm -= offset;
4532 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4533 if (stat < 0) {
4534 /* At the edges, it's possible we overflowed
4535 * beyond MINYEAR or MAXYEAR.
4536 */
4537 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4538 PyErr_Clear();
4539 else
4540 return NULL;
4541 }
4542 }
4543 return build_struct_time(y, m, d, hh, mm, ss, 0);
4544}
4545
Tim Peters371935f2003-02-01 01:52:50 +00004546/* Pickle support, a simple use of __reduce__. */
Tim Peters33e0f382003-01-10 02:05:14 +00004547
Tim Petersa9bc1682003-01-11 03:39:11 +00004548/* Let basestate be the non-tzinfo data string.
Tim Peters2a799bf2002-12-16 20:18:38 +00004549 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4550 * So it's a tuple in any (non-error) case.
Tim Petersb57f8f02003-02-01 02:54:15 +00004551 * __getstate__ isn't exposed.
Tim Peters2a799bf2002-12-16 20:18:38 +00004552 */
4553static PyObject *
Tim Petersa9bc1682003-01-11 03:39:11 +00004554datetime_getstate(PyDateTime_DateTime *self)
Tim Peters2a799bf2002-12-16 20:18:38 +00004555{
4556 PyObject *basestate;
4557 PyObject *result = NULL;
4558
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004559 basestate = PyString_FromStringAndSize((char *)self->data,
Tim Peters33e0f382003-01-10 02:05:14 +00004560 _PyDateTime_DATETIME_DATASIZE);
Tim Peters2a799bf2002-12-16 20:18:38 +00004561 if (basestate != NULL) {
Tim Petersa9bc1682003-01-11 03:39:11 +00004562 if (! HASTZINFO(self) || self->tzinfo == Py_None)
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004563 result = PyTuple_Pack(1, basestate);
Tim Peters2a799bf2002-12-16 20:18:38 +00004564 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004565 result = PyTuple_Pack(2, basestate, self->tzinfo);
Tim Peters2a799bf2002-12-16 20:18:38 +00004566 Py_DECREF(basestate);
4567 }
4568 return result;
4569}
4570
4571static PyObject *
Guido van Rossum177e41a2003-01-30 22:06:23 +00004572datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
Tim Peters2a799bf2002-12-16 20:18:38 +00004573{
Christian Heimese93237d2007-12-19 02:37:44 +00004574 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
Tim Peters2a799bf2002-12-16 20:18:38 +00004575}
4576
Tim Petersa9bc1682003-01-11 03:39:11 +00004577static PyMethodDef datetime_methods[] = {
Guido van Rossum177e41a2003-01-30 22:06:23 +00004578
Tim Peters2a799bf2002-12-16 20:18:38 +00004579 /* Class methods: */
Tim Peters2a799bf2002-12-16 20:18:38 +00004580
Tim Petersa9bc1682003-01-11 03:39:11 +00004581 {"now", (PyCFunction)datetime_now,
Neal Norwitza84dcd72007-05-22 07:16:44 +00004582 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
Neal Norwitz2fbe5372003-01-23 21:09:05 +00004583 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004584
Tim Petersa9bc1682003-01-11 03:39:11 +00004585 {"utcnow", (PyCFunction)datetime_utcnow,
4586 METH_NOARGS | METH_CLASS,
4587 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4588
4589 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
Neal Norwitza84dcd72007-05-22 07:16:44 +00004590 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
Tim Peters2a44a8d2003-01-23 20:53:10 +00004591 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
Tim Peters2a799bf2002-12-16 20:18:38 +00004592
Tim Petersa9bc1682003-01-11 03:39:11 +00004593 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4594 METH_VARARGS | METH_CLASS,
4595 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4596 "(like time.time()).")},
4597
Skip Montanaro0af3ade2005-01-13 04:12:31 +00004598 {"strptime", (PyCFunction)datetime_strptime,
4599 METH_VARARGS | METH_CLASS,
4600 PyDoc_STR("string, format -> new datetime parsed from a string "
4601 "(like time.strptime()).")},
4602
Tim Petersa9bc1682003-01-11 03:39:11 +00004603 {"combine", (PyCFunction)datetime_combine,
4604 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4605 PyDoc_STR("date, time -> datetime with same date and time fields")},
4606
Tim Peters2a799bf2002-12-16 20:18:38 +00004607 /* Instance methods: */
Guido van Rossum177e41a2003-01-30 22:06:23 +00004608
Tim Petersa9bc1682003-01-11 03:39:11 +00004609 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4610 PyDoc_STR("Return date object with same year, month and day.")},
4611
4612 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4613 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4614
4615 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4616 PyDoc_STR("Return time object with same time and tzinfo.")},
4617
4618 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4619 PyDoc_STR("Return ctime() style string.")},
4620
4621 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004622 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4623
Tim Petersa9bc1682003-01-11 03:39:11 +00004624 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004625 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4626
Neal Norwitza84dcd72007-05-22 07:16:44 +00004627 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004628 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4629 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4630 "sep is used to separate the year from the time, and "
4631 "defaults to 'T'.")},
4632
Tim Petersa9bc1682003-01-11 03:39:11 +00004633 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004634 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4635
Tim Petersa9bc1682003-01-11 03:39:11 +00004636 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004637 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4638
Tim Petersa9bc1682003-01-11 03:39:11 +00004639 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
Tim Peters2a799bf2002-12-16 20:18:38 +00004640 PyDoc_STR("Return self.tzinfo.dst(self).")},
4641
Neal Norwitza84dcd72007-05-22 07:16:44 +00004642 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
Tim Petersa9bc1682003-01-11 03:39:11 +00004643 PyDoc_STR("Return datetime with new specified fields.")},
Tim Peters12bf3392002-12-24 05:41:27 +00004644
Neal Norwitza84dcd72007-05-22 07:16:44 +00004645 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
Tim Peters80475bb2002-12-25 07:40:55 +00004646 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4647
Guido van Rossum177e41a2003-01-30 22:06:23 +00004648 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4649 PyDoc_STR("__reduce__() -> (cls, state)")},
4650
Tim Peters2a799bf2002-12-16 20:18:38 +00004651 {NULL, NULL}
4652};
4653
Tim Petersa9bc1682003-01-11 03:39:11 +00004654static char datetime_doc[] =
Raymond Hettinger3a4231d2004-12-19 20:13:24 +00004655PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4656\n\
4657The year, month and day arguments are required. tzinfo may be None, or an\n\
4658instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
Tim Peters2a799bf2002-12-16 20:18:38 +00004659
Tim Petersa9bc1682003-01-11 03:39:11 +00004660static PyNumberMethods datetime_as_number = {
4661 datetime_add, /* nb_add */
4662 datetime_subtract, /* nb_subtract */
Tim Peters2a799bf2002-12-16 20:18:38 +00004663 0, /* nb_multiply */
4664 0, /* nb_divide */
4665 0, /* nb_remainder */
4666 0, /* nb_divmod */
4667 0, /* nb_power */
4668 0, /* nb_negative */
4669 0, /* nb_positive */
4670 0, /* nb_absolute */
4671 0, /* nb_nonzero */
4672};
4673
Tim Petersa9bc1682003-01-11 03:39:11 +00004674statichere PyTypeObject PyDateTime_DateTimeType = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004675 PyObject_HEAD_INIT(NULL)
4676 0, /* ob_size */
Tim Peters0bf60bd2003-01-08 20:40:01 +00004677 "datetime.datetime", /* tp_name */
Tim Petersa9bc1682003-01-11 03:39:11 +00004678 sizeof(PyDateTime_DateTime), /* tp_basicsize */
Tim Peters2a799bf2002-12-16 20:18:38 +00004679 0, /* tp_itemsize */
Tim Petersa9bc1682003-01-11 03:39:11 +00004680 (destructor)datetime_dealloc, /* tp_dealloc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004681 0, /* tp_print */
4682 0, /* tp_getattr */
4683 0, /* tp_setattr */
4684 0, /* tp_compare */
Tim Petersa9bc1682003-01-11 03:39:11 +00004685 (reprfunc)datetime_repr, /* tp_repr */
4686 &datetime_as_number, /* tp_as_number */
Tim Peters2a799bf2002-12-16 20:18:38 +00004687 0, /* tp_as_sequence */
4688 0, /* tp_as_mapping */
Tim Petersa9bc1682003-01-11 03:39:11 +00004689 (hashfunc)datetime_hash, /* tp_hash */
Tim Peters2a799bf2002-12-16 20:18:38 +00004690 0, /* tp_call */
Tim Petersa9bc1682003-01-11 03:39:11 +00004691 (reprfunc)datetime_str, /* tp_str */
Tim Peters2a799bf2002-12-16 20:18:38 +00004692 PyObject_GenericGetAttr, /* tp_getattro */
4693 0, /* tp_setattro */
4694 0, /* tp_as_buffer */
4695 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4696 Py_TPFLAGS_BASETYPE, /* tp_flags */
Tim Petersa9bc1682003-01-11 03:39:11 +00004697 datetime_doc, /* tp_doc */
Tim Peters2a799bf2002-12-16 20:18:38 +00004698 0, /* tp_traverse */
4699 0, /* tp_clear */
Tim Petersa9bc1682003-01-11 03:39:11 +00004700 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
Tim Peters2a799bf2002-12-16 20:18:38 +00004701 0, /* tp_weaklistoffset */
4702 0, /* tp_iter */
4703 0, /* tp_iternext */
Tim Petersa9bc1682003-01-11 03:39:11 +00004704 datetime_methods, /* tp_methods */
Tim Peters2a799bf2002-12-16 20:18:38 +00004705 0, /* tp_members */
Tim Petersa9bc1682003-01-11 03:39:11 +00004706 datetime_getset, /* tp_getset */
4707 &PyDateTime_DateType, /* tp_base */
Tim Peters2a799bf2002-12-16 20:18:38 +00004708 0, /* tp_dict */
4709 0, /* tp_descr_get */
4710 0, /* tp_descr_set */
4711 0, /* tp_dictoffset */
4712 0, /* tp_init */
Tim Petersa98924a2003-05-17 05:55:19 +00004713 datetime_alloc, /* tp_alloc */
Tim Petersa9bc1682003-01-11 03:39:11 +00004714 datetime_new, /* tp_new */
Tim Peters4c530132003-05-16 22:44:06 +00004715 0, /* tp_free */
Tim Peters2a799bf2002-12-16 20:18:38 +00004716};
4717
4718/* ---------------------------------------------------------------------------
4719 * Module methods and initialization.
4720 */
4721
4722static PyMethodDef module_methods[] = {
Tim Peters2a799bf2002-12-16 20:18:38 +00004723 {NULL, NULL}
4724};
4725
Tim Peters9ddf40b2004-06-20 22:41:32 +00004726/* C API. Clients get at this via PyDateTime_IMPORT, defined in
4727 * datetime.h.
4728 */
4729static PyDateTime_CAPI CAPI = {
4730 &PyDateTime_DateType,
4731 &PyDateTime_DateTimeType,
4732 &PyDateTime_TimeType,
4733 &PyDateTime_DeltaType,
4734 &PyDateTime_TZInfoType,
4735 new_date_ex,
4736 new_datetime_ex,
4737 new_time_ex,
4738 new_delta_ex,
4739 datetime_fromtimestamp,
4740 date_fromtimestamp
4741};
4742
4743
Tim Peters2a799bf2002-12-16 20:18:38 +00004744PyMODINIT_FUNC
4745initdatetime(void)
4746{
4747 PyObject *m; /* a module object */
4748 PyObject *d; /* its dict */
4749 PyObject *x;
4750
Tim Peters2a799bf2002-12-16 20:18:38 +00004751 m = Py_InitModule3("datetime", module_methods,
4752 "Fast implementation of the datetime type.");
Neal Norwitz1ac754f2006-01-19 06:09:39 +00004753 if (m == NULL)
4754 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004755
4756 if (PyType_Ready(&PyDateTime_DateType) < 0)
4757 return;
4758 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4759 return;
4760 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4761 return;
4762 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4763 return;
4764 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4765 return;
Tim Peters2a799bf2002-12-16 20:18:38 +00004766
Tim Peters2a799bf2002-12-16 20:18:38 +00004767 /* timedelta values */
4768 d = PyDateTime_DeltaType.tp_dict;
4769
Tim Peters2a799bf2002-12-16 20:18:38 +00004770 x = new_delta(0, 0, 1, 0);
4771 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4772 return;
4773 Py_DECREF(x);
4774
4775 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4776 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4777 return;
4778 Py_DECREF(x);
4779
4780 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4781 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4782 return;
4783 Py_DECREF(x);
4784
4785 /* date values */
4786 d = PyDateTime_DateType.tp_dict;
4787
4788 x = new_date(1, 1, 1);
4789 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4790 return;
4791 Py_DECREF(x);
4792
4793 x = new_date(MAXYEAR, 12, 31);
4794 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4795 return;
4796 Py_DECREF(x);
4797
4798 x = new_delta(1, 0, 0, 0);
4799 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4800 return;
4801 Py_DECREF(x);
4802
Tim Peters37f39822003-01-10 03:49:02 +00004803 /* time values */
4804 d = PyDateTime_TimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004805
Tim Peters37f39822003-01-10 03:49:02 +00004806 x = new_time(0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004807 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4808 return;
4809 Py_DECREF(x);
4810
Tim Peters37f39822003-01-10 03:49:02 +00004811 x = new_time(23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004812 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4813 return;
4814 Py_DECREF(x);
4815
4816 x = new_delta(0, 0, 1, 0);
4817 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4818 return;
4819 Py_DECREF(x);
4820
Tim Petersa9bc1682003-01-11 03:39:11 +00004821 /* datetime values */
4822 d = PyDateTime_DateTimeType.tp_dict;
Tim Peters2a799bf2002-12-16 20:18:38 +00004823
Tim Petersa9bc1682003-01-11 03:39:11 +00004824 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004825 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4826 return;
4827 Py_DECREF(x);
4828
Tim Petersa9bc1682003-01-11 03:39:11 +00004829 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
Tim Peters2a799bf2002-12-16 20:18:38 +00004830 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4831 return;
4832 Py_DECREF(x);
4833
4834 x = new_delta(0, 0, 1, 0);
4835 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4836 return;
4837 Py_DECREF(x);
4838
Tim Peters2a799bf2002-12-16 20:18:38 +00004839 /* module initialization */
4840 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4841 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4842
4843 Py_INCREF(&PyDateTime_DateType);
4844 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4845
Tim Petersa9bc1682003-01-11 03:39:11 +00004846 Py_INCREF(&PyDateTime_DateTimeType);
4847 PyModule_AddObject(m, "datetime",
4848 (PyObject *)&PyDateTime_DateTimeType);
4849
4850 Py_INCREF(&PyDateTime_TimeType);
4851 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4852
Tim Peters2a799bf2002-12-16 20:18:38 +00004853 Py_INCREF(&PyDateTime_DeltaType);
4854 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4855
Tim Peters2a799bf2002-12-16 20:18:38 +00004856 Py_INCREF(&PyDateTime_TZInfoType);
4857 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4858
Larry Hastings402b73f2010-03-25 00:54:54 +00004859 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
4860 if (x == NULL)
Victor Stinnerc1f842b2010-03-25 01:18:38 +00004861 return;
Larry Hastings402b73f2010-03-25 00:54:54 +00004862 PyModule_AddObject(m, "datetime_CAPI", x);
Tim Peters9ddf40b2004-06-20 22:41:32 +00004863
Tim Peters2a799bf2002-12-16 20:18:38 +00004864 /* A 4-year cycle has an extra leap day over what we'd get from
4865 * pasting together 4 single years.
4866 */
4867 assert(DI4Y == 4 * 365 + 1);
4868 assert(DI4Y == days_before_year(4+1));
4869
4870 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4871 * get from pasting together 4 100-year cycles.
4872 */
4873 assert(DI400Y == 4 * DI100Y + 1);
4874 assert(DI400Y == days_before_year(400+1));
4875
4876 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4877 * pasting together 25 4-year cycles.
4878 */
4879 assert(DI100Y == 25 * DI4Y - 1);
4880 assert(DI100Y == days_before_year(100+1));
4881
4882 us_per_us = PyInt_FromLong(1);
4883 us_per_ms = PyInt_FromLong(1000);
4884 us_per_second = PyInt_FromLong(1000000);
4885 us_per_minute = PyInt_FromLong(60000000);
4886 seconds_per_day = PyInt_FromLong(24 * 3600);
4887 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4888 us_per_minute == NULL || seconds_per_day == NULL)
4889 return;
4890
4891 /* The rest are too big for 32-bit ints, but even
4892 * us_per_week fits in 40 bits, so doubles should be exact.
4893 */
4894 us_per_hour = PyLong_FromDouble(3600000000.0);
4895 us_per_day = PyLong_FromDouble(86400000000.0);
4896 us_per_week = PyLong_FromDouble(604800000000.0);
4897 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4898 return;
4899}
Tim Petersf3615152003-01-01 21:51:37 +00004900
4901/* ---------------------------------------------------------------------------
Tim Petersa9bc1682003-01-11 03:39:11 +00004902Some time zone algebra. For a datetime x, let
Tim Petersf3615152003-01-01 21:51:37 +00004903 x.n = x stripped of its timezone -- its naive time.
4904 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4905 return None
4906 x.d = x.dst(), and assuming that doesn't raise an exception or
4907 return None
4908 x.s = x's standard offset, x.o - x.d
4909
4910Now some derived rules, where k is a duration (timedelta).
4911
49121. x.o = x.s + x.d
4913 This follows from the definition of x.s.
4914
Tim Petersc5dc4da2003-01-02 17:55:03 +000049152. If x and y have the same tzinfo member, x.s = y.s.
Tim Petersf3615152003-01-01 21:51:37 +00004916 This is actually a requirement, an assumption we need to make about
4917 sane tzinfo classes.
4918
49193. The naive UTC time corresponding to x is x.n - x.o.
4920 This is again a requirement for a sane tzinfo class.
4921
49224. (x+k).s = x.s
Tim Peters8bb5ad22003-01-24 02:44:45 +00004923 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
Tim Petersf3615152003-01-01 21:51:37 +00004924
Tim Petersc5dc4da2003-01-02 17:55:03 +000049255. (x+k).n = x.n + k
Tim Petersf3615152003-01-01 21:51:37 +00004926 Again follows from how arithmetic is defined.
4927
Tim Peters8bb5ad22003-01-24 02:44:45 +00004928Now we can explain tz.fromutc(x). Let's assume it's an interesting case
Tim Petersf3615152003-01-01 21:51:37 +00004929(meaning that the various tzinfo methods exist, and don't blow up or return
4930None when called).
4931
Tim Petersa9bc1682003-01-11 03:39:11 +00004932The function wants to return a datetime y with timezone tz, equivalent to x.
Tim Peters8bb5ad22003-01-24 02:44:45 +00004933x is already in UTC.
Tim Petersf3615152003-01-01 21:51:37 +00004934
4935By #3, we want
4936
Tim Peters8bb5ad22003-01-24 02:44:45 +00004937 y.n - y.o = x.n [1]
Tim Petersf3615152003-01-01 21:51:37 +00004938
4939The algorithm starts by attaching tz to x.n, and calling that y. So
4940x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4941becomes true; in effect, we want to solve [2] for k:
4942
Tim Peters8bb5ad22003-01-24 02:44:45 +00004943 (y+k).n - (y+k).o = x.n [2]
Tim Petersf3615152003-01-01 21:51:37 +00004944
4945By #1, this is the same as
4946
Tim Peters8bb5ad22003-01-24 02:44:45 +00004947 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
Tim Petersf3615152003-01-01 21:51:37 +00004948
4949By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4950Substituting that into [3],
4951
Tim Peters8bb5ad22003-01-24 02:44:45 +00004952 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4953 k - (y+k).s - (y+k).d = 0; rearranging,
4954 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4955 k = y.s - (y+k).d
Tim Petersf3615152003-01-01 21:51:37 +00004956
Tim Peters8bb5ad22003-01-24 02:44:45 +00004957On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4958approximate k by ignoring the (y+k).d term at first. Note that k can't be
4959very large, since all offset-returning methods return a duration of magnitude
4960less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4961be 0, so ignoring it has no consequence then.
Tim Petersf3615152003-01-01 21:51:37 +00004962
4963In any case, the new value is
4964
Tim Peters8bb5ad22003-01-24 02:44:45 +00004965 z = y + y.s [4]
Tim Petersf3615152003-01-01 21:51:37 +00004966
Tim Peters8bb5ad22003-01-24 02:44:45 +00004967It's helpful to step back at look at [4] from a higher level: it's simply
4968mapping from UTC to tz's standard time.
Tim Petersc5dc4da2003-01-02 17:55:03 +00004969
4970At this point, if
4971
Tim Peters8bb5ad22003-01-24 02:44:45 +00004972 z.n - z.o = x.n [5]
Tim Petersc5dc4da2003-01-02 17:55:03 +00004973
4974we have an equivalent time, and are almost done. The insecurity here is
Tim Petersf3615152003-01-01 21:51:37 +00004975at the start of daylight time. Picture US Eastern for concreteness. The wall
4976time 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 +00004977sense then. The docs ask that an Eastern tzinfo class consider such a time to
4978be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4979on the day DST starts. We want to return the 1:MM EST spelling because that's
Tim Petersf3615152003-01-01 21:51:37 +00004980the only spelling that makes sense on the local wall clock.
4981
Tim Petersc5dc4da2003-01-02 17:55:03 +00004982In fact, if [5] holds at this point, we do have the standard-time spelling,
4983but that takes a bit of proof. We first prove a stronger result. What's the
4984difference between the LHS and RHS of [5]? Let
Tim Petersf3615152003-01-01 21:51:37 +00004985
Tim Peters8bb5ad22003-01-24 02:44:45 +00004986 diff = x.n - (z.n - z.o) [6]
Tim Petersf3615152003-01-01 21:51:37 +00004987
Tim Petersc5dc4da2003-01-02 17:55:03 +00004988Now
4989 z.n = by [4]
Tim Peters8bb5ad22003-01-24 02:44:45 +00004990 (y + y.s).n = by #5
4991 y.n + y.s = since y.n = x.n
4992 x.n + y.s = since z and y are have the same tzinfo member,
4993 y.s = z.s by #2
4994 x.n + z.s
Tim Petersf3615152003-01-01 21:51:37 +00004995
Tim Petersc5dc4da2003-01-02 17:55:03 +00004996Plugging that back into [6] gives
Tim Petersf3615152003-01-01 21:51:37 +00004997
Tim Petersc5dc4da2003-01-02 17:55:03 +00004998 diff =
Tim Peters8bb5ad22003-01-24 02:44:45 +00004999 x.n - ((x.n + z.s) - z.o) = expanding
5000 x.n - x.n - z.s + z.o = cancelling
5001 - z.s + z.o = by #2
Tim Petersc5dc4da2003-01-02 17:55:03 +00005002 z.d
Tim Petersf3615152003-01-01 21:51:37 +00005003
Tim Petersc5dc4da2003-01-02 17:55:03 +00005004So diff = z.d.
Tim Petersf3615152003-01-01 21:51:37 +00005005
Tim Petersc5dc4da2003-01-02 17:55:03 +00005006If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
Tim Peters8bb5ad22003-01-24 02:44:45 +00005007spelling we wanted in the endcase described above. We're done. Contrarily,
5008if z.d = 0, then we have a UTC equivalent, and are also done.
Tim Petersf3615152003-01-01 21:51:37 +00005009
Tim Petersc5dc4da2003-01-02 17:55:03 +00005010If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5011add to z (in effect, z is in tz's standard time, and we need to shift the
Tim Peters8bb5ad22003-01-24 02:44:45 +00005012local clock into tz's daylight time).
Tim Petersf3615152003-01-01 21:51:37 +00005013
Tim Petersc5dc4da2003-01-02 17:55:03 +00005014Let
Tim Petersf3615152003-01-01 21:51:37 +00005015
Tim Peters4fede1a2003-01-04 00:26:59 +00005016 z' = z + z.d = z + diff [7]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005017
Tim Peters4fede1a2003-01-04 00:26:59 +00005018and we can again ask whether
Tim Petersc3bb26a2003-01-02 03:14:59 +00005019
Tim Peters8bb5ad22003-01-24 02:44:45 +00005020 z'.n - z'.o = x.n [8]
Tim Petersc3bb26a2003-01-02 03:14:59 +00005021
Tim Peters8bb5ad22003-01-24 02:44:45 +00005022If so, we're done. If not, the tzinfo class is insane, according to the
5023assumptions we've made. This also requires a bit of proof. As before, let's
5024compute the difference between the LHS and RHS of [8] (and skipping some of
5025the justifications for the kinds of substitutions we've done several times
5026already):
Tim Peters4fede1a2003-01-04 00:26:59 +00005027
Tim Peters8bb5ad22003-01-24 02:44:45 +00005028 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5029 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5030 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5031 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5032 - z.n + z.n - z.o + z'.o = cancel z.n
Tim Peters4fede1a2003-01-04 00:26:59 +00005033 - z.o + z'.o = #1 twice
5034 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5035 z'.d - z.d
5036
5037So 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 +00005038we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5039return z', not bothering to compute z'.d.
Tim Peters4fede1a2003-01-04 00:26:59 +00005040
Tim Peters8bb5ad22003-01-24 02:44:45 +00005041How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5042a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5043would have to change the result dst() returns: we start in DST, and moving
5044a little further into it takes us out of DST.
Tim Peters4fede1a2003-01-04 00:26:59 +00005045
Tim Peters8bb5ad22003-01-24 02:44:45 +00005046There isn't a sane case where this can happen. The closest it gets is at
5047the end of DST, where there's an hour in UTC with no spelling in a hybrid
5048tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5049that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5050UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5051time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5052clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5053standard time. Since that's what the local clock *does*, we want to map both
5054UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
Tim Peters4fede1a2003-01-04 00:26:59 +00005055in local time, but so it goes -- it's the way the local clock works.
5056
Tim Peters8bb5ad22003-01-24 02:44:45 +00005057When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5058so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5059z' = 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 +00005060(correctly) concludes that z' is not UTC-equivalent to x.
5061
5062Because we know z.d said z was in daylight time (else [5] would have held and
5063we would have stopped then), and we know z.d != z'.d (else [8] would have held
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005064and we would have stopped then), and there are only 2 possible values dst() can
Tim Peters4fede1a2003-01-04 00:26:59 +00005065return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5066but the reasoning doesn't depend on the example -- it depends on there being
5067two possible dst() outcomes, one zero and the other non-zero). Therefore
Tim Peters8bb5ad22003-01-24 02:44:45 +00005068z' must be in standard time, and is the spelling we want in this case.
5069
5070Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5071concerned (because it takes z' as being in standard time rather than the
5072daylight time we intend here), but returning it gives the real-life "local
5073clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5074tz.
5075
5076When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5077the 1:MM standard time spelling we want.
5078
5079So how can this break? One of the assumptions must be violated. Two
5080possibilities:
5081
50821) [2] effectively says that y.s is invariant across all y belong to a given
5083 time zone. This isn't true if, for political reasons or continental drift,
5084 a region decides to change its base offset from UTC.
5085
50862) There may be versions of "double daylight" time where the tail end of
5087 the analysis gives up a step too early. I haven't thought about that
5088 enough to say.
5089
5090In any case, it's clear that the default fromutc() is strong enough to handle
5091"almost all" time zones: so long as the standard offset is invariant, it
5092doesn't matter if daylight time transition points change from year to year, or
5093if daylight time is skipped in some years; it doesn't matter how large or
5094small dst() may get within its bounds; and it doesn't even matter if some
5095perverse time zone returns a negative dst()). So a breaking case must be
5096pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
Tim Petersf3615152003-01-01 21:51:37 +00005097--------------------------------------------------------------------------- */