1 /* C implementation for the date/time type documented at
2 * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3 */
4
5 #define PY_SSIZE_T_CLEAN
6
7 #include "Python.h"
8 #include "modsupport.h"
9 #include "structmember.h"
10
11 #include <time.h>
12
13 #include "timefuncs.h"
14
15 /* Differentiate between building the core module and building extension
16 * modules.
17 */
18 #ifndef Py_BUILD_CORE
19 #define Py_BUILD_CORE
20 #endif
21 #include "datetime.h"
22 #undef Py_BUILD_CORE
23
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 #define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
36
37 /* Nine decimal digits is easy to communicate, and leaves enough room
38 * so that two delta days can be added w/o fear of overflowing a signed
39 * 32-bit int, and with plenty of room left over to absorb any possible
40 * carries from adding seconds.
41 */
42 #define MAX_DELTA_DAYS 999999999
43
44 /* Rename the long macros in datetime.h to more reasonable short names. */
45 #define GET_YEAR PyDateTime_GET_YEAR
46 #define GET_MONTH PyDateTime_GET_MONTH
47 #define GET_DAY PyDateTime_GET_DAY
48 #define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
49 #define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
50 #define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
51 #define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
52
53 /* Date accessors for date and datetime. */
54 #define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
55 ((o)->data[1] = ((v) & 0x00ff)))
56 #define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
57 #define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
58
59 /* Date/Time accessors for datetime. */
60 #define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
61 #define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
62 #define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
63 #define DATE_SET_MICROSECOND(o, v) \
64 (((o)->data[7] = ((v) & 0xff0000) >> 16), \
65 ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
66 ((o)->data[9] = ((v) & 0x0000ff)))
67
68 /* Time accessors for time. */
69 #define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
70 #define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
71 #define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
72 #define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
73 #define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
74 #define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
75 #define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
76 #define TIME_SET_MICROSECOND(o, v) \
77 (((o)->data[3] = ((v) & 0xff0000) >> 16), \
78 ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
79 ((o)->data[5] = ((v) & 0x0000ff)))
80
81 /* Delta accessors for timedelta. */
82 #define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
83 #define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
84 #define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
85
86 #define SET_TD_DAYS(o, v) ((o)->days = (v))
87 #define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
88 #define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
89
90 /* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
91 * p->hastzinfo.
92 */
93 #define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
94
95 /* M is a char or int claiming to be a valid month. The macro is equivalent
96 * to the two-sided Python test
97 * 1 <= M <= 12
98 */
99 #define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
100
101 /* Forward declarations. */
102 static PyTypeObject PyDateTime_DateType;
103 static PyTypeObject PyDateTime_DateTimeType;
104 static PyTypeObject PyDateTime_DeltaType;
105 static PyTypeObject PyDateTime_TimeType;
106 static PyTypeObject PyDateTime_TZInfoType;
107
108 /* ---------------------------------------------------------------------------
109 * Math utilities.
110 */
111
112 /* k = i+j overflows iff k differs in sign from both inputs,
113 * iff k^i has sign bit set and k^j has sign bit set,
114 * iff (k^i)&(k^j) has sign bit set.
115 */
116 #define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
117 ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
118
119 /* Compute Python divmod(x, y), returning the quotient and storing the
120 * remainder into *r. The quotient is the floor of x/y, and that's
121 * the real point of this. C will probably truncate instead (C99
122 * requires truncation; C89 left it implementation-defined).
123 * Simplification: we *require* that y > 0 here. That's appropriate
124 * for all the uses made of it. This simplifies the code and makes
125 * the overflow case impossible (divmod(LONG_MIN, -1) is the only
126 * overflow case).
127 */
128 static int
divmod(int x,int y,int * r)129 divmod(int x, int y, int *r)
130 {
131 int quo;
132
133 assert(y > 0);
134 quo = x / y;
135 *r = x - quo * y;
136 if (*r < 0) {
137 --quo;
138 *r += y;
139 }
140 assert(0 <= *r && *r < y);
141 return quo;
142 }
143
144 /* Round a double to the nearest long. |x| must be small enough to fit
145 * in a C long; this is not checked.
146 */
147 static long
round_to_long(double x)148 round_to_long(double x)
149 {
150 if (x >= 0.0)
151 x = floor(x + 0.5);
152 else
153 x = ceil(x - 0.5);
154 return (long)x;
155 }
156
157 /* ---------------------------------------------------------------------------
158 * General calendrical helper functions
159 */
160
161 /* For each month ordinal in 1..12, the number of days in that month,
162 * and the number of days before that month in the same year. These
163 * are correct for non-leap years only.
164 */
165 static int _days_in_month[] = {
166 0, /* unused; this vector uses 1-based indexing */
167 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
168 };
169
170 static int _days_before_month[] = {
171 0, /* unused; this vector uses 1-based indexing */
172 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
173 };
174
175 /* year -> 1 if leap year, else 0. */
176 static int
is_leap(int year)177 is_leap(int year)
178 {
179 /* Cast year to unsigned. The result is the same either way, but
180 * C can generate faster code for unsigned mod than for signed
181 * mod (especially for % 4 -- a good compiler should just grab
182 * the last 2 bits when the LHS is unsigned).
183 */
184 const unsigned int ayear = (unsigned int)year;
185 return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
186 }
187
188 /* year, month -> number of days in that month in that year */
189 static int
days_in_month(int year,int month)190 days_in_month(int year, int month)
191 {
192 assert(month >= 1);
193 assert(month <= 12);
194 if (month == 2 && is_leap(year))
195 return 29;
196 else
197 return _days_in_month[month];
198 }
199
200 /* year, month -> number of days in year preceding first day of month */
201 static int
days_before_month(int year,int month)202 days_before_month(int year, int month)
203 {
204 int days;
205
206 assert(month >= 1);
207 assert(month <= 12);
208 days = _days_before_month[month];
209 if (month > 2 && is_leap(year))
210 ++days;
211 return days;
212 }
213
214 /* year -> number of days before January 1st of year. Remember that we
215 * start with year 1, so days_before_year(1) == 0.
216 */
217 static int
days_before_year(int year)218 days_before_year(int year)
219 {
220 int y = year - 1;
221 /* This is incorrect if year <= 0; we really want the floor
222 * here. But so long as MINYEAR is 1, the smallest year this
223 * can see is 0 (this can happen in some normalization endcases),
224 * so we'll just special-case that.
225 */
226 assert (year >= 0);
227 if (y >= 0)
228 return y*365 + y/4 - y/100 + y/400;
229 else {
230 assert(y == -1);
231 return -366;
232 }
233 }
234
235 /* Number of days in 4, 100, and 400 year cycles. That these have
236 * the correct values is asserted in the module init function.
237 */
238 #define DI4Y 1461 /* days_before_year(5); days in 4 years */
239 #define DI100Y 36524 /* days_before_year(101); days in 100 years */
240 #define DI400Y 146097 /* days_before_year(401); days in 400 years */
241
242 /* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
243 static void
ord_to_ymd(int ordinal,int * year,int * month,int * day)244 ord_to_ymd(int ordinal, int *year, int *month, int *day)
245 {
246 int n, n1, n4, n100, n400, leapyear, preceding;
247
248 /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
249 * leap years repeats exactly every 400 years. The basic strategy is
250 * to find the closest 400-year boundary at or before ordinal, then
251 * work with the offset from that boundary to ordinal. Life is much
252 * clearer if we subtract 1 from ordinal first -- then the values
253 * of ordinal at 400-year boundaries are exactly those divisible
254 * by DI400Y:
255 *
256 * D M Y n n-1
257 * -- --- ---- ---------- ----------------
258 * 31 Dec -400 -DI400Y -DI400Y -1
259 * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
260 * ...
261 * 30 Dec 000 -1 -2
262 * 31 Dec 000 0 -1
263 * 1 Jan 001 1 0 400-year boundary
264 * 2 Jan 001 2 1
265 * 3 Jan 001 3 2
266 * ...
267 * 31 Dec 400 DI400Y DI400Y -1
268 * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
269 */
270 assert(ordinal >= 1);
271 --ordinal;
272 n400 = ordinal / DI400Y;
273 n = ordinal % DI400Y;
274 *year = n400 * 400 + 1;
275
276 /* Now n is the (non-negative) offset, in days, from January 1 of
277 * year, to the desired date. Now compute how many 100-year cycles
278 * precede n.
279 * Note that it's possible for n100 to equal 4! In that case 4 full
280 * 100-year cycles precede the desired day, which implies the
281 * desired day is December 31 at the end of a 400-year cycle.
282 */
283 n100 = n / DI100Y;
284 n = n % DI100Y;
285
286 /* Now compute how many 4-year cycles precede it. */
287 n4 = n / DI4Y;
288 n = n % DI4Y;
289
290 /* And now how many single years. Again n1 can be 4, and again
291 * meaning that the desired day is December 31 at the end of the
292 * 4-year cycle.
293 */
294 n1 = n / 365;
295 n = n % 365;
296
297 *year += n100 * 100 + n4 * 4 + n1;
298 if (n1 == 4 || n100 == 4) {
299 assert(n == 0);
300 *year -= 1;
301 *month = 12;
302 *day = 31;
303 return;
304 }
305
306 /* Now the year is correct, and n is the offset from January 1. We
307 * find the month via an estimate that's either exact or one too
308 * large.
309 */
310 leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
311 assert(leapyear == is_leap(*year));
312 *month = (n + 50) >> 5;
313 preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
314 if (preceding > n) {
315 /* estimate is too large */
316 *month -= 1;
317 preceding -= days_in_month(*year, *month);
318 }
319 n -= preceding;
320 assert(0 <= n);
321 assert(n < days_in_month(*year, *month));
322
323 *day = n + 1;
324 }
325
326 /* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
327 static int
ymd_to_ord(int year,int month,int day)328 ymd_to_ord(int year, int month, int day)
329 {
330 return days_before_year(year) + days_before_month(year, month) + day;
331 }
332
333 /* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
334 static int
weekday(int year,int month,int day)335 weekday(int year, int month, int day)
336 {
337 return (ymd_to_ord(year, month, day) + 6) % 7;
338 }
339
340 /* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
341 * first calendar week containing a Thursday.
342 */
343 static int
iso_week1_monday(int year)344 iso_week1_monday(int year)
345 {
346 int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
347 /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
348 int first_weekday = (first_day + 6) % 7;
349 /* ordinal of closest Monday at or before 1/1 */
350 int week1_monday = first_day - first_weekday;
351
352 if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
353 week1_monday += 7;
354 return week1_monday;
355 }
356
357 /* ---------------------------------------------------------------------------
358 * Range checkers.
359 */
360
361 /* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
362 * If not, raise OverflowError and return -1.
363 */
364 static int
check_delta_day_range(int days)365 check_delta_day_range(int days)
366 {
367 if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
368 return 0;
369 PyErr_Format(PyExc_OverflowError,
370 "days=%d; must have magnitude <= %d",
371 days, MAX_DELTA_DAYS);
372 return -1;
373 }
374
375 /* Check that date arguments are in range. Return 0 if they are. If they
376 * aren't, raise ValueError and return -1.
377 */
378 static int
check_date_args(int year,int month,int day)379 check_date_args(int year, int month, int day)
380 {
381
382 if (year < MINYEAR || year > MAXYEAR) {
383 PyErr_SetString(PyExc_ValueError,
384 "year is out of range");
385 return -1;
386 }
387 if (month < 1 || month > 12) {
388 PyErr_SetString(PyExc_ValueError,
389 "month must be in 1..12");
390 return -1;
391 }
392 if (day < 1 || day > days_in_month(year, month)) {
393 PyErr_SetString(PyExc_ValueError,
394 "day is out of range for month");
395 return -1;
396 }
397 return 0;
398 }
399
400 /* Check that time arguments are in range. Return 0 if they are. If they
401 * aren't, raise ValueError and return -1.
402 */
403 static int
check_time_args(int h,int m,int s,int us)404 check_time_args(int h, int m, int s, int us)
405 {
406 if (h < 0 || h > 23) {
407 PyErr_SetString(PyExc_ValueError,
408 "hour must be in 0..23");
409 return -1;
410 }
411 if (m < 0 || m > 59) {
412 PyErr_SetString(PyExc_ValueError,
413 "minute must be in 0..59");
414 return -1;
415 }
416 if (s < 0 || s > 59) {
417 PyErr_SetString(PyExc_ValueError,
418 "second must be in 0..59");
419 return -1;
420 }
421 if (us < 0 || us > 999999) {
422 PyErr_SetString(PyExc_ValueError,
423 "microsecond must be in 0..999999");
424 return -1;
425 }
426 return 0;
427 }
428
429 /* ---------------------------------------------------------------------------
430 * Normalization utilities.
431 */
432
433 /* One step of a mixed-radix conversion. A "hi" unit is equivalent to
434 * factor "lo" units. factor must be > 0. If *lo is less than 0, or
435 * at least factor, enough of *lo is converted into "hi" units so that
436 * 0 <= *lo < factor. The input values must be such that int overflow
437 * is impossible.
438 */
439 static void
normalize_pair(int * hi,int * lo,int factor)440 normalize_pair(int *hi, int *lo, int factor)
441 {
442 assert(factor > 0);
443 assert(lo != hi);
444 if (*lo < 0 || *lo >= factor) {
445 const int num_hi = divmod(*lo, factor, lo);
446 const int new_hi = *hi + num_hi;
447 assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
448 *hi = new_hi;
449 }
450 assert(0 <= *lo && *lo < factor);
451 }
452
453 /* Fiddle days (d), seconds (s), and microseconds (us) so that
454 * 0 <= *s < 24*3600
455 * 0 <= *us < 1000000
456 * The input values must be such that the internals don't overflow.
457 * The way this routine is used, we don't get close.
458 */
459 static void
normalize_d_s_us(int * d,int * s,int * us)460 normalize_d_s_us(int *d, int *s, int *us)
461 {
462 if (*us < 0 || *us >= 1000000) {
463 normalize_pair(s, us, 1000000);
464 /* |s| can't be bigger than about
465 * |original s| + |original us|/1000000 now.
466 */
467
468 }
469 if (*s < 0 || *s >= 24*3600) {
470 normalize_pair(d, s, 24*3600);
471 /* |d| can't be bigger than about
472 * |original d| +
473 * (|original s| + |original us|/1000000) / (24*3600) now.
474 */
475 }
476 assert(0 <= *s && *s < 24*3600);
477 assert(0 <= *us && *us < 1000000);
478 }
479
480 /* Fiddle years (y), months (m), and days (d) so that
481 * 1 <= *m <= 12
482 * 1 <= *d <= days_in_month(*y, *m)
483 * The input values must be such that the internals don't overflow.
484 * The way this routine is used, we don't get close.
485 */
486 static int
normalize_y_m_d(int * y,int * m,int * d)487 normalize_y_m_d(int *y, int *m, int *d)
488 {
489 int dim; /* # of days in month */
490
491 /* This gets muddy: the proper range for day can't be determined
492 * without knowing the correct month and year, but if day is, e.g.,
493 * plus or minus a million, the current month and year values make
494 * no sense (and may also be out of bounds themselves).
495 * Saying 12 months == 1 year should be non-controversial.
496 */
497 if (*m < 1 || *m > 12) {
498 --*m;
499 normalize_pair(y, m, 12);
500 ++*m;
501 /* |y| can't be bigger than about
502 * |original y| + |original m|/12 now.
503 */
504 }
505 assert(1 <= *m && *m <= 12);
506
507 /* Now only day can be out of bounds (year may also be out of bounds
508 * for a datetime object, but we don't care about that here).
509 * If day is out of bounds, what to do is arguable, but at least the
510 * method here is principled and explainable.
511 */
512 dim = days_in_month(*y, *m);
513 if (*d < 1 || *d > dim) {
514 /* Move day-1 days from the first of the month. First try to
515 * get off cheap if we're only one day out of range
516 * (adjustments for timezone alone can't be worse than that).
517 */
518 if (*d == 0) {
519 --*m;
520 if (*m > 0)
521 *d = days_in_month(*y, *m);
522 else {
523 --*y;
524 *m = 12;
525 *d = 31;
526 }
527 }
528 else if (*d == dim + 1) {
529 /* move forward a day */
530 ++*m;
531 *d = 1;
532 if (*m > 12) {
533 *m = 1;
534 ++*y;
535 }
536 }
537 else {
538 int ordinal = ymd_to_ord(*y, *m, 1) +
539 *d - 1;
540 if (ordinal < 1 || ordinal > MAXORDINAL) {
541 goto error;
542 } else {
543 ord_to_ymd(ordinal, y, m, d);
544 return 0;
545 }
546 }
547 }
548 assert(*m > 0);
549 assert(*d > 0);
550 if (MINYEAR <= *y && *y <= MAXYEAR)
551 return 0;
552 error:
553 PyErr_SetString(PyExc_OverflowError,
554 "date value out of range");
555 return -1;
556
557 }
558
559 /* Fiddle out-of-bounds months and days so that the result makes some kind
560 * of sense. The parameters are both inputs and outputs. Returns < 0 on
561 * failure, where failure means the adjusted year is out of bounds.
562 */
563 static int
normalize_date(int * year,int * month,int * day)564 normalize_date(int *year, int *month, int *day)
565 {
566 return normalize_y_m_d(year, month, day);
567 }
568
569 /* Force all the datetime fields into range. The parameters are both
570 * inputs and outputs. Returns < 0 on error.
571 */
572 static int
normalize_datetime(int * year,int * month,int * day,int * hour,int * minute,int * second,int * microsecond)573 normalize_datetime(int *year, int *month, int *day,
574 int *hour, int *minute, int *second,
575 int *microsecond)
576 {
577 normalize_pair(second, microsecond, 1000000);
578 normalize_pair(minute, second, 60);
579 normalize_pair(hour, minute, 60);
580 normalize_pair(day, hour, 24);
581 return normalize_date(year, month, day);
582 }
583
584 /* ---------------------------------------------------------------------------
585 * Basic object allocation: tp_alloc implementations. These allocate
586 * Python objects of the right size and type, and do the Python object-
587 * initialization bit. If there's not enough memory, they return NULL after
588 * setting MemoryError. All data members remain uninitialized trash.
589 *
590 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
591 * member is needed. This is ugly, imprecise, and possibly insecure.
592 * tp_basicsize for the time and datetime types is set to the size of the
593 * struct that has room for the tzinfo member, so subclasses in Python will
594 * allocate enough space for a tzinfo member whether or not one is actually
595 * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
596 * part is that PyType_GenericAlloc() (which subclasses in Python end up
597 * using) just happens today to effectively ignore the nitems argument
598 * when tp_itemsize is 0, which it is for these type objects. If that
599 * changes, perhaps the callers of tp_alloc slots in this file should
600 * be changed to force a 0 nitems argument unless the type being allocated
601 * is a base type implemented in this file (so that tp_alloc is time_alloc
602 * or datetime_alloc below, which know about the nitems abuse).
603 */
604
605 static PyObject *
time_alloc(PyTypeObject * type,Py_ssize_t aware)606 time_alloc(PyTypeObject *type, Py_ssize_t aware)
607 {
608 PyObject *self;
609
610 self = (PyObject *)
611 PyObject_MALLOC(aware ?
612 sizeof(PyDateTime_Time) :
613 sizeof(_PyDateTime_BaseTime));
614 if (self == NULL)
615 return (PyObject *)PyErr_NoMemory();
616 (void)PyObject_INIT(self, type);
617 return self;
618 }
619
620 static PyObject *
datetime_alloc(PyTypeObject * type,Py_ssize_t aware)621 datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
622 {
623 PyObject *self;
624
625 self = (PyObject *)
626 PyObject_MALLOC(aware ?
627 sizeof(PyDateTime_DateTime) :
628 sizeof(_PyDateTime_BaseDateTime));
629 if (self == NULL)
630 return (PyObject *)PyErr_NoMemory();
631 (void)PyObject_INIT(self, type);
632 return self;
633 }
634
635 /* ---------------------------------------------------------------------------
636 * Helpers for setting object fields. These work on pointers to the
637 * appropriate base class.
638 */
639
640 /* For date and datetime. */
641 static void
set_date_fields(PyDateTime_Date * self,int y,int m,int d)642 set_date_fields(PyDateTime_Date *self, int y, int m, int d)
643 {
644 self->hashcode = -1;
645 SET_YEAR(self, y);
646 SET_MONTH(self, m);
647 SET_DAY(self, d);
648 }
649
650 /* ---------------------------------------------------------------------------
651 * Create various objects, mostly without range checking.
652 */
653
654 /* Create a date instance with no range checking. */
655 static PyObject *
new_date_ex(int year,int month,int day,PyTypeObject * type)656 new_date_ex(int year, int month, int day, PyTypeObject *type)
657 {
658 PyDateTime_Date *self;
659
660 self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
661 if (self != NULL)
662 set_date_fields(self, year, month, day);
663 return (PyObject *) self;
664 }
665
666 #define new_date(year, month, day) \
667 new_date_ex(year, month, day, &PyDateTime_DateType)
668
669 /* Create a datetime instance with no range checking. */
670 static PyObject *
new_datetime_ex(int year,int month,int day,int hour,int minute,int second,int usecond,PyObject * tzinfo,PyTypeObject * type)671 new_datetime_ex(int year, int month, int day, int hour, int minute,
672 int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
673 {
674 PyDateTime_DateTime *self;
675 char aware = tzinfo != Py_None;
676
677 self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
678 if (self != NULL) {
679 self->hastzinfo = aware;
680 set_date_fields((PyDateTime_Date *)self, year, month, day);
681 DATE_SET_HOUR(self, hour);
682 DATE_SET_MINUTE(self, minute);
683 DATE_SET_SECOND(self, second);
684 DATE_SET_MICROSECOND(self, usecond);
685 if (aware) {
686 Py_INCREF(tzinfo);
687 self->tzinfo = tzinfo;
688 }
689 }
690 return (PyObject *)self;
691 }
692
693 #define new_datetime(y, m, d, hh, mm, ss, us, tzinfo) \
694 new_datetime_ex(y, m, d, hh, mm, ss, us, tzinfo, \
695 &PyDateTime_DateTimeType)
696
697 /* Create a time instance with no range checking. */
698 static PyObject *
new_time_ex(int hour,int minute,int second,int usecond,PyObject * tzinfo,PyTypeObject * type)699 new_time_ex(int hour, int minute, int second, int usecond,
700 PyObject *tzinfo, PyTypeObject *type)
701 {
702 PyDateTime_Time *self;
703 char aware = tzinfo != Py_None;
704
705 self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
706 if (self != NULL) {
707 self->hastzinfo = aware;
708 self->hashcode = -1;
709 TIME_SET_HOUR(self, hour);
710 TIME_SET_MINUTE(self, minute);
711 TIME_SET_SECOND(self, second);
712 TIME_SET_MICROSECOND(self, usecond);
713 if (aware) {
714 Py_INCREF(tzinfo);
715 self->tzinfo = tzinfo;
716 }
717 }
718 return (PyObject *)self;
719 }
720
721 #define new_time(hh, mm, ss, us, tzinfo) \
722 new_time_ex(hh, mm, ss, us, tzinfo, &PyDateTime_TimeType)
723
724 /* Create a timedelta instance. Normalize the members iff normalize is
725 * true. Passing false is a speed optimization, if you know for sure
726 * that seconds and microseconds are already in their proper ranges. In any
727 * case, raises OverflowError and returns NULL if the normalized days is out
728 * of range).
729 */
730 static PyObject *
new_delta_ex(int days,int seconds,int microseconds,int normalize,PyTypeObject * type)731 new_delta_ex(int days, int seconds, int microseconds, int normalize,
732 PyTypeObject *type)
733 {
734 PyDateTime_Delta *self;
735
736 if (normalize)
737 normalize_d_s_us(&days, &seconds, µseconds);
738 assert(0 <= seconds && seconds < 24*3600);
739 assert(0 <= microseconds && microseconds < 1000000);
740
741 if (check_delta_day_range(days) < 0)
742 return NULL;
743
744 self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
745 if (self != NULL) {
746 self->hashcode = -1;
747 SET_TD_DAYS(self, days);
748 SET_TD_SECONDS(self, seconds);
749 SET_TD_MICROSECONDS(self, microseconds);
750 }
751 return (PyObject *) self;
752 }
753
754 #define new_delta(d, s, us, normalize) \
755 new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
756
757 /* ---------------------------------------------------------------------------
758 * tzinfo helpers.
759 */
760
761 /* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
762 * raise TypeError and return -1.
763 */
764 static int
check_tzinfo_subclass(PyObject * p)765 check_tzinfo_subclass(PyObject *p)
766 {
767 if (p == Py_None || PyTZInfo_Check(p))
768 return 0;
769 PyErr_Format(PyExc_TypeError,
770 "tzinfo argument must be None or of a tzinfo subclass, "
771 "not type '%s'",
772 Py_TYPE(p)->tp_name);
773 return -1;
774 }
775
776 /* Return tzinfo.methname(tzinfoarg), without any checking of results.
777 * If tzinfo is None, returns None.
778 */
779 static PyObject *
call_tzinfo_method(PyObject * tzinfo,char * methname,PyObject * tzinfoarg)780 call_tzinfo_method(PyObject *tzinfo, char *methname, PyObject *tzinfoarg)
781 {
782 PyObject *result;
783
784 assert(tzinfo && methname && tzinfoarg);
785 assert(check_tzinfo_subclass(tzinfo) >= 0);
786 if (tzinfo == Py_None) {
787 result = Py_None;
788 Py_INCREF(result);
789 }
790 else
791 result = PyObject_CallMethod(tzinfo, methname, "O", tzinfoarg);
792 return result;
793 }
794
795 /* If self has a tzinfo member, return a BORROWED reference to it. Else
796 * return NULL, which is NOT AN ERROR. There are no error returns here,
797 * and the caller must not decref the result.
798 */
799 static PyObject *
get_tzinfo_member(PyObject * self)800 get_tzinfo_member(PyObject *self)
801 {
802 PyObject *tzinfo = NULL;
803
804 if (PyDateTime_Check(self) && HASTZINFO(self))
805 tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
806 else if (PyTime_Check(self) && HASTZINFO(self))
807 tzinfo = ((PyDateTime_Time *)self)->tzinfo;
808
809 return tzinfo;
810 }
811
812 /* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
813 * result. tzinfo must be an instance of the tzinfo class. If the method
814 * returns None, this returns 0 and sets *none to 1. If the method doesn't
815 * return None or timedelta, TypeError is raised and this returns -1. If it
816 * returnsa timedelta and the value is out of range or isn't a whole number
817 * of minutes, ValueError is raised and this returns -1.
818 * Else *none is set to 0 and the integer method result is returned.
819 */
820 static int
call_utc_tzinfo_method(PyObject * tzinfo,char * name,PyObject * tzinfoarg,int * none)821 call_utc_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg,
822 int *none)
823 {
824 PyObject *u;
825 int result = -1;
826
827 assert(tzinfo != NULL);
828 assert(PyTZInfo_Check(tzinfo));
829 assert(tzinfoarg != NULL);
830
831 *none = 0;
832 u = call_tzinfo_method(tzinfo, name, tzinfoarg);
833 if (u == NULL)
834 return -1;
835
836 else if (u == Py_None) {
837 result = 0;
838 *none = 1;
839 }
840 else if (PyDelta_Check(u)) {
841 const int days = GET_TD_DAYS(u);
842 if (days < -1 || days > 0)
843 result = 24*60; /* trigger ValueError below */
844 else {
845 /* next line can't overflow because we know days
846 * is -1 or 0 now
847 */
848 int ss = days * 24 * 3600 + GET_TD_SECONDS(u);
849 result = divmod(ss, 60, &ss);
850 if (ss || GET_TD_MICROSECONDS(u)) {
851 PyErr_Format(PyExc_ValueError,
852 "tzinfo.%s() must return a "
853 "whole number of minutes",
854 name);
855 result = -1;
856 }
857 }
858 }
859 else {
860 PyErr_Format(PyExc_TypeError,
861 "tzinfo.%s() must return None or "
862 "timedelta, not '%s'",
863 name, Py_TYPE(u)->tp_name);
864 }
865
866 Py_DECREF(u);
867 if (result < -1439 || result > 1439) {
868 PyErr_Format(PyExc_ValueError,
869 "tzinfo.%s() returned %d; must be in "
870 "-1439 .. 1439",
871 name, result);
872 result = -1;
873 }
874 return result;
875 }
876
877 /* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
878 * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
879 * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
880 * doesn't return None or timedelta, TypeError is raised and this returns -1.
881 * If utcoffset() returns an invalid timedelta (out of range, or not a whole
882 * # of minutes), ValueError is raised and this returns -1. Else *none is
883 * set to 0 and the offset is returned (as int # of minutes east of UTC).
884 */
885 static int
call_utcoffset(PyObject * tzinfo,PyObject * tzinfoarg,int * none)886 call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
887 {
888 return call_utc_tzinfo_method(tzinfo, "utcoffset", tzinfoarg, none);
889 }
890
891 /* Call tzinfo.name(tzinfoarg), and return the offset as a timedelta or None.
892 */
893 static PyObject *
offset_as_timedelta(PyObject * tzinfo,char * name,PyObject * tzinfoarg)894 offset_as_timedelta(PyObject *tzinfo, char *name, PyObject *tzinfoarg) {
895 PyObject *result;
896
897 assert(tzinfo && name && tzinfoarg);
898 if (tzinfo == Py_None) {
899 result = Py_None;
900 Py_INCREF(result);
901 }
902 else {
903 int none;
904 int offset = call_utc_tzinfo_method(tzinfo, name, tzinfoarg,
905 &none);
906 if (offset < 0 && PyErr_Occurred())
907 return NULL;
908 if (none) {
909 result = Py_None;
910 Py_INCREF(result);
911 }
912 else
913 result = new_delta(0, offset * 60, 0, 1);
914 }
915 return result;
916 }
917
918 /* Call tzinfo.dst(tzinfoarg), and extract an integer from the
919 * result. tzinfo must be an instance of the tzinfo class. If dst()
920 * returns None, call_dst returns 0 and sets *none to 1. If dst()
921 & doesn't return None or timedelta, TypeError is raised and this
922 * returns -1. If dst() returns an invalid timedelta for a UTC offset,
923 * ValueError is raised and this returns -1. Else *none is set to 0 and
924 * the offset is returned (as an int # of minutes east of UTC).
925 */
926 static int
call_dst(PyObject * tzinfo,PyObject * tzinfoarg,int * none)927 call_dst(PyObject *tzinfo, PyObject *tzinfoarg, int *none)
928 {
929 return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none);
930 }
931
932 /* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
933 * an instance of the tzinfo class or None. If tzinfo isn't None, and
934 * tzname() doesn't return None or a string, TypeError is raised and this
935 * returns NULL.
936 */
937 static PyObject *
call_tzname(PyObject * tzinfo,PyObject * tzinfoarg)938 call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
939 {
940 PyObject *result;
941
942 assert(tzinfo != NULL);
943 assert(check_tzinfo_subclass(tzinfo) >= 0);
944 assert(tzinfoarg != NULL);
945
946 if (tzinfo == Py_None) {
947 result = Py_None;
948 Py_INCREF(result);
949 }
950 else
951 result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
952
953 if (result != NULL && result != Py_None && ! PyString_Check(result)) {
954 PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
955 "return None or a string, not '%s'",
956 Py_TYPE(result)->tp_name);
957 Py_DECREF(result);
958 result = NULL;
959 }
960 return result;
961 }
962
963 typedef enum {
964 /* an exception has been set; the caller should pass it on */
965 OFFSET_ERROR,
966
967 /* type isn't date, datetime, or time subclass */
968 OFFSET_UNKNOWN,
969
970 /* date,
971 * datetime with !hastzinfo
972 * datetime with None tzinfo,
973 * datetime where utcoffset() returns None
974 * time with !hastzinfo
975 * time with None tzinfo,
976 * time where utcoffset() returns None
977 */
978 OFFSET_NAIVE,
979
980 /* time or datetime where utcoffset() doesn't return None */
981 OFFSET_AWARE
982 } naivety;
983
984 /* Classify an object as to whether it's naive or offset-aware. See
985 * the "naivety" typedef for details. If the type is aware, *offset is set
986 * to minutes east of UTC (as returned by the tzinfo.utcoffset() method).
987 * If the type is offset-naive (or unknown, or error), *offset is set to 0.
988 * tzinfoarg is the argument to pass to the tzinfo.utcoffset() method.
989 */
990 static naivety
classify_utcoffset(PyObject * op,PyObject * tzinfoarg,int * offset)991 classify_utcoffset(PyObject *op, PyObject *tzinfoarg, int *offset)
992 {
993 int none;
994 PyObject *tzinfo;
995
996 assert(tzinfoarg != NULL);
997 *offset = 0;
998 tzinfo = get_tzinfo_member(op); /* NULL means no tzinfo, not error */
999 if (tzinfo == Py_None)
1000 return OFFSET_NAIVE;
1001 if (tzinfo == NULL) {
1002 /* note that a datetime passes the PyDate_Check test */
1003 return (PyTime_Check(op) || PyDate_Check(op)) ?
1004 OFFSET_NAIVE : OFFSET_UNKNOWN;
1005 }
1006 *offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1007 if (*offset == -1 && PyErr_Occurred())
1008 return OFFSET_ERROR;
1009 return none ? OFFSET_NAIVE : OFFSET_AWARE;
1010 }
1011
1012 /* Classify two objects as to whether they're naive or offset-aware.
1013 * This isn't quite the same as calling classify_utcoffset() twice: for
1014 * binary operations (comparison and subtraction), we generally want to
1015 * ignore the tzinfo members if they're identical. This is by design,
1016 * so that results match "naive" expectations when mixing objects from a
1017 * single timezone. So in that case, this sets both offsets to 0 and
1018 * both naiveties to OFFSET_NAIVE.
1019 * The function returns 0 if everything's OK, and -1 on error.
1020 */
1021 static int
classify_two_utcoffsets(PyObject * o1,int * offset1,naivety * n1,PyObject * tzinfoarg1,PyObject * o2,int * offset2,naivety * n2,PyObject * tzinfoarg2)1022 classify_two_utcoffsets(PyObject *o1, int *offset1, naivety *n1,
1023 PyObject *tzinfoarg1,
1024 PyObject *o2, int *offset2, naivety *n2,
1025 PyObject *tzinfoarg2)
1026 {
1027 if (get_tzinfo_member(o1) == get_tzinfo_member(o2)) {
1028 *offset1 = *offset2 = 0;
1029 *n1 = *n2 = OFFSET_NAIVE;
1030 }
1031 else {
1032 *n1 = classify_utcoffset(o1, tzinfoarg1, offset1);
1033 if (*n1 == OFFSET_ERROR)
1034 return -1;
1035 *n2 = classify_utcoffset(o2, tzinfoarg2, offset2);
1036 if (*n2 == OFFSET_ERROR)
1037 return -1;
1038 }
1039 return 0;
1040 }
1041
1042 /* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1043 * stuff
1044 * ", tzinfo=" + repr(tzinfo)
1045 * before the closing ")".
1046 */
1047 static PyObject *
append_keyword_tzinfo(PyObject * repr,PyObject * tzinfo)1048 append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1049 {
1050 PyObject *temp;
1051
1052 assert(PyString_Check(repr));
1053 assert(tzinfo);
1054 if (tzinfo == Py_None)
1055 return repr;
1056 /* Get rid of the trailing ')'. */
1057 assert(PyString_AsString(repr)[PyString_Size(repr)-1] == ')');
1058 temp = PyString_FromStringAndSize(PyString_AsString(repr),
1059 PyString_Size(repr) - 1);
1060 Py_DECREF(repr);
1061 if (temp == NULL)
1062 return NULL;
1063 repr = temp;
1064
1065 /* Append ", tzinfo=". */
1066 PyString_ConcatAndDel(&repr, PyString_FromString(", tzinfo="));
1067
1068 /* Append repr(tzinfo). */
1069 PyString_ConcatAndDel(&repr, PyObject_Repr(tzinfo));
1070
1071 /* Add a closing paren. */
1072 PyString_ConcatAndDel(&repr, PyString_FromString(")"));
1073 return repr;
1074 }
1075
1076 /* ---------------------------------------------------------------------------
1077 * String format helpers.
1078 */
1079
1080 static PyObject *
format_ctime(PyDateTime_Date * date,int hours,int minutes,int seconds)1081 format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
1082 {
1083 static const char *DayNames[] = {
1084 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1085 };
1086 static const char *MonthNames[] = {
1087 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1088 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1089 };
1090
1091 char buffer[128];
1092 int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1093
1094 PyOS_snprintf(buffer, sizeof(buffer), "%s %s %2d %02d:%02d:%02d %04d",
1095 DayNames[wday], MonthNames[GET_MONTH(date) - 1],
1096 GET_DAY(date), hours, minutes, seconds,
1097 GET_YEAR(date));
1098 return PyString_FromString(buffer);
1099 }
1100
1101 /* Add an hours & minutes UTC offset string to buf. buf has no more than
1102 * buflen bytes remaining. The UTC offset is gotten by calling
1103 * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1104 * *buf, and that's all. Else the returned value is checked for sanity (an
1105 * integer in range), and if that's OK it's converted to an hours & minutes
1106 * string of the form
1107 * sign HH sep MM
1108 * Returns 0 if everything is OK. If the return value from utcoffset() is
1109 * bogus, an appropriate exception is set and -1 is returned.
1110 */
1111 static int
format_utcoffset(char * buf,size_t buflen,const char * sep,PyObject * tzinfo,PyObject * tzinfoarg)1112 format_utcoffset(char *buf, size_t buflen, const char *sep,
1113 PyObject *tzinfo, PyObject *tzinfoarg)
1114 {
1115 int offset;
1116 int hours;
1117 int minutes;
1118 char sign;
1119 int none;
1120
1121 assert(buflen >= 1);
1122
1123 offset = call_utcoffset(tzinfo, tzinfoarg, &none);
1124 if (offset == -1 && PyErr_Occurred())
1125 return -1;
1126 if (none) {
1127 *buf = '\0';
1128 return 0;
1129 }
1130 sign = '+';
1131 if (offset < 0) {
1132 sign = '-';
1133 offset = - offset;
1134 }
1135 hours = divmod(offset, 60, &minutes);
1136 PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1137 return 0;
1138 }
1139
1140 static PyObject *
make_freplacement(PyObject * object)1141 make_freplacement(PyObject *object)
1142 {
1143 char freplacement[64];
1144 if (PyTime_Check(object))
1145 sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1146 else if (PyDateTime_Check(object))
1147 sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1148 else
1149 sprintf(freplacement, "%06d", 0);
1150
1151 return PyString_FromStringAndSize(freplacement, strlen(freplacement));
1152 }
1153
1154 /* I sure don't want to reproduce the strftime code from the time module,
1155 * so this imports the module and calls it. All the hair is due to
1156 * giving special meanings to the %z, %Z and %f format codes via a
1157 * preprocessing step on the format string.
1158 * tzinfoarg is the argument to pass to the object's tzinfo method, if
1159 * needed.
1160 */
1161 static PyObject *
wrap_strftime(PyObject * object,const char * format,size_t format_len,PyObject * timetuple,PyObject * tzinfoarg)1162 wrap_strftime(PyObject *object, const char *format, size_t format_len,
1163 PyObject *timetuple, PyObject *tzinfoarg)
1164 {
1165 PyObject *result = NULL; /* guilty until proved innocent */
1166
1167 PyObject *zreplacement = NULL; /* py string, replacement for %z */
1168 PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1169 PyObject *freplacement = NULL; /* py string, replacement for %f */
1170
1171 const char *pin; /* pointer to next char in input format */
1172 char ch; /* next char in input format */
1173
1174 PyObject *newfmt = NULL; /* py string, the output format */
1175 char *pnew; /* pointer to available byte in output format */
1176 size_t totalnew; /* number bytes total in output format buffer,
1177 exclusive of trailing \0 */
1178 size_t usednew; /* number bytes used so far in output format buffer */
1179
1180 const char *ptoappend; /* ptr to string to append to output buffer */
1181 size_t ntoappend; /* # of bytes to append to output buffer */
1182
1183 assert(object && format && timetuple);
1184
1185 /* Give up if the year is before 1900.
1186 * Python strftime() plays games with the year, and different
1187 * games depending on whether envar PYTHON2K is set. This makes
1188 * years before 1900 a nightmare, even if the platform strftime
1189 * supports them (and not all do).
1190 * We could get a lot farther here by avoiding Python's strftime
1191 * wrapper and calling the C strftime() directly, but that isn't
1192 * an option in the Python implementation of this module.
1193 */
1194 {
1195 long year;
1196 PyObject *pyyear = PySequence_GetItem(timetuple, 0);
1197 if (pyyear == NULL) return NULL;
1198 assert(PyInt_Check(pyyear));
1199 year = PyInt_AsLong(pyyear);
1200 Py_DECREF(pyyear);
1201 if (year < 1900) {
1202 PyErr_Format(PyExc_ValueError, "year=%ld is before "
1203 "1900; the datetime strftime() "
1204 "methods require year >= 1900",
1205 year);
1206 return NULL;
1207 }
1208 }
1209
1210 /* Scan the input format, looking for %z/%Z/%f escapes, building
1211 * a new format. Since computing the replacements for those codes
1212 * is expensive, don't unless they're actually used.
1213 */
1214 if (format_len > INT_MAX - 1) {
1215 PyErr_NoMemory();
1216 goto Done;
1217 }
1218
1219 totalnew = format_len + 1; /* realistic if no %z/%Z/%f */
1220 newfmt = PyString_FromStringAndSize(NULL, totalnew);
1221 if (newfmt == NULL) goto Done;
1222 pnew = PyString_AsString(newfmt);
1223 usednew = 0;
1224
1225 pin = format;
1226 while ((ch = *pin++) != '\0') {
1227 if (ch != '%') {
1228 ptoappend = pin - 1;
1229 ntoappend = 1;
1230 }
1231 else if ((ch = *pin++) == '\0') {
1232 /* There's a lone trailing %; doesn't make sense. */
1233 PyErr_SetString(PyExc_ValueError, "strftime format "
1234 "ends with raw %");
1235 goto Done;
1236 }
1237 /* A % has been seen and ch is the character after it. */
1238 else if (ch == 'z') {
1239 if (zreplacement == NULL) {
1240 /* format utcoffset */
1241 char buf[100];
1242 PyObject *tzinfo = get_tzinfo_member(object);
1243 zreplacement = PyString_FromString("");
1244 if (zreplacement == NULL) goto Done;
1245 if (tzinfo != Py_None && tzinfo != NULL) {
1246 assert(tzinfoarg != NULL);
1247 if (format_utcoffset(buf,
1248 sizeof(buf),
1249 "",
1250 tzinfo,
1251 tzinfoarg) < 0)
1252 goto Done;
1253 Py_DECREF(zreplacement);
1254 zreplacement = PyString_FromString(buf);
1255 if (zreplacement == NULL) goto Done;
1256 }
1257 }
1258 assert(zreplacement != NULL);
1259 ptoappend = PyString_AS_STRING(zreplacement);
1260 ntoappend = PyString_GET_SIZE(zreplacement);
1261 }
1262 else if (ch == 'Z') {
1263 /* format tzname */
1264 if (Zreplacement == NULL) {
1265 PyObject *tzinfo = get_tzinfo_member(object);
1266 Zreplacement = PyString_FromString("");
1267 if (Zreplacement == NULL) goto Done;
1268 if (tzinfo != Py_None && tzinfo != NULL) {
1269 PyObject *temp;
1270 assert(tzinfoarg != NULL);
1271 temp = call_tzname(tzinfo, tzinfoarg);
1272 if (temp == NULL) goto Done;
1273 if (temp != Py_None) {
1274 assert(PyString_Check(temp));
1275 /* Since the tzname is getting
1276 * stuffed into the format, we
1277 * have to double any % signs
1278 * so that strftime doesn't
1279 * treat them as format codes.
1280 */
1281 Py_DECREF(Zreplacement);
1282 Zreplacement = PyObject_CallMethod(
1283 temp, "replace",
1284 "ss", "%", "%%");
1285 Py_DECREF(temp);
1286 if (Zreplacement == NULL)
1287 goto Done;
1288 if (!PyString_Check(Zreplacement)) {
1289 PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
1290 goto Done;
1291 }
1292 }
1293 else
1294 Py_DECREF(temp);
1295 }
1296 }
1297 assert(Zreplacement != NULL);
1298 ptoappend = PyString_AS_STRING(Zreplacement);
1299 ntoappend = PyString_GET_SIZE(Zreplacement);
1300 }
1301 else if (ch == 'f') {
1302 /* format microseconds */
1303 if (freplacement == NULL) {
1304 freplacement = make_freplacement(object);
1305 if (freplacement == NULL)
1306 goto Done;
1307 }
1308 assert(freplacement != NULL);
1309 assert(PyString_Check(freplacement));
1310 ptoappend = PyString_AS_STRING(freplacement);
1311 ntoappend = PyString_GET_SIZE(freplacement);
1312 }
1313 else {
1314 /* percent followed by neither z nor Z */
1315 ptoappend = pin - 2;
1316 ntoappend = 2;
1317 }
1318
1319 /* Append the ntoappend chars starting at ptoappend to
1320 * the new format.
1321 */
1322 assert(ptoappend != NULL);
1323 assert(ntoappend >= 0);
1324 if (ntoappend == 0)
1325 continue;
1326 while (usednew + ntoappend > totalnew) {
1327 size_t bigger = totalnew << 1;
1328 if ((bigger >> 1) != totalnew) { /* overflow */
1329 PyErr_NoMemory();
1330 goto Done;
1331 }
1332 if (_PyString_Resize(&newfmt, bigger) < 0)
1333 goto Done;
1334 totalnew = bigger;
1335 pnew = PyString_AsString(newfmt) + usednew;
1336 }
1337 memcpy(pnew, ptoappend, ntoappend);
1338 pnew += ntoappend;
1339 usednew += ntoappend;
1340 assert(usednew <= totalnew);
1341 } /* end while() */
1342
1343 if (_PyString_Resize(&newfmt, usednew) < 0)
1344 goto Done;
1345 {
1346 PyObject *time = PyImport_ImportModuleNoBlock("time");
1347 if (time == NULL)
1348 goto Done;
1349 result = PyObject_CallMethod(time, "strftime", "OO",
1350 newfmt, timetuple);
1351 Py_DECREF(time);
1352 }
1353 Done:
1354 Py_XDECREF(freplacement);
1355 Py_XDECREF(zreplacement);
1356 Py_XDECREF(Zreplacement);
1357 Py_XDECREF(newfmt);
1358 return result;
1359 }
1360
1361 static char *
isoformat_date(PyDateTime_Date * dt,char buffer[],int bufflen)1362 isoformat_date(PyDateTime_Date *dt, char buffer[], int bufflen)
1363 {
1364 int x;
1365 x = PyOS_snprintf(buffer, bufflen,
1366 "%04d-%02d-%02d",
1367 GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt));
1368 assert(bufflen >= x);
1369 return buffer + x;
1370 }
1371
1372 static char *
isoformat_time(PyDateTime_DateTime * dt,char buffer[],int bufflen)1373 isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen)
1374 {
1375 int x;
1376 int us = DATE_GET_MICROSECOND(dt);
1377
1378 x = PyOS_snprintf(buffer, bufflen,
1379 "%02d:%02d:%02d",
1380 DATE_GET_HOUR(dt),
1381 DATE_GET_MINUTE(dt),
1382 DATE_GET_SECOND(dt));
1383 assert(bufflen >= x);
1384 if (us)
1385 x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us);
1386 assert(bufflen >= x);
1387 return buffer + x;
1388 }
1389
1390 /* ---------------------------------------------------------------------------
1391 * Wrap functions from the time module. These aren't directly available
1392 * from C. Perhaps they should be.
1393 */
1394
1395 /* Call time.time() and return its result (a Python float). */
1396 static PyObject *
time_time(void)1397 time_time(void)
1398 {
1399 PyObject *result = NULL;
1400 PyObject *time = PyImport_ImportModuleNoBlock("time");
1401
1402 if (time != NULL) {
1403 result = PyObject_CallMethod(time, "time", "()");
1404 Py_DECREF(time);
1405 }
1406 return result;
1407 }
1408
1409 /* Build a time.struct_time. The weekday and day number are automatically
1410 * computed from the y,m,d args.
1411 */
1412 static PyObject *
build_struct_time(int y,int m,int d,int hh,int mm,int ss,int dstflag)1413 build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1414 {
1415 PyObject *time;
1416 PyObject *result = NULL;
1417
1418 time = PyImport_ImportModuleNoBlock("time");
1419 if (time != NULL) {
1420 result = PyObject_CallMethod(time, "struct_time",
1421 "((iiiiiiiii))",
1422 y, m, d,
1423 hh, mm, ss,
1424 weekday(y, m, d),
1425 days_before_month(y, m) + d,
1426 dstflag);
1427 Py_DECREF(time);
1428 }
1429 return result;
1430 }
1431
1432 /* ---------------------------------------------------------------------------
1433 * Miscellaneous helpers.
1434 */
1435
1436 /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
1437 * The comparisons here all most naturally compute a cmp()-like result.
1438 * This little helper turns that into a bool result for rich comparisons.
1439 */
1440 static PyObject *
diff_to_bool(int diff,int op)1441 diff_to_bool(int diff, int op)
1442 {
1443 PyObject *result;
1444 int istrue;
1445
1446 switch (op) {
1447 case Py_EQ: istrue = diff == 0; break;
1448 case Py_NE: istrue = diff != 0; break;
1449 case Py_LE: istrue = diff <= 0; break;
1450 case Py_GE: istrue = diff >= 0; break;
1451 case Py_LT: istrue = diff < 0; break;
1452 case Py_GT: istrue = diff > 0; break;
1453 default:
1454 assert(! "op unknown");
1455 istrue = 0; /* To shut up compiler */
1456 }
1457 result = istrue ? Py_True : Py_False;
1458 Py_INCREF(result);
1459 return result;
1460 }
1461
1462 /* Raises a "can't compare" TypeError and returns NULL. */
1463 static PyObject *
cmperror(PyObject * a,PyObject * b)1464 cmperror(PyObject *a, PyObject *b)
1465 {
1466 PyErr_Format(PyExc_TypeError,
1467 "can't compare %s to %s",
1468 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1469 return NULL;
1470 }
1471
1472 /* ---------------------------------------------------------------------------
1473 * Cached Python objects; these are set by the module init function.
1474 */
1475
1476 /* Conversion factors. */
1477 static PyObject *us_per_us = NULL; /* 1 */
1478 static PyObject *us_per_ms = NULL; /* 1000 */
1479 static PyObject *us_per_second = NULL; /* 1000000 */
1480 static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1481 static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python long */
1482 static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python long */
1483 static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python long */
1484 static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1485
1486 /* ---------------------------------------------------------------------------
1487 * Class implementations.
1488 */
1489
1490 /*
1491 * PyDateTime_Delta implementation.
1492 */
1493
1494 /* Convert a timedelta to a number of us,
1495 * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1496 * as a Python int or long.
1497 * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1498 * due to ubiquitous overflow possibilities.
1499 */
1500 static PyObject *
delta_to_microseconds(PyDateTime_Delta * self)1501 delta_to_microseconds(PyDateTime_Delta *self)
1502 {
1503 PyObject *x1 = NULL;
1504 PyObject *x2 = NULL;
1505 PyObject *x3 = NULL;
1506 PyObject *result = NULL;
1507
1508 x1 = PyInt_FromLong(GET_TD_DAYS(self));
1509 if (x1 == NULL)
1510 goto Done;
1511 x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1512 if (x2 == NULL)
1513 goto Done;
1514 Py_DECREF(x1);
1515 x1 = NULL;
1516
1517 /* x2 has days in seconds */
1518 x1 = PyInt_FromLong(GET_TD_SECONDS(self)); /* seconds */
1519 if (x1 == NULL)
1520 goto Done;
1521 x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1522 if (x3 == NULL)
1523 goto Done;
1524 Py_DECREF(x1);
1525 Py_DECREF(x2);
1526 x2 = NULL;
1527
1528 /* x3 has days+seconds in seconds */
1529 x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1530 if (x1 == NULL)
1531 goto Done;
1532 Py_DECREF(x3);
1533 x3 = NULL;
1534
1535 /* x1 has days+seconds in us */
1536 x2 = PyInt_FromLong(GET_TD_MICROSECONDS(self));
1537 if (x2 == NULL)
1538 goto Done;
1539 result = PyNumber_Add(x1, x2);
1540
1541 Done:
1542 Py_XDECREF(x1);
1543 Py_XDECREF(x2);
1544 Py_XDECREF(x3);
1545 return result;
1546 }
1547
1548 /* Convert a number of us (as a Python int or long) to a timedelta.
1549 */
1550 static PyObject *
microseconds_to_delta_ex(PyObject * pyus,PyTypeObject * type)1551 microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1552 {
1553 int us;
1554 int s;
1555 int d;
1556 long temp;
1557
1558 PyObject *tuple = NULL;
1559 PyObject *num = NULL;
1560 PyObject *result = NULL;
1561
1562 tuple = PyNumber_Divmod(pyus, us_per_second);
1563 if (tuple == NULL)
1564 goto Done;
1565
1566 num = PyTuple_GetItem(tuple, 1); /* us */
1567 if (num == NULL)
1568 goto Done;
1569 temp = PyLong_AsLong(num);
1570 num = NULL;
1571 if (temp == -1 && PyErr_Occurred())
1572 goto Done;
1573 assert(0 <= temp && temp < 1000000);
1574 us = (int)temp;
1575 if (us < 0) {
1576 /* The divisor was positive, so this must be an error. */
1577 assert(PyErr_Occurred());
1578 goto Done;
1579 }
1580
1581 num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1582 if (num == NULL)
1583 goto Done;
1584 Py_INCREF(num);
1585 Py_DECREF(tuple);
1586
1587 tuple = PyNumber_Divmod(num, seconds_per_day);
1588 if (tuple == NULL)
1589 goto Done;
1590 Py_DECREF(num);
1591
1592 num = PyTuple_GetItem(tuple, 1); /* seconds */
1593 if (num == NULL)
1594 goto Done;
1595 temp = PyLong_AsLong(num);
1596 num = NULL;
1597 if (temp == -1 && PyErr_Occurred())
1598 goto Done;
1599 assert(0 <= temp && temp < 24*3600);
1600 s = (int)temp;
1601
1602 if (s < 0) {
1603 /* The divisor was positive, so this must be an error. */
1604 assert(PyErr_Occurred());
1605 goto Done;
1606 }
1607
1608 num = PyTuple_GetItem(tuple, 0); /* leftover days */
1609 if (num == NULL)
1610 goto Done;
1611 Py_INCREF(num);
1612 temp = PyLong_AsLong(num);
1613 if (temp == -1 && PyErr_Occurred())
1614 goto Done;
1615 d = (int)temp;
1616 if ((long)d != temp) {
1617 PyErr_SetString(PyExc_OverflowError, "normalized days too "
1618 "large to fit in a C int");
1619 goto Done;
1620 }
1621 result = new_delta_ex(d, s, us, 0, type);
1622
1623 Done:
1624 Py_XDECREF(tuple);
1625 Py_XDECREF(num);
1626 return result;
1627 }
1628
1629 #define microseconds_to_delta(pymicros) \
1630 microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1631
1632 static PyObject *
multiply_int_timedelta(PyObject * intobj,PyDateTime_Delta * delta)1633 multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1634 {
1635 PyObject *pyus_in;
1636 PyObject *pyus_out;
1637 PyObject *result;
1638
1639 pyus_in = delta_to_microseconds(delta);
1640 if (pyus_in == NULL)
1641 return NULL;
1642
1643 pyus_out = PyNumber_Multiply(pyus_in, intobj);
1644 Py_DECREF(pyus_in);
1645 if (pyus_out == NULL)
1646 return NULL;
1647
1648 result = microseconds_to_delta(pyus_out);
1649 Py_DECREF(pyus_out);
1650 return result;
1651 }
1652
1653 static PyObject *
divide_timedelta_int(PyDateTime_Delta * delta,PyObject * intobj)1654 divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1655 {
1656 PyObject *pyus_in;
1657 PyObject *pyus_out;
1658 PyObject *result;
1659
1660 pyus_in = delta_to_microseconds(delta);
1661 if (pyus_in == NULL)
1662 return NULL;
1663
1664 pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1665 Py_DECREF(pyus_in);
1666 if (pyus_out == NULL)
1667 return NULL;
1668
1669 result = microseconds_to_delta(pyus_out);
1670 Py_DECREF(pyus_out);
1671 return result;
1672 }
1673
1674 static PyObject *
delta_add(PyObject * left,PyObject * right)1675 delta_add(PyObject *left, PyObject *right)
1676 {
1677 PyObject *result = Py_NotImplemented;
1678
1679 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1680 /* delta + delta */
1681 /* The C-level additions can't overflow because of the
1682 * invariant bounds.
1683 */
1684 int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1685 int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1686 int microseconds = GET_TD_MICROSECONDS(left) +
1687 GET_TD_MICROSECONDS(right);
1688 result = new_delta(days, seconds, microseconds, 1);
1689 }
1690
1691 if (result == Py_NotImplemented)
1692 Py_INCREF(result);
1693 return result;
1694 }
1695
1696 static PyObject *
delta_negative(PyDateTime_Delta * self)1697 delta_negative(PyDateTime_Delta *self)
1698 {
1699 return new_delta(-GET_TD_DAYS(self),
1700 -GET_TD_SECONDS(self),
1701 -GET_TD_MICROSECONDS(self),
1702 1);
1703 }
1704
1705 static PyObject *
delta_positive(PyDateTime_Delta * self)1706 delta_positive(PyDateTime_Delta *self)
1707 {
1708 /* Could optimize this (by returning self) if this isn't a
1709 * subclass -- but who uses unary + ? Approximately nobody.
1710 */
1711 return new_delta(GET_TD_DAYS(self),
1712 GET_TD_SECONDS(self),
1713 GET_TD_MICROSECONDS(self),
1714 0);
1715 }
1716
1717 static PyObject *
delta_abs(PyDateTime_Delta * self)1718 delta_abs(PyDateTime_Delta *self)
1719 {
1720 PyObject *result;
1721
1722 assert(GET_TD_MICROSECONDS(self) >= 0);
1723 assert(GET_TD_SECONDS(self) >= 0);
1724
1725 if (GET_TD_DAYS(self) < 0)
1726 result = delta_negative(self);
1727 else
1728 result = delta_positive(self);
1729
1730 return result;
1731 }
1732
1733 static PyObject *
delta_subtract(PyObject * left,PyObject * right)1734 delta_subtract(PyObject *left, PyObject *right)
1735 {
1736 PyObject *result = Py_NotImplemented;
1737
1738 if (PyDelta_Check(left) && PyDelta_Check(right)) {
1739 /* delta - delta */
1740 /* The C-level additions can't overflow because of the
1741 * invariant bounds.
1742 */
1743 int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1744 int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1745 int microseconds = GET_TD_MICROSECONDS(left) -
1746 GET_TD_MICROSECONDS(right);
1747 result = new_delta(days, seconds, microseconds, 1);
1748 }
1749
1750 if (result == Py_NotImplemented)
1751 Py_INCREF(result);
1752 return result;
1753 }
1754
1755 /* This is more natural as a tp_compare, but doesn't work then: for whatever
1756 * reason, Python's try_3way_compare ignores tp_compare unless
1757 * PyInstance_Check returns true, but these aren't old-style classes.
1758 */
1759 static PyObject *
delta_richcompare(PyDateTime_Delta * self,PyObject * other,int op)1760 delta_richcompare(PyDateTime_Delta *self, PyObject *other, int op)
1761 {
1762 int diff = 42; /* nonsense */
1763
1764 if (PyDelta_Check(other)) {
1765 diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1766 if (diff == 0) {
1767 diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1768 if (diff == 0)
1769 diff = GET_TD_MICROSECONDS(self) -
1770 GET_TD_MICROSECONDS(other);
1771 }
1772 }
1773 else if (op == Py_EQ || op == Py_NE)
1774 diff = 1; /* any non-zero value will do */
1775
1776 else /* stop this from falling back to address comparison */
1777 return cmperror((PyObject *)self, other);
1778
1779 return diff_to_bool(diff, op);
1780 }
1781
1782 static PyObject *delta_getstate(PyDateTime_Delta *self);
1783
1784 static long
delta_hash(PyDateTime_Delta * self)1785 delta_hash(PyDateTime_Delta *self)
1786 {
1787 if (self->hashcode == -1) {
1788 PyObject *temp = delta_getstate(self);
1789 if (temp != NULL) {
1790 self->hashcode = PyObject_Hash(temp);
1791 Py_DECREF(temp);
1792 }
1793 }
1794 return self->hashcode;
1795 }
1796
1797 static PyObject *
delta_multiply(PyObject * left,PyObject * right)1798 delta_multiply(PyObject *left, PyObject *right)
1799 {
1800 PyObject *result = Py_NotImplemented;
1801
1802 if (PyDelta_Check(left)) {
1803 /* delta * ??? */
1804 if (PyInt_Check(right) || PyLong_Check(right))
1805 result = multiply_int_timedelta(right,
1806 (PyDateTime_Delta *) left);
1807 }
1808 else if (PyInt_Check(left) || PyLong_Check(left))
1809 result = multiply_int_timedelta(left,
1810 (PyDateTime_Delta *) right);
1811
1812 if (result == Py_NotImplemented)
1813 Py_INCREF(result);
1814 return result;
1815 }
1816
1817 static PyObject *
delta_divide(PyObject * left,PyObject * right)1818 delta_divide(PyObject *left, PyObject *right)
1819 {
1820 PyObject *result = Py_NotImplemented;
1821
1822 if (PyDelta_Check(left)) {
1823 /* delta * ??? */
1824 if (PyInt_Check(right) || PyLong_Check(right))
1825 result = divide_timedelta_int(
1826 (PyDateTime_Delta *)left,
1827 right);
1828 }
1829
1830 if (result == Py_NotImplemented)
1831 Py_INCREF(result);
1832 return result;
1833 }
1834
1835 /* Fold in the value of the tag ("seconds", "weeks", etc) component of a
1836 * timedelta constructor. sofar is the # of microseconds accounted for
1837 * so far, and there are factor microseconds per current unit, the number
1838 * of which is given by num. num * factor is added to sofar in a
1839 * numerically careful way, and that's the result. Any fractional
1840 * microseconds left over (this can happen if num is a float type) are
1841 * added into *leftover.
1842 * Note that there are many ways this can give an error (NULL) return.
1843 */
1844 static PyObject *
accum(const char * tag,PyObject * sofar,PyObject * num,PyObject * factor,double * leftover)1845 accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
1846 double *leftover)
1847 {
1848 PyObject *prod;
1849 PyObject *sum;
1850
1851 assert(num != NULL);
1852
1853 if (PyInt_Check(num) || PyLong_Check(num)) {
1854 prod = PyNumber_Multiply(num, factor);
1855 if (prod == NULL)
1856 return NULL;
1857 sum = PyNumber_Add(sofar, prod);
1858 Py_DECREF(prod);
1859 return sum;
1860 }
1861
1862 if (PyFloat_Check(num)) {
1863 double dnum;
1864 double fracpart;
1865 double intpart;
1866 PyObject *x;
1867 PyObject *y;
1868
1869 /* The Plan: decompose num into an integer part and a
1870 * fractional part, num = intpart + fracpart.
1871 * Then num * factor ==
1872 * intpart * factor + fracpart * factor
1873 * and the LHS can be computed exactly in long arithmetic.
1874 * The RHS is again broken into an int part and frac part.
1875 * and the frac part is added into *leftover.
1876 */
1877 dnum = PyFloat_AsDouble(num);
1878 if (dnum == -1.0 && PyErr_Occurred())
1879 return NULL;
1880 fracpart = modf(dnum, &intpart);
1881 x = PyLong_FromDouble(intpart);
1882 if (x == NULL)
1883 return NULL;
1884
1885 prod = PyNumber_Multiply(x, factor);
1886 Py_DECREF(x);
1887 if (prod == NULL)
1888 return NULL;
1889
1890 sum = PyNumber_Add(sofar, prod);
1891 Py_DECREF(prod);
1892 if (sum == NULL)
1893 return NULL;
1894
1895 if (fracpart == 0.0)
1896 return sum;
1897 /* So far we've lost no information. Dealing with the
1898 * fractional part requires float arithmetic, and may
1899 * lose a little info.
1900 */
1901 assert(PyInt_Check(factor) || PyLong_Check(factor));
1902 if (PyInt_Check(factor))
1903 dnum = (double)PyInt_AsLong(factor);
1904 else
1905 dnum = PyLong_AsDouble(factor);
1906
1907 dnum *= fracpart;
1908 fracpart = modf(dnum, &intpart);
1909 x = PyLong_FromDouble(intpart);
1910 if (x == NULL) {
1911 Py_DECREF(sum);
1912 return NULL;
1913 }
1914
1915 y = PyNumber_Add(sum, x);
1916 Py_DECREF(sum);
1917 Py_DECREF(x);
1918 *leftover += fracpart;
1919 return y;
1920 }
1921
1922 PyErr_Format(PyExc_TypeError,
1923 "unsupported type for timedelta %s component: %s",
1924 tag, Py_TYPE(num)->tp_name);
1925 return NULL;
1926 }
1927
1928 static PyObject *
delta_new(PyTypeObject * type,PyObject * args,PyObject * kw)1929 delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1930 {
1931 PyObject *self = NULL;
1932
1933 /* Argument objects. */
1934 PyObject *day = NULL;
1935 PyObject *second = NULL;
1936 PyObject *us = NULL;
1937 PyObject *ms = NULL;
1938 PyObject *minute = NULL;
1939 PyObject *hour = NULL;
1940 PyObject *week = NULL;
1941
1942 PyObject *x = NULL; /* running sum of microseconds */
1943 PyObject *y = NULL; /* temp sum of microseconds */
1944 double leftover_us = 0.0;
1945
1946 static char *keywords[] = {
1947 "days", "seconds", "microseconds", "milliseconds",
1948 "minutes", "hours", "weeks", NULL
1949 };
1950
1951 if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
1952 keywords,
1953 &day, &second, &us,
1954 &ms, &minute, &hour, &week) == 0)
1955 goto Done;
1956
1957 x = PyInt_FromLong(0);
1958 if (x == NULL)
1959 goto Done;
1960
1961 #define CLEANUP \
1962 Py_DECREF(x); \
1963 x = y; \
1964 if (x == NULL) \
1965 goto Done
1966
1967 if (us) {
1968 y = accum("microseconds", x, us, us_per_us, &leftover_us);
1969 CLEANUP;
1970 }
1971 if (ms) {
1972 y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
1973 CLEANUP;
1974 }
1975 if (second) {
1976 y = accum("seconds", x, second, us_per_second, &leftover_us);
1977 CLEANUP;
1978 }
1979 if (minute) {
1980 y = accum("minutes", x, minute, us_per_minute, &leftover_us);
1981 CLEANUP;
1982 }
1983 if (hour) {
1984 y = accum("hours", x, hour, us_per_hour, &leftover_us);
1985 CLEANUP;
1986 }
1987 if (day) {
1988 y = accum("days", x, day, us_per_day, &leftover_us);
1989 CLEANUP;
1990 }
1991 if (week) {
1992 y = accum("weeks", x, week, us_per_week, &leftover_us);
1993 CLEANUP;
1994 }
1995 if (leftover_us) {
1996 /* Round to nearest whole # of us, and add into x. */
1997 PyObject *temp = PyLong_FromLong(round_to_long(leftover_us));
1998 if (temp == NULL) {
1999 Py_DECREF(x);
2000 goto Done;
2001 }
2002 y = PyNumber_Add(x, temp);
2003 Py_DECREF(temp);
2004 CLEANUP;
2005 }
2006
2007 self = microseconds_to_delta_ex(x, type);
2008 Py_DECREF(x);
2009 Done:
2010 return self;
2011
2012 #undef CLEANUP
2013 }
2014
2015 static int
delta_nonzero(PyDateTime_Delta * self)2016 delta_nonzero(PyDateTime_Delta *self)
2017 {
2018 return (GET_TD_DAYS(self) != 0
2019 || GET_TD_SECONDS(self) != 0
2020 || GET_TD_MICROSECONDS(self) != 0);
2021 }
2022
2023 static PyObject *
delta_repr(PyDateTime_Delta * self)2024 delta_repr(PyDateTime_Delta *self)
2025 {
2026 if (GET_TD_MICROSECONDS(self) != 0)
2027 return PyString_FromFormat("%s(%d, %d, %d)",
2028 Py_TYPE(self)->tp_name,
2029 GET_TD_DAYS(self),
2030 GET_TD_SECONDS(self),
2031 GET_TD_MICROSECONDS(self));
2032 if (GET_TD_SECONDS(self) != 0)
2033 return PyString_FromFormat("%s(%d, %d)",
2034 Py_TYPE(self)->tp_name,
2035 GET_TD_DAYS(self),
2036 GET_TD_SECONDS(self));
2037
2038 return PyString_FromFormat("%s(%d)",
2039 Py_TYPE(self)->tp_name,
2040 GET_TD_DAYS(self));
2041 }
2042
2043 static PyObject *
delta_str(PyDateTime_Delta * self)2044 delta_str(PyDateTime_Delta *self)
2045 {
2046 int days = GET_TD_DAYS(self);
2047 int seconds = GET_TD_SECONDS(self);
2048 int us = GET_TD_MICROSECONDS(self);
2049 int hours;
2050 int minutes;
2051 char buf[100];
2052 char *pbuf = buf;
2053 size_t buflen = sizeof(buf);
2054 int n;
2055
2056 minutes = divmod(seconds, 60, &seconds);
2057 hours = divmod(minutes, 60, &minutes);
2058
2059 if (days) {
2060 n = PyOS_snprintf(pbuf, buflen, "%d day%s, ", days,
2061 (days == 1 || days == -1) ? "" : "s");
2062 if (n < 0 || (size_t)n >= buflen)
2063 goto Fail;
2064 pbuf += n;
2065 buflen -= (size_t)n;
2066 }
2067
2068 n = PyOS_snprintf(pbuf, buflen, "%d:%02d:%02d",
2069 hours, minutes, seconds);
2070 if (n < 0 || (size_t)n >= buflen)
2071 goto Fail;
2072 pbuf += n;
2073 buflen -= (size_t)n;
2074
2075 if (us) {
2076 n = PyOS_snprintf(pbuf, buflen, ".%06d", us);
2077 if (n < 0 || (size_t)n >= buflen)
2078 goto Fail;
2079 pbuf += n;
2080 }
2081
2082 return PyString_FromStringAndSize(buf, pbuf - buf);
2083
2084 Fail:
2085 PyErr_SetString(PyExc_SystemError, "goofy result from PyOS_snprintf");
2086 return NULL;
2087 }
2088
2089 /* Pickle support, a simple use of __reduce__. */
2090
2091 /* __getstate__ isn't exposed */
2092 static PyObject *
delta_getstate(PyDateTime_Delta * self)2093 delta_getstate(PyDateTime_Delta *self)
2094 {
2095 return Py_BuildValue("iii", GET_TD_DAYS(self),
2096 GET_TD_SECONDS(self),
2097 GET_TD_MICROSECONDS(self));
2098 }
2099
2100 static PyObject *
delta_total_seconds(PyObject * self)2101 delta_total_seconds(PyObject *self)
2102 {
2103 PyObject *total_seconds;
2104 PyObject *total_microseconds;
2105 PyObject *one_million;
2106
2107 total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2108 if (total_microseconds == NULL)
2109 return NULL;
2110
2111 one_million = PyLong_FromLong(1000000L);
2112 if (one_million == NULL) {
2113 Py_DECREF(total_microseconds);
2114 return NULL;
2115 }
2116
2117 total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
2118
2119 Py_DECREF(total_microseconds);
2120 Py_DECREF(one_million);
2121 return total_seconds;
2122 }
2123
2124 static PyObject *
delta_reduce(PyDateTime_Delta * self)2125 delta_reduce(PyDateTime_Delta* self)
2126 {
2127 return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
2128 }
2129
2130 #define OFFSET(field) offsetof(PyDateTime_Delta, field)
2131
2132 static PyMemberDef delta_members[] = {
2133
2134 {"days", T_INT, OFFSET(days), READONLY,
2135 PyDoc_STR("Number of days.")},
2136
2137 {"seconds", T_INT, OFFSET(seconds), READONLY,
2138 PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2139
2140 {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2141 PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2142 {NULL}
2143 };
2144
2145 static PyMethodDef delta_methods[] = {
2146 {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2147 PyDoc_STR("Total seconds in the duration.")},
2148
2149 {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2150 PyDoc_STR("__reduce__() -> (cls, state)")},
2151
2152 {NULL, NULL},
2153 };
2154
2155 static char delta_doc[] =
2156 PyDoc_STR("Difference between two datetime values.");
2157
2158 static PyNumberMethods delta_as_number = {
2159 delta_add, /* nb_add */
2160 delta_subtract, /* nb_subtract */
2161 delta_multiply, /* nb_multiply */
2162 delta_divide, /* nb_divide */
2163 0, /* nb_remainder */
2164 0, /* nb_divmod */
2165 0, /* nb_power */
2166 (unaryfunc)delta_negative, /* nb_negative */
2167 (unaryfunc)delta_positive, /* nb_positive */
2168 (unaryfunc)delta_abs, /* nb_absolute */
2169 (inquiry)delta_nonzero, /* nb_nonzero */
2170 0, /*nb_invert*/
2171 0, /*nb_lshift*/
2172 0, /*nb_rshift*/
2173 0, /*nb_and*/
2174 0, /*nb_xor*/
2175 0, /*nb_or*/
2176 0, /*nb_coerce*/
2177 0, /*nb_int*/
2178 0, /*nb_long*/
2179 0, /*nb_float*/
2180 0, /*nb_oct*/
2181 0, /*nb_hex*/
2182 0, /*nb_inplace_add*/
2183 0, /*nb_inplace_subtract*/
2184 0, /*nb_inplace_multiply*/
2185 0, /*nb_inplace_divide*/
2186 0, /*nb_inplace_remainder*/
2187 0, /*nb_inplace_power*/
2188 0, /*nb_inplace_lshift*/
2189 0, /*nb_inplace_rshift*/
2190 0, /*nb_inplace_and*/
2191 0, /*nb_inplace_xor*/
2192 0, /*nb_inplace_or*/
2193 delta_divide, /* nb_floor_divide */
2194 0, /* nb_true_divide */
2195 0, /* nb_inplace_floor_divide */
2196 0, /* nb_inplace_true_divide */
2197 };
2198
2199 static PyTypeObject PyDateTime_DeltaType = {
2200 PyVarObject_HEAD_INIT(NULL, 0)
2201 "datetime.timedelta", /* tp_name */
2202 sizeof(PyDateTime_Delta), /* tp_basicsize */
2203 0, /* tp_itemsize */
2204 0, /* tp_dealloc */
2205 0, /* tp_print */
2206 0, /* tp_getattr */
2207 0, /* tp_setattr */
2208 0, /* tp_compare */
2209 (reprfunc)delta_repr, /* tp_repr */
2210 &delta_as_number, /* tp_as_number */
2211 0, /* tp_as_sequence */
2212 0, /* tp_as_mapping */
2213 (hashfunc)delta_hash, /* tp_hash */
2214 0, /* tp_call */
2215 (reprfunc)delta_str, /* tp_str */
2216 PyObject_GenericGetAttr, /* tp_getattro */
2217 0, /* tp_setattro */
2218 0, /* tp_as_buffer */
2219 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2220 Py_TPFLAGS_BASETYPE, /* tp_flags */
2221 delta_doc, /* tp_doc */
2222 0, /* tp_traverse */
2223 0, /* tp_clear */
2224 (richcmpfunc)delta_richcompare, /* tp_richcompare */
2225 0, /* tp_weaklistoffset */
2226 0, /* tp_iter */
2227 0, /* tp_iternext */
2228 delta_methods, /* tp_methods */
2229 delta_members, /* tp_members */
2230 0, /* tp_getset */
2231 0, /* tp_base */
2232 0, /* tp_dict */
2233 0, /* tp_descr_get */
2234 0, /* tp_descr_set */
2235 0, /* tp_dictoffset */
2236 0, /* tp_init */
2237 0, /* tp_alloc */
2238 delta_new, /* tp_new */
2239 0, /* tp_free */
2240 };
2241
2242 /*
2243 * PyDateTime_Date implementation.
2244 */
2245
2246 /* Accessor properties. */
2247
2248 static PyObject *
date_year(PyDateTime_Date * self,void * unused)2249 date_year(PyDateTime_Date *self, void *unused)
2250 {
2251 return PyInt_FromLong(GET_YEAR(self));
2252 }
2253
2254 static PyObject *
date_month(PyDateTime_Date * self,void * unused)2255 date_month(PyDateTime_Date *self, void *unused)
2256 {
2257 return PyInt_FromLong(GET_MONTH(self));
2258 }
2259
2260 static PyObject *
date_day(PyDateTime_Date * self,void * unused)2261 date_day(PyDateTime_Date *self, void *unused)
2262 {
2263 return PyInt_FromLong(GET_DAY(self));
2264 }
2265
2266 static PyGetSetDef date_getset[] = {
2267 {"year", (getter)date_year},
2268 {"month", (getter)date_month},
2269 {"day", (getter)date_day},
2270 {NULL}
2271 };
2272
2273 /* Constructors. */
2274
2275 static char *date_kws[] = {"year", "month", "day", NULL};
2276
2277 static PyObject *
date_new(PyTypeObject * type,PyObject * args,PyObject * kw)2278 date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2279 {
2280 PyObject *self = NULL;
2281 PyObject *state;
2282 int year;
2283 int month;
2284 int day;
2285
2286 /* Check for invocation from pickle with __getstate__ state */
2287 if (PyTuple_GET_SIZE(args) == 1 &&
2288 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2289 PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2290 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
2291 {
2292 PyDateTime_Date *me;
2293
2294 me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2295 if (me != NULL) {
2296 char *pdata = PyString_AS_STRING(state);
2297 memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2298 me->hashcode = -1;
2299 }
2300 return (PyObject *)me;
2301 }
2302
2303 if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2304 &year, &month, &day)) {
2305 if (check_date_args(year, month, day) < 0)
2306 return NULL;
2307 self = new_date_ex(year, month, day, type);
2308 }
2309 return self;
2310 }
2311
2312 /* Return new date from localtime(t). */
2313 static PyObject *
date_local_from_time_t(PyObject * cls,double ts)2314 date_local_from_time_t(PyObject *cls, double ts)
2315 {
2316 struct tm *tm;
2317 time_t t;
2318 PyObject *result = NULL;
2319
2320 t = _PyTime_DoubleToTimet(ts);
2321 if (t == (time_t)-1 && PyErr_Occurred())
2322 return NULL;
2323 tm = localtime(&t);
2324 if (tm)
2325 result = PyObject_CallFunction(cls, "iii",
2326 tm->tm_year + 1900,
2327 tm->tm_mon + 1,
2328 tm->tm_mday);
2329 else
2330 PyErr_SetString(PyExc_ValueError,
2331 "timestamp out of range for "
2332 "platform localtime() function");
2333 return result;
2334 }
2335
2336 /* Return new date from current time.
2337 * We say this is equivalent to fromtimestamp(time.time()), and the
2338 * only way to be sure of that is to *call* time.time(). That's not
2339 * generally the same as calling C's time.
2340 */
2341 static PyObject *
date_today(PyObject * cls,PyObject * dummy)2342 date_today(PyObject *cls, PyObject *dummy)
2343 {
2344 PyObject *time;
2345 PyObject *result;
2346
2347 time = time_time();
2348 if (time == NULL)
2349 return NULL;
2350
2351 /* Note well: today() is a class method, so this may not call
2352 * date.fromtimestamp. For example, it may call
2353 * datetime.fromtimestamp. That's why we need all the accuracy
2354 * time.time() delivers; if someone were gonzo about optimization,
2355 * date.today() could get away with plain C time().
2356 */
2357 result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
2358 Py_DECREF(time);
2359 return result;
2360 }
2361
2362 /* Return new date from given timestamp (Python timestamp -- a double). */
2363 static PyObject *
date_fromtimestamp(PyObject * cls,PyObject * args)2364 date_fromtimestamp(PyObject *cls, PyObject *args)
2365 {
2366 double timestamp;
2367 PyObject *result = NULL;
2368
2369 if (PyArg_ParseTuple(args, "d:fromtimestamp", ×tamp))
2370 result = date_local_from_time_t(cls, timestamp);
2371 return result;
2372 }
2373
2374 /* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2375 * the ordinal is out of range.
2376 */
2377 static PyObject *
date_fromordinal(PyObject * cls,PyObject * args)2378 date_fromordinal(PyObject *cls, PyObject *args)
2379 {
2380 PyObject *result = NULL;
2381 int ordinal;
2382
2383 if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2384 int year;
2385 int month;
2386 int day;
2387
2388 if (ordinal < 1)
2389 PyErr_SetString(PyExc_ValueError, "ordinal must be "
2390 ">= 1");
2391 else {
2392 ord_to_ymd(ordinal, &year, &month, &day);
2393 result = PyObject_CallFunction(cls, "iii",
2394 year, month, day);
2395 }
2396 }
2397 return result;
2398 }
2399
2400 /*
2401 * Date arithmetic.
2402 */
2403
2404 /* date + timedelta -> date. If arg negate is true, subtract the timedelta
2405 * instead.
2406 */
2407 static PyObject *
add_date_timedelta(PyDateTime_Date * date,PyDateTime_Delta * delta,int negate)2408 add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2409 {
2410 PyObject *result = NULL;
2411 int year = GET_YEAR(date);
2412 int month = GET_MONTH(date);
2413 int deltadays = GET_TD_DAYS(delta);
2414 /* C-level overflow is impossible because |deltadays| < 1e9. */
2415 int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2416
2417 if (normalize_date(&year, &month, &day) >= 0)
2418 result = new_date(year, month, day);
2419 return result;
2420 }
2421
2422 static PyObject *
date_add(PyObject * left,PyObject * right)2423 date_add(PyObject *left, PyObject *right)
2424 {
2425 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2426 Py_INCREF(Py_NotImplemented);
2427 return Py_NotImplemented;
2428 }
2429 if (PyDate_Check(left)) {
2430 /* date + ??? */
2431 if (PyDelta_Check(right))
2432 /* date + delta */
2433 return add_date_timedelta((PyDateTime_Date *) left,
2434 (PyDateTime_Delta *) right,
2435 0);
2436 }
2437 else {
2438 /* ??? + date
2439 * 'right' must be one of us, or we wouldn't have been called
2440 */
2441 if (PyDelta_Check(left))
2442 /* delta + date */
2443 return add_date_timedelta((PyDateTime_Date *) right,
2444 (PyDateTime_Delta *) left,
2445 0);
2446 }
2447 Py_INCREF(Py_NotImplemented);
2448 return Py_NotImplemented;
2449 }
2450
2451 static PyObject *
date_subtract(PyObject * left,PyObject * right)2452 date_subtract(PyObject *left, PyObject *right)
2453 {
2454 if (PyDateTime_Check(left) || PyDateTime_Check(right)) {
2455 Py_INCREF(Py_NotImplemented);
2456 return Py_NotImplemented;
2457 }
2458 if (PyDate_Check(left)) {
2459 if (PyDate_Check(right)) {
2460 /* date - date */
2461 int left_ord = ymd_to_ord(GET_YEAR(left),
2462 GET_MONTH(left),
2463 GET_DAY(left));
2464 int right_ord = ymd_to_ord(GET_YEAR(right),
2465 GET_MONTH(right),
2466 GET_DAY(right));
2467 return new_delta(left_ord - right_ord, 0, 0, 0);
2468 }
2469 if (PyDelta_Check(right)) {
2470 /* date - delta */
2471 return add_date_timedelta((PyDateTime_Date *) left,
2472 (PyDateTime_Delta *) right,
2473 1);
2474 }
2475 }
2476 Py_INCREF(Py_NotImplemented);
2477 return Py_NotImplemented;
2478 }
2479
2480
2481 /* Various ways to turn a date into a string. */
2482
2483 static PyObject *
date_repr(PyDateTime_Date * self)2484 date_repr(PyDateTime_Date *self)
2485 {
2486 char buffer[1028];
2487 const char *type_name;
2488
2489 type_name = Py_TYPE(self)->tp_name;
2490 PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2491 type_name,
2492 GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2493
2494 return PyString_FromString(buffer);
2495 }
2496
2497 static PyObject *
date_isoformat(PyDateTime_Date * self)2498 date_isoformat(PyDateTime_Date *self)
2499 {
2500 char buffer[128];
2501
2502 isoformat_date(self, buffer, sizeof(buffer));
2503 return PyString_FromString(buffer);
2504 }
2505
2506 /* str() calls the appropriate isoformat() method. */
2507 static PyObject *
date_str(PyDateTime_Date * self)2508 date_str(PyDateTime_Date *self)
2509 {
2510 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
2511 }
2512
2513
2514 static PyObject *
date_ctime(PyDateTime_Date * self)2515 date_ctime(PyDateTime_Date *self)
2516 {
2517 return format_ctime(self, 0, 0, 0);
2518 }
2519
2520 static PyObject *
date_strftime(PyDateTime_Date * self,PyObject * args,PyObject * kw)2521 date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2522 {
2523 /* This method can be inherited, and needs to call the
2524 * timetuple() method appropriate to self's class.
2525 */
2526 PyObject *result;
2527 PyObject *tuple;
2528 const char *format;
2529 Py_ssize_t format_len;
2530 static char *keywords[] = {"format", NULL};
2531
2532 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
2533 &format, &format_len))
2534 return NULL;
2535
2536 tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
2537 if (tuple == NULL)
2538 return NULL;
2539 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
2540 (PyObject *)self);
2541 Py_DECREF(tuple);
2542 return result;
2543 }
2544
2545 static PyObject *
date_format(PyDateTime_Date * self,PyObject * args)2546 date_format(PyDateTime_Date *self, PyObject *args)
2547 {
2548 PyObject *format;
2549
2550 if (!PyArg_ParseTuple(args, "O:__format__", &format))
2551 return NULL;
2552
2553 /* Check for str or unicode */
2554 if (PyString_Check(format)) {
2555 /* If format is zero length, return str(self) */
2556 if (PyString_GET_SIZE(format) == 0)
2557 return PyObject_Str((PyObject *)self);
2558 } else if (PyUnicode_Check(format)) {
2559 /* If format is zero length, return str(self) */
2560 if (PyUnicode_GET_SIZE(format) == 0)
2561 return PyObject_Unicode((PyObject *)self);
2562 } else {
2563 PyErr_Format(PyExc_ValueError,
2564 "__format__ expects str or unicode, not %.200s",
2565 Py_TYPE(format)->tp_name);
2566 return NULL;
2567 }
2568 return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
2569 }
2570
2571 /* ISO methods. */
2572
2573 static PyObject *
date_isoweekday(PyDateTime_Date * self)2574 date_isoweekday(PyDateTime_Date *self)
2575 {
2576 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2577
2578 return PyInt_FromLong(dow + 1);
2579 }
2580
2581 static PyObject *
date_isocalendar(PyDateTime_Date * self)2582 date_isocalendar(PyDateTime_Date *self)
2583 {
2584 int year = GET_YEAR(self);
2585 int week1_monday = iso_week1_monday(year);
2586 int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2587 int week;
2588 int day;
2589
2590 week = divmod(today - week1_monday, 7, &day);
2591 if (week < 0) {
2592 --year;
2593 week1_monday = iso_week1_monday(year);
2594 week = divmod(today - week1_monday, 7, &day);
2595 }
2596 else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2597 ++year;
2598 week = 0;
2599 }
2600 return Py_BuildValue("iii", year, week + 1, day + 1);
2601 }
2602
2603 /* Miscellaneous methods. */
2604
2605 /* This is more natural as a tp_compare, but doesn't work then: for whatever
2606 * reason, Python's try_3way_compare ignores tp_compare unless
2607 * PyInstance_Check returns true, but these aren't old-style classes.
2608 */
2609 static PyObject *
date_richcompare(PyDateTime_Date * self,PyObject * other,int op)2610 date_richcompare(PyDateTime_Date *self, PyObject *other, int op)
2611 {
2612 int diff = 42; /* nonsense */
2613
2614 if (PyDate_Check(other))
2615 diff = memcmp(self->data, ((PyDateTime_Date *)other)->data,
2616 _PyDateTime_DATE_DATASIZE);
2617
2618 else if (PyObject_HasAttrString(other, "timetuple")) {
2619 /* A hook for other kinds of date objects. */
2620 Py_INCREF(Py_NotImplemented);
2621 return Py_NotImplemented;
2622 }
2623 else if (op == Py_EQ || op == Py_NE)
2624 diff = 1; /* any non-zero value will do */
2625
2626 else /* stop this from falling back to address comparison */
2627 return cmperror((PyObject *)self, other);
2628
2629 return diff_to_bool(diff, op);
2630 }
2631
2632 static PyObject *
date_timetuple(PyDateTime_Date * self)2633 date_timetuple(PyDateTime_Date *self)
2634 {
2635 return build_struct_time(GET_YEAR(self),
2636 GET_MONTH(self),
2637 GET_DAY(self),
2638 0, 0, 0, -1);
2639 }
2640
2641 static PyObject *
date_replace(PyDateTime_Date * self,PyObject * args,PyObject * kw)2642 date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2643 {
2644 PyObject *clone;
2645 PyObject *tuple;
2646 int year = GET_YEAR(self);
2647 int month = GET_MONTH(self);
2648 int day = GET_DAY(self);
2649
2650 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2651 &year, &month, &day))
2652 return NULL;
2653 tuple = Py_BuildValue("iii", year, month, day);
2654 if (tuple == NULL)
2655 return NULL;
2656 clone = date_new(Py_TYPE(self), tuple, NULL);
2657 Py_DECREF(tuple);
2658 return clone;
2659 }
2660
2661 static PyObject *date_getstate(PyDateTime_Date *self);
2662
2663 static long
date_hash(PyDateTime_Date * self)2664 date_hash(PyDateTime_Date *self)
2665 {
2666 if (self->hashcode == -1) {
2667 PyObject *temp = date_getstate(self);
2668 if (temp != NULL) {
2669 self->hashcode = PyObject_Hash(temp);
2670 Py_DECREF(temp);
2671 }
2672 }
2673 return self->hashcode;
2674 }
2675
2676 static PyObject *
date_toordinal(PyDateTime_Date * self)2677 date_toordinal(PyDateTime_Date *self)
2678 {
2679 return PyInt_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2680 GET_DAY(self)));
2681 }
2682
2683 static PyObject *
date_weekday(PyDateTime_Date * self)2684 date_weekday(PyDateTime_Date *self)
2685 {
2686 int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2687
2688 return PyInt_FromLong(dow);
2689 }
2690
2691 /* Pickle support, a simple use of __reduce__. */
2692
2693 /* __getstate__ isn't exposed */
2694 static PyObject *
date_getstate(PyDateTime_Date * self)2695 date_getstate(PyDateTime_Date *self)
2696 {
2697 return Py_BuildValue(
2698 "(N)",
2699 PyString_FromStringAndSize((char *)self->data,
2700 _PyDateTime_DATE_DATASIZE));
2701 }
2702
2703 static PyObject *
date_reduce(PyDateTime_Date * self,PyObject * arg)2704 date_reduce(PyDateTime_Date *self, PyObject *arg)
2705 {
2706 return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
2707 }
2708
2709 static PyMethodDef date_methods[] = {
2710
2711 /* Class methods: */
2712
2713 {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2714 METH_CLASS,
2715 PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2716 "time.time()).")},
2717
2718 {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2719 METH_CLASS,
2720 PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2721 "ordinal.")},
2722
2723 {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2724 PyDoc_STR("Current date or datetime: same as "
2725 "self.__class__.fromtimestamp(time.time()).")},
2726
2727 /* Instance methods: */
2728
2729 {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2730 PyDoc_STR("Return ctime() style string.")},
2731
2732 {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2733 PyDoc_STR("format -> strftime() style string.")},
2734
2735 {"__format__", (PyCFunction)date_format, METH_VARARGS,
2736 PyDoc_STR("Formats self with strftime.")},
2737
2738 {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2739 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2740
2741 {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2742 PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2743 "weekday.")},
2744
2745 {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2746 PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2747
2748 {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2749 PyDoc_STR("Return the day of the week represented by the date.\n"
2750 "Monday == 1 ... Sunday == 7")},
2751
2752 {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2753 PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2754 "1 is day 1.")},
2755
2756 {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2757 PyDoc_STR("Return the day of the week represented by the date.\n"
2758 "Monday == 0 ... Sunday == 6")},
2759
2760 {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2761 PyDoc_STR("Return date with new specified fields.")},
2762
2763 {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2764 PyDoc_STR("__reduce__() -> (cls, state)")},
2765
2766 {NULL, NULL}
2767 };
2768
2769 static char date_doc[] =
2770 PyDoc_STR("date(year, month, day) --> date object");
2771
2772 static PyNumberMethods date_as_number = {
2773 date_add, /* nb_add */
2774 date_subtract, /* nb_subtract */
2775 0, /* nb_multiply */
2776 0, /* nb_divide */
2777 0, /* nb_remainder */
2778 0, /* nb_divmod */
2779 0, /* nb_power */
2780 0, /* nb_negative */
2781 0, /* nb_positive */
2782 0, /* nb_absolute */
2783 0, /* nb_nonzero */
2784 };
2785
2786 static PyTypeObject PyDateTime_DateType = {
2787 PyVarObject_HEAD_INIT(NULL, 0)
2788 "datetime.date", /* tp_name */
2789 sizeof(PyDateTime_Date), /* tp_basicsize */
2790 0, /* tp_itemsize */
2791 0, /* tp_dealloc */
2792 0, /* tp_print */
2793 0, /* tp_getattr */
2794 0, /* tp_setattr */
2795 0, /* tp_compare */
2796 (reprfunc)date_repr, /* tp_repr */
2797 &date_as_number, /* tp_as_number */
2798 0, /* tp_as_sequence */
2799 0, /* tp_as_mapping */
2800 (hashfunc)date_hash, /* tp_hash */
2801 0, /* tp_call */
2802 (reprfunc)date_str, /* tp_str */
2803 PyObject_GenericGetAttr, /* tp_getattro */
2804 0, /* tp_setattro */
2805 0, /* tp_as_buffer */
2806 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2807 Py_TPFLAGS_BASETYPE, /* tp_flags */
2808 date_doc, /* tp_doc */
2809 0, /* tp_traverse */
2810 0, /* tp_clear */
2811 (richcmpfunc)date_richcompare, /* tp_richcompare */
2812 0, /* tp_weaklistoffset */
2813 0, /* tp_iter */
2814 0, /* tp_iternext */
2815 date_methods, /* tp_methods */
2816 0, /* tp_members */
2817 date_getset, /* tp_getset */
2818 0, /* tp_base */
2819 0, /* tp_dict */
2820 0, /* tp_descr_get */
2821 0, /* tp_descr_set */
2822 0, /* tp_dictoffset */
2823 0, /* tp_init */
2824 0, /* tp_alloc */
2825 date_new, /* tp_new */
2826 0, /* tp_free */
2827 };
2828
2829 /*
2830 * PyDateTime_TZInfo implementation.
2831 */
2832
2833 /* This is a pure abstract base class, so doesn't do anything beyond
2834 * raising NotImplemented exceptions. Real tzinfo classes need
2835 * to derive from this. This is mostly for clarity, and for efficiency in
2836 * datetime and time constructors (their tzinfo arguments need to
2837 * be subclasses of this tzinfo class, which is easy and quick to check).
2838 *
2839 * Note: For reasons having to do with pickling of subclasses, we have
2840 * to allow tzinfo objects to be instantiated. This wasn't an issue
2841 * in the Python implementation (__init__() could raise NotImplementedError
2842 * there without ill effect), but doing so in the C implementation hit a
2843 * brick wall.
2844 */
2845
2846 static PyObject *
tzinfo_nogo(const char * methodname)2847 tzinfo_nogo(const char* methodname)
2848 {
2849 PyErr_Format(PyExc_NotImplementedError,
2850 "a tzinfo subclass must implement %s()",
2851 methodname);
2852 return NULL;
2853 }
2854
2855 /* Methods. A subclass must implement these. */
2856
2857 static PyObject *
tzinfo_tzname(PyDateTime_TZInfo * self,PyObject * dt)2858 tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
2859 {
2860 return tzinfo_nogo("tzname");
2861 }
2862
2863 static PyObject *
tzinfo_utcoffset(PyDateTime_TZInfo * self,PyObject * dt)2864 tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
2865 {
2866 return tzinfo_nogo("utcoffset");
2867 }
2868
2869 static PyObject *
tzinfo_dst(PyDateTime_TZInfo * self,PyObject * dt)2870 tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
2871 {
2872 return tzinfo_nogo("dst");
2873 }
2874
2875 static PyObject *
tzinfo_fromutc(PyDateTime_TZInfo * self,PyDateTime_DateTime * dt)2876 tzinfo_fromutc(PyDateTime_TZInfo *self, PyDateTime_DateTime *dt)
2877 {
2878 int y, m, d, hh, mm, ss, us;
2879
2880 PyObject *result;
2881 int off, dst;
2882 int none;
2883 int delta;
2884
2885 if (! PyDateTime_Check(dt)) {
2886 PyErr_SetString(PyExc_TypeError,
2887 "fromutc: argument must be a datetime");
2888 return NULL;
2889 }
2890 if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
2891 PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
2892 "is not self");
2893 return NULL;
2894 }
2895
2896 off = call_utcoffset(dt->tzinfo, (PyObject *)dt, &none);
2897 if (off == -1 && PyErr_Occurred())
2898 return NULL;
2899 if (none) {
2900 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2901 "utcoffset() result required");
2902 return NULL;
2903 }
2904
2905 dst = call_dst(dt->tzinfo, (PyObject *)dt, &none);
2906 if (dst == -1 && PyErr_Occurred())
2907 return NULL;
2908 if (none) {
2909 PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
2910 "dst() result required");
2911 return NULL;
2912 }
2913
2914 y = GET_YEAR(dt);
2915 m = GET_MONTH(dt);
2916 d = GET_DAY(dt);
2917 hh = DATE_GET_HOUR(dt);
2918 mm = DATE_GET_MINUTE(dt);
2919 ss = DATE_GET_SECOND(dt);
2920 us = DATE_GET_MICROSECOND(dt);
2921
2922 delta = off - dst;
2923 mm += delta;
2924 if ((mm < 0 || mm >= 60) &&
2925 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2926 return NULL;
2927 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2928 if (result == NULL)
2929 return result;
2930
2931 dst = call_dst(dt->tzinfo, result, &none);
2932 if (dst == -1 && PyErr_Occurred())
2933 goto Fail;
2934 if (none)
2935 goto Inconsistent;
2936 if (dst == 0)
2937 return result;
2938
2939 mm += dst;
2940 if ((mm < 0 || mm >= 60) &&
2941 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
2942 goto Fail;
2943 Py_DECREF(result);
2944 result = new_datetime(y, m, d, hh, mm, ss, us, dt->tzinfo);
2945 return result;
2946
2947 Inconsistent:
2948 PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
2949 "inconsistent results; cannot convert");
2950
2951 /* fall thru to failure */
2952 Fail:
2953 Py_DECREF(result);
2954 return NULL;
2955 }
2956
2957 /*
2958 * Pickle support. This is solely so that tzinfo subclasses can use
2959 * pickling -- tzinfo itself is supposed to be uninstantiable.
2960 */
2961
2962 static PyObject *
tzinfo_reduce(PyObject * self)2963 tzinfo_reduce(PyObject *self)
2964 {
2965 PyObject *args, *state, *tmp;
2966 PyObject *getinitargs, *getstate;
2967
2968 tmp = PyTuple_New(0);
2969 if (tmp == NULL)
2970 return NULL;
2971
2972 getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
2973 if (getinitargs != NULL) {
2974 args = PyObject_CallObject(getinitargs, tmp);
2975 Py_DECREF(getinitargs);
2976 if (args == NULL) {
2977 Py_DECREF(tmp);
2978 return NULL;
2979 }
2980 }
2981 else {
2982 PyErr_Clear();
2983 args = tmp;
2984 Py_INCREF(args);
2985 }
2986
2987 getstate = PyObject_GetAttrString(self, "__getstate__");
2988 if (getstate != NULL) {
2989 state = PyObject_CallObject(getstate, tmp);
2990 Py_DECREF(getstate);
2991 if (state == NULL) {
2992 Py_DECREF(args);
2993 Py_DECREF(tmp);
2994 return NULL;
2995 }
2996 }
2997 else {
2998 PyObject **dictptr;
2999 PyErr_Clear();
3000 state = Py_None;
3001 dictptr = _PyObject_GetDictPtr(self);
3002 if (dictptr && *dictptr && PyDict_Size(*dictptr))
3003 state = *dictptr;
3004 Py_INCREF(state);
3005 }
3006
3007 Py_DECREF(tmp);
3008
3009 if (state == Py_None) {
3010 Py_DECREF(state);
3011 return Py_BuildValue("(ON)", Py_TYPE(self), args);
3012 }
3013 else
3014 return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
3015 }
3016
3017 static PyMethodDef tzinfo_methods[] = {
3018
3019 {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3020 PyDoc_STR("datetime -> string name of time zone.")},
3021
3022 {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
3023 PyDoc_STR("datetime -> minutes east of UTC (negative for "
3024 "west of UTC).")},
3025
3026 {"dst", (PyCFunction)tzinfo_dst, METH_O,
3027 PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3028
3029 {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
3030 PyDoc_STR("datetime in UTC -> datetime in local time.")},
3031
3032 {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3033 PyDoc_STR("-> (cls, state)")},
3034
3035 {NULL, NULL}
3036 };
3037
3038 static char tzinfo_doc[] =
3039 PyDoc_STR("Abstract base class for time zone info objects.");
3040
3041 statichere PyTypeObject PyDateTime_TZInfoType = {
3042 PyObject_HEAD_INIT(NULL)
3043 0, /* ob_size */
3044 "datetime.tzinfo", /* tp_name */
3045 sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3046 0, /* tp_itemsize */
3047 0, /* tp_dealloc */
3048 0, /* tp_print */
3049 0, /* tp_getattr */
3050 0, /* tp_setattr */
3051 0, /* tp_compare */
3052 0, /* tp_repr */
3053 0, /* tp_as_number */
3054 0, /* tp_as_sequence */
3055 0, /* tp_as_mapping */
3056 0, /* tp_hash */
3057 0, /* tp_call */
3058 0, /* tp_str */
3059 PyObject_GenericGetAttr, /* tp_getattro */
3060 0, /* tp_setattro */
3061 0, /* tp_as_buffer */
3062 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3063 Py_TPFLAGS_BASETYPE, /* tp_flags */
3064 tzinfo_doc, /* tp_doc */
3065 0, /* tp_traverse */
3066 0, /* tp_clear */
3067 0, /* tp_richcompare */
3068 0, /* tp_weaklistoffset */
3069 0, /* tp_iter */
3070 0, /* tp_iternext */
3071 tzinfo_methods, /* tp_methods */
3072 0, /* tp_members */
3073 0, /* tp_getset */
3074 0, /* tp_base */
3075 0, /* tp_dict */
3076 0, /* tp_descr_get */
3077 0, /* tp_descr_set */
3078 0, /* tp_dictoffset */
3079 0, /* tp_init */
3080 0, /* tp_alloc */
3081 PyType_GenericNew, /* tp_new */
3082 0, /* tp_free */
3083 };
3084
3085 /*
3086 * PyDateTime_Time implementation.
3087 */
3088
3089 /* Accessor properties.
3090 */
3091
3092 static PyObject *
time_hour(PyDateTime_Time * self,void * unused)3093 time_hour(PyDateTime_Time *self, void *unused)
3094 {
3095 return PyInt_FromLong(TIME_GET_HOUR(self));
3096 }
3097
3098 static PyObject *
time_minute(PyDateTime_Time * self,void * unused)3099 time_minute(PyDateTime_Time *self, void *unused)
3100 {
3101 return PyInt_FromLong(TIME_GET_MINUTE(self));
3102 }
3103
3104 /* The name time_second conflicted with some platform header file. */
3105 static PyObject *
py_time_second(PyDateTime_Time * self,void * unused)3106 py_time_second(PyDateTime_Time *self, void *unused)
3107 {
3108 return PyInt_FromLong(TIME_GET_SECOND(self));
3109 }
3110
3111 static PyObject *
time_microsecond(PyDateTime_Time * self,void * unused)3112 time_microsecond(PyDateTime_Time *self, void *unused)
3113 {
3114 return PyInt_FromLong(TIME_GET_MICROSECOND(self));
3115 }
3116
3117 static PyObject *
time_tzinfo(PyDateTime_Time * self,void * unused)3118 time_tzinfo(PyDateTime_Time *self, void *unused)
3119 {
3120 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3121 Py_INCREF(result);
3122 return result;
3123 }
3124
3125 static PyGetSetDef time_getset[] = {
3126 {"hour", (getter)time_hour},
3127 {"minute", (getter)time_minute},
3128 {"second", (getter)py_time_second},
3129 {"microsecond", (getter)time_microsecond},
3130 {"tzinfo", (getter)time_tzinfo},
3131 {NULL}
3132 };
3133
3134 /*
3135 * Constructors.
3136 */
3137
3138 static char *time_kws[] = {"hour", "minute", "second", "microsecond",
3139 "tzinfo", NULL};
3140
3141 static PyObject *
time_new(PyTypeObject * type,PyObject * args,PyObject * kw)3142 time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3143 {
3144 PyObject *self = NULL;
3145 PyObject *state;
3146 int hour = 0;
3147 int minute = 0;
3148 int second = 0;
3149 int usecond = 0;
3150 PyObject *tzinfo = Py_None;
3151
3152 /* Check for invocation from pickle with __getstate__ state */
3153 if (PyTuple_GET_SIZE(args) >= 1 &&
3154 PyTuple_GET_SIZE(args) <= 2 &&
3155 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3156 PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3157 ((unsigned char) (PyString_AS_STRING(state)[0])) < 24)
3158 {
3159 PyDateTime_Time *me;
3160 char aware;
3161
3162 if (PyTuple_GET_SIZE(args) == 2) {
3163 tzinfo = PyTuple_GET_ITEM(args, 1);
3164 if (check_tzinfo_subclass(tzinfo) < 0) {
3165 PyErr_SetString(PyExc_TypeError, "bad "
3166 "tzinfo state arg");
3167 return NULL;
3168 }
3169 }
3170 aware = (char)(tzinfo != Py_None);
3171 me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3172 if (me != NULL) {
3173 char *pdata = PyString_AS_STRING(state);
3174
3175 memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3176 me->hashcode = -1;
3177 me->hastzinfo = aware;
3178 if (aware) {
3179 Py_INCREF(tzinfo);
3180 me->tzinfo = tzinfo;
3181 }
3182 }
3183 return (PyObject *)me;
3184 }
3185
3186 if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", time_kws,
3187 &hour, &minute, &second, &usecond,
3188 &tzinfo)) {
3189 if (check_time_args(hour, minute, second, usecond) < 0)
3190 return NULL;
3191 if (check_tzinfo_subclass(tzinfo) < 0)
3192 return NULL;
3193 self = new_time_ex(hour, minute, second, usecond, tzinfo,
3194 type);
3195 }
3196 return self;
3197 }
3198
3199 /*
3200 * Destructor.
3201 */
3202
3203 static void
time_dealloc(PyDateTime_Time * self)3204 time_dealloc(PyDateTime_Time *self)
3205 {
3206 if (HASTZINFO(self)) {
3207 Py_XDECREF(self->tzinfo);
3208 }
3209 Py_TYPE(self)->tp_free((PyObject *)self);
3210 }
3211
3212 /*
3213 * Indirect access to tzinfo methods.
3214 */
3215
3216 /* These are all METH_NOARGS, so don't need to check the arglist. */
3217 static PyObject *
time_utcoffset(PyDateTime_Time * self,PyObject * unused)3218 time_utcoffset(PyDateTime_Time *self, PyObject *unused) {
3219 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3220 "utcoffset", Py_None);
3221 }
3222
3223 static PyObject *
time_dst(PyDateTime_Time * self,PyObject * unused)3224 time_dst(PyDateTime_Time *self, PyObject *unused) {
3225 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
3226 "dst", Py_None);
3227 }
3228
3229 static PyObject *
time_tzname(PyDateTime_Time * self,PyObject * unused)3230 time_tzname(PyDateTime_Time *self, PyObject *unused) {
3231 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
3232 Py_None);
3233 }
3234
3235 /*
3236 * Various ways to turn a time into a string.
3237 */
3238
3239 static PyObject *
time_repr(PyDateTime_Time * self)3240 time_repr(PyDateTime_Time *self)
3241 {
3242 char buffer[100];
3243 const char *type_name = Py_TYPE(self)->tp_name;
3244 int h = TIME_GET_HOUR(self);
3245 int m = TIME_GET_MINUTE(self);
3246 int s = TIME_GET_SECOND(self);
3247 int us = TIME_GET_MICROSECOND(self);
3248 PyObject *result = NULL;
3249
3250 if (us)
3251 PyOS_snprintf(buffer, sizeof(buffer),
3252 "%s(%d, %d, %d, %d)", type_name, h, m, s, us);
3253 else if (s)
3254 PyOS_snprintf(buffer, sizeof(buffer),
3255 "%s(%d, %d, %d)", type_name, h, m, s);
3256 else
3257 PyOS_snprintf(buffer, sizeof(buffer),
3258 "%s(%d, %d)", type_name, h, m);
3259 result = PyString_FromString(buffer);
3260 if (result != NULL && HASTZINFO(self))
3261 result = append_keyword_tzinfo(result, self->tzinfo);
3262 return result;
3263 }
3264
3265 static PyObject *
time_str(PyDateTime_Time * self)3266 time_str(PyDateTime_Time *self)
3267 {
3268 return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
3269 }
3270
3271 static PyObject *
time_isoformat(PyDateTime_Time * self,PyObject * unused)3272 time_isoformat(PyDateTime_Time *self, PyObject *unused)
3273 {
3274 char buf[100];
3275 PyObject *result;
3276 /* Reuse the time format code from the datetime type. */
3277 PyDateTime_DateTime datetime;
3278 PyDateTime_DateTime *pdatetime = &datetime;
3279
3280 /* Copy over just the time bytes. */
3281 memcpy(pdatetime->data + _PyDateTime_DATE_DATASIZE,
3282 self->data,
3283 _PyDateTime_TIME_DATASIZE);
3284
3285 isoformat_time(pdatetime, buf, sizeof(buf));
3286 result = PyString_FromString(buf);
3287 if (result == NULL || ! HASTZINFO(self) || self->tzinfo == Py_None)
3288 return result;
3289
3290 /* We need to append the UTC offset. */
3291 if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3292 Py_None) < 0) {
3293 Py_DECREF(result);
3294 return NULL;
3295 }
3296 PyString_ConcatAndDel(&result, PyString_FromString(buf));
3297 return result;
3298 }
3299
3300 static PyObject *
time_strftime(PyDateTime_Time * self,PyObject * args,PyObject * kw)3301 time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3302 {
3303 PyObject *result;
3304 PyObject *tuple;
3305 const char *format;
3306 Py_ssize_t format_len;
3307 static char *keywords[] = {"format", NULL};
3308
3309 if (! PyArg_ParseTupleAndKeywords(args, kw, "s#:strftime", keywords,
3310 &format, &format_len))
3311 return NULL;
3312
3313 /* Python's strftime does insane things with the year part of the
3314 * timetuple. The year is forced to (the otherwise nonsensical)
3315 * 1900 to worm around that.
3316 */
3317 tuple = Py_BuildValue("iiiiiiiii",
3318 1900, 1, 1, /* year, month, day */
3319 TIME_GET_HOUR(self),
3320 TIME_GET_MINUTE(self),
3321 TIME_GET_SECOND(self),
3322 0, 1, -1); /* weekday, daynum, dst */
3323 if (tuple == NULL)
3324 return NULL;
3325 assert(PyTuple_Size(tuple) == 9);
3326 result = wrap_strftime((PyObject *)self, format, format_len, tuple,
3327 Py_None);
3328 Py_DECREF(tuple);
3329 return result;
3330 }
3331
3332 /*
3333 * Miscellaneous methods.
3334 */
3335
3336 /* This is more natural as a tp_compare, but doesn't work then: for whatever
3337 * reason, Python's try_3way_compare ignores tp_compare unless
3338 * PyInstance_Check returns true, but these aren't old-style classes.
3339 */
3340 static PyObject *
time_richcompare(PyDateTime_Time * self,PyObject * other,int op)3341 time_richcompare(PyDateTime_Time *self, PyObject *other, int op)
3342 {
3343 int diff;
3344 naivety n1, n2;
3345 int offset1, offset2;
3346
3347 if (! PyTime_Check(other)) {
3348 if (op == Py_EQ || op == Py_NE) {
3349 PyObject *result = op == Py_EQ ? Py_False : Py_True;
3350 Py_INCREF(result);
3351 return result;
3352 }
3353 /* Stop this from falling back to address comparison. */
3354 return cmperror((PyObject *)self, other);
3355 }
3356 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1, Py_None,
3357 other, &offset2, &n2, Py_None) < 0)
3358 return NULL;
3359 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
3360 /* If they're both naive, or both aware and have the same offsets,
3361 * we get off cheap. Note that if they're both naive, offset1 ==
3362 * offset2 == 0 at this point.
3363 */
3364 if (n1 == n2 && offset1 == offset2) {
3365 diff = memcmp(self->data, ((PyDateTime_Time *)other)->data,
3366 _PyDateTime_TIME_DATASIZE);
3367 return diff_to_bool(diff, op);
3368 }
3369
3370 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
3371 assert(offset1 != offset2); /* else last "if" handled it */
3372 /* Convert everything except microseconds to seconds. These
3373 * can't overflow (no more than the # of seconds in 2 days).
3374 */
3375 offset1 = TIME_GET_HOUR(self) * 3600 +
3376 (TIME_GET_MINUTE(self) - offset1) * 60 +
3377 TIME_GET_SECOND(self);
3378 offset2 = TIME_GET_HOUR(other) * 3600 +
3379 (TIME_GET_MINUTE(other) - offset2) * 60 +
3380 TIME_GET_SECOND(other);
3381 diff = offset1 - offset2;
3382 if (diff == 0)
3383 diff = TIME_GET_MICROSECOND(self) -
3384 TIME_GET_MICROSECOND(other);
3385 return diff_to_bool(diff, op);
3386 }
3387
3388 assert(n1 != n2);
3389 PyErr_SetString(PyExc_TypeError,
3390 "can't compare offset-naive and "
3391 "offset-aware times");
3392 return NULL;
3393 }
3394
3395 static long
time_hash(PyDateTime_Time * self)3396 time_hash(PyDateTime_Time *self)
3397 {
3398 if (self->hashcode == -1) {
3399 naivety n;
3400 int offset;
3401 PyObject *temp;
3402
3403 n = classify_utcoffset((PyObject *)self, Py_None, &offset);
3404 assert(n != OFFSET_UNKNOWN);
3405 if (n == OFFSET_ERROR)
3406 return -1;
3407
3408 /* Reduce this to a hash of another object. */
3409 if (offset == 0)
3410 temp = PyString_FromStringAndSize((char *)self->data,
3411 _PyDateTime_TIME_DATASIZE);
3412 else {
3413 int hour;
3414 int minute;
3415
3416 assert(n == OFFSET_AWARE);
3417 assert(HASTZINFO(self));
3418 hour = divmod(TIME_GET_HOUR(self) * 60 +
3419 TIME_GET_MINUTE(self) - offset,
3420 60,
3421 &minute);
3422 if (0 <= hour && hour < 24)
3423 temp = new_time(hour, minute,
3424 TIME_GET_SECOND(self),
3425 TIME_GET_MICROSECOND(self),
3426 Py_None);
3427 else
3428 temp = Py_BuildValue("iiii",
3429 hour, minute,
3430 TIME_GET_SECOND(self),
3431 TIME_GET_MICROSECOND(self));
3432 }
3433 if (temp != NULL) {
3434 self->hashcode = PyObject_Hash(temp);
3435 Py_DECREF(temp);
3436 }
3437 }
3438 return self->hashcode;
3439 }
3440
3441 static PyObject *
time_replace(PyDateTime_Time * self,PyObject * args,PyObject * kw)3442 time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3443 {
3444 PyObject *clone;
3445 PyObject *tuple;
3446 int hh = TIME_GET_HOUR(self);
3447 int mm = TIME_GET_MINUTE(self);
3448 int ss = TIME_GET_SECOND(self);
3449 int us = TIME_GET_MICROSECOND(self);
3450 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
3451
3452 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO:replace",
3453 time_kws,
3454 &hh, &mm, &ss, &us, &tzinfo))
3455 return NULL;
3456 tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3457 if (tuple == NULL)
3458 return NULL;
3459 clone = time_new(Py_TYPE(self), tuple, NULL);
3460 Py_DECREF(tuple);
3461 return clone;
3462 }
3463
3464 static int
time_nonzero(PyDateTime_Time * self)3465 time_nonzero(PyDateTime_Time *self)
3466 {
3467 int offset;
3468 int none;
3469
3470 if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) {
3471 /* Since utcoffset is in whole minutes, nothing can
3472 * alter the conclusion that this is nonzero.
3473 */
3474 return 1;
3475 }
3476 offset = 0;
3477 if (HASTZINFO(self) && self->tzinfo != Py_None) {
3478 offset = call_utcoffset(self->tzinfo, Py_None, &none);
3479 if (offset == -1 && PyErr_Occurred())
3480 return -1;
3481 }
3482 return (TIME_GET_MINUTE(self) - offset + TIME_GET_HOUR(self)*60) != 0;
3483 }
3484
3485 /* Pickle support, a simple use of __reduce__. */
3486
3487 /* Let basestate be the non-tzinfo data string.
3488 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3489 * So it's a tuple in any (non-error) case.
3490 * __getstate__ isn't exposed.
3491 */
3492 static PyObject *
time_getstate(PyDateTime_Time * self)3493 time_getstate(PyDateTime_Time *self)
3494 {
3495 PyObject *basestate;
3496 PyObject *result = NULL;
3497
3498 basestate = PyString_FromStringAndSize((char *)self->data,
3499 _PyDateTime_TIME_DATASIZE);
3500 if (basestate != NULL) {
3501 if (! HASTZINFO(self) || self->tzinfo == Py_None)
3502 result = PyTuple_Pack(1, basestate);
3503 else
3504 result = PyTuple_Pack(2, basestate, self->tzinfo);
3505 Py_DECREF(basestate);
3506 }
3507 return result;
3508 }
3509
3510 static PyObject *
time_reduce(PyDateTime_Time * self,PyObject * arg)3511 time_reduce(PyDateTime_Time *self, PyObject *arg)
3512 {
3513 return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self));
3514 }
3515
3516 static PyMethodDef time_methods[] = {
3517
3518 {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS,
3519 PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]"
3520 "[+HH:MM].")},
3521
3522 {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
3523 PyDoc_STR("format -> strftime() style string.")},
3524
3525 {"__format__", (PyCFunction)date_format, METH_VARARGS,
3526 PyDoc_STR("Formats self with strftime.")},
3527
3528 {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
3529 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
3530
3531 {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
3532 PyDoc_STR("Return self.tzinfo.tzname(self).")},
3533
3534 {"dst", (PyCFunction)time_dst, METH_NOARGS,
3535 PyDoc_STR("Return self.tzinfo.dst(self).")},
3536
3537 {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
3538 PyDoc_STR("Return time with new specified fields.")},
3539
3540 {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
3541 PyDoc_STR("__reduce__() -> (cls, state)")},
3542
3543 {NULL, NULL}
3544 };
3545
3546 static char time_doc[] =
3547 PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
3548 \n\
3549 All arguments are optional. tzinfo may be None, or an instance of\n\
3550 a tzinfo subclass. The remaining arguments may be ints or longs.\n");
3551
3552 static PyNumberMethods time_as_number = {
3553 0, /* nb_add */
3554 0, /* nb_subtract */
3555 0, /* nb_multiply */
3556 0, /* nb_divide */
3557 0, /* nb_remainder */
3558 0, /* nb_divmod */
3559 0, /* nb_power */
3560 0, /* nb_negative */
3561 0, /* nb_positive */
3562 0, /* nb_absolute */
3563 (inquiry)time_nonzero, /* nb_nonzero */
3564 };
3565
3566 statichere PyTypeObject PyDateTime_TimeType = {
3567 PyObject_HEAD_INIT(NULL)
3568 0, /* ob_size */
3569 "datetime.time", /* tp_name */
3570 sizeof(PyDateTime_Time), /* tp_basicsize */
3571 0, /* tp_itemsize */
3572 (destructor)time_dealloc, /* tp_dealloc */
3573 0, /* tp_print */
3574 0, /* tp_getattr */
3575 0, /* tp_setattr */
3576 0, /* tp_compare */
3577 (reprfunc)time_repr, /* tp_repr */
3578 &time_as_number, /* tp_as_number */
3579 0, /* tp_as_sequence */
3580 0, /* tp_as_mapping */
3581 (hashfunc)time_hash, /* tp_hash */
3582 0, /* tp_call */
3583 (reprfunc)time_str, /* tp_str */
3584 PyObject_GenericGetAttr, /* tp_getattro */
3585 0, /* tp_setattro */
3586 0, /* tp_as_buffer */
3587 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
3588 Py_TPFLAGS_BASETYPE, /* tp_flags */
3589 time_doc, /* tp_doc */
3590 0, /* tp_traverse */
3591 0, /* tp_clear */
3592 (richcmpfunc)time_richcompare, /* tp_richcompare */
3593 0, /* tp_weaklistoffset */
3594 0, /* tp_iter */
3595 0, /* tp_iternext */
3596 time_methods, /* tp_methods */
3597 0, /* tp_members */
3598 time_getset, /* tp_getset */
3599 0, /* tp_base */
3600 0, /* tp_dict */
3601 0, /* tp_descr_get */
3602 0, /* tp_descr_set */
3603 0, /* tp_dictoffset */
3604 0, /* tp_init */
3605 time_alloc, /* tp_alloc */
3606 time_new, /* tp_new */
3607 0, /* tp_free */
3608 };
3609
3610 /*
3611 * PyDateTime_DateTime implementation.
3612 */
3613
3614 /* Accessor properties. Properties for day, month, and year are inherited
3615 * from date.
3616 */
3617
3618 static PyObject *
datetime_hour(PyDateTime_DateTime * self,void * unused)3619 datetime_hour(PyDateTime_DateTime *self, void *unused)
3620 {
3621 return PyInt_FromLong(DATE_GET_HOUR(self));
3622 }
3623
3624 static PyObject *
datetime_minute(PyDateTime_DateTime * self,void * unused)3625 datetime_minute(PyDateTime_DateTime *self, void *unused)
3626 {
3627 return PyInt_FromLong(DATE_GET_MINUTE(self));
3628 }
3629
3630 static PyObject *
datetime_second(PyDateTime_DateTime * self,void * unused)3631 datetime_second(PyDateTime_DateTime *self, void *unused)
3632 {
3633 return PyInt_FromLong(DATE_GET_SECOND(self));
3634 }
3635
3636 static PyObject *
datetime_microsecond(PyDateTime_DateTime * self,void * unused)3637 datetime_microsecond(PyDateTime_DateTime *self, void *unused)
3638 {
3639 return PyInt_FromLong(DATE_GET_MICROSECOND(self));
3640 }
3641
3642 static PyObject *
datetime_tzinfo(PyDateTime_DateTime * self,void * unused)3643 datetime_tzinfo(PyDateTime_DateTime *self, void *unused)
3644 {
3645 PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3646 Py_INCREF(result);
3647 return result;
3648 }
3649
3650 static PyGetSetDef datetime_getset[] = {
3651 {"hour", (getter)datetime_hour},
3652 {"minute", (getter)datetime_minute},
3653 {"second", (getter)datetime_second},
3654 {"microsecond", (getter)datetime_microsecond},
3655 {"tzinfo", (getter)datetime_tzinfo},
3656 {NULL}
3657 };
3658
3659 /*
3660 * Constructors.
3661 */
3662
3663 static char *datetime_kws[] = {
3664 "year", "month", "day", "hour", "minute", "second",
3665 "microsecond", "tzinfo", NULL
3666 };
3667
3668 static PyObject *
datetime_new(PyTypeObject * type,PyObject * args,PyObject * kw)3669 datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3670 {
3671 PyObject *self = NULL;
3672 PyObject *state;
3673 int year;
3674 int month;
3675 int day;
3676 int hour = 0;
3677 int minute = 0;
3678 int second = 0;
3679 int usecond = 0;
3680 PyObject *tzinfo = Py_None;
3681
3682 /* Check for invocation from pickle with __getstate__ state */
3683 if (PyTuple_GET_SIZE(args) >= 1 &&
3684 PyTuple_GET_SIZE(args) <= 2 &&
3685 PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3686 PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
3687 MONTH_IS_SANE(PyString_AS_STRING(state)[2]))
3688 {
3689 PyDateTime_DateTime *me;
3690 char aware;
3691
3692 if (PyTuple_GET_SIZE(args) == 2) {
3693 tzinfo = PyTuple_GET_ITEM(args, 1);
3694 if (check_tzinfo_subclass(tzinfo) < 0) {
3695 PyErr_SetString(PyExc_TypeError, "bad "
3696 "tzinfo state arg");
3697 return NULL;
3698 }
3699 }
3700 aware = (char)(tzinfo != Py_None);
3701 me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
3702 if (me != NULL) {
3703 char *pdata = PyString_AS_STRING(state);
3704
3705 memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
3706 me->hashcode = -1;
3707 me->hastzinfo = aware;
3708 if (aware) {
3709 Py_INCREF(tzinfo);
3710 me->tzinfo = tzinfo;
3711 }
3712 }
3713 return (PyObject *)me;
3714 }
3715
3716 if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO", datetime_kws,
3717 &year, &month, &day, &hour, &minute,
3718 &second, &usecond, &tzinfo)) {
3719 if (check_date_args(year, month, day) < 0)
3720 return NULL;
3721 if (check_time_args(hour, minute, second, usecond) < 0)
3722 return NULL;
3723 if (check_tzinfo_subclass(tzinfo) < 0)
3724 return NULL;
3725 self = new_datetime_ex(year, month, day,
3726 hour, minute, second, usecond,
3727 tzinfo, type);
3728 }
3729 return self;
3730 }
3731
3732 /* TM_FUNC is the shared type of localtime() and gmtime(). */
3733 typedef struct tm *(*TM_FUNC)(const time_t *timer);
3734
3735 /* Internal helper.
3736 * Build datetime from a time_t and a distinct count of microseconds.
3737 * Pass localtime or gmtime for f, to control the interpretation of timet.
3738 */
3739 static PyObject *
datetime_from_timet_and_us(PyObject * cls,TM_FUNC f,time_t timet,int us,PyObject * tzinfo)3740 datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
3741 PyObject *tzinfo)
3742 {
3743 struct tm *tm;
3744 PyObject *result = NULL;
3745
3746 tm = f(&timet);
3747 if (tm) {
3748 /* The platform localtime/gmtime may insert leap seconds,
3749 * indicated by tm->tm_sec > 59. We don't care about them,
3750 * except to the extent that passing them on to the datetime
3751 * constructor would raise ValueError for a reason that
3752 * made no sense to the user.
3753 */
3754 if (tm->tm_sec > 59)
3755 tm->tm_sec = 59;
3756 result = PyObject_CallFunction(cls, "iiiiiiiO",
3757 tm->tm_year + 1900,
3758 tm->tm_mon + 1,
3759 tm->tm_mday,
3760 tm->tm_hour,
3761 tm->tm_min,
3762 tm->tm_sec,
3763 us,
3764 tzinfo);
3765 }
3766 else
3767 PyErr_SetString(PyExc_ValueError,
3768 "timestamp out of range for "
3769 "platform localtime()/gmtime() function");
3770 return result;
3771 }
3772
3773 /* Internal helper.
3774 * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
3775 * to control the interpretation of the timestamp. Since a double doesn't
3776 * have enough bits to cover a datetime's full range of precision, it's
3777 * better to call datetime_from_timet_and_us provided you have a way
3778 * to get that much precision (e.g., C time() isn't good enough).
3779 */
3780 static PyObject *
datetime_from_timestamp(PyObject * cls,TM_FUNC f,double timestamp,PyObject * tzinfo)3781 datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
3782 PyObject *tzinfo)
3783 {
3784 time_t timet;
3785 double fraction;
3786 int us;
3787
3788 timet = _PyTime_DoubleToTimet(timestamp);
3789 if (timet == (time_t)-1 && PyErr_Occurred())
3790 return NULL;
3791 fraction = timestamp - (double)timet;
3792 us = (int)round_to_long(fraction * 1e6);
3793 if (us < 0) {
3794 /* Truncation towards zero is not what we wanted
3795 for negative numbers (Python's mod semantics) */
3796 timet -= 1;
3797 us += 1000000;
3798 }
3799 /* If timestamp is less than one microsecond smaller than a
3800 * full second, round up. Otherwise, ValueErrors are raised
3801 * for some floats. */
3802 if (us == 1000000) {
3803 timet += 1;
3804 us = 0;
3805 }
3806 return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
3807 }
3808
3809 /* Internal helper.
3810 * Build most accurate possible datetime for current time. Pass localtime or
3811 * gmtime for f as appropriate.
3812 */
3813 static PyObject *
datetime_best_possible(PyObject * cls,TM_FUNC f,PyObject * tzinfo)3814 datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
3815 {
3816 #ifdef HAVE_GETTIMEOFDAY
3817 struct timeval t;
3818
3819 #ifdef GETTIMEOFDAY_NO_TZ
3820 gettimeofday(&t);
3821 #else
3822 gettimeofday(&t, (struct timezone *)NULL);
3823 #endif
3824 return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
3825 tzinfo);
3826
3827 #else /* ! HAVE_GETTIMEOFDAY */
3828 /* No flavor of gettimeofday exists on this platform. Python's
3829 * time.time() does a lot of other platform tricks to get the
3830 * best time it can on the platform, and we're not going to do
3831 * better than that (if we could, the better code would belong
3832 * in time.time()!) We're limited by the precision of a double,
3833 * though.
3834 */
3835 PyObject *time;
3836 double dtime;
3837
3838 time = time_time();
3839 if (time == NULL)
3840 return NULL;
3841 dtime = PyFloat_AsDouble(time);
3842 Py_DECREF(time);
3843 if (dtime == -1.0 && PyErr_Occurred())
3844 return NULL;
3845 return datetime_from_timestamp(cls, f, dtime, tzinfo);
3846 #endif /* ! HAVE_GETTIMEOFDAY */
3847 }
3848
3849 /* Return best possible local time -- this isn't constrained by the
3850 * precision of a timestamp.
3851 */
3852 static PyObject *
datetime_now(PyObject * cls,PyObject * args,PyObject * kw)3853 datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
3854 {
3855 PyObject *self;
3856 PyObject *tzinfo = Py_None;
3857 static char *keywords[] = {"tz", NULL};
3858
3859 if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
3860 &tzinfo))
3861 return NULL;
3862 if (check_tzinfo_subclass(tzinfo) < 0)
3863 return NULL;
3864
3865 self = datetime_best_possible(cls,
3866 tzinfo == Py_None ? localtime : gmtime,
3867 tzinfo);
3868 if (self != NULL && tzinfo != Py_None) {
3869 /* Convert UTC to tzinfo's zone. */
3870 PyObject *temp = self;
3871 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3872 Py_DECREF(temp);
3873 }
3874 return self;
3875 }
3876
3877 /* Return best possible UTC time -- this isn't constrained by the
3878 * precision of a timestamp.
3879 */
3880 static PyObject *
datetime_utcnow(PyObject * cls,PyObject * dummy)3881 datetime_utcnow(PyObject *cls, PyObject *dummy)
3882 {
3883 return datetime_best_possible(cls, gmtime, Py_None);
3884 }
3885
3886 /* Return new local datetime from timestamp (Python timestamp -- a double). */
3887 static PyObject *
datetime_fromtimestamp(PyObject * cls,PyObject * args,PyObject * kw)3888 datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
3889 {
3890 PyObject *self;
3891 double timestamp;
3892 PyObject *tzinfo = Py_None;
3893 static char *keywords[] = {"timestamp", "tz", NULL};
3894
3895 if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
3896 keywords, ×tamp, &tzinfo))
3897 return NULL;
3898 if (check_tzinfo_subclass(tzinfo) < 0)
3899 return NULL;
3900
3901 self = datetime_from_timestamp(cls,
3902 tzinfo == Py_None ? localtime : gmtime,
3903 timestamp,
3904 tzinfo);
3905 if (self != NULL && tzinfo != Py_None) {
3906 /* Convert UTC to tzinfo's zone. */
3907 PyObject *temp = self;
3908 self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
3909 Py_DECREF(temp);
3910 }
3911 return self;
3912 }
3913
3914 /* Return new UTC datetime from timestamp (Python timestamp -- a double). */
3915 static PyObject *
datetime_utcfromtimestamp(PyObject * cls,PyObject * args)3916 datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
3917 {
3918 double timestamp;
3919 PyObject *result = NULL;
3920
3921 if (PyArg_ParseTuple(args, "d:utcfromtimestamp", ×tamp))
3922 result = datetime_from_timestamp(cls, gmtime, timestamp,
3923 Py_None);
3924 return result;
3925 }
3926
3927 /* Return new datetime from time.strptime(). */
3928 static PyObject *
datetime_strptime(PyObject * cls,PyObject * args)3929 datetime_strptime(PyObject *cls, PyObject *args)
3930 {
3931 static PyObject *module = NULL;
3932 PyObject *result = NULL, *obj, *st = NULL, *frac = NULL;
3933 const char *string, *format;
3934
3935 if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
3936 return NULL;
3937
3938 if (module == NULL &&
3939 (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL)
3940 return NULL;
3941
3942 /* _strptime._strptime returns a two-element tuple. The first
3943 element is a time.struct_time object. The second is the
3944 microseconds (which are not defined for time.struct_time). */
3945 obj = PyObject_CallMethod(module, "_strptime", "ss", string, format);
3946 if (obj != NULL) {
3947 int i, good_timetuple = 1;
3948 long int ia[7];
3949 if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
3950 st = PySequence_GetItem(obj, 0);
3951 frac = PySequence_GetItem(obj, 1);
3952 if (st == NULL || frac == NULL)
3953 good_timetuple = 0;
3954 /* copy y/m/d/h/m/s values out of the
3955 time.struct_time */
3956 if (good_timetuple &&
3957 PySequence_Check(st) &&
3958 PySequence_Size(st) >= 6) {
3959 for (i=0; i < 6; i++) {
3960 PyObject *p = PySequence_GetItem(st, i);
3961 if (p == NULL) {
3962 good_timetuple = 0;
3963 break;
3964 }
3965 if (PyInt_Check(p))
3966 ia[i] = PyInt_AsLong(p);
3967 else
3968 good_timetuple = 0;
3969 Py_DECREF(p);
3970 }
3971 }
3972 else
3973 good_timetuple = 0;
3974 /* follow that up with a little dose of microseconds */
3975 if (good_timetuple && PyInt_Check(frac))
3976 ia[6] = PyInt_AsLong(frac);
3977 else
3978 good_timetuple = 0;
3979 }
3980 else
3981 good_timetuple = 0;
3982 if (good_timetuple)
3983 result = PyObject_CallFunction(cls, "iiiiiii",
3984 ia[0], ia[1], ia[2],
3985 ia[3], ia[4], ia[5],
3986 ia[6]);
3987 else
3988 PyErr_SetString(PyExc_ValueError,
3989 "unexpected value from _strptime._strptime");
3990 }
3991 Py_XDECREF(obj);
3992 Py_XDECREF(st);
3993 Py_XDECREF(frac);
3994 return result;
3995 }
3996
3997 /* Return new datetime from date/datetime and time arguments. */
3998 static PyObject *
datetime_combine(PyObject * cls,PyObject * args,PyObject * kw)3999 datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4000 {
4001 static char *keywords[] = {"date", "time", NULL};
4002 PyObject *date;
4003 PyObject *time;
4004 PyObject *result = NULL;
4005
4006 if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!:combine", keywords,
4007 &PyDateTime_DateType, &date,
4008 &PyDateTime_TimeType, &time)) {
4009 PyObject *tzinfo = Py_None;
4010
4011 if (HASTZINFO(time))
4012 tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4013 result = PyObject_CallFunction(cls, "iiiiiiiO",
4014 GET_YEAR(date),
4015 GET_MONTH(date),
4016 GET_DAY(date),
4017 TIME_GET_HOUR(time),
4018 TIME_GET_MINUTE(time),
4019 TIME_GET_SECOND(time),
4020 TIME_GET_MICROSECOND(time),
4021 tzinfo);
4022 }
4023 return result;
4024 }
4025
4026 /*
4027 * Destructor.
4028 */
4029
4030 static void
datetime_dealloc(PyDateTime_DateTime * self)4031 datetime_dealloc(PyDateTime_DateTime *self)
4032 {
4033 if (HASTZINFO(self)) {
4034 Py_XDECREF(self->tzinfo);
4035 }
4036 Py_TYPE(self)->tp_free((PyObject *)self);
4037 }
4038
4039 /*
4040 * Indirect access to tzinfo methods.
4041 */
4042
4043 /* These are all METH_NOARGS, so don't need to check the arglist. */
4044 static PyObject *
datetime_utcoffset(PyDateTime_DateTime * self,PyObject * unused)4045 datetime_utcoffset(PyDateTime_DateTime *self, PyObject *unused) {
4046 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4047 "utcoffset", (PyObject *)self);
4048 }
4049
4050 static PyObject *
datetime_dst(PyDateTime_DateTime * self,PyObject * unused)4051 datetime_dst(PyDateTime_DateTime *self, PyObject *unused) {
4052 return offset_as_timedelta(HASTZINFO(self) ? self->tzinfo : Py_None,
4053 "dst", (PyObject *)self);
4054 }
4055
4056 static PyObject *
datetime_tzname(PyDateTime_DateTime * self,PyObject * unused)4057 datetime_tzname(PyDateTime_DateTime *self, PyObject *unused) {
4058 return call_tzname(HASTZINFO(self) ? self->tzinfo : Py_None,
4059 (PyObject *)self);
4060 }
4061
4062 /*
4063 * datetime arithmetic.
4064 */
4065
4066 /* factor must be 1 (to add) or -1 (to subtract). The result inherits
4067 * the tzinfo state of date.
4068 */
4069 static PyObject *
add_datetime_timedelta(PyDateTime_DateTime * date,PyDateTime_Delta * delta,int factor)4070 add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4071 int factor)
4072 {
4073 /* Note that the C-level additions can't overflow, because of
4074 * invariant bounds on the member values.
4075 */
4076 int year = GET_YEAR(date);
4077 int month = GET_MONTH(date);
4078 int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4079 int hour = DATE_GET_HOUR(date);
4080 int minute = DATE_GET_MINUTE(date);
4081 int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4082 int microsecond = DATE_GET_MICROSECOND(date) +
4083 GET_TD_MICROSECONDS(delta) * factor;
4084
4085 assert(factor == 1 || factor == -1);
4086 if (normalize_datetime(&year, &month, &day,
4087 &hour, &minute, &second, µsecond) < 0)
4088 return NULL;
4089 else
4090 return new_datetime(year, month, day,
4091 hour, minute, second, microsecond,
4092 HASTZINFO(date) ? date->tzinfo : Py_None);
4093 }
4094
4095 static PyObject *
datetime_add(PyObject * left,PyObject * right)4096 datetime_add(PyObject *left, PyObject *right)
4097 {
4098 if (PyDateTime_Check(left)) {
4099 /* datetime + ??? */
4100 if (PyDelta_Check(right))
4101 /* datetime + delta */
4102 return add_datetime_timedelta(
4103 (PyDateTime_DateTime *)left,
4104 (PyDateTime_Delta *)right,
4105 1);
4106 }
4107 else if (PyDelta_Check(left)) {
4108 /* delta + datetime */
4109 return add_datetime_timedelta((PyDateTime_DateTime *) right,
4110 (PyDateTime_Delta *) left,
4111 1);
4112 }
4113 Py_INCREF(Py_NotImplemented);
4114 return Py_NotImplemented;
4115 }
4116
4117 static PyObject *
datetime_subtract(PyObject * left,PyObject * right)4118 datetime_subtract(PyObject *left, PyObject *right)
4119 {
4120 PyObject *result = Py_NotImplemented;
4121
4122 if (PyDateTime_Check(left)) {
4123 /* datetime - ??? */
4124 if (PyDateTime_Check(right)) {
4125 /* datetime - datetime */
4126 naivety n1, n2;
4127 int offset1, offset2;
4128 int delta_d, delta_s, delta_us;
4129
4130 if (classify_two_utcoffsets(left, &offset1, &n1, left,
4131 right, &offset2, &n2,
4132 right) < 0)
4133 return NULL;
4134 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4135 if (n1 != n2) {
4136 PyErr_SetString(PyExc_TypeError,
4137 "can't subtract offset-naive and "
4138 "offset-aware datetimes");
4139 return NULL;
4140 }
4141 delta_d = ymd_to_ord(GET_YEAR(left),
4142 GET_MONTH(left),
4143 GET_DAY(left)) -
4144 ymd_to_ord(GET_YEAR(right),
4145 GET_MONTH(right),
4146 GET_DAY(right));
4147 /* These can't overflow, since the values are
4148 * normalized. At most this gives the number of
4149 * seconds in one day.
4150 */
4151 delta_s = (DATE_GET_HOUR(left) -
4152 DATE_GET_HOUR(right)) * 3600 +
4153 (DATE_GET_MINUTE(left) -
4154 DATE_GET_MINUTE(right)) * 60 +
4155 (DATE_GET_SECOND(left) -
4156 DATE_GET_SECOND(right));
4157 delta_us = DATE_GET_MICROSECOND(left) -
4158 DATE_GET_MICROSECOND(right);
4159 /* (left - offset1) - (right - offset2) =
4160 * (left - right) + (offset2 - offset1)
4161 */
4162 delta_s += (offset2 - offset1) * 60;
4163 result = new_delta(delta_d, delta_s, delta_us, 1);
4164 }
4165 else if (PyDelta_Check(right)) {
4166 /* datetime - delta */
4167 result = add_datetime_timedelta(
4168 (PyDateTime_DateTime *)left,
4169 (PyDateTime_Delta *)right,
4170 -1);
4171 }
4172 }
4173
4174 if (result == Py_NotImplemented)
4175 Py_INCREF(result);
4176 return result;
4177 }
4178
4179 /* Various ways to turn a datetime into a string. */
4180
4181 static PyObject *
datetime_repr(PyDateTime_DateTime * self)4182 datetime_repr(PyDateTime_DateTime *self)
4183 {
4184 char buffer[1000];
4185 const char *type_name = Py_TYPE(self)->tp_name;
4186 PyObject *baserepr;
4187
4188 if (DATE_GET_MICROSECOND(self)) {
4189 PyOS_snprintf(buffer, sizeof(buffer),
4190 "%s(%d, %d, %d, %d, %d, %d, %d)",
4191 type_name,
4192 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4193 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4194 DATE_GET_SECOND(self),
4195 DATE_GET_MICROSECOND(self));
4196 }
4197 else if (DATE_GET_SECOND(self)) {
4198 PyOS_snprintf(buffer, sizeof(buffer),
4199 "%s(%d, %d, %d, %d, %d, %d)",
4200 type_name,
4201 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4202 DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4203 DATE_GET_SECOND(self));
4204 }
4205 else {
4206 PyOS_snprintf(buffer, sizeof(buffer),
4207 "%s(%d, %d, %d, %d, %d)",
4208 type_name,
4209 GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4210 DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4211 }
4212 baserepr = PyString_FromString(buffer);
4213 if (baserepr == NULL || ! HASTZINFO(self))
4214 return baserepr;
4215 return append_keyword_tzinfo(baserepr, self->tzinfo);
4216 }
4217
4218 static PyObject *
datetime_str(PyDateTime_DateTime * self)4219 datetime_str(PyDateTime_DateTime *self)
4220 {
4221 return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
4222 }
4223
4224 static PyObject *
datetime_isoformat(PyDateTime_DateTime * self,PyObject * args,PyObject * kw)4225 datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4226 {
4227 char sep = 'T';
4228 static char *keywords[] = {"sep", NULL};
4229 char buffer[100];
4230 char *cp;
4231 PyObject *result;
4232
4233 if (!PyArg_ParseTupleAndKeywords(args, kw, "|c:isoformat", keywords,
4234 &sep))
4235 return NULL;
4236 cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer));
4237 assert(cp != NULL);
4238 *cp++ = sep;
4239 cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer));
4240 result = PyString_FromStringAndSize(buffer, cp - buffer);
4241 if (result == NULL || ! HASTZINFO(self))
4242 return result;
4243
4244 /* We need to append the UTC offset. */
4245 if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4246 (PyObject *)self) < 0) {
4247 Py_DECREF(result);
4248 return NULL;
4249 }
4250 PyString_ConcatAndDel(&result, PyString_FromString(buffer));
4251 return result;
4252 }
4253
4254 static PyObject *
datetime_ctime(PyDateTime_DateTime * self)4255 datetime_ctime(PyDateTime_DateTime *self)
4256 {
4257 return format_ctime((PyDateTime_Date *)self,
4258 DATE_GET_HOUR(self),
4259 DATE_GET_MINUTE(self),
4260 DATE_GET_SECOND(self));
4261 }
4262
4263 /* Miscellaneous methods. */
4264
4265 /* This is more natural as a tp_compare, but doesn't work then: for whatever
4266 * reason, Python's try_3way_compare ignores tp_compare unless
4267 * PyInstance_Check returns true, but these aren't old-style classes.
4268 */
4269 static PyObject *
datetime_richcompare(PyDateTime_DateTime * self,PyObject * other,int op)4270 datetime_richcompare(PyDateTime_DateTime *self, PyObject *other, int op)
4271 {
4272 int diff;
4273 naivety n1, n2;
4274 int offset1, offset2;
4275
4276 if (! PyDateTime_Check(other)) {
4277 /* If other has a "timetuple" attr, that's an advertised
4278 * hook for other classes to ask to get comparison control.
4279 * However, date instances have a timetuple attr, and we
4280 * don't want to allow that comparison. Because datetime
4281 * is a subclass of date, when mixing date and datetime
4282 * in a comparison, Python gives datetime the first shot
4283 * (it's the more specific subtype). So we can stop that
4284 * combination here reliably.
4285 */
4286 if (PyObject_HasAttrString(other, "timetuple") &&
4287 ! PyDate_Check(other)) {
4288 /* A hook for other kinds of datetime objects. */
4289 Py_INCREF(Py_NotImplemented);
4290 return Py_NotImplemented;
4291 }
4292 if (op == Py_EQ || op == Py_NE) {
4293 PyObject *result = op == Py_EQ ? Py_False : Py_True;
4294 Py_INCREF(result);
4295 return result;
4296 }
4297 /* Stop this from falling back to address comparison. */
4298 return cmperror((PyObject *)self, other);
4299 }
4300
4301 if (classify_two_utcoffsets((PyObject *)self, &offset1, &n1,
4302 (PyObject *)self,
4303 other, &offset2, &n2,
4304 other) < 0)
4305 return NULL;
4306 assert(n1 != OFFSET_UNKNOWN && n2 != OFFSET_UNKNOWN);
4307 /* If they're both naive, or both aware and have the same offsets,
4308 * we get off cheap. Note that if they're both naive, offset1 ==
4309 * offset2 == 0 at this point.
4310 */
4311 if (n1 == n2 && offset1 == offset2) {
4312 diff = memcmp(self->data, ((PyDateTime_DateTime *)other)->data,
4313 _PyDateTime_DATETIME_DATASIZE);
4314 return diff_to_bool(diff, op);
4315 }
4316
4317 if (n1 == OFFSET_AWARE && n2 == OFFSET_AWARE) {
4318 PyDateTime_Delta *delta;
4319
4320 assert(offset1 != offset2); /* else last "if" handled it */
4321 delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4322 other);
4323 if (delta == NULL)
4324 return NULL;
4325 diff = GET_TD_DAYS(delta);
4326 if (diff == 0)
4327 diff = GET_TD_SECONDS(delta) |
4328 GET_TD_MICROSECONDS(delta);
4329 Py_DECREF(delta);
4330 return diff_to_bool(diff, op);
4331 }
4332
4333 assert(n1 != n2);
4334 PyErr_SetString(PyExc_TypeError,
4335 "can't compare offset-naive and "
4336 "offset-aware datetimes");
4337 return NULL;
4338 }
4339
4340 static long
datetime_hash(PyDateTime_DateTime * self)4341 datetime_hash(PyDateTime_DateTime *self)
4342 {
4343 if (self->hashcode == -1) {
4344 naivety n;
4345 int offset;
4346 PyObject *temp;
4347
4348 n = classify_utcoffset((PyObject *)self, (PyObject *)self,
4349 &offset);
4350 assert(n != OFFSET_UNKNOWN);
4351 if (n == OFFSET_ERROR)
4352 return -1;
4353
4354 /* Reduce this to a hash of another object. */
4355 if (n == OFFSET_NAIVE)
4356 temp = PyString_FromStringAndSize(
4357 (char *)self->data,
4358 _PyDateTime_DATETIME_DATASIZE);
4359 else {
4360 int days;
4361 int seconds;
4362
4363 assert(n == OFFSET_AWARE);
4364 assert(HASTZINFO(self));
4365 days = ymd_to_ord(GET_YEAR(self),
4366 GET_MONTH(self),
4367 GET_DAY(self));
4368 seconds = DATE_GET_HOUR(self) * 3600 +
4369 (DATE_GET_MINUTE(self) - offset) * 60 +
4370 DATE_GET_SECOND(self);
4371 temp = new_delta(days,
4372 seconds,
4373 DATE_GET_MICROSECOND(self),
4374 1);
4375 }
4376 if (temp != NULL) {
4377 self->hashcode = PyObject_Hash(temp);
4378 Py_DECREF(temp);
4379 }
4380 }
4381 return self->hashcode;
4382 }
4383
4384 static PyObject *
datetime_replace(PyDateTime_DateTime * self,PyObject * args,PyObject * kw)4385 datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4386 {
4387 PyObject *clone;
4388 PyObject *tuple;
4389 int y = GET_YEAR(self);
4390 int m = GET_MONTH(self);
4391 int d = GET_DAY(self);
4392 int hh = DATE_GET_HOUR(self);
4393 int mm = DATE_GET_MINUTE(self);
4394 int ss = DATE_GET_SECOND(self);
4395 int us = DATE_GET_MICROSECOND(self);
4396 PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
4397
4398 if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO:replace",
4399 datetime_kws,
4400 &y, &m, &d, &hh, &mm, &ss, &us,
4401 &tzinfo))
4402 return NULL;
4403 tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
4404 if (tuple == NULL)
4405 return NULL;
4406 clone = datetime_new(Py_TYPE(self), tuple, NULL);
4407 Py_DECREF(tuple);
4408 return clone;
4409 }
4410
4411 static PyObject *
datetime_astimezone(PyDateTime_DateTime * self,PyObject * args,PyObject * kw)4412 datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4413 {
4414 int y, m, d, hh, mm, ss, us;
4415 PyObject *result;
4416 int offset, none;
4417
4418 PyObject *tzinfo;
4419 static char *keywords[] = {"tz", NULL};
4420
4421 if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
4422 &PyDateTime_TZInfoType, &tzinfo))
4423 return NULL;
4424
4425 if (!HASTZINFO(self) || self->tzinfo == Py_None)
4426 goto NeedAware;
4427
4428 /* Conversion to self's own time zone is a NOP. */
4429 if (self->tzinfo == tzinfo) {
4430 Py_INCREF(self);
4431 return (PyObject *)self;
4432 }
4433
4434 /* Convert self to UTC. */
4435 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4436 if (offset == -1 && PyErr_Occurred())
4437 return NULL;
4438 if (none)
4439 goto NeedAware;
4440
4441 y = GET_YEAR(self);
4442 m = GET_MONTH(self);
4443 d = GET_DAY(self);
4444 hh = DATE_GET_HOUR(self);
4445 mm = DATE_GET_MINUTE(self);
4446 ss = DATE_GET_SECOND(self);
4447 us = DATE_GET_MICROSECOND(self);
4448
4449 mm -= offset;
4450 if ((mm < 0 || mm >= 60) &&
4451 normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us) < 0)
4452 return NULL;
4453
4454 /* Attach new tzinfo and let fromutc() do the rest. */
4455 result = new_datetime(y, m, d, hh, mm, ss, us, tzinfo);
4456 if (result != NULL) {
4457 PyObject *temp = result;
4458
4459 result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
4460 Py_DECREF(temp);
4461 }
4462 return result;
4463
4464 NeedAware:
4465 PyErr_SetString(PyExc_ValueError, "astimezone() cannot be applied to "
4466 "a naive datetime");
4467 return NULL;
4468 }
4469
4470 static PyObject *
datetime_timetuple(PyDateTime_DateTime * self)4471 datetime_timetuple(PyDateTime_DateTime *self)
4472 {
4473 int dstflag = -1;
4474
4475 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4476 int none;
4477
4478 dstflag = call_dst(self->tzinfo, (PyObject *)self, &none);
4479 if (dstflag == -1 && PyErr_Occurred())
4480 return NULL;
4481
4482 if (none)
4483 dstflag = -1;
4484 else if (dstflag != 0)
4485 dstflag = 1;
4486
4487 }
4488 return build_struct_time(GET_YEAR(self),
4489 GET_MONTH(self),
4490 GET_DAY(self),
4491 DATE_GET_HOUR(self),
4492 DATE_GET_MINUTE(self),
4493 DATE_GET_SECOND(self),
4494 dstflag);
4495 }
4496
4497 static PyObject *
datetime_getdate(PyDateTime_DateTime * self)4498 datetime_getdate(PyDateTime_DateTime *self)
4499 {
4500 return new_date(GET_YEAR(self),
4501 GET_MONTH(self),
4502 GET_DAY(self));
4503 }
4504
4505 static PyObject *
datetime_gettime(PyDateTime_DateTime * self)4506 datetime_gettime(PyDateTime_DateTime *self)
4507 {
4508 return new_time(DATE_GET_HOUR(self),
4509 DATE_GET_MINUTE(self),
4510 DATE_GET_SECOND(self),
4511 DATE_GET_MICROSECOND(self),
4512 Py_None);
4513 }
4514
4515 static PyObject *
datetime_gettimetz(PyDateTime_DateTime * self)4516 datetime_gettimetz(PyDateTime_DateTime *self)
4517 {
4518 return new_time(DATE_GET_HOUR(self),
4519 DATE_GET_MINUTE(self),
4520 DATE_GET_SECOND(self),
4521 DATE_GET_MICROSECOND(self),
4522 HASTZINFO(self) ? self->tzinfo : Py_None);
4523 }
4524
4525 static PyObject *
datetime_utctimetuple(PyDateTime_DateTime * self)4526 datetime_utctimetuple(PyDateTime_DateTime *self)
4527 {
4528 int y = GET_YEAR(self);
4529 int m = GET_MONTH(self);
4530 int d = GET_DAY(self);
4531 int hh = DATE_GET_HOUR(self);
4532 int mm = DATE_GET_MINUTE(self);
4533 int ss = DATE_GET_SECOND(self);
4534 int us = 0; /* microseconds are ignored in a timetuple */
4535 int offset = 0;
4536
4537 if (HASTZINFO(self) && self->tzinfo != Py_None) {
4538 int none;
4539
4540 offset = call_utcoffset(self->tzinfo, (PyObject *)self, &none);
4541 if (offset == -1 && PyErr_Occurred())
4542 return NULL;
4543 }
4544 /* Even if offset is 0, don't call timetuple() -- tm_isdst should be
4545 * 0 in a UTC timetuple regardless of what dst() says.
4546 */
4547 if (offset) {
4548 /* Subtract offset minutes & normalize. */
4549 int stat;
4550
4551 mm -= offset;
4552 stat = normalize_datetime(&y, &m, &d, &hh, &mm, &ss, &us);
4553 if (stat < 0) {
4554 /* At the edges, it's possible we overflowed
4555 * beyond MINYEAR or MAXYEAR.
4556 */
4557 if (PyErr_ExceptionMatches(PyExc_OverflowError))
4558 PyErr_Clear();
4559 else
4560 return NULL;
4561 }
4562 }
4563 return build_struct_time(y, m, d, hh, mm, ss, 0);
4564 }
4565
4566 /* Pickle support, a simple use of __reduce__. */
4567
4568 /* Let basestate be the non-tzinfo data string.
4569 * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
4570 * So it's a tuple in any (non-error) case.
4571 * __getstate__ isn't exposed.
4572 */
4573 static PyObject *
datetime_getstate(PyDateTime_DateTime * self)4574 datetime_getstate(PyDateTime_DateTime *self)
4575 {
4576 PyObject *basestate;
4577 PyObject *result = NULL;
4578
4579 basestate = PyString_FromStringAndSize((char *)self->data,
4580 _PyDateTime_DATETIME_DATASIZE);
4581 if (basestate != NULL) {
4582 if (! HASTZINFO(self) || self->tzinfo == Py_None)
4583 result = PyTuple_Pack(1, basestate);
4584 else
4585 result = PyTuple_Pack(2, basestate, self->tzinfo);
4586 Py_DECREF(basestate);
4587 }
4588 return result;
4589 }
4590
4591 static PyObject *
datetime_reduce(PyDateTime_DateTime * self,PyObject * arg)4592 datetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
4593 {
4594 return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self));
4595 }
4596
4597 static PyMethodDef datetime_methods[] = {
4598
4599 /* Class methods: */
4600
4601 {"now", (PyCFunction)datetime_now,
4602 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4603 PyDoc_STR("[tz] -> new datetime with tz's local day and time.")},
4604
4605 {"utcnow", (PyCFunction)datetime_utcnow,
4606 METH_NOARGS | METH_CLASS,
4607 PyDoc_STR("Return a new datetime representing UTC day and time.")},
4608
4609 {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
4610 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4611 PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
4612
4613 {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
4614 METH_VARARGS | METH_CLASS,
4615 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
4616 "(like time.time()).")},
4617
4618 {"strptime", (PyCFunction)datetime_strptime,
4619 METH_VARARGS | METH_CLASS,
4620 PyDoc_STR("string, format -> new datetime parsed from a string "
4621 "(like time.strptime()).")},
4622
4623 {"combine", (PyCFunction)datetime_combine,
4624 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
4625 PyDoc_STR("date, time -> datetime with same date and time fields")},
4626
4627 /* Instance methods: */
4628
4629 {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
4630 PyDoc_STR("Return date object with same year, month and day.")},
4631
4632 {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
4633 PyDoc_STR("Return time object with same time but with tzinfo=None.")},
4634
4635 {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
4636 PyDoc_STR("Return time object with same time and tzinfo.")},
4637
4638 {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
4639 PyDoc_STR("Return ctime() style string.")},
4640
4641 {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
4642 PyDoc_STR("Return time tuple, compatible with time.localtime().")},
4643
4644 {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
4645 PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
4646
4647 {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
4648 PyDoc_STR("[sep] -> string in ISO 8601 format, "
4649 "YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM].\n\n"
4650 "sep is used to separate the year from the time, and "
4651 "defaults to 'T'.")},
4652
4653 {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
4654 PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4655
4656 {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
4657 PyDoc_STR("Return self.tzinfo.tzname(self).")},
4658
4659 {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
4660 PyDoc_STR("Return self.tzinfo.dst(self).")},
4661
4662 {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
4663 PyDoc_STR("Return datetime with new specified fields.")},
4664
4665 {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
4666 PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
4667
4668 {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
4669 PyDoc_STR("__reduce__() -> (cls, state)")},
4670
4671 {NULL, NULL}
4672 };
4673
4674 static char datetime_doc[] =
4675 PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
4676 \n\
4677 The year, month and day arguments are required. tzinfo may be None, or an\n\
4678 instance of a tzinfo subclass. The remaining arguments may be ints or longs.\n");
4679
4680 static PyNumberMethods datetime_as_number = {
4681 datetime_add, /* nb_add */
4682 datetime_subtract, /* nb_subtract */
4683 0, /* nb_multiply */
4684 0, /* nb_divide */
4685 0, /* nb_remainder */
4686 0, /* nb_divmod */
4687 0, /* nb_power */
4688 0, /* nb_negative */
4689 0, /* nb_positive */
4690 0, /* nb_absolute */
4691 0, /* nb_nonzero */
4692 };
4693
4694 statichere PyTypeObject PyDateTime_DateTimeType = {
4695 PyObject_HEAD_INIT(NULL)
4696 0, /* ob_size */
4697 "datetime.datetime", /* tp_name */
4698 sizeof(PyDateTime_DateTime), /* tp_basicsize */
4699 0, /* tp_itemsize */
4700 (destructor)datetime_dealloc, /* tp_dealloc */
4701 0, /* tp_print */
4702 0, /* tp_getattr */
4703 0, /* tp_setattr */
4704 0, /* tp_compare */
4705 (reprfunc)datetime_repr, /* tp_repr */
4706 &datetime_as_number, /* tp_as_number */
4707 0, /* tp_as_sequence */
4708 0, /* tp_as_mapping */
4709 (hashfunc)datetime_hash, /* tp_hash */
4710 0, /* tp_call */
4711 (reprfunc)datetime_str, /* tp_str */
4712 PyObject_GenericGetAttr, /* tp_getattro */
4713 0, /* tp_setattro */
4714 0, /* tp_as_buffer */
4715 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
4716 Py_TPFLAGS_BASETYPE, /* tp_flags */
4717 datetime_doc, /* tp_doc */
4718 0, /* tp_traverse */
4719 0, /* tp_clear */
4720 (richcmpfunc)datetime_richcompare, /* tp_richcompare */
4721 0, /* tp_weaklistoffset */
4722 0, /* tp_iter */
4723 0, /* tp_iternext */
4724 datetime_methods, /* tp_methods */
4725 0, /* tp_members */
4726 datetime_getset, /* tp_getset */
4727 &PyDateTime_DateType, /* tp_base */
4728 0, /* tp_dict */
4729 0, /* tp_descr_get */
4730 0, /* tp_descr_set */
4731 0, /* tp_dictoffset */
4732 0, /* tp_init */
4733 datetime_alloc, /* tp_alloc */
4734 datetime_new, /* tp_new */
4735 0, /* tp_free */
4736 };
4737
4738 /* ---------------------------------------------------------------------------
4739 * Module methods and initialization.
4740 */
4741
4742 static PyMethodDef module_methods[] = {
4743 {NULL, NULL}
4744 };
4745
4746 /* C API. Clients get at this via PyDateTime_IMPORT, defined in
4747 * datetime.h.
4748 */
4749 static PyDateTime_CAPI CAPI = {
4750 &PyDateTime_DateType,
4751 &PyDateTime_DateTimeType,
4752 &PyDateTime_TimeType,
4753 &PyDateTime_DeltaType,
4754 &PyDateTime_TZInfoType,
4755 new_date_ex,
4756 new_datetime_ex,
4757 new_time_ex,
4758 new_delta_ex,
4759 datetime_fromtimestamp,
4760 date_fromtimestamp
4761 };
4762
4763
4764 PyMODINIT_FUNC
initdatetime(void)4765 initdatetime(void)
4766 {
4767 PyObject *m; /* a module object */
4768 PyObject *d; /* its dict */
4769 PyObject *x;
4770
4771 m = Py_InitModule3("datetime", module_methods,
4772 "Fast implementation of the datetime type.");
4773 if (m == NULL)
4774 return;
4775
4776 if (PyType_Ready(&PyDateTime_DateType) < 0)
4777 return;
4778 if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
4779 return;
4780 if (PyType_Ready(&PyDateTime_DeltaType) < 0)
4781 return;
4782 if (PyType_Ready(&PyDateTime_TimeType) < 0)
4783 return;
4784 if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
4785 return;
4786
4787 /* timedelta values */
4788 d = PyDateTime_DeltaType.tp_dict;
4789
4790 x = new_delta(0, 0, 1, 0);
4791 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4792 return;
4793 Py_DECREF(x);
4794
4795 x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
4796 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4797 return;
4798 Py_DECREF(x);
4799
4800 x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
4801 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4802 return;
4803 Py_DECREF(x);
4804
4805 /* date values */
4806 d = PyDateTime_DateType.tp_dict;
4807
4808 x = new_date(1, 1, 1);
4809 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4810 return;
4811 Py_DECREF(x);
4812
4813 x = new_date(MAXYEAR, 12, 31);
4814 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4815 return;
4816 Py_DECREF(x);
4817
4818 x = new_delta(1, 0, 0, 0);
4819 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4820 return;
4821 Py_DECREF(x);
4822
4823 /* time values */
4824 d = PyDateTime_TimeType.tp_dict;
4825
4826 x = new_time(0, 0, 0, 0, Py_None);
4827 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4828 return;
4829 Py_DECREF(x);
4830
4831 x = new_time(23, 59, 59, 999999, Py_None);
4832 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4833 return;
4834 Py_DECREF(x);
4835
4836 x = new_delta(0, 0, 1, 0);
4837 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4838 return;
4839 Py_DECREF(x);
4840
4841 /* datetime values */
4842 d = PyDateTime_DateTimeType.tp_dict;
4843
4844 x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
4845 if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
4846 return;
4847 Py_DECREF(x);
4848
4849 x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
4850 if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
4851 return;
4852 Py_DECREF(x);
4853
4854 x = new_delta(0, 0, 1, 0);
4855 if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
4856 return;
4857 Py_DECREF(x);
4858
4859 /* module initialization */
4860 PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
4861 PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR);
4862
4863 Py_INCREF(&PyDateTime_DateType);
4864 PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
4865
4866 Py_INCREF(&PyDateTime_DateTimeType);
4867 PyModule_AddObject(m, "datetime",
4868 (PyObject *)&PyDateTime_DateTimeType);
4869
4870 Py_INCREF(&PyDateTime_TimeType);
4871 PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
4872
4873 Py_INCREF(&PyDateTime_DeltaType);
4874 PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
4875
4876 Py_INCREF(&PyDateTime_TZInfoType);
4877 PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
4878
4879 x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
4880 if (x == NULL)
4881 return;
4882 PyModule_AddObject(m, "datetime_CAPI", x);
4883
4884 /* A 4-year cycle has an extra leap day over what we'd get from
4885 * pasting together 4 single years.
4886 */
4887 assert(DI4Y == 4 * 365 + 1);
4888 assert(DI4Y == days_before_year(4+1));
4889
4890 /* Similarly, a 400-year cycle has an extra leap day over what we'd
4891 * get from pasting together 4 100-year cycles.
4892 */
4893 assert(DI400Y == 4 * DI100Y + 1);
4894 assert(DI400Y == days_before_year(400+1));
4895
4896 /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
4897 * pasting together 25 4-year cycles.
4898 */
4899 assert(DI100Y == 25 * DI4Y - 1);
4900 assert(DI100Y == days_before_year(100+1));
4901
4902 us_per_us = PyInt_FromLong(1);
4903 us_per_ms = PyInt_FromLong(1000);
4904 us_per_second = PyInt_FromLong(1000000);
4905 us_per_minute = PyInt_FromLong(60000000);
4906 seconds_per_day = PyInt_FromLong(24 * 3600);
4907 if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
4908 us_per_minute == NULL || seconds_per_day == NULL)
4909 return;
4910
4911 /* The rest are too big for 32-bit ints, but even
4912 * us_per_week fits in 40 bits, so doubles should be exact.
4913 */
4914 us_per_hour = PyLong_FromDouble(3600000000.0);
4915 us_per_day = PyLong_FromDouble(86400000000.0);
4916 us_per_week = PyLong_FromDouble(604800000000.0);
4917 if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
4918 return;
4919 }
4920
4921 /* ---------------------------------------------------------------------------
4922 Some time zone algebra. For a datetime x, let
4923 x.n = x stripped of its timezone -- its naive time.
4924 x.o = x.utcoffset(), and assuming that doesn't raise an exception or
4925 return None
4926 x.d = x.dst(), and assuming that doesn't raise an exception or
4927 return None
4928 x.s = x's standard offset, x.o - x.d
4929
4930 Now some derived rules, where k is a duration (timedelta).
4931
4932 1. x.o = x.s + x.d
4933 This follows from the definition of x.s.
4934
4935 2. If x and y have the same tzinfo member, x.s = y.s.
4936 This is actually a requirement, an assumption we need to make about
4937 sane tzinfo classes.
4938
4939 3. The naive UTC time corresponding to x is x.n - x.o.
4940 This is again a requirement for a sane tzinfo class.
4941
4942 4. (x+k).s = x.s
4943 This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
4944
4945 5. (x+k).n = x.n + k
4946 Again follows from how arithmetic is defined.
4947
4948 Now we can explain tz.fromutc(x). Let's assume it's an interesting case
4949 (meaning that the various tzinfo methods exist, and don't blow up or return
4950 None when called).
4951
4952 The function wants to return a datetime y with timezone tz, equivalent to x.
4953 x is already in UTC.
4954
4955 By #3, we want
4956
4957 y.n - y.o = x.n [1]
4958
4959 The algorithm starts by attaching tz to x.n, and calling that y. So
4960 x.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
4961 becomes true; in effect, we want to solve [2] for k:
4962
4963 (y+k).n - (y+k).o = x.n [2]
4964
4965 By #1, this is the same as
4966
4967 (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
4968
4969 By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
4970 Substituting that into [3],
4971
4972 x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
4973 k - (y+k).s - (y+k).d = 0; rearranging,
4974 k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
4975 k = y.s - (y+k).d
4976
4977 On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
4978 approximate k by ignoring the (y+k).d term at first. Note that k can't be
4979 very large, since all offset-returning methods return a duration of magnitude
4980 less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
4981 be 0, so ignoring it has no consequence then.
4982
4983 In any case, the new value is
4984
4985 z = y + y.s [4]
4986
4987 It's helpful to step back at look at [4] from a higher level: it's simply
4988 mapping from UTC to tz's standard time.
4989
4990 At this point, if
4991
4992 z.n - z.o = x.n [5]
4993
4994 we have an equivalent time, and are almost done. The insecurity here is
4995 at the start of daylight time. Picture US Eastern for concreteness. The wall
4996 time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
4997 sense then. The docs ask that an Eastern tzinfo class consider such a time to
4998 be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
4999 on the day DST starts. We want to return the 1:MM EST spelling because that's
5000 the only spelling that makes sense on the local wall clock.
5001
5002 In fact, if [5] holds at this point, we do have the standard-time spelling,
5003 but that takes a bit of proof. We first prove a stronger result. What's the
5004 difference between the LHS and RHS of [5]? Let
5005
5006 diff = x.n - (z.n - z.o) [6]
5007
5008 Now
5009 z.n = by [4]
5010 (y + y.s).n = by #5
5011 y.n + y.s = since y.n = x.n
5012 x.n + y.s = since z and y are have the same tzinfo member,
5013 y.s = z.s by #2
5014 x.n + z.s
5015
5016 Plugging that back into [6] gives
5017
5018 diff =
5019 x.n - ((x.n + z.s) - z.o) = expanding
5020 x.n - x.n - z.s + z.o = cancelling
5021 - z.s + z.o = by #2
5022 z.d
5023
5024 So diff = z.d.
5025
5026 If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
5027 spelling we wanted in the endcase described above. We're done. Contrarily,
5028 if z.d = 0, then we have a UTC equivalent, and are also done.
5029
5030 If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5031 add to z (in effect, z is in tz's standard time, and we need to shift the
5032 local clock into tz's daylight time).
5033
5034 Let
5035
5036 z' = z + z.d = z + diff [7]
5037
5038 and we can again ask whether
5039
5040 z'.n - z'.o = x.n [8]
5041
5042 If so, we're done. If not, the tzinfo class is insane, according to the
5043 assumptions we've made. This also requires a bit of proof. As before, let's
5044 compute the difference between the LHS and RHS of [8] (and skipping some of
5045 the justifications for the kinds of substitutions we've done several times
5046 already):
5047
5048 diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5049 x.n - (z.n + diff - z'.o) = replacing diff via [6]
5050 x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5051 x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5052 - z.n + z.n - z.o + z'.o = cancel z.n
5053 - z.o + z'.o = #1 twice
5054 -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5055 z'.d - z.d
5056
5057 So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
5058 we've found the UTC-equivalent so are done. In fact, we stop with [7] and
5059 return z', not bothering to compute z'.d.
5060
5061 How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
5062 a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
5063 would have to change the result dst() returns: we start in DST, and moving
5064 a little further into it takes us out of DST.
5065
5066 There isn't a sane case where this can happen. The closest it gets is at
5067 the end of DST, where there's an hour in UTC with no spelling in a hybrid
5068 tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
5069 that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
5070 UTC) because the docs insist on that, but 0:MM is taken as being in daylight
5071 time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
5072 clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
5073 standard time. Since that's what the local clock *does*, we want to map both
5074 UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
5075 in local time, but so it goes -- it's the way the local clock works.
5076
5077 When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
5078 so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
5079 z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
5080 (correctly) concludes that z' is not UTC-equivalent to x.
5081
5082 Because we know z.d said z was in daylight time (else [5] would have held and
5083 we would have stopped then), and we know z.d != z'.d (else [8] would have held
5084 and we would have stopped then), and there are only 2 possible values dst() can
5085 return in Eastern, it follows that z'.d must be 0 (which it is in the example,
5086 but the reasoning doesn't depend on the example -- it depends on there being
5087 two possible dst() outcomes, one zero and the other non-zero). Therefore
5088 z' must be in standard time, and is the spelling we want in this case.
5089
5090 Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
5091 concerned (because it takes z' as being in standard time rather than the
5092 daylight time we intend here), but returning it gives the real-life "local
5093 clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
5094 tz.
5095
5096 When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
5097 the 1:MM standard time spelling we want.
5098
5099 So how can this break? One of the assumptions must be violated. Two
5100 possibilities:
5101
5102 1) [2] effectively says that y.s is invariant across all y belong to a given
5103 time zone. This isn't true if, for political reasons or continental drift,
5104 a region decides to change its base offset from UTC.
5105
5106 2) There may be versions of "double daylight" time where the tail end of
5107 the analysis gives up a step too early. I haven't thought about that
5108 enough to say.
5109
5110 In any case, it's clear that the default fromutc() is strong enough to handle
5111 "almost all" time zones: so long as the standard offset is invariant, it
5112 doesn't matter if daylight time transition points change from year to year, or
5113 if daylight time is skipped in some years; it doesn't matter how large or
5114 small dst() may get within its bounds; and it doesn't even matter if some
5115 perverse time zone returns a negative dst()). So a breaking case must be
5116 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
5117 --------------------------------------------------------------------------- */
5118