ยปCore Development>Code coverage>Modules/_datetimemodule.c

Python code coverage for Modules/_datetimemodule.c

#countcontent
1n/a/* C implementation for the date/time type documented at
2n/a * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage
3n/a */
4n/a
5n/a#include "Python.h"
6n/a#include "structmember.h"
7n/a
8n/a#include <time.h>
9n/a
10n/a#ifdef MS_WINDOWS
11n/a# include <winsock2.h> /* struct timeval */
12n/a#endif
13n/a
14n/a/* Differentiate between building the core module and building extension
15n/a * modules.
16n/a */
17n/a#ifndef Py_BUILD_CORE
18n/a#define Py_BUILD_CORE
19n/a#endif
20n/a#include "datetime.h"
21n/a#undef Py_BUILD_CORE
22n/a
23n/a/*[clinic input]
24n/amodule datetime
25n/aclass datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
26n/a[clinic start generated code]*/
27n/a/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/
28n/a
29n/a#include "clinic/_datetimemodule.c.h"
30n/a
31n/a/* We require that C int be at least 32 bits, and use int virtually
32n/a * everywhere. In just a few cases we use a temp long, where a Python
33n/a * API returns a C long. In such cases, we have to ensure that the
34n/a * final result fits in a C int (this can be an issue on 64-bit boxes).
35n/a */
36n/a#if SIZEOF_INT < 4
37n/a# error "_datetime.c requires that C int have at least 32 bits"
38n/a#endif
39n/a
40n/a#define MINYEAR 1
41n/a#define MAXYEAR 9999
42n/a#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
43n/a
44n/a/* Nine decimal digits is easy to communicate, and leaves enough room
45n/a * so that two delta days can be added w/o fear of overflowing a signed
46n/a * 32-bit int, and with plenty of room left over to absorb any possible
47n/a * carries from adding seconds.
48n/a */
49n/a#define MAX_DELTA_DAYS 999999999
50n/a
51n/a/* Rename the long macros in datetime.h to more reasonable short names. */
52n/a#define GET_YEAR PyDateTime_GET_YEAR
53n/a#define GET_MONTH PyDateTime_GET_MONTH
54n/a#define GET_DAY PyDateTime_GET_DAY
55n/a#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR
56n/a#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE
57n/a#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND
58n/a#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND
59n/a#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD
60n/a
61n/a/* Date accessors for date and datetime. */
62n/a#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \
63n/a ((o)->data[1] = ((v) & 0x00ff)))
64n/a#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v))
65n/a#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v))
66n/a
67n/a/* Date/Time accessors for datetime. */
68n/a#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v))
69n/a#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v))
70n/a#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v))
71n/a#define DATE_SET_MICROSECOND(o, v) \
72n/a (((o)->data[7] = ((v) & 0xff0000) >> 16), \
73n/a ((o)->data[8] = ((v) & 0x00ff00) >> 8), \
74n/a ((o)->data[9] = ((v) & 0x0000ff)))
75n/a#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v))
76n/a
77n/a/* Time accessors for time. */
78n/a#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR
79n/a#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE
80n/a#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND
81n/a#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND
82n/a#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD
83n/a#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v))
84n/a#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v))
85n/a#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v))
86n/a#define TIME_SET_MICROSECOND(o, v) \
87n/a (((o)->data[3] = ((v) & 0xff0000) >> 16), \
88n/a ((o)->data[4] = ((v) & 0x00ff00) >> 8), \
89n/a ((o)->data[5] = ((v) & 0x0000ff)))
90n/a#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v))
91n/a
92n/a/* Delta accessors for timedelta. */
93n/a#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days)
94n/a#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds)
95n/a#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds)
96n/a
97n/a#define SET_TD_DAYS(o, v) ((o)->days = (v))
98n/a#define SET_TD_SECONDS(o, v) ((o)->seconds = (v))
99n/a#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v))
100n/a
101n/a/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns
102n/a * p->hastzinfo.
103n/a */
104n/a#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo)
105n/a#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \
106n/a ((PyDateTime_Time *)(p))->tzinfo : Py_None)
107n/a#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \
108n/a ((PyDateTime_DateTime *)(p))->tzinfo : Py_None)
109n/a/* M is a char or int claiming to be a valid month. The macro is equivalent
110n/a * to the two-sided Python test
111n/a * 1 <= M <= 12
112n/a */
113n/a#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12)
114n/a
115n/a/* Forward declarations. */
116n/astatic PyTypeObject PyDateTime_DateType;
117n/astatic PyTypeObject PyDateTime_DateTimeType;
118n/astatic PyTypeObject PyDateTime_DeltaType;
119n/astatic PyTypeObject PyDateTime_TimeType;
120n/astatic PyTypeObject PyDateTime_TZInfoType;
121n/astatic PyTypeObject PyDateTime_TimeZoneType;
122n/a
123n/astatic int check_tzinfo_subclass(PyObject *p);
124n/a
125n/a_Py_IDENTIFIER(as_integer_ratio);
126n/a_Py_IDENTIFIER(fromutc);
127n/a_Py_IDENTIFIER(isoformat);
128n/a_Py_IDENTIFIER(strftime);
129n/a
130n/a/* ---------------------------------------------------------------------------
131n/a * Math utilities.
132n/a */
133n/a
134n/a/* k = i+j overflows iff k differs in sign from both inputs,
135n/a * iff k^i has sign bit set and k^j has sign bit set,
136n/a * iff (k^i)&(k^j) has sign bit set.
137n/a */
138n/a#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \
139n/a ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0)
140n/a
141n/a/* Compute Python divmod(x, y), returning the quotient and storing the
142n/a * remainder into *r. The quotient is the floor of x/y, and that's
143n/a * the real point of this. C will probably truncate instead (C99
144n/a * requires truncation; C89 left it implementation-defined).
145n/a * Simplification: we *require* that y > 0 here. That's appropriate
146n/a * for all the uses made of it. This simplifies the code and makes
147n/a * the overflow case impossible (divmod(LONG_MIN, -1) is the only
148n/a * overflow case).
149n/a */
150n/astatic int
151n/adivmod(int x, int y, int *r)
152n/a{
153n/a int quo;
154n/a
155n/a assert(y > 0);
156n/a quo = x / y;
157n/a *r = x - quo * y;
158n/a if (*r < 0) {
159n/a --quo;
160n/a *r += y;
161n/a }
162n/a assert(0 <= *r && *r < y);
163n/a return quo;
164n/a}
165n/a
166n/a/* Nearest integer to m / n for integers m and n. Half-integer results
167n/a * are rounded to even.
168n/a */
169n/astatic PyObject *
170n/adivide_nearest(PyObject *m, PyObject *n)
171n/a{
172n/a PyObject *result;
173n/a PyObject *temp;
174n/a
175n/a temp = _PyLong_DivmodNear(m, n);
176n/a if (temp == NULL)
177n/a return NULL;
178n/a result = PyTuple_GET_ITEM(temp, 0);
179n/a Py_INCREF(result);
180n/a Py_DECREF(temp);
181n/a
182n/a return result;
183n/a}
184n/a
185n/a/* ---------------------------------------------------------------------------
186n/a * General calendrical helper functions
187n/a */
188n/a
189n/a/* For each month ordinal in 1..12, the number of days in that month,
190n/a * and the number of days before that month in the same year. These
191n/a * are correct for non-leap years only.
192n/a */
193n/astatic const int _days_in_month[] = {
194n/a 0, /* unused; this vector uses 1-based indexing */
195n/a 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
196n/a};
197n/a
198n/astatic const int _days_before_month[] = {
199n/a 0, /* unused; this vector uses 1-based indexing */
200n/a 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
201n/a};
202n/a
203n/a/* year -> 1 if leap year, else 0. */
204n/astatic int
205n/ais_leap(int year)
206n/a{
207n/a /* Cast year to unsigned. The result is the same either way, but
208n/a * C can generate faster code for unsigned mod than for signed
209n/a * mod (especially for % 4 -- a good compiler should just grab
210n/a * the last 2 bits when the LHS is unsigned).
211n/a */
212n/a const unsigned int ayear = (unsigned int)year;
213n/a return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0);
214n/a}
215n/a
216n/a/* year, month -> number of days in that month in that year */
217n/astatic int
218n/adays_in_month(int year, int month)
219n/a{
220n/a assert(month >= 1);
221n/a assert(month <= 12);
222n/a if (month == 2 && is_leap(year))
223n/a return 29;
224n/a else
225n/a return _days_in_month[month];
226n/a}
227n/a
228n/a/* year, month -> number of days in year preceding first day of month */
229n/astatic int
230n/adays_before_month(int year, int month)
231n/a{
232n/a int days;
233n/a
234n/a assert(month >= 1);
235n/a assert(month <= 12);
236n/a days = _days_before_month[month];
237n/a if (month > 2 && is_leap(year))
238n/a ++days;
239n/a return days;
240n/a}
241n/a
242n/a/* year -> number of days before January 1st of year. Remember that we
243n/a * start with year 1, so days_before_year(1) == 0.
244n/a */
245n/astatic int
246n/adays_before_year(int year)
247n/a{
248n/a int y = year - 1;
249n/a /* This is incorrect if year <= 0; we really want the floor
250n/a * here. But so long as MINYEAR is 1, the smallest year this
251n/a * can see is 1.
252n/a */
253n/a assert (year >= 1);
254n/a return y*365 + y/4 - y/100 + y/400;
255n/a}
256n/a
257n/a/* Number of days in 4, 100, and 400 year cycles. That these have
258n/a * the correct values is asserted in the module init function.
259n/a */
260n/a#define DI4Y 1461 /* days_before_year(5); days in 4 years */
261n/a#define DI100Y 36524 /* days_before_year(101); days in 100 years */
262n/a#define DI400Y 146097 /* days_before_year(401); days in 400 years */
263n/a
264n/a/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */
265n/astatic void
266n/aord_to_ymd(int ordinal, int *year, int *month, int *day)
267n/a{
268n/a int n, n1, n4, n100, n400, leapyear, preceding;
269n/a
270n/a /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of
271n/a * leap years repeats exactly every 400 years. The basic strategy is
272n/a * to find the closest 400-year boundary at or before ordinal, then
273n/a * work with the offset from that boundary to ordinal. Life is much
274n/a * clearer if we subtract 1 from ordinal first -- then the values
275n/a * of ordinal at 400-year boundaries are exactly those divisible
276n/a * by DI400Y:
277n/a *
278n/a * D M Y n n-1
279n/a * -- --- ---- ---------- ----------------
280n/a * 31 Dec -400 -DI400Y -DI400Y -1
281n/a * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary
282n/a * ...
283n/a * 30 Dec 000 -1 -2
284n/a * 31 Dec 000 0 -1
285n/a * 1 Jan 001 1 0 400-year boundary
286n/a * 2 Jan 001 2 1
287n/a * 3 Jan 001 3 2
288n/a * ...
289n/a * 31 Dec 400 DI400Y DI400Y -1
290n/a * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary
291n/a */
292n/a assert(ordinal >= 1);
293n/a --ordinal;
294n/a n400 = ordinal / DI400Y;
295n/a n = ordinal % DI400Y;
296n/a *year = n400 * 400 + 1;
297n/a
298n/a /* Now n is the (non-negative) offset, in days, from January 1 of
299n/a * year, to the desired date. Now compute how many 100-year cycles
300n/a * precede n.
301n/a * Note that it's possible for n100 to equal 4! In that case 4 full
302n/a * 100-year cycles precede the desired day, which implies the
303n/a * desired day is December 31 at the end of a 400-year cycle.
304n/a */
305n/a n100 = n / DI100Y;
306n/a n = n % DI100Y;
307n/a
308n/a /* Now compute how many 4-year cycles precede it. */
309n/a n4 = n / DI4Y;
310n/a n = n % DI4Y;
311n/a
312n/a /* And now how many single years. Again n1 can be 4, and again
313n/a * meaning that the desired day is December 31 at the end of the
314n/a * 4-year cycle.
315n/a */
316n/a n1 = n / 365;
317n/a n = n % 365;
318n/a
319n/a *year += n100 * 100 + n4 * 4 + n1;
320n/a if (n1 == 4 || n100 == 4) {
321n/a assert(n == 0);
322n/a *year -= 1;
323n/a *month = 12;
324n/a *day = 31;
325n/a return;
326n/a }
327n/a
328n/a /* Now the year is correct, and n is the offset from January 1. We
329n/a * find the month via an estimate that's either exact or one too
330n/a * large.
331n/a */
332n/a leapyear = n1 == 3 && (n4 != 24 || n100 == 3);
333n/a assert(leapyear == is_leap(*year));
334n/a *month = (n + 50) >> 5;
335n/a preceding = (_days_before_month[*month] + (*month > 2 && leapyear));
336n/a if (preceding > n) {
337n/a /* estimate is too large */
338n/a *month -= 1;
339n/a preceding -= days_in_month(*year, *month);
340n/a }
341n/a n -= preceding;
342n/a assert(0 <= n);
343n/a assert(n < days_in_month(*year, *month));
344n/a
345n/a *day = n + 1;
346n/a}
347n/a
348n/a/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */
349n/astatic int
350n/aymd_to_ord(int year, int month, int day)
351n/a{
352n/a return days_before_year(year) + days_before_month(year, month) + day;
353n/a}
354n/a
355n/a/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */
356n/astatic int
357n/aweekday(int year, int month, int day)
358n/a{
359n/a return (ymd_to_ord(year, month, day) + 6) % 7;
360n/a}
361n/a
362n/a/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the
363n/a * first calendar week containing a Thursday.
364n/a */
365n/astatic int
366n/aiso_week1_monday(int year)
367n/a{
368n/a int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */
369n/a /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */
370n/a int first_weekday = (first_day + 6) % 7;
371n/a /* ordinal of closest Monday at or before 1/1 */
372n/a int week1_monday = first_day - first_weekday;
373n/a
374n/a if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */
375n/a week1_monday += 7;
376n/a return week1_monday;
377n/a}
378n/a
379n/a/* ---------------------------------------------------------------------------
380n/a * Range checkers.
381n/a */
382n/a
383n/a/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0.
384n/a * If not, raise OverflowError and return -1.
385n/a */
386n/astatic int
387n/acheck_delta_day_range(int days)
388n/a{
389n/a if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS)
390n/a return 0;
391n/a PyErr_Format(PyExc_OverflowError,
392n/a "days=%d; must have magnitude <= %d",
393n/a days, MAX_DELTA_DAYS);
394n/a return -1;
395n/a}
396n/a
397n/a/* Check that date arguments are in range. Return 0 if they are. If they
398n/a * aren't, raise ValueError and return -1.
399n/a */
400n/astatic int
401n/acheck_date_args(int year, int month, int day)
402n/a{
403n/a
404n/a if (year < MINYEAR || year > MAXYEAR) {
405n/a PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
406n/a return -1;
407n/a }
408n/a if (month < 1 || month > 12) {
409n/a PyErr_SetString(PyExc_ValueError,
410n/a "month must be in 1..12");
411n/a return -1;
412n/a }
413n/a if (day < 1 || day > days_in_month(year, month)) {
414n/a PyErr_SetString(PyExc_ValueError,
415n/a "day is out of range for month");
416n/a return -1;
417n/a }
418n/a return 0;
419n/a}
420n/a
421n/a/* Check that time arguments are in range. Return 0 if they are. If they
422n/a * aren't, raise ValueError and return -1.
423n/a */
424n/astatic int
425n/acheck_time_args(int h, int m, int s, int us, int fold)
426n/a{
427n/a if (h < 0 || h > 23) {
428n/a PyErr_SetString(PyExc_ValueError,
429n/a "hour must be in 0..23");
430n/a return -1;
431n/a }
432n/a if (m < 0 || m > 59) {
433n/a PyErr_SetString(PyExc_ValueError,
434n/a "minute must be in 0..59");
435n/a return -1;
436n/a }
437n/a if (s < 0 || s > 59) {
438n/a PyErr_SetString(PyExc_ValueError,
439n/a "second must be in 0..59");
440n/a return -1;
441n/a }
442n/a if (us < 0 || us > 999999) {
443n/a PyErr_SetString(PyExc_ValueError,
444n/a "microsecond must be in 0..999999");
445n/a return -1;
446n/a }
447n/a if (fold != 0 && fold != 1) {
448n/a PyErr_SetString(PyExc_ValueError,
449n/a "fold must be either 0 or 1");
450n/a return -1;
451n/a }
452n/a return 0;
453n/a}
454n/a
455n/a/* ---------------------------------------------------------------------------
456n/a * Normalization utilities.
457n/a */
458n/a
459n/a/* One step of a mixed-radix conversion. A "hi" unit is equivalent to
460n/a * factor "lo" units. factor must be > 0. If *lo is less than 0, or
461n/a * at least factor, enough of *lo is converted into "hi" units so that
462n/a * 0 <= *lo < factor. The input values must be such that int overflow
463n/a * is impossible.
464n/a */
465n/astatic void
466n/anormalize_pair(int *hi, int *lo, int factor)
467n/a{
468n/a assert(factor > 0);
469n/a assert(lo != hi);
470n/a if (*lo < 0 || *lo >= factor) {
471n/a const int num_hi = divmod(*lo, factor, lo);
472n/a const int new_hi = *hi + num_hi;
473n/a assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi));
474n/a *hi = new_hi;
475n/a }
476n/a assert(0 <= *lo && *lo < factor);
477n/a}
478n/a
479n/a/* Fiddle days (d), seconds (s), and microseconds (us) so that
480n/a * 0 <= *s < 24*3600
481n/a * 0 <= *us < 1000000
482n/a * The input values must be such that the internals don't overflow.
483n/a * The way this routine is used, we don't get close.
484n/a */
485n/astatic void
486n/anormalize_d_s_us(int *d, int *s, int *us)
487n/a{
488n/a if (*us < 0 || *us >= 1000000) {
489n/a normalize_pair(s, us, 1000000);
490n/a /* |s| can't be bigger than about
491n/a * |original s| + |original us|/1000000 now.
492n/a */
493n/a
494n/a }
495n/a if (*s < 0 || *s >= 24*3600) {
496n/a normalize_pair(d, s, 24*3600);
497n/a /* |d| can't be bigger than about
498n/a * |original d| +
499n/a * (|original s| + |original us|/1000000) / (24*3600) now.
500n/a */
501n/a }
502n/a assert(0 <= *s && *s < 24*3600);
503n/a assert(0 <= *us && *us < 1000000);
504n/a}
505n/a
506n/a/* Fiddle years (y), months (m), and days (d) so that
507n/a * 1 <= *m <= 12
508n/a * 1 <= *d <= days_in_month(*y, *m)
509n/a * The input values must be such that the internals don't overflow.
510n/a * The way this routine is used, we don't get close.
511n/a */
512n/astatic int
513n/anormalize_y_m_d(int *y, int *m, int *d)
514n/a{
515n/a int dim; /* # of days in month */
516n/a
517n/a /* In actual use, m is always the month component extracted from a
518n/a * date/datetime object. Therefore it is always in [1, 12] range.
519n/a */
520n/a
521n/a assert(1 <= *m && *m <= 12);
522n/a
523n/a /* Now only day can be out of bounds (year may also be out of bounds
524n/a * for a datetime object, but we don't care about that here).
525n/a * If day is out of bounds, what to do is arguable, but at least the
526n/a * method here is principled and explainable.
527n/a */
528n/a dim = days_in_month(*y, *m);
529n/a if (*d < 1 || *d > dim) {
530n/a /* Move day-1 days from the first of the month. First try to
531n/a * get off cheap if we're only one day out of range
532n/a * (adjustments for timezone alone can't be worse than that).
533n/a */
534n/a if (*d == 0) {
535n/a --*m;
536n/a if (*m > 0)
537n/a *d = days_in_month(*y, *m);
538n/a else {
539n/a --*y;
540n/a *m = 12;
541n/a *d = 31;
542n/a }
543n/a }
544n/a else if (*d == dim + 1) {
545n/a /* move forward a day */
546n/a ++*m;
547n/a *d = 1;
548n/a if (*m > 12) {
549n/a *m = 1;
550n/a ++*y;
551n/a }
552n/a }
553n/a else {
554n/a int ordinal = ymd_to_ord(*y, *m, 1) +
555n/a *d - 1;
556n/a if (ordinal < 1 || ordinal > MAXORDINAL) {
557n/a goto error;
558n/a } else {
559n/a ord_to_ymd(ordinal, y, m, d);
560n/a return 0;
561n/a }
562n/a }
563n/a }
564n/a assert(*m > 0);
565n/a assert(*d > 0);
566n/a if (MINYEAR <= *y && *y <= MAXYEAR)
567n/a return 0;
568n/a error:
569n/a PyErr_SetString(PyExc_OverflowError,
570n/a "date value out of range");
571n/a return -1;
572n/a
573n/a}
574n/a
575n/a/* Fiddle out-of-bounds months and days so that the result makes some kind
576n/a * of sense. The parameters are both inputs and outputs. Returns < 0 on
577n/a * failure, where failure means the adjusted year is out of bounds.
578n/a */
579n/astatic int
580n/anormalize_date(int *year, int *month, int *day)
581n/a{
582n/a return normalize_y_m_d(year, month, day);
583n/a}
584n/a
585n/a/* Force all the datetime fields into range. The parameters are both
586n/a * inputs and outputs. Returns < 0 on error.
587n/a */
588n/astatic int
589n/anormalize_datetime(int *year, int *month, int *day,
590n/a int *hour, int *minute, int *second,
591n/a int *microsecond)
592n/a{
593n/a normalize_pair(second, microsecond, 1000000);
594n/a normalize_pair(minute, second, 60);
595n/a normalize_pair(hour, minute, 60);
596n/a normalize_pair(day, hour, 24);
597n/a return normalize_date(year, month, day);
598n/a}
599n/a
600n/a/* ---------------------------------------------------------------------------
601n/a * Basic object allocation: tp_alloc implementations. These allocate
602n/a * Python objects of the right size and type, and do the Python object-
603n/a * initialization bit. If there's not enough memory, they return NULL after
604n/a * setting MemoryError. All data members remain uninitialized trash.
605n/a *
606n/a * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
607n/a * member is needed. This is ugly, imprecise, and possibly insecure.
608n/a * tp_basicsize for the time and datetime types is set to the size of the
609n/a * struct that has room for the tzinfo member, so subclasses in Python will
610n/a * allocate enough space for a tzinfo member whether or not one is actually
611n/a * needed. That's the "ugly and imprecise" parts. The "possibly insecure"
612n/a * part is that PyType_GenericAlloc() (which subclasses in Python end up
613n/a * using) just happens today to effectively ignore the nitems argument
614n/a * when tp_itemsize is 0, which it is for these type objects. If that
615n/a * changes, perhaps the callers of tp_alloc slots in this file should
616n/a * be changed to force a 0 nitems argument unless the type being allocated
617n/a * is a base type implemented in this file (so that tp_alloc is time_alloc
618n/a * or datetime_alloc below, which know about the nitems abuse).
619n/a */
620n/a
621n/astatic PyObject *
622n/atime_alloc(PyTypeObject *type, Py_ssize_t aware)
623n/a{
624n/a PyObject *self;
625n/a
626n/a self = (PyObject *)
627n/a PyObject_MALLOC(aware ?
628n/a sizeof(PyDateTime_Time) :
629n/a sizeof(_PyDateTime_BaseTime));
630n/a if (self == NULL)
631n/a return (PyObject *)PyErr_NoMemory();
632n/a (void)PyObject_INIT(self, type);
633n/a return self;
634n/a}
635n/a
636n/astatic PyObject *
637n/adatetime_alloc(PyTypeObject *type, Py_ssize_t aware)
638n/a{
639n/a PyObject *self;
640n/a
641n/a self = (PyObject *)
642n/a PyObject_MALLOC(aware ?
643n/a sizeof(PyDateTime_DateTime) :
644n/a sizeof(_PyDateTime_BaseDateTime));
645n/a if (self == NULL)
646n/a return (PyObject *)PyErr_NoMemory();
647n/a (void)PyObject_INIT(self, type);
648n/a return self;
649n/a}
650n/a
651n/a/* ---------------------------------------------------------------------------
652n/a * Helpers for setting object fields. These work on pointers to the
653n/a * appropriate base class.
654n/a */
655n/a
656n/a/* For date and datetime. */
657n/astatic void
658n/aset_date_fields(PyDateTime_Date *self, int y, int m, int d)
659n/a{
660n/a self->hashcode = -1;
661n/a SET_YEAR(self, y);
662n/a SET_MONTH(self, m);
663n/a SET_DAY(self, d);
664n/a}
665n/a
666n/a/* ---------------------------------------------------------------------------
667n/a * Create various objects, mostly without range checking.
668n/a */
669n/a
670n/a/* Create a date instance with no range checking. */
671n/astatic PyObject *
672n/anew_date_ex(int year, int month, int day, PyTypeObject *type)
673n/a{
674n/a PyDateTime_Date *self;
675n/a
676n/a if (check_date_args(year, month, day) < 0) {
677n/a return NULL;
678n/a }
679n/a
680n/a self = (PyDateTime_Date *) (type->tp_alloc(type, 0));
681n/a if (self != NULL)
682n/a set_date_fields(self, year, month, day);
683n/a return (PyObject *) self;
684n/a}
685n/a
686n/a#define new_date(year, month, day) \
687n/a new_date_ex(year, month, day, &PyDateTime_DateType)
688n/a
689n/a/* Create a datetime instance with no range checking. */
690n/astatic PyObject *
691n/anew_datetime_ex2(int year, int month, int day, int hour, int minute,
692n/a int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type)
693n/a{
694n/a PyDateTime_DateTime *self;
695n/a char aware = tzinfo != Py_None;
696n/a
697n/a if (check_date_args(year, month, day) < 0) {
698n/a return NULL;
699n/a }
700n/a if (check_time_args(hour, minute, second, usecond, fold) < 0) {
701n/a return NULL;
702n/a }
703n/a if (check_tzinfo_subclass(tzinfo) < 0) {
704n/a return NULL;
705n/a }
706n/a
707n/a self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware));
708n/a if (self != NULL) {
709n/a self->hastzinfo = aware;
710n/a set_date_fields((PyDateTime_Date *)self, year, month, day);
711n/a DATE_SET_HOUR(self, hour);
712n/a DATE_SET_MINUTE(self, minute);
713n/a DATE_SET_SECOND(self, second);
714n/a DATE_SET_MICROSECOND(self, usecond);
715n/a if (aware) {
716n/a Py_INCREF(tzinfo);
717n/a self->tzinfo = tzinfo;
718n/a }
719n/a DATE_SET_FOLD(self, fold);
720n/a }
721n/a return (PyObject *)self;
722n/a}
723n/a
724n/astatic PyObject *
725n/anew_datetime_ex(int year, int month, int day, int hour, int minute,
726n/a int second, int usecond, PyObject *tzinfo, PyTypeObject *type)
727n/a{
728n/a return new_datetime_ex2(year, month, day, hour, minute, second, usecond,
729n/a tzinfo, 0, type);
730n/a}
731n/a
732n/a#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \
733n/a new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \
734n/a &PyDateTime_DateTimeType)
735n/a
736n/a/* Create a time instance with no range checking. */
737n/astatic PyObject *
738n/anew_time_ex2(int hour, int minute, int second, int usecond,
739n/a PyObject *tzinfo, int fold, PyTypeObject *type)
740n/a{
741n/a PyDateTime_Time *self;
742n/a char aware = tzinfo != Py_None;
743n/a
744n/a if (check_time_args(hour, minute, second, usecond, fold) < 0) {
745n/a return NULL;
746n/a }
747n/a if (check_tzinfo_subclass(tzinfo) < 0) {
748n/a return NULL;
749n/a }
750n/a
751n/a self = (PyDateTime_Time *) (type->tp_alloc(type, aware));
752n/a if (self != NULL) {
753n/a self->hastzinfo = aware;
754n/a self->hashcode = -1;
755n/a TIME_SET_HOUR(self, hour);
756n/a TIME_SET_MINUTE(self, minute);
757n/a TIME_SET_SECOND(self, second);
758n/a TIME_SET_MICROSECOND(self, usecond);
759n/a if (aware) {
760n/a Py_INCREF(tzinfo);
761n/a self->tzinfo = tzinfo;
762n/a }
763n/a TIME_SET_FOLD(self, fold);
764n/a }
765n/a return (PyObject *)self;
766n/a}
767n/a
768n/astatic PyObject *
769n/anew_time_ex(int hour, int minute, int second, int usecond,
770n/a PyObject *tzinfo, PyTypeObject *type)
771n/a{
772n/a return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type);
773n/a}
774n/a
775n/a#define new_time(hh, mm, ss, us, tzinfo, fold) \
776n/a new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType)
777n/a
778n/a/* Create a timedelta instance. Normalize the members iff normalize is
779n/a * true. Passing false is a speed optimization, if you know for sure
780n/a * that seconds and microseconds are already in their proper ranges. In any
781n/a * case, raises OverflowError and returns NULL if the normalized days is out
782n/a * of range).
783n/a */
784n/astatic PyObject *
785n/anew_delta_ex(int days, int seconds, int microseconds, int normalize,
786n/a PyTypeObject *type)
787n/a{
788n/a PyDateTime_Delta *self;
789n/a
790n/a if (normalize)
791n/a normalize_d_s_us(&days, &seconds, &microseconds);
792n/a assert(0 <= seconds && seconds < 24*3600);
793n/a assert(0 <= microseconds && microseconds < 1000000);
794n/a
795n/a if (check_delta_day_range(days) < 0)
796n/a return NULL;
797n/a
798n/a self = (PyDateTime_Delta *) (type->tp_alloc(type, 0));
799n/a if (self != NULL) {
800n/a self->hashcode = -1;
801n/a SET_TD_DAYS(self, days);
802n/a SET_TD_SECONDS(self, seconds);
803n/a SET_TD_MICROSECONDS(self, microseconds);
804n/a }
805n/a return (PyObject *) self;
806n/a}
807n/a
808n/a#define new_delta(d, s, us, normalize) \
809n/a new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType)
810n/a
811n/a
812n/atypedef struct
813n/a{
814n/a PyObject_HEAD
815n/a PyObject *offset;
816n/a PyObject *name;
817n/a} PyDateTime_TimeZone;
818n/a
819n/a/* The interned UTC timezone instance */
820n/astatic PyObject *PyDateTime_TimeZone_UTC;
821n/a/* The interned Epoch datetime instance */
822n/astatic PyObject *PyDateTime_Epoch;
823n/a
824n/a/* Create new timezone instance checking offset range. This
825n/a function does not check the name argument. Caller must assure
826n/a that offset is a timedelta instance and name is either NULL
827n/a or a unicode object. */
828n/astatic PyObject *
829n/acreate_timezone(PyObject *offset, PyObject *name)
830n/a{
831n/a PyDateTime_TimeZone *self;
832n/a PyTypeObject *type = &PyDateTime_TimeZoneType;
833n/a
834n/a assert(offset != NULL);
835n/a assert(PyDelta_Check(offset));
836n/a assert(name == NULL || PyUnicode_Check(name));
837n/a
838n/a self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0));
839n/a if (self == NULL) {
840n/a return NULL;
841n/a }
842n/a Py_INCREF(offset);
843n/a self->offset = offset;
844n/a Py_XINCREF(name);
845n/a self->name = name;
846n/a return (PyObject *)self;
847n/a}
848n/a
849n/astatic int delta_bool(PyDateTime_Delta *self);
850n/a
851n/astatic PyObject *
852n/anew_timezone(PyObject *offset, PyObject *name)
853n/a{
854n/a assert(offset != NULL);
855n/a assert(PyDelta_Check(offset));
856n/a assert(name == NULL || PyUnicode_Check(name));
857n/a
858n/a if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) {
859n/a Py_INCREF(PyDateTime_TimeZone_UTC);
860n/a return PyDateTime_TimeZone_UTC;
861n/a }
862n/a if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) {
863n/a PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
864n/a " representing a whole number of minutes,"
865n/a " not %R.", offset);
866n/a return NULL;
867n/a }
868n/a if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
869n/a GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
870n/a PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
871n/a " strictly between -timedelta(hours=24) and"
872n/a " timedelta(hours=24),"
873n/a " not %R.", offset);
874n/a return NULL;
875n/a }
876n/a
877n/a return create_timezone(offset, name);
878n/a}
879n/a
880n/a/* ---------------------------------------------------------------------------
881n/a * tzinfo helpers.
882n/a */
883n/a
884n/a/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not
885n/a * raise TypeError and return -1.
886n/a */
887n/astatic int
888n/acheck_tzinfo_subclass(PyObject *p)
889n/a{
890n/a if (p == Py_None || PyTZInfo_Check(p))
891n/a return 0;
892n/a PyErr_Format(PyExc_TypeError,
893n/a "tzinfo argument must be None or of a tzinfo subclass, "
894n/a "not type '%s'",
895n/a Py_TYPE(p)->tp_name);
896n/a return -1;
897n/a}
898n/a
899n/a/* If self has a tzinfo member, return a BORROWED reference to it. Else
900n/a * return NULL, which is NOT AN ERROR. There are no error returns here,
901n/a * and the caller must not decref the result.
902n/a */
903n/astatic PyObject *
904n/aget_tzinfo_member(PyObject *self)
905n/a{
906n/a PyObject *tzinfo = NULL;
907n/a
908n/a if (PyDateTime_Check(self) && HASTZINFO(self))
909n/a tzinfo = ((PyDateTime_DateTime *)self)->tzinfo;
910n/a else if (PyTime_Check(self) && HASTZINFO(self))
911n/a tzinfo = ((PyDateTime_Time *)self)->tzinfo;
912n/a
913n/a return tzinfo;
914n/a}
915n/a
916n/a/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must
917n/a * be an instance of the tzinfo class. If the method returns None, this
918n/a * returns None. If the method doesn't return None or timedelta, TypeError is
919n/a * raised and this returns NULL. If it returns a timedelta and the value is
920n/a * out of range or isn't a whole number of minutes, ValueError is raised and
921n/a * this returns NULL. Else result is returned.
922n/a */
923n/astatic PyObject *
924n/acall_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
925n/a{
926n/a PyObject *offset;
927n/a
928n/a assert(tzinfo != NULL);
929n/a assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None);
930n/a assert(tzinfoarg != NULL);
931n/a
932n/a if (tzinfo == Py_None)
933n/a Py_RETURN_NONE;
934n/a offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg);
935n/a if (offset == Py_None || offset == NULL)
936n/a return offset;
937n/a if (PyDelta_Check(offset)) {
938n/a if (GET_TD_MICROSECONDS(offset) != 0) {
939n/a Py_DECREF(offset);
940n/a PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
941n/a " representing a whole number of seconds");
942n/a return NULL;
943n/a }
944n/a if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
945n/a GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
946n/a Py_DECREF(offset);
947n/a PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
948n/a " strictly between -timedelta(hours=24) and"
949n/a " timedelta(hours=24).");
950n/a return NULL;
951n/a }
952n/a }
953n/a else {
954n/a PyErr_Format(PyExc_TypeError,
955n/a "tzinfo.%s() must return None or "
956n/a "timedelta, not '%.200s'",
957n/a name, Py_TYPE(offset)->tp_name);
958n/a Py_DECREF(offset);
959n/a return NULL;
960n/a }
961n/a
962n/a return offset;
963n/a}
964n/a
965n/a/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the
966n/a * result. tzinfo must be an instance of the tzinfo class. If utcoffset()
967n/a * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset()
968n/a * doesn't return None or timedelta, TypeError is raised and this returns -1.
969n/a * If utcoffset() returns an invalid timedelta (out of range, or not a whole
970n/a * # of minutes), ValueError is raised and this returns -1. Else *none is
971n/a * set to 0 and the offset is returned (as int # of minutes east of UTC).
972n/a */
973n/astatic PyObject *
974n/acall_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg)
975n/a{
976n/a return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg);
977n/a}
978n/a
979n/a/* Call tzinfo.dst(tzinfoarg), and extract an integer from the
980n/a * result. tzinfo must be an instance of the tzinfo class. If dst()
981n/a * returns None, call_dst returns 0 and sets *none to 1. If dst()
982n/a & doesn't return None or timedelta, TypeError is raised and this
983n/a * returns -1. If dst() returns an invalid timedelta for a UTC offset,
984n/a * ValueError is raised and this returns -1. Else *none is set to 0 and
985n/a * the offset is returned (as an int # of minutes east of UTC).
986n/a */
987n/astatic PyObject *
988n/acall_dst(PyObject *tzinfo, PyObject *tzinfoarg)
989n/a{
990n/a return call_tzinfo_method(tzinfo, "dst", tzinfoarg);
991n/a}
992n/a
993n/a/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be
994n/a * an instance of the tzinfo class or None. If tzinfo isn't None, and
995n/a * tzname() doesn't return None or a string, TypeError is raised and this
996n/a * returns NULL. If the result is a string, we ensure it is a Unicode
997n/a * string.
998n/a */
999n/astatic PyObject *
1000n/acall_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
1001n/a{
1002n/a PyObject *result;
1003n/a _Py_IDENTIFIER(tzname);
1004n/a
1005n/a assert(tzinfo != NULL);
1006n/a assert(check_tzinfo_subclass(tzinfo) >= 0);
1007n/a assert(tzinfoarg != NULL);
1008n/a
1009n/a if (tzinfo == Py_None)
1010n/a Py_RETURN_NONE;
1011n/a
1012n/a result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname,
1013n/a tzinfoarg, NULL);
1014n/a
1015n/a if (result == NULL || result == Py_None)
1016n/a return result;
1017n/a
1018n/a if (!PyUnicode_Check(result)) {
1019n/a PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
1020n/a "return None or a string, not '%s'",
1021n/a Py_TYPE(result)->tp_name);
1022n/a Py_DECREF(result);
1023n/a result = NULL;
1024n/a }
1025n/a
1026n/a return result;
1027n/a}
1028n/a
1029n/a/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None,
1030n/a * stuff
1031n/a * ", tzinfo=" + repr(tzinfo)
1032n/a * before the closing ")".
1033n/a */
1034n/astatic PyObject *
1035n/aappend_keyword_tzinfo(PyObject *repr, PyObject *tzinfo)
1036n/a{
1037n/a PyObject *temp;
1038n/a
1039n/a assert(PyUnicode_Check(repr));
1040n/a assert(tzinfo);
1041n/a if (tzinfo == Py_None)
1042n/a return repr;
1043n/a /* Get rid of the trailing ')'. */
1044n/a assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1045n/a temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1046n/a Py_DECREF(repr);
1047n/a if (temp == NULL)
1048n/a return NULL;
1049n/a repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo);
1050n/a Py_DECREF(temp);
1051n/a return repr;
1052n/a}
1053n/a
1054n/a/* repr is like "someclass(arg1, arg2)". If fold isn't 0,
1055n/a * stuff
1056n/a * ", fold=" + repr(tzinfo)
1057n/a * before the closing ")".
1058n/a */
1059n/astatic PyObject *
1060n/aappend_keyword_fold(PyObject *repr, int fold)
1061n/a{
1062n/a PyObject *temp;
1063n/a
1064n/a assert(PyUnicode_Check(repr));
1065n/a if (fold == 0)
1066n/a return repr;
1067n/a /* Get rid of the trailing ')'. */
1068n/a assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')');
1069n/a temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1);
1070n/a Py_DECREF(repr);
1071n/a if (temp == NULL)
1072n/a return NULL;
1073n/a repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold);
1074n/a Py_DECREF(temp);
1075n/a return repr;
1076n/a}
1077n/a
1078n/a/* ---------------------------------------------------------------------------
1079n/a * String format helpers.
1080n/a */
1081n/a
1082n/astatic PyObject *
1083n/aformat_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds)
1084n/a{
1085n/a static const char * const DayNames[] = {
1086n/a "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
1087n/a };
1088n/a static const char * const MonthNames[] = {
1089n/a "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1090n/a "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1091n/a };
1092n/a
1093n/a int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date));
1094n/a
1095n/a return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d",
1096n/a DayNames[wday], MonthNames[GET_MONTH(date)-1],
1097n/a GET_DAY(date), hours, minutes, seconds,
1098n/a GET_YEAR(date));
1099n/a}
1100n/a
1101n/astatic PyObject *delta_negative(PyDateTime_Delta *self);
1102n/a
1103n/a/* Add an hours & minutes UTC offset string to buf. buf has no more than
1104n/a * buflen bytes remaining. The UTC offset is gotten by calling
1105n/a * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into
1106n/a * *buf, and that's all. Else the returned value is checked for sanity (an
1107n/a * integer in range), and if that's OK it's converted to an hours & minutes
1108n/a * string of the form
1109n/a * sign HH sep MM
1110n/a * Returns 0 if everything is OK. If the return value from utcoffset() is
1111n/a * bogus, an appropriate exception is set and -1 is returned.
1112n/a */
1113n/astatic int
1114n/aformat_utcoffset(char *buf, size_t buflen, const char *sep,
1115n/a PyObject *tzinfo, PyObject *tzinfoarg)
1116n/a{
1117n/a PyObject *offset;
1118n/a int hours, minutes, seconds;
1119n/a char sign;
1120n/a
1121n/a assert(buflen >= 1);
1122n/a
1123n/a offset = call_utcoffset(tzinfo, tzinfoarg);
1124n/a if (offset == NULL)
1125n/a return -1;
1126n/a if (offset == Py_None) {
1127n/a Py_DECREF(offset);
1128n/a *buf = '\0';
1129n/a return 0;
1130n/a }
1131n/a /* Offset is normalized, so it is negative if days < 0 */
1132n/a if (GET_TD_DAYS(offset) < 0) {
1133n/a sign = '-';
1134n/a Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset));
1135n/a if (offset == NULL)
1136n/a return -1;
1137n/a }
1138n/a else {
1139n/a sign = '+';
1140n/a }
1141n/a /* Offset is not negative here. */
1142n/a seconds = GET_TD_SECONDS(offset);
1143n/a Py_DECREF(offset);
1144n/a minutes = divmod(seconds, 60, &seconds);
1145n/a hours = divmod(minutes, 60, &minutes);
1146n/a if (seconds == 0)
1147n/a PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
1148n/a else
1149n/a PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours,
1150n/a sep, minutes, sep, seconds);
1151n/a return 0;
1152n/a}
1153n/a
1154n/astatic PyObject *
1155n/amake_Zreplacement(PyObject *object, PyObject *tzinfoarg)
1156n/a{
1157n/a PyObject *temp;
1158n/a PyObject *tzinfo = get_tzinfo_member(object);
1159n/a PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
1160n/a _Py_IDENTIFIER(replace);
1161n/a
1162n/a if (Zreplacement == NULL)
1163n/a return NULL;
1164n/a if (tzinfo == Py_None || tzinfo == NULL)
1165n/a return Zreplacement;
1166n/a
1167n/a assert(tzinfoarg != NULL);
1168n/a temp = call_tzname(tzinfo, tzinfoarg);
1169n/a if (temp == NULL)
1170n/a goto Error;
1171n/a if (temp == Py_None) {
1172n/a Py_DECREF(temp);
1173n/a return Zreplacement;
1174n/a }
1175n/a
1176n/a assert(PyUnicode_Check(temp));
1177n/a /* Since the tzname is getting stuffed into the
1178n/a * format, we have to double any % signs so that
1179n/a * strftime doesn't treat them as format codes.
1180n/a */
1181n/a Py_DECREF(Zreplacement);
1182n/a Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
1183n/a Py_DECREF(temp);
1184n/a if (Zreplacement == NULL)
1185n/a return NULL;
1186n/a if (!PyUnicode_Check(Zreplacement)) {
1187n/a PyErr_SetString(PyExc_TypeError,
1188n/a "tzname.replace() did not return a string");
1189n/a goto Error;
1190n/a }
1191n/a return Zreplacement;
1192n/a
1193n/a Error:
1194n/a Py_DECREF(Zreplacement);
1195n/a return NULL;
1196n/a}
1197n/a
1198n/astatic PyObject *
1199n/amake_freplacement(PyObject *object)
1200n/a{
1201n/a char freplacement[64];
1202n/a if (PyTime_Check(object))
1203n/a sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1204n/a else if (PyDateTime_Check(object))
1205n/a sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1206n/a else
1207n/a sprintf(freplacement, "%06d", 0);
1208n/a
1209n/a return PyBytes_FromStringAndSize(freplacement, strlen(freplacement));
1210n/a}
1211n/a
1212n/a/* I sure don't want to reproduce the strftime code from the time module,
1213n/a * so this imports the module and calls it. All the hair is due to
1214n/a * giving special meanings to the %z, %Z and %f format codes via a
1215n/a * preprocessing step on the format string.
1216n/a * tzinfoarg is the argument to pass to the object's tzinfo method, if
1217n/a * needed.
1218n/a */
1219n/astatic PyObject *
1220n/awrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
1221n/a PyObject *tzinfoarg)
1222n/a{
1223n/a PyObject *result = NULL; /* guilty until proved innocent */
1224n/a
1225n/a PyObject *zreplacement = NULL; /* py string, replacement for %z */
1226n/a PyObject *Zreplacement = NULL; /* py string, replacement for %Z */
1227n/a PyObject *freplacement = NULL; /* py string, replacement for %f */
1228n/a
1229n/a const char *pin; /* pointer to next char in input format */
1230n/a Py_ssize_t flen; /* length of input format */
1231n/a char ch; /* next char in input format */
1232n/a
1233n/a PyObject *newfmt = NULL; /* py string, the output format */
1234n/a char *pnew; /* pointer to available byte in output format */
1235n/a size_t totalnew; /* number bytes total in output format buffer,
1236n/a exclusive of trailing \0 */
1237n/a size_t usednew; /* number bytes used so far in output format buffer */
1238n/a
1239n/a const char *ptoappend; /* ptr to string to append to output buffer */
1240n/a Py_ssize_t ntoappend; /* # of bytes to append to output buffer */
1241n/a
1242n/a assert(object && format && timetuple);
1243n/a assert(PyUnicode_Check(format));
1244n/a /* Convert the input format to a C string and size */
1245n/a pin = PyUnicode_AsUTF8AndSize(format, &flen);
1246n/a if (!pin)
1247n/a return NULL;
1248n/a
1249n/a /* Scan the input format, looking for %z/%Z/%f escapes, building
1250n/a * a new format. Since computing the replacements for those codes
1251n/a * is expensive, don't unless they're actually used.
1252n/a */
1253n/a if (flen > INT_MAX - 1) {
1254n/a PyErr_NoMemory();
1255n/a goto Done;
1256n/a }
1257n/a
1258n/a totalnew = flen + 1; /* realistic if no %z/%Z */
1259n/a newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
1260n/a if (newfmt == NULL) goto Done;
1261n/a pnew = PyBytes_AsString(newfmt);
1262n/a usednew = 0;
1263n/a
1264n/a while ((ch = *pin++) != '\0') {
1265n/a if (ch != '%') {
1266n/a ptoappend = pin - 1;
1267n/a ntoappend = 1;
1268n/a }
1269n/a else if ((ch = *pin++) == '\0') {
1270n/a /* There's a lone trailing %; doesn't make sense. */
1271n/a PyErr_SetString(PyExc_ValueError, "strftime format "
1272n/a "ends with raw %");
1273n/a goto Done;
1274n/a }
1275n/a /* A % has been seen and ch is the character after it. */
1276n/a else if (ch == 'z') {
1277n/a if (zreplacement == NULL) {
1278n/a /* format utcoffset */
1279n/a char buf[100];
1280n/a PyObject *tzinfo = get_tzinfo_member(object);
1281n/a zreplacement = PyBytes_FromStringAndSize("", 0);
1282n/a if (zreplacement == NULL) goto Done;
1283n/a if (tzinfo != Py_None && tzinfo != NULL) {
1284n/a assert(tzinfoarg != NULL);
1285n/a if (format_utcoffset(buf,
1286n/a sizeof(buf),
1287n/a "",
1288n/a tzinfo,
1289n/a tzinfoarg) < 0)
1290n/a goto Done;
1291n/a Py_DECREF(zreplacement);
1292n/a zreplacement =
1293n/a PyBytes_FromStringAndSize(buf,
1294n/a strlen(buf));
1295n/a if (zreplacement == NULL)
1296n/a goto Done;
1297n/a }
1298n/a }
1299n/a assert(zreplacement != NULL);
1300n/a ptoappend = PyBytes_AS_STRING(zreplacement);
1301n/a ntoappend = PyBytes_GET_SIZE(zreplacement);
1302n/a }
1303n/a else if (ch == 'Z') {
1304n/a /* format tzname */
1305n/a if (Zreplacement == NULL) {
1306n/a Zreplacement = make_Zreplacement(object,
1307n/a tzinfoarg);
1308n/a if (Zreplacement == NULL)
1309n/a goto Done;
1310n/a }
1311n/a assert(Zreplacement != NULL);
1312n/a assert(PyUnicode_Check(Zreplacement));
1313n/a ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement,
1314n/a &ntoappend);
1315n/a if (ptoappend == NULL)
1316n/a goto Done;
1317n/a }
1318n/a else if (ch == 'f') {
1319n/a /* format microseconds */
1320n/a if (freplacement == NULL) {
1321n/a freplacement = make_freplacement(object);
1322n/a if (freplacement == NULL)
1323n/a goto Done;
1324n/a }
1325n/a assert(freplacement != NULL);
1326n/a assert(PyBytes_Check(freplacement));
1327n/a ptoappend = PyBytes_AS_STRING(freplacement);
1328n/a ntoappend = PyBytes_GET_SIZE(freplacement);
1329n/a }
1330n/a else {
1331n/a /* percent followed by neither z nor Z */
1332n/a ptoappend = pin - 2;
1333n/a ntoappend = 2;
1334n/a }
1335n/a
1336n/a /* Append the ntoappend chars starting at ptoappend to
1337n/a * the new format.
1338n/a */
1339n/a if (ntoappend == 0)
1340n/a continue;
1341n/a assert(ptoappend != NULL);
1342n/a assert(ntoappend > 0);
1343n/a while (usednew + ntoappend > totalnew) {
1344n/a if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
1345n/a PyErr_NoMemory();
1346n/a goto Done;
1347n/a }
1348n/a totalnew <<= 1;
1349n/a if (_PyBytes_Resize(&newfmt, totalnew) < 0)
1350n/a goto Done;
1351n/a pnew = PyBytes_AsString(newfmt) + usednew;
1352n/a }
1353n/a memcpy(pnew, ptoappend, ntoappend);
1354n/a pnew += ntoappend;
1355n/a usednew += ntoappend;
1356n/a assert(usednew <= totalnew);
1357n/a } /* end while() */
1358n/a
1359n/a if (_PyBytes_Resize(&newfmt, usednew) < 0)
1360n/a goto Done;
1361n/a {
1362n/a PyObject *format;
1363n/a PyObject *time = PyImport_ImportModuleNoBlock("time");
1364n/a
1365n/a if (time == NULL)
1366n/a goto Done;
1367n/a format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
1368n/a if (format != NULL) {
1369n/a result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime,
1370n/a format, timetuple, NULL);
1371n/a Py_DECREF(format);
1372n/a }
1373n/a Py_DECREF(time);
1374n/a }
1375n/a Done:
1376n/a Py_XDECREF(freplacement);
1377n/a Py_XDECREF(zreplacement);
1378n/a Py_XDECREF(Zreplacement);
1379n/a Py_XDECREF(newfmt);
1380n/a return result;
1381n/a}
1382n/a
1383n/a/* ---------------------------------------------------------------------------
1384n/a * Wrap functions from the time module. These aren't directly available
1385n/a * from C. Perhaps they should be.
1386n/a */
1387n/a
1388n/a/* Call time.time() and return its result (a Python float). */
1389n/astatic PyObject *
1390n/atime_time(void)
1391n/a{
1392n/a PyObject *result = NULL;
1393n/a PyObject *time = PyImport_ImportModuleNoBlock("time");
1394n/a
1395n/a if (time != NULL) {
1396n/a _Py_IDENTIFIER(time);
1397n/a
1398n/a result = _PyObject_CallMethodId(time, &PyId_time, NULL);
1399n/a Py_DECREF(time);
1400n/a }
1401n/a return result;
1402n/a}
1403n/a
1404n/a/* Build a time.struct_time. The weekday and day number are automatically
1405n/a * computed from the y,m,d args.
1406n/a */
1407n/astatic PyObject *
1408n/abuild_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
1409n/a{
1410n/a PyObject *time;
1411n/a PyObject *result;
1412n/a _Py_IDENTIFIER(struct_time);
1413n/a PyObject *args;
1414n/a
1415n/a
1416n/a time = PyImport_ImportModuleNoBlock("time");
1417n/a if (time == NULL) {
1418n/a return NULL;
1419n/a }
1420n/a
1421n/a args = Py_BuildValue("iiiiiiiii",
1422n/a y, m, d,
1423n/a hh, mm, ss,
1424n/a weekday(y, m, d),
1425n/a days_before_month(y, m) + d,
1426n/a dstflag);
1427n/a if (args == NULL) {
1428n/a Py_DECREF(time);
1429n/a return NULL;
1430n/a }
1431n/a
1432n/a result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time,
1433n/a args, NULL);
1434n/a Py_DECREF(time);
1435n/a Py_DECREF(args);
1436n/a return result;
1437n/a}
1438n/a
1439n/a/* ---------------------------------------------------------------------------
1440n/a * Miscellaneous helpers.
1441n/a */
1442n/a
1443n/a/* For various reasons, we need to use tp_richcompare instead of tp_reserved.
1444n/a * The comparisons here all most naturally compute a cmp()-like result.
1445n/a * This little helper turns that into a bool result for rich comparisons.
1446n/a */
1447n/astatic PyObject *
1448n/adiff_to_bool(int diff, int op)
1449n/a{
1450n/a PyObject *result;
1451n/a int istrue;
1452n/a
1453n/a switch (op) {
1454n/a case Py_EQ: istrue = diff == 0; break;
1455n/a case Py_NE: istrue = diff != 0; break;
1456n/a case Py_LE: istrue = diff <= 0; break;
1457n/a case Py_GE: istrue = diff >= 0; break;
1458n/a case Py_LT: istrue = diff < 0; break;
1459n/a case Py_GT: istrue = diff > 0; break;
1460n/a default:
1461n/a assert(! "op unknown");
1462n/a istrue = 0; /* To shut up compiler */
1463n/a }
1464n/a result = istrue ? Py_True : Py_False;
1465n/a Py_INCREF(result);
1466n/a return result;
1467n/a}
1468n/a
1469n/a/* Raises a "can't compare" TypeError and returns NULL. */
1470n/astatic PyObject *
1471n/acmperror(PyObject *a, PyObject *b)
1472n/a{
1473n/a PyErr_Format(PyExc_TypeError,
1474n/a "can't compare %s to %s",
1475n/a Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
1476n/a return NULL;
1477n/a}
1478n/a
1479n/a/* ---------------------------------------------------------------------------
1480n/a * Cached Python objects; these are set by the module init function.
1481n/a */
1482n/a
1483n/a/* Conversion factors. */
1484n/astatic PyObject *one = NULL; /* 1 */
1485n/astatic PyObject *us_per_ms = NULL; /* 1000 */
1486n/astatic PyObject *us_per_second = NULL; /* 1000000 */
1487n/astatic PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */
1488n/astatic PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */
1489n/astatic PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */
1490n/astatic PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */
1491n/astatic PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
1492n/a
1493n/a/* ---------------------------------------------------------------------------
1494n/a * Class implementations.
1495n/a */
1496n/a
1497n/a/*
1498n/a * PyDateTime_Delta implementation.
1499n/a */
1500n/a
1501n/a/* Convert a timedelta to a number of us,
1502n/a * (24*3600*self.days + self.seconds)*1000000 + self.microseconds
1503n/a * as a Python int.
1504n/a * Doing mixed-radix arithmetic by hand instead is excruciating in C,
1505n/a * due to ubiquitous overflow possibilities.
1506n/a */
1507n/astatic PyObject *
1508n/adelta_to_microseconds(PyDateTime_Delta *self)
1509n/a{
1510n/a PyObject *x1 = NULL;
1511n/a PyObject *x2 = NULL;
1512n/a PyObject *x3 = NULL;
1513n/a PyObject *result = NULL;
1514n/a
1515n/a x1 = PyLong_FromLong(GET_TD_DAYS(self));
1516n/a if (x1 == NULL)
1517n/a goto Done;
1518n/a x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */
1519n/a if (x2 == NULL)
1520n/a goto Done;
1521n/a Py_DECREF(x1);
1522n/a x1 = NULL;
1523n/a
1524n/a /* x2 has days in seconds */
1525n/a x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */
1526n/a if (x1 == NULL)
1527n/a goto Done;
1528n/a x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */
1529n/a if (x3 == NULL)
1530n/a goto Done;
1531n/a Py_DECREF(x1);
1532n/a Py_DECREF(x2);
1533n/a /* x1 = */ x2 = NULL;
1534n/a
1535n/a /* x3 has days+seconds in seconds */
1536n/a x1 = PyNumber_Multiply(x3, us_per_second); /* us */
1537n/a if (x1 == NULL)
1538n/a goto Done;
1539n/a Py_DECREF(x3);
1540n/a x3 = NULL;
1541n/a
1542n/a /* x1 has days+seconds in us */
1543n/a x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self));
1544n/a if (x2 == NULL)
1545n/a goto Done;
1546n/a result = PyNumber_Add(x1, x2);
1547n/a
1548n/aDone:
1549n/a Py_XDECREF(x1);
1550n/a Py_XDECREF(x2);
1551n/a Py_XDECREF(x3);
1552n/a return result;
1553n/a}
1554n/a
1555n/a/* Convert a number of us (as a Python int) to a timedelta.
1556n/a */
1557n/astatic PyObject *
1558n/amicroseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1559n/a{
1560n/a int us;
1561n/a int s;
1562n/a int d;
1563n/a long temp;
1564n/a
1565n/a PyObject *tuple = NULL;
1566n/a PyObject *num = NULL;
1567n/a PyObject *result = NULL;
1568n/a
1569n/a tuple = PyNumber_Divmod(pyus, us_per_second);
1570n/a if (tuple == NULL)
1571n/a goto Done;
1572n/a
1573n/a num = PyTuple_GetItem(tuple, 1); /* us */
1574n/a if (num == NULL)
1575n/a goto Done;
1576n/a temp = PyLong_AsLong(num);
1577n/a num = NULL;
1578n/a if (temp == -1 && PyErr_Occurred())
1579n/a goto Done;
1580n/a assert(0 <= temp && temp < 1000000);
1581n/a us = (int)temp;
1582n/a if (us < 0) {
1583n/a /* The divisor was positive, so this must be an error. */
1584n/a assert(PyErr_Occurred());
1585n/a goto Done;
1586n/a }
1587n/a
1588n/a num = PyTuple_GetItem(tuple, 0); /* leftover seconds */
1589n/a if (num == NULL)
1590n/a goto Done;
1591n/a Py_INCREF(num);
1592n/a Py_DECREF(tuple);
1593n/a
1594n/a tuple = PyNumber_Divmod(num, seconds_per_day);
1595n/a if (tuple == NULL)
1596n/a goto Done;
1597n/a Py_DECREF(num);
1598n/a
1599n/a num = PyTuple_GetItem(tuple, 1); /* seconds */
1600n/a if (num == NULL)
1601n/a goto Done;
1602n/a temp = PyLong_AsLong(num);
1603n/a num = NULL;
1604n/a if (temp == -1 && PyErr_Occurred())
1605n/a goto Done;
1606n/a assert(0 <= temp && temp < 24*3600);
1607n/a s = (int)temp;
1608n/a
1609n/a if (s < 0) {
1610n/a /* The divisor was positive, so this must be an error. */
1611n/a assert(PyErr_Occurred());
1612n/a goto Done;
1613n/a }
1614n/a
1615n/a num = PyTuple_GetItem(tuple, 0); /* leftover days */
1616n/a if (num == NULL)
1617n/a goto Done;
1618n/a Py_INCREF(num);
1619n/a temp = PyLong_AsLong(num);
1620n/a if (temp == -1 && PyErr_Occurred())
1621n/a goto Done;
1622n/a d = (int)temp;
1623n/a if ((long)d != temp) {
1624n/a PyErr_SetString(PyExc_OverflowError, "normalized days too "
1625n/a "large to fit in a C int");
1626n/a goto Done;
1627n/a }
1628n/a result = new_delta_ex(d, s, us, 0, type);
1629n/a
1630n/aDone:
1631n/a Py_XDECREF(tuple);
1632n/a Py_XDECREF(num);
1633n/a return result;
1634n/a}
1635n/a
1636n/a#define microseconds_to_delta(pymicros) \
1637n/a microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType)
1638n/a
1639n/astatic PyObject *
1640n/amultiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1641n/a{
1642n/a PyObject *pyus_in;
1643n/a PyObject *pyus_out;
1644n/a PyObject *result;
1645n/a
1646n/a pyus_in = delta_to_microseconds(delta);
1647n/a if (pyus_in == NULL)
1648n/a return NULL;
1649n/a
1650n/a pyus_out = PyNumber_Multiply(pyus_in, intobj);
1651n/a Py_DECREF(pyus_in);
1652n/a if (pyus_out == NULL)
1653n/a return NULL;
1654n/a
1655n/a result = microseconds_to_delta(pyus_out);
1656n/a Py_DECREF(pyus_out);
1657n/a return result;
1658n/a}
1659n/a
1660n/astatic PyObject *
1661n/amultiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
1662n/a{
1663n/a PyObject *result = NULL;
1664n/a PyObject *pyus_in = NULL, *temp, *pyus_out;
1665n/a PyObject *ratio = NULL;
1666n/a
1667n/a pyus_in = delta_to_microseconds(delta);
1668n/a if (pyus_in == NULL)
1669n/a return NULL;
1670n/a ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1671n/a if (ratio == NULL)
1672n/a goto error;
1673n/a temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
1674n/a Py_DECREF(pyus_in);
1675n/a pyus_in = NULL;
1676n/a if (temp == NULL)
1677n/a goto error;
1678n/a pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1));
1679n/a Py_DECREF(temp);
1680n/a if (pyus_out == NULL)
1681n/a goto error;
1682n/a result = microseconds_to_delta(pyus_out);
1683n/a Py_DECREF(pyus_out);
1684n/a error:
1685n/a Py_XDECREF(pyus_in);
1686n/a Py_XDECREF(ratio);
1687n/a
1688n/a return result;
1689n/a}
1690n/a
1691n/astatic PyObject *
1692n/adivide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj)
1693n/a{
1694n/a PyObject *pyus_in;
1695n/a PyObject *pyus_out;
1696n/a PyObject *result;
1697n/a
1698n/a pyus_in = delta_to_microseconds(delta);
1699n/a if (pyus_in == NULL)
1700n/a return NULL;
1701n/a
1702n/a pyus_out = PyNumber_FloorDivide(pyus_in, intobj);
1703n/a Py_DECREF(pyus_in);
1704n/a if (pyus_out == NULL)
1705n/a return NULL;
1706n/a
1707n/a result = microseconds_to_delta(pyus_out);
1708n/a Py_DECREF(pyus_out);
1709n/a return result;
1710n/a}
1711n/a
1712n/astatic PyObject *
1713n/adivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1714n/a{
1715n/a PyObject *pyus_left;
1716n/a PyObject *pyus_right;
1717n/a PyObject *result;
1718n/a
1719n/a pyus_left = delta_to_microseconds(left);
1720n/a if (pyus_left == NULL)
1721n/a return NULL;
1722n/a
1723n/a pyus_right = delta_to_microseconds(right);
1724n/a if (pyus_right == NULL) {
1725n/a Py_DECREF(pyus_left);
1726n/a return NULL;
1727n/a }
1728n/a
1729n/a result = PyNumber_FloorDivide(pyus_left, pyus_right);
1730n/a Py_DECREF(pyus_left);
1731n/a Py_DECREF(pyus_right);
1732n/a return result;
1733n/a}
1734n/a
1735n/astatic PyObject *
1736n/atruedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right)
1737n/a{
1738n/a PyObject *pyus_left;
1739n/a PyObject *pyus_right;
1740n/a PyObject *result;
1741n/a
1742n/a pyus_left = delta_to_microseconds(left);
1743n/a if (pyus_left == NULL)
1744n/a return NULL;
1745n/a
1746n/a pyus_right = delta_to_microseconds(right);
1747n/a if (pyus_right == NULL) {
1748n/a Py_DECREF(pyus_left);
1749n/a return NULL;
1750n/a }
1751n/a
1752n/a result = PyNumber_TrueDivide(pyus_left, pyus_right);
1753n/a Py_DECREF(pyus_left);
1754n/a Py_DECREF(pyus_right);
1755n/a return result;
1756n/a}
1757n/a
1758n/astatic PyObject *
1759n/atruedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
1760n/a{
1761n/a PyObject *result = NULL;
1762n/a PyObject *pyus_in = NULL, *temp, *pyus_out;
1763n/a PyObject *ratio = NULL;
1764n/a
1765n/a pyus_in = delta_to_microseconds(delta);
1766n/a if (pyus_in == NULL)
1767n/a return NULL;
1768n/a ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
1769n/a if (ratio == NULL)
1770n/a goto error;
1771n/a temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
1772n/a Py_DECREF(pyus_in);
1773n/a pyus_in = NULL;
1774n/a if (temp == NULL)
1775n/a goto error;
1776n/a pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0));
1777n/a Py_DECREF(temp);
1778n/a if (pyus_out == NULL)
1779n/a goto error;
1780n/a result = microseconds_to_delta(pyus_out);
1781n/a Py_DECREF(pyus_out);
1782n/a error:
1783n/a Py_XDECREF(pyus_in);
1784n/a Py_XDECREF(ratio);
1785n/a
1786n/a return result;
1787n/a}
1788n/a
1789n/astatic PyObject *
1790n/atruedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i)
1791n/a{
1792n/a PyObject *result;
1793n/a PyObject *pyus_in, *pyus_out;
1794n/a pyus_in = delta_to_microseconds(delta);
1795n/a if (pyus_in == NULL)
1796n/a return NULL;
1797n/a pyus_out = divide_nearest(pyus_in, i);
1798n/a Py_DECREF(pyus_in);
1799n/a if (pyus_out == NULL)
1800n/a return NULL;
1801n/a result = microseconds_to_delta(pyus_out);
1802n/a Py_DECREF(pyus_out);
1803n/a
1804n/a return result;
1805n/a}
1806n/a
1807n/astatic PyObject *
1808n/adelta_add(PyObject *left, PyObject *right)
1809n/a{
1810n/a PyObject *result = Py_NotImplemented;
1811n/a
1812n/a if (PyDelta_Check(left) && PyDelta_Check(right)) {
1813n/a /* delta + delta */
1814n/a /* The C-level additions can't overflow because of the
1815n/a * invariant bounds.
1816n/a */
1817n/a int days = GET_TD_DAYS(left) + GET_TD_DAYS(right);
1818n/a int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right);
1819n/a int microseconds = GET_TD_MICROSECONDS(left) +
1820n/a GET_TD_MICROSECONDS(right);
1821n/a result = new_delta(days, seconds, microseconds, 1);
1822n/a }
1823n/a
1824n/a if (result == Py_NotImplemented)
1825n/a Py_INCREF(result);
1826n/a return result;
1827n/a}
1828n/a
1829n/astatic PyObject *
1830n/adelta_negative(PyDateTime_Delta *self)
1831n/a{
1832n/a return new_delta(-GET_TD_DAYS(self),
1833n/a -GET_TD_SECONDS(self),
1834n/a -GET_TD_MICROSECONDS(self),
1835n/a 1);
1836n/a}
1837n/a
1838n/astatic PyObject *
1839n/adelta_positive(PyDateTime_Delta *self)
1840n/a{
1841n/a /* Could optimize this (by returning self) if this isn't a
1842n/a * subclass -- but who uses unary + ? Approximately nobody.
1843n/a */
1844n/a return new_delta(GET_TD_DAYS(self),
1845n/a GET_TD_SECONDS(self),
1846n/a GET_TD_MICROSECONDS(self),
1847n/a 0);
1848n/a}
1849n/a
1850n/astatic PyObject *
1851n/adelta_abs(PyDateTime_Delta *self)
1852n/a{
1853n/a PyObject *result;
1854n/a
1855n/a assert(GET_TD_MICROSECONDS(self) >= 0);
1856n/a assert(GET_TD_SECONDS(self) >= 0);
1857n/a
1858n/a if (GET_TD_DAYS(self) < 0)
1859n/a result = delta_negative(self);
1860n/a else
1861n/a result = delta_positive(self);
1862n/a
1863n/a return result;
1864n/a}
1865n/a
1866n/astatic PyObject *
1867n/adelta_subtract(PyObject *left, PyObject *right)
1868n/a{
1869n/a PyObject *result = Py_NotImplemented;
1870n/a
1871n/a if (PyDelta_Check(left) && PyDelta_Check(right)) {
1872n/a /* delta - delta */
1873n/a /* The C-level additions can't overflow because of the
1874n/a * invariant bounds.
1875n/a */
1876n/a int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1877n/a int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1878n/a int microseconds = GET_TD_MICROSECONDS(left) -
1879n/a GET_TD_MICROSECONDS(right);
1880n/a result = new_delta(days, seconds, microseconds, 1);
1881n/a }
1882n/a
1883n/a if (result == Py_NotImplemented)
1884n/a Py_INCREF(result);
1885n/a return result;
1886n/a}
1887n/a
1888n/astatic int
1889n/adelta_cmp(PyObject *self, PyObject *other)
1890n/a{
1891n/a int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other);
1892n/a if (diff == 0) {
1893n/a diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other);
1894n/a if (diff == 0)
1895n/a diff = GET_TD_MICROSECONDS(self) -
1896n/a GET_TD_MICROSECONDS(other);
1897n/a }
1898n/a return diff;
1899n/a}
1900n/a
1901n/astatic PyObject *
1902n/adelta_richcompare(PyObject *self, PyObject *other, int op)
1903n/a{
1904n/a if (PyDelta_Check(other)) {
1905n/a int diff = delta_cmp(self, other);
1906n/a return diff_to_bool(diff, op);
1907n/a }
1908n/a else {
1909n/a Py_RETURN_NOTIMPLEMENTED;
1910n/a }
1911n/a}
1912n/a
1913n/astatic PyObject *delta_getstate(PyDateTime_Delta *self);
1914n/a
1915n/astatic Py_hash_t
1916n/adelta_hash(PyDateTime_Delta *self)
1917n/a{
1918n/a if (self->hashcode == -1) {
1919n/a PyObject *temp = delta_getstate(self);
1920n/a if (temp != NULL) {
1921n/a self->hashcode = PyObject_Hash(temp);
1922n/a Py_DECREF(temp);
1923n/a }
1924n/a }
1925n/a return self->hashcode;
1926n/a}
1927n/a
1928n/astatic PyObject *
1929n/adelta_multiply(PyObject *left, PyObject *right)
1930n/a{
1931n/a PyObject *result = Py_NotImplemented;
1932n/a
1933n/a if (PyDelta_Check(left)) {
1934n/a /* delta * ??? */
1935n/a if (PyLong_Check(right))
1936n/a result = multiply_int_timedelta(right,
1937n/a (PyDateTime_Delta *) left);
1938n/a else if (PyFloat_Check(right))
1939n/a result = multiply_float_timedelta(right,
1940n/a (PyDateTime_Delta *) left);
1941n/a }
1942n/a else if (PyLong_Check(left))
1943n/a result = multiply_int_timedelta(left,
1944n/a (PyDateTime_Delta *) right);
1945n/a else if (PyFloat_Check(left))
1946n/a result = multiply_float_timedelta(left,
1947n/a (PyDateTime_Delta *) right);
1948n/a
1949n/a if (result == Py_NotImplemented)
1950n/a Py_INCREF(result);
1951n/a return result;
1952n/a}
1953n/a
1954n/astatic PyObject *
1955n/adelta_divide(PyObject *left, PyObject *right)
1956n/a{
1957n/a PyObject *result = Py_NotImplemented;
1958n/a
1959n/a if (PyDelta_Check(left)) {
1960n/a /* delta * ??? */
1961n/a if (PyLong_Check(right))
1962n/a result = divide_timedelta_int(
1963n/a (PyDateTime_Delta *)left,
1964n/a right);
1965n/a else if (PyDelta_Check(right))
1966n/a result = divide_timedelta_timedelta(
1967n/a (PyDateTime_Delta *)left,
1968n/a (PyDateTime_Delta *)right);
1969n/a }
1970n/a
1971n/a if (result == Py_NotImplemented)
1972n/a Py_INCREF(result);
1973n/a return result;
1974n/a}
1975n/a
1976n/astatic PyObject *
1977n/adelta_truedivide(PyObject *left, PyObject *right)
1978n/a{
1979n/a PyObject *result = Py_NotImplemented;
1980n/a
1981n/a if (PyDelta_Check(left)) {
1982n/a if (PyDelta_Check(right))
1983n/a result = truedivide_timedelta_timedelta(
1984n/a (PyDateTime_Delta *)left,
1985n/a (PyDateTime_Delta *)right);
1986n/a else if (PyFloat_Check(right))
1987n/a result = truedivide_timedelta_float(
1988n/a (PyDateTime_Delta *)left, right);
1989n/a else if (PyLong_Check(right))
1990n/a result = truedivide_timedelta_int(
1991n/a (PyDateTime_Delta *)left, right);
1992n/a }
1993n/a
1994n/a if (result == Py_NotImplemented)
1995n/a Py_INCREF(result);
1996n/a return result;
1997n/a}
1998n/a
1999n/astatic PyObject *
2000n/adelta_remainder(PyObject *left, PyObject *right)
2001n/a{
2002n/a PyObject *pyus_left;
2003n/a PyObject *pyus_right;
2004n/a PyObject *pyus_remainder;
2005n/a PyObject *remainder;
2006n/a
2007n/a if (!PyDelta_Check(left) || !PyDelta_Check(right))
2008n/a Py_RETURN_NOTIMPLEMENTED;
2009n/a
2010n/a pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2011n/a if (pyus_left == NULL)
2012n/a return NULL;
2013n/a
2014n/a pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2015n/a if (pyus_right == NULL) {
2016n/a Py_DECREF(pyus_left);
2017n/a return NULL;
2018n/a }
2019n/a
2020n/a pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right);
2021n/a Py_DECREF(pyus_left);
2022n/a Py_DECREF(pyus_right);
2023n/a if (pyus_remainder == NULL)
2024n/a return NULL;
2025n/a
2026n/a remainder = microseconds_to_delta(pyus_remainder);
2027n/a Py_DECREF(pyus_remainder);
2028n/a if (remainder == NULL)
2029n/a return NULL;
2030n/a
2031n/a return remainder;
2032n/a}
2033n/a
2034n/astatic PyObject *
2035n/adelta_divmod(PyObject *left, PyObject *right)
2036n/a{
2037n/a PyObject *pyus_left;
2038n/a PyObject *pyus_right;
2039n/a PyObject *divmod;
2040n/a PyObject *delta;
2041n/a PyObject *result;
2042n/a
2043n/a if (!PyDelta_Check(left) || !PyDelta_Check(right))
2044n/a Py_RETURN_NOTIMPLEMENTED;
2045n/a
2046n/a pyus_left = delta_to_microseconds((PyDateTime_Delta *)left);
2047n/a if (pyus_left == NULL)
2048n/a return NULL;
2049n/a
2050n/a pyus_right = delta_to_microseconds((PyDateTime_Delta *)right);
2051n/a if (pyus_right == NULL) {
2052n/a Py_DECREF(pyus_left);
2053n/a return NULL;
2054n/a }
2055n/a
2056n/a divmod = PyNumber_Divmod(pyus_left, pyus_right);
2057n/a Py_DECREF(pyus_left);
2058n/a Py_DECREF(pyus_right);
2059n/a if (divmod == NULL)
2060n/a return NULL;
2061n/a
2062n/a assert(PyTuple_Size(divmod) == 2);
2063n/a delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1));
2064n/a if (delta == NULL) {
2065n/a Py_DECREF(divmod);
2066n/a return NULL;
2067n/a }
2068n/a result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta);
2069n/a Py_DECREF(delta);
2070n/a Py_DECREF(divmod);
2071n/a return result;
2072n/a}
2073n/a
2074n/a/* Fold in the value of the tag ("seconds", "weeks", etc) component of a
2075n/a * timedelta constructor. sofar is the # of microseconds accounted for
2076n/a * so far, and there are factor microseconds per current unit, the number
2077n/a * of which is given by num. num * factor is added to sofar in a
2078n/a * numerically careful way, and that's the result. Any fractional
2079n/a * microseconds left over (this can happen if num is a float type) are
2080n/a * added into *leftover.
2081n/a * Note that there are many ways this can give an error (NULL) return.
2082n/a */
2083n/astatic PyObject *
2084n/aaccum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2085n/a double *leftover)
2086n/a{
2087n/a PyObject *prod;
2088n/a PyObject *sum;
2089n/a
2090n/a assert(num != NULL);
2091n/a
2092n/a if (PyLong_Check(num)) {
2093n/a prod = PyNumber_Multiply(num, factor);
2094n/a if (prod == NULL)
2095n/a return NULL;
2096n/a sum = PyNumber_Add(sofar, prod);
2097n/a Py_DECREF(prod);
2098n/a return sum;
2099n/a }
2100n/a
2101n/a if (PyFloat_Check(num)) {
2102n/a double dnum;
2103n/a double fracpart;
2104n/a double intpart;
2105n/a PyObject *x;
2106n/a PyObject *y;
2107n/a
2108n/a /* The Plan: decompose num into an integer part and a
2109n/a * fractional part, num = intpart + fracpart.
2110n/a * Then num * factor ==
2111n/a * intpart * factor + fracpart * factor
2112n/a * and the LHS can be computed exactly in long arithmetic.
2113n/a * The RHS is again broken into an int part and frac part.
2114n/a * and the frac part is added into *leftover.
2115n/a */
2116n/a dnum = PyFloat_AsDouble(num);
2117n/a if (dnum == -1.0 && PyErr_Occurred())
2118n/a return NULL;
2119n/a fracpart = modf(dnum, &intpart);
2120n/a x = PyLong_FromDouble(intpart);
2121n/a if (x == NULL)
2122n/a return NULL;
2123n/a
2124n/a prod = PyNumber_Multiply(x, factor);
2125n/a Py_DECREF(x);
2126n/a if (prod == NULL)
2127n/a return NULL;
2128n/a
2129n/a sum = PyNumber_Add(sofar, prod);
2130n/a Py_DECREF(prod);
2131n/a if (sum == NULL)
2132n/a return NULL;
2133n/a
2134n/a if (fracpart == 0.0)
2135n/a return sum;
2136n/a /* So far we've lost no information. Dealing with the
2137n/a * fractional part requires float arithmetic, and may
2138n/a * lose a little info.
2139n/a */
2140n/a assert(PyLong_Check(factor));
2141n/a dnum = PyLong_AsDouble(factor);
2142n/a
2143n/a dnum *= fracpart;
2144n/a fracpart = modf(dnum, &intpart);
2145n/a x = PyLong_FromDouble(intpart);
2146n/a if (x == NULL) {
2147n/a Py_DECREF(sum);
2148n/a return NULL;
2149n/a }
2150n/a
2151n/a y = PyNumber_Add(sum, x);
2152n/a Py_DECREF(sum);
2153n/a Py_DECREF(x);
2154n/a *leftover += fracpart;
2155n/a return y;
2156n/a }
2157n/a
2158n/a PyErr_Format(PyExc_TypeError,
2159n/a "unsupported type for timedelta %s component: %s",
2160n/a tag, Py_TYPE(num)->tp_name);
2161n/a return NULL;
2162n/a}
2163n/a
2164n/astatic PyObject *
2165n/adelta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2166n/a{
2167n/a PyObject *self = NULL;
2168n/a
2169n/a /* Argument objects. */
2170n/a PyObject *day = NULL;
2171n/a PyObject *second = NULL;
2172n/a PyObject *us = NULL;
2173n/a PyObject *ms = NULL;
2174n/a PyObject *minute = NULL;
2175n/a PyObject *hour = NULL;
2176n/a PyObject *week = NULL;
2177n/a
2178n/a PyObject *x = NULL; /* running sum of microseconds */
2179n/a PyObject *y = NULL; /* temp sum of microseconds */
2180n/a double leftover_us = 0.0;
2181n/a
2182n/a static char *keywords[] = {
2183n/a "days", "seconds", "microseconds", "milliseconds",
2184n/a "minutes", "hours", "weeks", NULL
2185n/a };
2186n/a
2187n/a if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__",
2188n/a keywords,
2189n/a &day, &second, &us,
2190n/a &ms, &minute, &hour, &week) == 0)
2191n/a goto Done;
2192n/a
2193n/a x = PyLong_FromLong(0);
2194n/a if (x == NULL)
2195n/a goto Done;
2196n/a
2197n/a#define CLEANUP \
2198n/a Py_DECREF(x); \
2199n/a x = y; \
2200n/a if (x == NULL) \
2201n/a goto Done
2202n/a
2203n/a if (us) {
2204n/a y = accum("microseconds", x, us, one, &leftover_us);
2205n/a CLEANUP;
2206n/a }
2207n/a if (ms) {
2208n/a y = accum("milliseconds", x, ms, us_per_ms, &leftover_us);
2209n/a CLEANUP;
2210n/a }
2211n/a if (second) {
2212n/a y = accum("seconds", x, second, us_per_second, &leftover_us);
2213n/a CLEANUP;
2214n/a }
2215n/a if (minute) {
2216n/a y = accum("minutes", x, minute, us_per_minute, &leftover_us);
2217n/a CLEANUP;
2218n/a }
2219n/a if (hour) {
2220n/a y = accum("hours", x, hour, us_per_hour, &leftover_us);
2221n/a CLEANUP;
2222n/a }
2223n/a if (day) {
2224n/a y = accum("days", x, day, us_per_day, &leftover_us);
2225n/a CLEANUP;
2226n/a }
2227n/a if (week) {
2228n/a y = accum("weeks", x, week, us_per_week, &leftover_us);
2229n/a CLEANUP;
2230n/a }
2231n/a if (leftover_us) {
2232n/a /* Round to nearest whole # of us, and add into x. */
2233n/a double whole_us = round(leftover_us);
2234n/a int x_is_odd;
2235n/a PyObject *temp;
2236n/a
2237n/a whole_us = round(leftover_us);
2238n/a if (fabs(whole_us - leftover_us) == 0.5) {
2239n/a /* We're exactly halfway between two integers. In order
2240n/a * to do round-half-to-even, we must determine whether x
2241n/a * is odd. Note that x is odd when it's last bit is 1. The
2242n/a * code below uses bitwise and operation to check the last
2243n/a * bit. */
2244n/a temp = PyNumber_And(x, one); /* temp <- x & 1 */
2245n/a if (temp == NULL) {
2246n/a Py_DECREF(x);
2247n/a goto Done;
2248n/a }
2249n/a x_is_odd = PyObject_IsTrue(temp);
2250n/a Py_DECREF(temp);
2251n/a if (x_is_odd == -1) {
2252n/a Py_DECREF(x);
2253n/a goto Done;
2254n/a }
2255n/a whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2256n/a }
2257n/a
2258n/a temp = PyLong_FromLong((long)whole_us);
2259n/a
2260n/a if (temp == NULL) {
2261n/a Py_DECREF(x);
2262n/a goto Done;
2263n/a }
2264n/a y = PyNumber_Add(x, temp);
2265n/a Py_DECREF(temp);
2266n/a CLEANUP;
2267n/a }
2268n/a
2269n/a self = microseconds_to_delta_ex(x, type);
2270n/a Py_DECREF(x);
2271n/aDone:
2272n/a return self;
2273n/a
2274n/a#undef CLEANUP
2275n/a}
2276n/a
2277n/astatic int
2278n/adelta_bool(PyDateTime_Delta *self)
2279n/a{
2280n/a return (GET_TD_DAYS(self) != 0
2281n/a || GET_TD_SECONDS(self) != 0
2282n/a || GET_TD_MICROSECONDS(self) != 0);
2283n/a}
2284n/a
2285n/astatic PyObject *
2286n/adelta_repr(PyDateTime_Delta *self)
2287n/a{
2288n/a if (GET_TD_MICROSECONDS(self) != 0)
2289n/a return PyUnicode_FromFormat("%s(%d, %d, %d)",
2290n/a Py_TYPE(self)->tp_name,
2291n/a GET_TD_DAYS(self),
2292n/a GET_TD_SECONDS(self),
2293n/a GET_TD_MICROSECONDS(self));
2294n/a if (GET_TD_SECONDS(self) != 0)
2295n/a return PyUnicode_FromFormat("%s(%d, %d)",
2296n/a Py_TYPE(self)->tp_name,
2297n/a GET_TD_DAYS(self),
2298n/a GET_TD_SECONDS(self));
2299n/a
2300n/a return PyUnicode_FromFormat("%s(%d)",
2301n/a Py_TYPE(self)->tp_name,
2302n/a GET_TD_DAYS(self));
2303n/a}
2304n/a
2305n/astatic PyObject *
2306n/adelta_str(PyDateTime_Delta *self)
2307n/a{
2308n/a int us = GET_TD_MICROSECONDS(self);
2309n/a int seconds = GET_TD_SECONDS(self);
2310n/a int minutes = divmod(seconds, 60, &seconds);
2311n/a int hours = divmod(minutes, 60, &minutes);
2312n/a int days = GET_TD_DAYS(self);
2313n/a
2314n/a if (days) {
2315n/a if (us)
2316n/a return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d",
2317n/a days, (days == 1 || days == -1) ? "" : "s",
2318n/a hours, minutes, seconds, us);
2319n/a else
2320n/a return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d",
2321n/a days, (days == 1 || days == -1) ? "" : "s",
2322n/a hours, minutes, seconds);
2323n/a } else {
2324n/a if (us)
2325n/a return PyUnicode_FromFormat("%d:%02d:%02d.%06d",
2326n/a hours, minutes, seconds, us);
2327n/a else
2328n/a return PyUnicode_FromFormat("%d:%02d:%02d",
2329n/a hours, minutes, seconds);
2330n/a }
2331n/a
2332n/a}
2333n/a
2334n/a/* Pickle support, a simple use of __reduce__. */
2335n/a
2336n/a/* __getstate__ isn't exposed */
2337n/astatic PyObject *
2338n/adelta_getstate(PyDateTime_Delta *self)
2339n/a{
2340n/a return Py_BuildValue("iii", GET_TD_DAYS(self),
2341n/a GET_TD_SECONDS(self),
2342n/a GET_TD_MICROSECONDS(self));
2343n/a}
2344n/a
2345n/astatic PyObject *
2346n/adelta_total_seconds(PyObject *self)
2347n/a{
2348n/a PyObject *total_seconds;
2349n/a PyObject *total_microseconds;
2350n/a
2351n/a total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
2352n/a if (total_microseconds == NULL)
2353n/a return NULL;
2354n/a
2355n/a total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second);
2356n/a
2357n/a Py_DECREF(total_microseconds);
2358n/a return total_seconds;
2359n/a}
2360n/a
2361n/astatic PyObject *
2362n/adelta_reduce(PyDateTime_Delta* self)
2363n/a{
2364n/a return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self));
2365n/a}
2366n/a
2367n/a#define OFFSET(field) offsetof(PyDateTime_Delta, field)
2368n/a
2369n/astatic PyMemberDef delta_members[] = {
2370n/a
2371n/a {"days", T_INT, OFFSET(days), READONLY,
2372n/a PyDoc_STR("Number of days.")},
2373n/a
2374n/a {"seconds", T_INT, OFFSET(seconds), READONLY,
2375n/a PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")},
2376n/a
2377n/a {"microseconds", T_INT, OFFSET(microseconds), READONLY,
2378n/a PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")},
2379n/a {NULL}
2380n/a};
2381n/a
2382n/astatic PyMethodDef delta_methods[] = {
2383n/a {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS,
2384n/a PyDoc_STR("Total seconds in the duration.")},
2385n/a
2386n/a {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS,
2387n/a PyDoc_STR("__reduce__() -> (cls, state)")},
2388n/a
2389n/a {NULL, NULL},
2390n/a};
2391n/a
2392n/astatic const char delta_doc[] =
2393n/aPyDoc_STR("Difference between two datetime values.");
2394n/a
2395n/astatic PyNumberMethods delta_as_number = {
2396n/a delta_add, /* nb_add */
2397n/a delta_subtract, /* nb_subtract */
2398n/a delta_multiply, /* nb_multiply */
2399n/a delta_remainder, /* nb_remainder */
2400n/a delta_divmod, /* nb_divmod */
2401n/a 0, /* nb_power */
2402n/a (unaryfunc)delta_negative, /* nb_negative */
2403n/a (unaryfunc)delta_positive, /* nb_positive */
2404n/a (unaryfunc)delta_abs, /* nb_absolute */
2405n/a (inquiry)delta_bool, /* nb_bool */
2406n/a 0, /*nb_invert*/
2407n/a 0, /*nb_lshift*/
2408n/a 0, /*nb_rshift*/
2409n/a 0, /*nb_and*/
2410n/a 0, /*nb_xor*/
2411n/a 0, /*nb_or*/
2412n/a 0, /*nb_int*/
2413n/a 0, /*nb_reserved*/
2414n/a 0, /*nb_float*/
2415n/a 0, /*nb_inplace_add*/
2416n/a 0, /*nb_inplace_subtract*/
2417n/a 0, /*nb_inplace_multiply*/
2418n/a 0, /*nb_inplace_remainder*/
2419n/a 0, /*nb_inplace_power*/
2420n/a 0, /*nb_inplace_lshift*/
2421n/a 0, /*nb_inplace_rshift*/
2422n/a 0, /*nb_inplace_and*/
2423n/a 0, /*nb_inplace_xor*/
2424n/a 0, /*nb_inplace_or*/
2425n/a delta_divide, /* nb_floor_divide */
2426n/a delta_truedivide, /* nb_true_divide */
2427n/a 0, /* nb_inplace_floor_divide */
2428n/a 0, /* nb_inplace_true_divide */
2429n/a};
2430n/a
2431n/astatic PyTypeObject PyDateTime_DeltaType = {
2432n/a PyVarObject_HEAD_INIT(NULL, 0)
2433n/a "datetime.timedelta", /* tp_name */
2434n/a sizeof(PyDateTime_Delta), /* tp_basicsize */
2435n/a 0, /* tp_itemsize */
2436n/a 0, /* tp_dealloc */
2437n/a 0, /* tp_print */
2438n/a 0, /* tp_getattr */
2439n/a 0, /* tp_setattr */
2440n/a 0, /* tp_reserved */
2441n/a (reprfunc)delta_repr, /* tp_repr */
2442n/a &delta_as_number, /* tp_as_number */
2443n/a 0, /* tp_as_sequence */
2444n/a 0, /* tp_as_mapping */
2445n/a (hashfunc)delta_hash, /* tp_hash */
2446n/a 0, /* tp_call */
2447n/a (reprfunc)delta_str, /* tp_str */
2448n/a PyObject_GenericGetAttr, /* tp_getattro */
2449n/a 0, /* tp_setattro */
2450n/a 0, /* tp_as_buffer */
2451n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2452n/a delta_doc, /* tp_doc */
2453n/a 0, /* tp_traverse */
2454n/a 0, /* tp_clear */
2455n/a delta_richcompare, /* tp_richcompare */
2456n/a 0, /* tp_weaklistoffset */
2457n/a 0, /* tp_iter */
2458n/a 0, /* tp_iternext */
2459n/a delta_methods, /* tp_methods */
2460n/a delta_members, /* tp_members */
2461n/a 0, /* tp_getset */
2462n/a 0, /* tp_base */
2463n/a 0, /* tp_dict */
2464n/a 0, /* tp_descr_get */
2465n/a 0, /* tp_descr_set */
2466n/a 0, /* tp_dictoffset */
2467n/a 0, /* tp_init */
2468n/a 0, /* tp_alloc */
2469n/a delta_new, /* tp_new */
2470n/a 0, /* tp_free */
2471n/a};
2472n/a
2473n/a/*
2474n/a * PyDateTime_Date implementation.
2475n/a */
2476n/a
2477n/a/* Accessor properties. */
2478n/a
2479n/astatic PyObject *
2480n/adate_year(PyDateTime_Date *self, void *unused)
2481n/a{
2482n/a return PyLong_FromLong(GET_YEAR(self));
2483n/a}
2484n/a
2485n/astatic PyObject *
2486n/adate_month(PyDateTime_Date *self, void *unused)
2487n/a{
2488n/a return PyLong_FromLong(GET_MONTH(self));
2489n/a}
2490n/a
2491n/astatic PyObject *
2492n/adate_day(PyDateTime_Date *self, void *unused)
2493n/a{
2494n/a return PyLong_FromLong(GET_DAY(self));
2495n/a}
2496n/a
2497n/astatic PyGetSetDef date_getset[] = {
2498n/a {"year", (getter)date_year},
2499n/a {"month", (getter)date_month},
2500n/a {"day", (getter)date_day},
2501n/a {NULL}
2502n/a};
2503n/a
2504n/a/* Constructors. */
2505n/a
2506n/astatic char *date_kws[] = {"year", "month", "day", NULL};
2507n/a
2508n/astatic PyObject *
2509n/adate_new(PyTypeObject *type, PyObject *args, PyObject *kw)
2510n/a{
2511n/a PyObject *self = NULL;
2512n/a PyObject *state;
2513n/a int year;
2514n/a int month;
2515n/a int day;
2516n/a
2517n/a /* Check for invocation from pickle with __getstate__ state */
2518n/a if (PyTuple_GET_SIZE(args) == 1 &&
2519n/a PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
2520n/a PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE &&
2521n/a MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))
2522n/a {
2523n/a PyDateTime_Date *me;
2524n/a
2525n/a me = (PyDateTime_Date *) (type->tp_alloc(type, 0));
2526n/a if (me != NULL) {
2527n/a char *pdata = PyBytes_AS_STRING(state);
2528n/a memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
2529n/a me->hashcode = -1;
2530n/a }
2531n/a return (PyObject *)me;
2532n/a }
2533n/a
2534n/a if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws,
2535n/a &year, &month, &day)) {
2536n/a self = new_date_ex(year, month, day, type);
2537n/a }
2538n/a return self;
2539n/a}
2540n/a
2541n/a/* Return new date from localtime(t). */
2542n/astatic PyObject *
2543n/adate_local_from_object(PyObject *cls, PyObject *obj)
2544n/a{
2545n/a struct tm tm;
2546n/a time_t t;
2547n/a
2548n/a if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1)
2549n/a return NULL;
2550n/a
2551n/a if (_PyTime_localtime(t, &tm) != 0)
2552n/a return NULL;
2553n/a
2554n/a return PyObject_CallFunction(cls, "iii",
2555n/a tm.tm_year + 1900,
2556n/a tm.tm_mon + 1,
2557n/a tm.tm_mday);
2558n/a}
2559n/a
2560n/a/* Return new date from current time.
2561n/a * We say this is equivalent to fromtimestamp(time.time()), and the
2562n/a * only way to be sure of that is to *call* time.time(). That's not
2563n/a * generally the same as calling C's time.
2564n/a */
2565n/astatic PyObject *
2566n/adate_today(PyObject *cls, PyObject *dummy)
2567n/a{
2568n/a PyObject *time;
2569n/a PyObject *result;
2570n/a _Py_IDENTIFIER(fromtimestamp);
2571n/a
2572n/a time = time_time();
2573n/a if (time == NULL)
2574n/a return NULL;
2575n/a
2576n/a /* Note well: today() is a class method, so this may not call
2577n/a * date.fromtimestamp. For example, it may call
2578n/a * datetime.fromtimestamp. That's why we need all the accuracy
2579n/a * time.time() delivers; if someone were gonzo about optimization,
2580n/a * date.today() could get away with plain C time().
2581n/a */
2582n/a result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp,
2583n/a time, NULL);
2584n/a Py_DECREF(time);
2585n/a return result;
2586n/a}
2587n/a
2588n/a/* Return new date from given timestamp (Python timestamp -- a double). */
2589n/astatic PyObject *
2590n/adate_fromtimestamp(PyObject *cls, PyObject *args)
2591n/a{
2592n/a PyObject *timestamp;
2593n/a PyObject *result = NULL;
2594n/a
2595n/a if (PyArg_ParseTuple(args, "O:fromtimestamp", &timestamp))
2596n/a result = date_local_from_object(cls, timestamp);
2597n/a return result;
2598n/a}
2599n/a
2600n/a/* Return new date from proleptic Gregorian ordinal. Raises ValueError if
2601n/a * the ordinal is out of range.
2602n/a */
2603n/astatic PyObject *
2604n/adate_fromordinal(PyObject *cls, PyObject *args)
2605n/a{
2606n/a PyObject *result = NULL;
2607n/a int ordinal;
2608n/a
2609n/a if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) {
2610n/a int year;
2611n/a int month;
2612n/a int day;
2613n/a
2614n/a if (ordinal < 1)
2615n/a PyErr_SetString(PyExc_ValueError, "ordinal must be "
2616n/a ">= 1");
2617n/a else {
2618n/a ord_to_ymd(ordinal, &year, &month, &day);
2619n/a result = PyObject_CallFunction(cls, "iii",
2620n/a year, month, day);
2621n/a }
2622n/a }
2623n/a return result;
2624n/a}
2625n/a
2626n/a/*
2627n/a * Date arithmetic.
2628n/a */
2629n/a
2630n/a/* date + timedelta -> date. If arg negate is true, subtract the timedelta
2631n/a * instead.
2632n/a */
2633n/astatic PyObject *
2634n/aadd_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate)
2635n/a{
2636n/a PyObject *result = NULL;
2637n/a int year = GET_YEAR(date);
2638n/a int month = GET_MONTH(date);
2639n/a int deltadays = GET_TD_DAYS(delta);
2640n/a /* C-level overflow is impossible because |deltadays| < 1e9. */
2641n/a int day = GET_DAY(date) + (negate ? -deltadays : deltadays);
2642n/a
2643n/a if (normalize_date(&year, &month, &day) >= 0)
2644n/a result = new_date(year, month, day);
2645n/a return result;
2646n/a}
2647n/a
2648n/astatic PyObject *
2649n/adate_add(PyObject *left, PyObject *right)
2650n/a{
2651n/a if (PyDateTime_Check(left) || PyDateTime_Check(right))
2652n/a Py_RETURN_NOTIMPLEMENTED;
2653n/a
2654n/a if (PyDate_Check(left)) {
2655n/a /* date + ??? */
2656n/a if (PyDelta_Check(right))
2657n/a /* date + delta */
2658n/a return add_date_timedelta((PyDateTime_Date *) left,
2659n/a (PyDateTime_Delta *) right,
2660n/a 0);
2661n/a }
2662n/a else {
2663n/a /* ??? + date
2664n/a * 'right' must be one of us, or we wouldn't have been called
2665n/a */
2666n/a if (PyDelta_Check(left))
2667n/a /* delta + date */
2668n/a return add_date_timedelta((PyDateTime_Date *) right,
2669n/a (PyDateTime_Delta *) left,
2670n/a 0);
2671n/a }
2672n/a Py_RETURN_NOTIMPLEMENTED;
2673n/a}
2674n/a
2675n/astatic PyObject *
2676n/adate_subtract(PyObject *left, PyObject *right)
2677n/a{
2678n/a if (PyDateTime_Check(left) || PyDateTime_Check(right))
2679n/a Py_RETURN_NOTIMPLEMENTED;
2680n/a
2681n/a if (PyDate_Check(left)) {
2682n/a if (PyDate_Check(right)) {
2683n/a /* date - date */
2684n/a int left_ord = ymd_to_ord(GET_YEAR(left),
2685n/a GET_MONTH(left),
2686n/a GET_DAY(left));
2687n/a int right_ord = ymd_to_ord(GET_YEAR(right),
2688n/a GET_MONTH(right),
2689n/a GET_DAY(right));
2690n/a return new_delta(left_ord - right_ord, 0, 0, 0);
2691n/a }
2692n/a if (PyDelta_Check(right)) {
2693n/a /* date - delta */
2694n/a return add_date_timedelta((PyDateTime_Date *) left,
2695n/a (PyDateTime_Delta *) right,
2696n/a 1);
2697n/a }
2698n/a }
2699n/a Py_RETURN_NOTIMPLEMENTED;
2700n/a}
2701n/a
2702n/a
2703n/a/* Various ways to turn a date into a string. */
2704n/a
2705n/astatic PyObject *
2706n/adate_repr(PyDateTime_Date *self)
2707n/a{
2708n/a return PyUnicode_FromFormat("%s(%d, %d, %d)",
2709n/a Py_TYPE(self)->tp_name,
2710n/a GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2711n/a}
2712n/a
2713n/astatic PyObject *
2714n/adate_isoformat(PyDateTime_Date *self)
2715n/a{
2716n/a return PyUnicode_FromFormat("%04d-%02d-%02d",
2717n/a GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2718n/a}
2719n/a
2720n/a/* str() calls the appropriate isoformat() method. */
2721n/astatic PyObject *
2722n/adate_str(PyDateTime_Date *self)
2723n/a{
2724n/a return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
2725n/a}
2726n/a
2727n/a
2728n/astatic PyObject *
2729n/adate_ctime(PyDateTime_Date *self)
2730n/a{
2731n/a return format_ctime(self, 0, 0, 0);
2732n/a}
2733n/a
2734n/astatic PyObject *
2735n/adate_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2736n/a{
2737n/a /* This method can be inherited, and needs to call the
2738n/a * timetuple() method appropriate to self's class.
2739n/a */
2740n/a PyObject *result;
2741n/a PyObject *tuple;
2742n/a PyObject *format;
2743n/a _Py_IDENTIFIER(timetuple);
2744n/a static char *keywords[] = {"format", NULL};
2745n/a
2746n/a if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
2747n/a &format))
2748n/a return NULL;
2749n/a
2750n/a tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
2751n/a if (tuple == NULL)
2752n/a return NULL;
2753n/a result = wrap_strftime((PyObject *)self, format, tuple,
2754n/a (PyObject *)self);
2755n/a Py_DECREF(tuple);
2756n/a return result;
2757n/a}
2758n/a
2759n/astatic PyObject *
2760n/adate_format(PyDateTime_Date *self, PyObject *args)
2761n/a{
2762n/a PyObject *format;
2763n/a
2764n/a if (!PyArg_ParseTuple(args, "U:__format__", &format))
2765n/a return NULL;
2766n/a
2767n/a /* if the format is zero length, return str(self) */
2768n/a if (PyUnicode_GetLength(format) == 0)
2769n/a return PyObject_Str((PyObject *)self);
2770n/a
2771n/a return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime,
2772n/a format, NULL);
2773n/a}
2774n/a
2775n/a/* ISO methods. */
2776n/a
2777n/astatic PyObject *
2778n/adate_isoweekday(PyDateTime_Date *self)
2779n/a{
2780n/a int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2781n/a
2782n/a return PyLong_FromLong(dow + 1);
2783n/a}
2784n/a
2785n/astatic PyObject *
2786n/adate_isocalendar(PyDateTime_Date *self)
2787n/a{
2788n/a int year = GET_YEAR(self);
2789n/a int week1_monday = iso_week1_monday(year);
2790n/a int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self));
2791n/a int week;
2792n/a int day;
2793n/a
2794n/a week = divmod(today - week1_monday, 7, &day);
2795n/a if (week < 0) {
2796n/a --year;
2797n/a week1_monday = iso_week1_monday(year);
2798n/a week = divmod(today - week1_monday, 7, &day);
2799n/a }
2800n/a else if (week >= 52 && today >= iso_week1_monday(year + 1)) {
2801n/a ++year;
2802n/a week = 0;
2803n/a }
2804n/a return Py_BuildValue("iii", year, week + 1, day + 1);
2805n/a}
2806n/a
2807n/a/* Miscellaneous methods. */
2808n/a
2809n/astatic PyObject *
2810n/adate_richcompare(PyObject *self, PyObject *other, int op)
2811n/a{
2812n/a if (PyDate_Check(other)) {
2813n/a int diff = memcmp(((PyDateTime_Date *)self)->data,
2814n/a ((PyDateTime_Date *)other)->data,
2815n/a _PyDateTime_DATE_DATASIZE);
2816n/a return diff_to_bool(diff, op);
2817n/a }
2818n/a else
2819n/a Py_RETURN_NOTIMPLEMENTED;
2820n/a}
2821n/a
2822n/astatic PyObject *
2823n/adate_timetuple(PyDateTime_Date *self)
2824n/a{
2825n/a return build_struct_time(GET_YEAR(self),
2826n/a GET_MONTH(self),
2827n/a GET_DAY(self),
2828n/a 0, 0, 0, -1);
2829n/a}
2830n/a
2831n/astatic PyObject *
2832n/adate_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
2833n/a{
2834n/a PyObject *clone;
2835n/a PyObject *tuple;
2836n/a int year = GET_YEAR(self);
2837n/a int month = GET_MONTH(self);
2838n/a int day = GET_DAY(self);
2839n/a
2840n/a if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws,
2841n/a &year, &month, &day))
2842n/a return NULL;
2843n/a tuple = Py_BuildValue("iii", year, month, day);
2844n/a if (tuple == NULL)
2845n/a return NULL;
2846n/a clone = date_new(Py_TYPE(self), tuple, NULL);
2847n/a Py_DECREF(tuple);
2848n/a return clone;
2849n/a}
2850n/a
2851n/astatic Py_hash_t
2852n/ageneric_hash(unsigned char *data, int len)
2853n/a{
2854n/a return _Py_HashBytes(data, len);
2855n/a}
2856n/a
2857n/a
2858n/astatic PyObject *date_getstate(PyDateTime_Date *self);
2859n/a
2860n/astatic Py_hash_t
2861n/adate_hash(PyDateTime_Date *self)
2862n/a{
2863n/a if (self->hashcode == -1) {
2864n/a self->hashcode = generic_hash(
2865n/a (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
2866n/a }
2867n/a
2868n/a return self->hashcode;
2869n/a}
2870n/a
2871n/astatic PyObject *
2872n/adate_toordinal(PyDateTime_Date *self)
2873n/a{
2874n/a return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self),
2875n/a GET_DAY(self)));
2876n/a}
2877n/a
2878n/astatic PyObject *
2879n/adate_weekday(PyDateTime_Date *self)
2880n/a{
2881n/a int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2882n/a
2883n/a return PyLong_FromLong(dow);
2884n/a}
2885n/a
2886n/a/* Pickle support, a simple use of __reduce__. */
2887n/a
2888n/a/* __getstate__ isn't exposed */
2889n/astatic PyObject *
2890n/adate_getstate(PyDateTime_Date *self)
2891n/a{
2892n/a PyObject* field;
2893n/a field = PyBytes_FromStringAndSize((char*)self->data,
2894n/a _PyDateTime_DATE_DATASIZE);
2895n/a return Py_BuildValue("(N)", field);
2896n/a}
2897n/a
2898n/astatic PyObject *
2899n/adate_reduce(PyDateTime_Date *self, PyObject *arg)
2900n/a{
2901n/a return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self));
2902n/a}
2903n/a
2904n/astatic PyMethodDef date_methods[] = {
2905n/a
2906n/a /* Class methods: */
2907n/a
2908n/a {"fromtimestamp", (PyCFunction)date_fromtimestamp, METH_VARARGS |
2909n/a METH_CLASS,
2910n/a PyDoc_STR("timestamp -> local date from a POSIX timestamp (like "
2911n/a "time.time()).")},
2912n/a
2913n/a {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS |
2914n/a METH_CLASS,
2915n/a PyDoc_STR("int -> date corresponding to a proleptic Gregorian "
2916n/a "ordinal.")},
2917n/a
2918n/a {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS,
2919n/a PyDoc_STR("Current date or datetime: same as "
2920n/a "self.__class__.fromtimestamp(time.time()).")},
2921n/a
2922n/a /* Instance methods: */
2923n/a
2924n/a {"ctime", (PyCFunction)date_ctime, METH_NOARGS,
2925n/a PyDoc_STR("Return ctime() style string.")},
2926n/a
2927n/a {"strftime", (PyCFunction)date_strftime, METH_VARARGS | METH_KEYWORDS,
2928n/a PyDoc_STR("format -> strftime() style string.")},
2929n/a
2930n/a {"__format__", (PyCFunction)date_format, METH_VARARGS,
2931n/a PyDoc_STR("Formats self with strftime.")},
2932n/a
2933n/a {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS,
2934n/a PyDoc_STR("Return time tuple, compatible with time.localtime().")},
2935n/a
2936n/a {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS,
2937n/a PyDoc_STR("Return a 3-tuple containing ISO year, week number, and "
2938n/a "weekday.")},
2939n/a
2940n/a {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS,
2941n/a PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")},
2942n/a
2943n/a {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS,
2944n/a PyDoc_STR("Return the day of the week represented by the date.\n"
2945n/a "Monday == 1 ... Sunday == 7")},
2946n/a
2947n/a {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS,
2948n/a PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year "
2949n/a "1 is day 1.")},
2950n/a
2951n/a {"weekday", (PyCFunction)date_weekday, METH_NOARGS,
2952n/a PyDoc_STR("Return the day of the week represented by the date.\n"
2953n/a "Monday == 0 ... Sunday == 6")},
2954n/a
2955n/a {"replace", (PyCFunction)date_replace, METH_VARARGS | METH_KEYWORDS,
2956n/a PyDoc_STR("Return date with new specified fields.")},
2957n/a
2958n/a {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS,
2959n/a PyDoc_STR("__reduce__() -> (cls, state)")},
2960n/a
2961n/a {NULL, NULL}
2962n/a};
2963n/a
2964n/astatic const char date_doc[] =
2965n/aPyDoc_STR("date(year, month, day) --> date object");
2966n/a
2967n/astatic PyNumberMethods date_as_number = {
2968n/a date_add, /* nb_add */
2969n/a date_subtract, /* nb_subtract */
2970n/a 0, /* nb_multiply */
2971n/a 0, /* nb_remainder */
2972n/a 0, /* nb_divmod */
2973n/a 0, /* nb_power */
2974n/a 0, /* nb_negative */
2975n/a 0, /* nb_positive */
2976n/a 0, /* nb_absolute */
2977n/a 0, /* nb_bool */
2978n/a};
2979n/a
2980n/astatic PyTypeObject PyDateTime_DateType = {
2981n/a PyVarObject_HEAD_INIT(NULL, 0)
2982n/a "datetime.date", /* tp_name */
2983n/a sizeof(PyDateTime_Date), /* tp_basicsize */
2984n/a 0, /* tp_itemsize */
2985n/a 0, /* tp_dealloc */
2986n/a 0, /* tp_print */
2987n/a 0, /* tp_getattr */
2988n/a 0, /* tp_setattr */
2989n/a 0, /* tp_reserved */
2990n/a (reprfunc)date_repr, /* tp_repr */
2991n/a &date_as_number, /* tp_as_number */
2992n/a 0, /* tp_as_sequence */
2993n/a 0, /* tp_as_mapping */
2994n/a (hashfunc)date_hash, /* tp_hash */
2995n/a 0, /* tp_call */
2996n/a (reprfunc)date_str, /* tp_str */
2997n/a PyObject_GenericGetAttr, /* tp_getattro */
2998n/a 0, /* tp_setattro */
2999n/a 0, /* tp_as_buffer */
3000n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3001n/a date_doc, /* tp_doc */
3002n/a 0, /* tp_traverse */
3003n/a 0, /* tp_clear */
3004n/a date_richcompare, /* tp_richcompare */
3005n/a 0, /* tp_weaklistoffset */
3006n/a 0, /* tp_iter */
3007n/a 0, /* tp_iternext */
3008n/a date_methods, /* tp_methods */
3009n/a 0, /* tp_members */
3010n/a date_getset, /* tp_getset */
3011n/a 0, /* tp_base */
3012n/a 0, /* tp_dict */
3013n/a 0, /* tp_descr_get */
3014n/a 0, /* tp_descr_set */
3015n/a 0, /* tp_dictoffset */
3016n/a 0, /* tp_init */
3017n/a 0, /* tp_alloc */
3018n/a date_new, /* tp_new */
3019n/a 0, /* tp_free */
3020n/a};
3021n/a
3022n/a/*
3023n/a * PyDateTime_TZInfo implementation.
3024n/a */
3025n/a
3026n/a/* This is a pure abstract base class, so doesn't do anything beyond
3027n/a * raising NotImplemented exceptions. Real tzinfo classes need
3028n/a * to derive from this. This is mostly for clarity, and for efficiency in
3029n/a * datetime and time constructors (their tzinfo arguments need to
3030n/a * be subclasses of this tzinfo class, which is easy and quick to check).
3031n/a *
3032n/a * Note: For reasons having to do with pickling of subclasses, we have
3033n/a * to allow tzinfo objects to be instantiated. This wasn't an issue
3034n/a * in the Python implementation (__init__() could raise NotImplementedError
3035n/a * there without ill effect), but doing so in the C implementation hit a
3036n/a * brick wall.
3037n/a */
3038n/a
3039n/astatic PyObject *
3040n/atzinfo_nogo(const char* methodname)
3041n/a{
3042n/a PyErr_Format(PyExc_NotImplementedError,
3043n/a "a tzinfo subclass must implement %s()",
3044n/a methodname);
3045n/a return NULL;
3046n/a}
3047n/a
3048n/a/* Methods. A subclass must implement these. */
3049n/a
3050n/astatic PyObject *
3051n/atzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt)
3052n/a{
3053n/a return tzinfo_nogo("tzname");
3054n/a}
3055n/a
3056n/astatic PyObject *
3057n/atzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt)
3058n/a{
3059n/a return tzinfo_nogo("utcoffset");
3060n/a}
3061n/a
3062n/astatic PyObject *
3063n/atzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt)
3064n/a{
3065n/a return tzinfo_nogo("dst");
3066n/a}
3067n/a
3068n/a
3069n/astatic PyObject *add_datetime_timedelta(PyDateTime_DateTime *date,
3070n/a PyDateTime_Delta *delta,
3071n/a int factor);
3072n/astatic PyObject *datetime_utcoffset(PyObject *self, PyObject *);
3073n/astatic PyObject *datetime_dst(PyObject *self, PyObject *);
3074n/a
3075n/astatic PyObject *
3076n/atzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt)
3077n/a{
3078n/a PyObject *result = NULL;
3079n/a PyObject *off = NULL, *dst = NULL;
3080n/a PyDateTime_Delta *delta = NULL;
3081n/a
3082n/a if (!PyDateTime_Check(dt)) {
3083n/a PyErr_SetString(PyExc_TypeError,
3084n/a "fromutc: argument must be a datetime");
3085n/a return NULL;
3086n/a }
3087n/a if (GET_DT_TZINFO(dt) != (PyObject *)self) {
3088n/a PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3089n/a "is not self");
3090n/a return NULL;
3091n/a }
3092n/a
3093n/a off = datetime_utcoffset(dt, NULL);
3094n/a if (off == NULL)
3095n/a return NULL;
3096n/a if (off == Py_None) {
3097n/a PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3098n/a "utcoffset() result required");
3099n/a goto Fail;
3100n/a }
3101n/a
3102n/a dst = datetime_dst(dt, NULL);
3103n/a if (dst == NULL)
3104n/a goto Fail;
3105n/a if (dst == Py_None) {
3106n/a PyErr_SetString(PyExc_ValueError, "fromutc: non-None "
3107n/a "dst() result required");
3108n/a goto Fail;
3109n/a }
3110n/a
3111n/a delta = (PyDateTime_Delta *)delta_subtract(off, dst);
3112n/a if (delta == NULL)
3113n/a goto Fail;
3114n/a result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1);
3115n/a if (result == NULL)
3116n/a goto Fail;
3117n/a
3118n/a Py_DECREF(dst);
3119n/a dst = call_dst(GET_DT_TZINFO(dt), result);
3120n/a if (dst == NULL)
3121n/a goto Fail;
3122n/a if (dst == Py_None)
3123n/a goto Inconsistent;
3124n/a if (delta_bool((PyDateTime_Delta *)dst) != 0) {
3125n/a Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result,
3126n/a (PyDateTime_Delta *)dst, 1));
3127n/a if (result == NULL)
3128n/a goto Fail;
3129n/a }
3130n/a Py_DECREF(delta);
3131n/a Py_DECREF(dst);
3132n/a Py_DECREF(off);
3133n/a return result;
3134n/a
3135n/aInconsistent:
3136n/a PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave"
3137n/a "inconsistent results; cannot convert");
3138n/a
3139n/a /* fall thru to failure */
3140n/aFail:
3141n/a Py_XDECREF(off);
3142n/a Py_XDECREF(dst);
3143n/a Py_XDECREF(delta);
3144n/a Py_XDECREF(result);
3145n/a return NULL;
3146n/a}
3147n/a
3148n/a/*
3149n/a * Pickle support. This is solely so that tzinfo subclasses can use
3150n/a * pickling -- tzinfo itself is supposed to be uninstantiable.
3151n/a */
3152n/a
3153n/astatic PyObject *
3154n/atzinfo_reduce(PyObject *self)
3155n/a{
3156n/a PyObject *args, *state;
3157n/a PyObject *getinitargs, *getstate;
3158n/a _Py_IDENTIFIER(__getinitargs__);
3159n/a _Py_IDENTIFIER(__getstate__);
3160n/a
3161n/a getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
3162n/a if (getinitargs != NULL) {
3163n/a args = _PyObject_CallNoArg(getinitargs);
3164n/a Py_DECREF(getinitargs);
3165n/a if (args == NULL) {
3166n/a return NULL;
3167n/a }
3168n/a }
3169n/a else {
3170n/a PyErr_Clear();
3171n/a
3172n/a args = PyTuple_New(0);
3173n/a if (args == NULL) {
3174n/a return NULL;
3175n/a }
3176n/a }
3177n/a
3178n/a getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
3179n/a if (getstate != NULL) {
3180n/a state = _PyObject_CallNoArg(getstate);
3181n/a Py_DECREF(getstate);
3182n/a if (state == NULL) {
3183n/a Py_DECREF(args);
3184n/a return NULL;
3185n/a }
3186n/a }
3187n/a else {
3188n/a PyObject **dictptr;
3189n/a PyErr_Clear();
3190n/a state = Py_None;
3191n/a dictptr = _PyObject_GetDictPtr(self);
3192n/a if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) {
3193n/a state = *dictptr;
3194n/a }
3195n/a Py_INCREF(state);
3196n/a }
3197n/a
3198n/a if (state == Py_None) {
3199n/a Py_DECREF(state);
3200n/a return Py_BuildValue("(ON)", Py_TYPE(self), args);
3201n/a }
3202n/a else
3203n/a return Py_BuildValue("(ONN)", Py_TYPE(self), args, state);
3204n/a}
3205n/a
3206n/astatic PyMethodDef tzinfo_methods[] = {
3207n/a
3208n/a {"tzname", (PyCFunction)tzinfo_tzname, METH_O,
3209n/a PyDoc_STR("datetime -> string name of time zone.")},
3210n/a
3211n/a {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O,
3212n/a PyDoc_STR("datetime -> timedelta showing offset from UTC, negative "
3213n/a "values indicating West of UTC")},
3214n/a
3215n/a {"dst", (PyCFunction)tzinfo_dst, METH_O,
3216n/a PyDoc_STR("datetime -> DST offset in minutes east of UTC.")},
3217n/a
3218n/a {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O,
3219n/a PyDoc_STR("datetime in UTC -> datetime in local time.")},
3220n/a
3221n/a {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS,
3222n/a PyDoc_STR("-> (cls, state)")},
3223n/a
3224n/a {NULL, NULL}
3225n/a};
3226n/a
3227n/astatic const char tzinfo_doc[] =
3228n/aPyDoc_STR("Abstract base class for time zone info objects.");
3229n/a
3230n/astatic PyTypeObject PyDateTime_TZInfoType = {
3231n/a PyVarObject_HEAD_INIT(NULL, 0)
3232n/a "datetime.tzinfo", /* tp_name */
3233n/a sizeof(PyDateTime_TZInfo), /* tp_basicsize */
3234n/a 0, /* tp_itemsize */
3235n/a 0, /* tp_dealloc */
3236n/a 0, /* tp_print */
3237n/a 0, /* tp_getattr */
3238n/a 0, /* tp_setattr */
3239n/a 0, /* tp_reserved */
3240n/a 0, /* tp_repr */
3241n/a 0, /* tp_as_number */
3242n/a 0, /* tp_as_sequence */
3243n/a 0, /* tp_as_mapping */
3244n/a 0, /* tp_hash */
3245n/a 0, /* tp_call */
3246n/a 0, /* tp_str */
3247n/a PyObject_GenericGetAttr, /* tp_getattro */
3248n/a 0, /* tp_setattro */
3249n/a 0, /* tp_as_buffer */
3250n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3251n/a tzinfo_doc, /* tp_doc */
3252n/a 0, /* tp_traverse */
3253n/a 0, /* tp_clear */
3254n/a 0, /* tp_richcompare */
3255n/a 0, /* tp_weaklistoffset */
3256n/a 0, /* tp_iter */
3257n/a 0, /* tp_iternext */
3258n/a tzinfo_methods, /* tp_methods */
3259n/a 0, /* tp_members */
3260n/a 0, /* tp_getset */
3261n/a 0, /* tp_base */
3262n/a 0, /* tp_dict */
3263n/a 0, /* tp_descr_get */
3264n/a 0, /* tp_descr_set */
3265n/a 0, /* tp_dictoffset */
3266n/a 0, /* tp_init */
3267n/a 0, /* tp_alloc */
3268n/a PyType_GenericNew, /* tp_new */
3269n/a 0, /* tp_free */
3270n/a};
3271n/a
3272n/astatic char *timezone_kws[] = {"offset", "name", NULL};
3273n/a
3274n/astatic PyObject *
3275n/atimezone_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3276n/a{
3277n/a PyObject *offset;
3278n/a PyObject *name = NULL;
3279n/a if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws,
3280n/a &PyDateTime_DeltaType, &offset, &name))
3281n/a return new_timezone(offset, name);
3282n/a
3283n/a return NULL;
3284n/a}
3285n/a
3286n/astatic void
3287n/atimezone_dealloc(PyDateTime_TimeZone *self)
3288n/a{
3289n/a Py_CLEAR(self->offset);
3290n/a Py_CLEAR(self->name);
3291n/a Py_TYPE(self)->tp_free((PyObject *)self);
3292n/a}
3293n/a
3294n/astatic PyObject *
3295n/atimezone_richcompare(PyDateTime_TimeZone *self,
3296n/a PyDateTime_TimeZone *other, int op)
3297n/a{
3298n/a if (op != Py_EQ && op != Py_NE)
3299n/a Py_RETURN_NOTIMPLEMENTED;
3300n/a if (Py_TYPE(other) != &PyDateTime_TimeZoneType) {
3301n/a if (op == Py_EQ)
3302n/a Py_RETURN_FALSE;
3303n/a else
3304n/a Py_RETURN_TRUE;
3305n/a }
3306n/a return delta_richcompare(self->offset, other->offset, op);
3307n/a}
3308n/a
3309n/astatic Py_hash_t
3310n/atimezone_hash(PyDateTime_TimeZone *self)
3311n/a{
3312n/a return delta_hash((PyDateTime_Delta *)self->offset);
3313n/a}
3314n/a
3315n/a/* Check argument type passed to tzname, utcoffset, or dst methods.
3316n/a Returns 0 for good argument. Returns -1 and sets exception info
3317n/a otherwise.
3318n/a */
3319n/astatic int
3320n/a_timezone_check_argument(PyObject *dt, const char *meth)
3321n/a{
3322n/a if (dt == Py_None || PyDateTime_Check(dt))
3323n/a return 0;
3324n/a PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance"
3325n/a " or None, not %.200s", meth, Py_TYPE(dt)->tp_name);
3326n/a return -1;
3327n/a}
3328n/a
3329n/astatic PyObject *
3330n/atimezone_repr(PyDateTime_TimeZone *self)
3331n/a{
3332n/a /* Note that although timezone is not subclassable, it is convenient
3333n/a to use Py_TYPE(self)->tp_name here. */
3334n/a const char *type_name = Py_TYPE(self)->tp_name;
3335n/a
3336n/a if (((PyObject *)self) == PyDateTime_TimeZone_UTC)
3337n/a return PyUnicode_FromFormat("%s.utc", type_name);
3338n/a
3339n/a if (self->name == NULL)
3340n/a return PyUnicode_FromFormat("%s(%R)", type_name, self->offset);
3341n/a
3342n/a return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset,
3343n/a self->name);
3344n/a}
3345n/a
3346n/a
3347n/astatic PyObject *
3348n/atimezone_str(PyDateTime_TimeZone *self)
3349n/a{
3350n/a int hours, minutes, seconds;
3351n/a PyObject *offset;
3352n/a char sign;
3353n/a
3354n/a if (self->name != NULL) {
3355n/a Py_INCREF(self->name);
3356n/a return self->name;
3357n/a }
3358n/a if ((PyObject *)self == PyDateTime_TimeZone_UTC ||
3359n/a (GET_TD_DAYS(self->offset) == 0 &&
3360n/a GET_TD_SECONDS(self->offset) == 0 &&
3361n/a GET_TD_MICROSECONDS(self->offset) == 0))
3362n/a return PyUnicode_FromString("UTC");
3363n/a /* Offset is normalized, so it is negative if days < 0 */
3364n/a if (GET_TD_DAYS(self->offset) < 0) {
3365n/a sign = '-';
3366n/a offset = delta_negative((PyDateTime_Delta *)self->offset);
3367n/a if (offset == NULL)
3368n/a return NULL;
3369n/a }
3370n/a else {
3371n/a sign = '+';
3372n/a offset = self->offset;
3373n/a Py_INCREF(offset);
3374n/a }
3375n/a /* Offset is not negative here. */
3376n/a seconds = GET_TD_SECONDS(offset);
3377n/a Py_DECREF(offset);
3378n/a minutes = divmod(seconds, 60, &seconds);
3379n/a hours = divmod(minutes, 60, &minutes);
3380n/a /* XXX ignore sub-minute data, currently not allowed. */
3381n/a assert(seconds == 0);
3382n/a return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes);
3383n/a}
3384n/a
3385n/astatic PyObject *
3386n/atimezone_tzname(PyDateTime_TimeZone *self, PyObject *dt)
3387n/a{
3388n/a if (_timezone_check_argument(dt, "tzname") == -1)
3389n/a return NULL;
3390n/a
3391n/a return timezone_str(self);
3392n/a}
3393n/a
3394n/astatic PyObject *
3395n/atimezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt)
3396n/a{
3397n/a if (_timezone_check_argument(dt, "utcoffset") == -1)
3398n/a return NULL;
3399n/a
3400n/a Py_INCREF(self->offset);
3401n/a return self->offset;
3402n/a}
3403n/a
3404n/astatic PyObject *
3405n/atimezone_dst(PyObject *self, PyObject *dt)
3406n/a{
3407n/a if (_timezone_check_argument(dt, "dst") == -1)
3408n/a return NULL;
3409n/a
3410n/a Py_RETURN_NONE;
3411n/a}
3412n/a
3413n/astatic PyObject *
3414n/atimezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt)
3415n/a{
3416n/a if (!PyDateTime_Check(dt)) {
3417n/a PyErr_SetString(PyExc_TypeError,
3418n/a "fromutc: argument must be a datetime");
3419n/a return NULL;
3420n/a }
3421n/a if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) {
3422n/a PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo "
3423n/a "is not self");
3424n/a return NULL;
3425n/a }
3426n/a
3427n/a return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1);
3428n/a}
3429n/a
3430n/astatic PyObject *
3431n/atimezone_getinitargs(PyDateTime_TimeZone *self)
3432n/a{
3433n/a if (self->name == NULL)
3434n/a return Py_BuildValue("(O)", self->offset);
3435n/a return Py_BuildValue("(OO)", self->offset, self->name);
3436n/a}
3437n/a
3438n/astatic PyMethodDef timezone_methods[] = {
3439n/a {"tzname", (PyCFunction)timezone_tzname, METH_O,
3440n/a PyDoc_STR("If name is specified when timezone is created, returns the name."
3441n/a " Otherwise returns offset as 'UTC(+|-)HH:MM'.")},
3442n/a
3443n/a {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O,
3444n/a PyDoc_STR("Return fixed offset.")},
3445n/a
3446n/a {"dst", (PyCFunction)timezone_dst, METH_O,
3447n/a PyDoc_STR("Return None.")},
3448n/a
3449n/a {"fromutc", (PyCFunction)timezone_fromutc, METH_O,
3450n/a PyDoc_STR("datetime in UTC -> datetime in local time.")},
3451n/a
3452n/a {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS,
3453n/a PyDoc_STR("pickle support")},
3454n/a
3455n/a {NULL, NULL}
3456n/a};
3457n/a
3458n/astatic const char timezone_doc[] =
3459n/aPyDoc_STR("Fixed offset from UTC implementation of tzinfo.");
3460n/a
3461n/astatic PyTypeObject PyDateTime_TimeZoneType = {
3462n/a PyVarObject_HEAD_INIT(NULL, 0)
3463n/a "datetime.timezone", /* tp_name */
3464n/a sizeof(PyDateTime_TimeZone), /* tp_basicsize */
3465n/a 0, /* tp_itemsize */
3466n/a (destructor)timezone_dealloc, /* tp_dealloc */
3467n/a 0, /* tp_print */
3468n/a 0, /* tp_getattr */
3469n/a 0, /* tp_setattr */
3470n/a 0, /* tp_reserved */
3471n/a (reprfunc)timezone_repr, /* tp_repr */
3472n/a 0, /* tp_as_number */
3473n/a 0, /* tp_as_sequence */
3474n/a 0, /* tp_as_mapping */
3475n/a (hashfunc)timezone_hash, /* tp_hash */
3476n/a 0, /* tp_call */
3477n/a (reprfunc)timezone_str, /* tp_str */
3478n/a 0, /* tp_getattro */
3479n/a 0, /* tp_setattro */
3480n/a 0, /* tp_as_buffer */
3481n/a Py_TPFLAGS_DEFAULT, /* tp_flags */
3482n/a timezone_doc, /* tp_doc */
3483n/a 0, /* tp_traverse */
3484n/a 0, /* tp_clear */
3485n/a (richcmpfunc)timezone_richcompare,/* tp_richcompare */
3486n/a 0, /* tp_weaklistoffset */
3487n/a 0, /* tp_iter */
3488n/a 0, /* tp_iternext */
3489n/a timezone_methods, /* tp_methods */
3490n/a 0, /* tp_members */
3491n/a 0, /* tp_getset */
3492n/a &PyDateTime_TZInfoType, /* tp_base */
3493n/a 0, /* tp_dict */
3494n/a 0, /* tp_descr_get */
3495n/a 0, /* tp_descr_set */
3496n/a 0, /* tp_dictoffset */
3497n/a 0, /* tp_init */
3498n/a 0, /* tp_alloc */
3499n/a timezone_new, /* tp_new */
3500n/a};
3501n/a
3502n/a/*
3503n/a * PyDateTime_Time implementation.
3504n/a */
3505n/a
3506n/a/* Accessor properties.
3507n/a */
3508n/a
3509n/astatic PyObject *
3510n/atime_hour(PyDateTime_Time *self, void *unused)
3511n/a{
3512n/a return PyLong_FromLong(TIME_GET_HOUR(self));
3513n/a}
3514n/a
3515n/astatic PyObject *
3516n/atime_minute(PyDateTime_Time *self, void *unused)
3517n/a{
3518n/a return PyLong_FromLong(TIME_GET_MINUTE(self));
3519n/a}
3520n/a
3521n/a/* The name time_second conflicted with some platform header file. */
3522n/astatic PyObject *
3523n/apy_time_second(PyDateTime_Time *self, void *unused)
3524n/a{
3525n/a return PyLong_FromLong(TIME_GET_SECOND(self));
3526n/a}
3527n/a
3528n/astatic PyObject *
3529n/atime_microsecond(PyDateTime_Time *self, void *unused)
3530n/a{
3531n/a return PyLong_FromLong(TIME_GET_MICROSECOND(self));
3532n/a}
3533n/a
3534n/astatic PyObject *
3535n/atime_tzinfo(PyDateTime_Time *self, void *unused)
3536n/a{
3537n/a PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
3538n/a Py_INCREF(result);
3539n/a return result;
3540n/a}
3541n/a
3542n/astatic PyObject *
3543n/atime_fold(PyDateTime_Time *self, void *unused)
3544n/a{
3545n/a return PyLong_FromLong(TIME_GET_FOLD(self));
3546n/a}
3547n/a
3548n/astatic PyGetSetDef time_getset[] = {
3549n/a {"hour", (getter)time_hour},
3550n/a {"minute", (getter)time_minute},
3551n/a {"second", (getter)py_time_second},
3552n/a {"microsecond", (getter)time_microsecond},
3553n/a {"tzinfo", (getter)time_tzinfo},
3554n/a {"fold", (getter)time_fold},
3555n/a {NULL}
3556n/a};
3557n/a
3558n/a/*
3559n/a * Constructors.
3560n/a */
3561n/a
3562n/astatic char *time_kws[] = {"hour", "minute", "second", "microsecond",
3563n/a "tzinfo", "fold", NULL};
3564n/a
3565n/astatic PyObject *
3566n/atime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
3567n/a{
3568n/a PyObject *self = NULL;
3569n/a PyObject *state;
3570n/a int hour = 0;
3571n/a int minute = 0;
3572n/a int second = 0;
3573n/a int usecond = 0;
3574n/a PyObject *tzinfo = Py_None;
3575n/a int fold = 0;
3576n/a
3577n/a /* Check for invocation from pickle with __getstate__ state */
3578n/a if (PyTuple_GET_SIZE(args) >= 1 &&
3579n/a PyTuple_GET_SIZE(args) <= 2 &&
3580n/a PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
3581n/a PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE &&
3582n/a (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24)
3583n/a {
3584n/a PyDateTime_Time *me;
3585n/a char aware;
3586n/a
3587n/a if (PyTuple_GET_SIZE(args) == 2) {
3588n/a tzinfo = PyTuple_GET_ITEM(args, 1);
3589n/a if (check_tzinfo_subclass(tzinfo) < 0) {
3590n/a PyErr_SetString(PyExc_TypeError, "bad "
3591n/a "tzinfo state arg");
3592n/a return NULL;
3593n/a }
3594n/a }
3595n/a aware = (char)(tzinfo != Py_None);
3596n/a me = (PyDateTime_Time *) (type->tp_alloc(type, aware));
3597n/a if (me != NULL) {
3598n/a char *pdata = PyBytes_AS_STRING(state);
3599n/a
3600n/a memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
3601n/a me->hashcode = -1;
3602n/a me->hastzinfo = aware;
3603n/a if (aware) {
3604n/a Py_INCREF(tzinfo);
3605n/a me->tzinfo = tzinfo;
3606n/a }
3607n/a if (pdata[0] & (1 << 7)) {
3608n/a me->data[0] -= 128;
3609n/a me->fold = 1;
3610n/a }
3611n/a else {
3612n/a me->fold = 0;
3613n/a }
3614n/a }
3615n/a return (PyObject *)me;
3616n/a }
3617n/a
3618n/a if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
3619n/a &hour, &minute, &second, &usecond,
3620n/a &tzinfo, &fold)) {
3621n/a self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold,
3622n/a type);
3623n/a }
3624n/a return self;
3625n/a}
3626n/a
3627n/a/*
3628n/a * Destructor.
3629n/a */
3630n/a
3631n/astatic void
3632n/atime_dealloc(PyDateTime_Time *self)
3633n/a{
3634n/a if (HASTZINFO(self)) {
3635n/a Py_XDECREF(self->tzinfo);
3636n/a }
3637n/a Py_TYPE(self)->tp_free((PyObject *)self);
3638n/a}
3639n/a
3640n/a/*
3641n/a * Indirect access to tzinfo methods.
3642n/a */
3643n/a
3644n/a/* These are all METH_NOARGS, so don't need to check the arglist. */
3645n/astatic PyObject *
3646n/atime_utcoffset(PyObject *self, PyObject *unused) {
3647n/a return call_utcoffset(GET_TIME_TZINFO(self), Py_None);
3648n/a}
3649n/a
3650n/astatic PyObject *
3651n/atime_dst(PyObject *self, PyObject *unused) {
3652n/a return call_dst(GET_TIME_TZINFO(self), Py_None);
3653n/a}
3654n/a
3655n/astatic PyObject *
3656n/atime_tzname(PyDateTime_Time *self, PyObject *unused) {
3657n/a return call_tzname(GET_TIME_TZINFO(self), Py_None);
3658n/a}
3659n/a
3660n/a/*
3661n/a * Various ways to turn a time into a string.
3662n/a */
3663n/a
3664n/astatic PyObject *
3665n/atime_repr(PyDateTime_Time *self)
3666n/a{
3667n/a const char *type_name = Py_TYPE(self)->tp_name;
3668n/a int h = TIME_GET_HOUR(self);
3669n/a int m = TIME_GET_MINUTE(self);
3670n/a int s = TIME_GET_SECOND(self);
3671n/a int us = TIME_GET_MICROSECOND(self);
3672n/a int fold = TIME_GET_FOLD(self);
3673n/a PyObject *result = NULL;
3674n/a
3675n/a if (us)
3676n/a result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3677n/a type_name, h, m, s, us);
3678n/a else if (s)
3679n/a result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3680n/a type_name, h, m, s);
3681n/a else
3682n/a result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
3683n/a if (result != NULL && HASTZINFO(self))
3684n/a result = append_keyword_tzinfo(result, self->tzinfo);
3685n/a if (result != NULL && fold)
3686n/a result = append_keyword_fold(result, fold);
3687n/a return result;
3688n/a}
3689n/a
3690n/astatic PyObject *
3691n/atime_str(PyDateTime_Time *self)
3692n/a{
3693n/a return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
3694n/a}
3695n/a
3696n/astatic PyObject *
3697n/atime_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3698n/a{
3699n/a char buf[100];
3700n/a char *timespec = NULL;
3701n/a static char *keywords[] = {"timespec", NULL};
3702n/a PyObject *result;
3703n/a int us = TIME_GET_MICROSECOND(self);
3704n/a static char *specs[][2] = {
3705n/a {"hours", "%02d"},
3706n/a {"minutes", "%02d:%02d"},
3707n/a {"seconds", "%02d:%02d:%02d"},
3708n/a {"milliseconds", "%02d:%02d:%02d.%03d"},
3709n/a {"microseconds", "%02d:%02d:%02d.%06d"},
3710n/a };
3711n/a size_t given_spec;
3712n/a
3713n/a if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, &timespec))
3714n/a return NULL;
3715n/a
3716n/a if (timespec == NULL || strcmp(timespec, "auto") == 0) {
3717n/a if (us == 0) {
3718n/a /* seconds */
3719n/a given_spec = 2;
3720n/a }
3721n/a else {
3722n/a /* microseconds */
3723n/a given_spec = 4;
3724n/a }
3725n/a }
3726n/a else {
3727n/a for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
3728n/a if (strcmp(timespec, specs[given_spec][0]) == 0) {
3729n/a if (given_spec == 3) {
3730n/a /* milliseconds */
3731n/a us = us / 1000;
3732n/a }
3733n/a break;
3734n/a }
3735n/a }
3736n/a }
3737n/a
3738n/a if (given_spec == Py_ARRAY_LENGTH(specs)) {
3739n/a PyErr_Format(PyExc_ValueError, "Unknown timespec value");
3740n/a return NULL;
3741n/a }
3742n/a else {
3743n/a result = PyUnicode_FromFormat(specs[given_spec][1],
3744n/a TIME_GET_HOUR(self), TIME_GET_MINUTE(self),
3745n/a TIME_GET_SECOND(self), us);
3746n/a }
3747n/a
3748n/a if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None)
3749n/a return result;
3750n/a
3751n/a /* We need to append the UTC offset. */
3752n/a if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo,
3753n/a Py_None) < 0) {
3754n/a Py_DECREF(result);
3755n/a return NULL;
3756n/a }
3757n/a PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf));
3758n/a return result;
3759n/a}
3760n/a
3761n/astatic PyObject *
3762n/atime_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3763n/a{
3764n/a PyObject *result;
3765n/a PyObject *tuple;
3766n/a PyObject *format;
3767n/a static char *keywords[] = {"format", NULL};
3768n/a
3769n/a if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
3770n/a &format))
3771n/a return NULL;
3772n/a
3773n/a /* Python's strftime does insane things with the year part of the
3774n/a * timetuple. The year is forced to (the otherwise nonsensical)
3775n/a * 1900 to work around that.
3776n/a */
3777n/a tuple = Py_BuildValue("iiiiiiiii",
3778n/a 1900, 1, 1, /* year, month, day */
3779n/a TIME_GET_HOUR(self),
3780n/a TIME_GET_MINUTE(self),
3781n/a TIME_GET_SECOND(self),
3782n/a 0, 1, -1); /* weekday, daynum, dst */
3783n/a if (tuple == NULL)
3784n/a return NULL;
3785n/a assert(PyTuple_Size(tuple) == 9);
3786n/a result = wrap_strftime((PyObject *)self, format, tuple,
3787n/a Py_None);
3788n/a Py_DECREF(tuple);
3789n/a return result;
3790n/a}
3791n/a
3792n/a/*
3793n/a * Miscellaneous methods.
3794n/a */
3795n/a
3796n/astatic PyObject *
3797n/atime_richcompare(PyObject *self, PyObject *other, int op)
3798n/a{
3799n/a PyObject *result = NULL;
3800n/a PyObject *offset1, *offset2;
3801n/a int diff;
3802n/a
3803n/a if (! PyTime_Check(other))
3804n/a Py_RETURN_NOTIMPLEMENTED;
3805n/a
3806n/a if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) {
3807n/a diff = memcmp(((PyDateTime_Time *)self)->data,
3808n/a ((PyDateTime_Time *)other)->data,
3809n/a _PyDateTime_TIME_DATASIZE);
3810n/a return diff_to_bool(diff, op);
3811n/a }
3812n/a offset1 = time_utcoffset(self, NULL);
3813n/a if (offset1 == NULL)
3814n/a return NULL;
3815n/a offset2 = time_utcoffset(other, NULL);
3816n/a if (offset2 == NULL)
3817n/a goto done;
3818n/a /* If they're both naive, or both aware and have the same offsets,
3819n/a * we get off cheap. Note that if they're both naive, offset1 ==
3820n/a * offset2 == Py_None at this point.
3821n/a */
3822n/a if ((offset1 == offset2) ||
3823n/a (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
3824n/a delta_cmp(offset1, offset2) == 0)) {
3825n/a diff = memcmp(((PyDateTime_Time *)self)->data,
3826n/a ((PyDateTime_Time *)other)->data,
3827n/a _PyDateTime_TIME_DATASIZE);
3828n/a result = diff_to_bool(diff, op);
3829n/a }
3830n/a /* The hard case: both aware with different UTC offsets */
3831n/a else if (offset1 != Py_None && offset2 != Py_None) {
3832n/a int offsecs1, offsecs2;
3833n/a assert(offset1 != offset2); /* else last "if" handled it */
3834n/a offsecs1 = TIME_GET_HOUR(self) * 3600 +
3835n/a TIME_GET_MINUTE(self) * 60 +
3836n/a TIME_GET_SECOND(self) -
3837n/a GET_TD_DAYS(offset1) * 86400 -
3838n/a GET_TD_SECONDS(offset1);
3839n/a offsecs2 = TIME_GET_HOUR(other) * 3600 +
3840n/a TIME_GET_MINUTE(other) * 60 +
3841n/a TIME_GET_SECOND(other) -
3842n/a GET_TD_DAYS(offset2) * 86400 -
3843n/a GET_TD_SECONDS(offset2);
3844n/a diff = offsecs1 - offsecs2;
3845n/a if (diff == 0)
3846n/a diff = TIME_GET_MICROSECOND(self) -
3847n/a TIME_GET_MICROSECOND(other);
3848n/a result = diff_to_bool(diff, op);
3849n/a }
3850n/a else if (op == Py_EQ) {
3851n/a result = Py_False;
3852n/a Py_INCREF(result);
3853n/a }
3854n/a else if (op == Py_NE) {
3855n/a result = Py_True;
3856n/a Py_INCREF(result);
3857n/a }
3858n/a else {
3859n/a PyErr_SetString(PyExc_TypeError,
3860n/a "can't compare offset-naive and "
3861n/a "offset-aware times");
3862n/a }
3863n/a done:
3864n/a Py_DECREF(offset1);
3865n/a Py_XDECREF(offset2);
3866n/a return result;
3867n/a}
3868n/a
3869n/astatic Py_hash_t
3870n/atime_hash(PyDateTime_Time *self)
3871n/a{
3872n/a if (self->hashcode == -1) {
3873n/a PyObject *offset, *self0;
3874n/a if (TIME_GET_FOLD(self)) {
3875n/a self0 = new_time_ex2(TIME_GET_HOUR(self),
3876n/a TIME_GET_MINUTE(self),
3877n/a TIME_GET_SECOND(self),
3878n/a TIME_GET_MICROSECOND(self),
3879n/a HASTZINFO(self) ? self->tzinfo : Py_None,
3880n/a 0, Py_TYPE(self));
3881n/a if (self0 == NULL)
3882n/a return -1;
3883n/a }
3884n/a else {
3885n/a self0 = (PyObject *)self;
3886n/a Py_INCREF(self0);
3887n/a }
3888n/a offset = time_utcoffset(self0, NULL);
3889n/a Py_DECREF(self0);
3890n/a
3891n/a if (offset == NULL)
3892n/a return -1;
3893n/a
3894n/a /* Reduce this to a hash of another object. */
3895n/a if (offset == Py_None)
3896n/a self->hashcode = generic_hash(
3897n/a (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
3898n/a else {
3899n/a PyObject *temp1, *temp2;
3900n/a int seconds, microseconds;
3901n/a assert(HASTZINFO(self));
3902n/a seconds = TIME_GET_HOUR(self) * 3600 +
3903n/a TIME_GET_MINUTE(self) * 60 +
3904n/a TIME_GET_SECOND(self);
3905n/a microseconds = TIME_GET_MICROSECOND(self);
3906n/a temp1 = new_delta(0, seconds, microseconds, 1);
3907n/a if (temp1 == NULL) {
3908n/a Py_DECREF(offset);
3909n/a return -1;
3910n/a }
3911n/a temp2 = delta_subtract(temp1, offset);
3912n/a Py_DECREF(temp1);
3913n/a if (temp2 == NULL) {
3914n/a Py_DECREF(offset);
3915n/a return -1;
3916n/a }
3917n/a self->hashcode = PyObject_Hash(temp2);
3918n/a Py_DECREF(temp2);
3919n/a }
3920n/a Py_DECREF(offset);
3921n/a }
3922n/a return self->hashcode;
3923n/a}
3924n/a
3925n/astatic PyObject *
3926n/atime_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
3927n/a{
3928n/a PyObject *clone;
3929n/a PyObject *tuple;
3930n/a int hh = TIME_GET_HOUR(self);
3931n/a int mm = TIME_GET_MINUTE(self);
3932n/a int ss = TIME_GET_SECOND(self);
3933n/a int us = TIME_GET_MICROSECOND(self);
3934n/a PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
3935n/a int fold = TIME_GET_FOLD(self);
3936n/a
3937n/a if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace",
3938n/a time_kws,
3939n/a &hh, &mm, &ss, &us, &tzinfo, &fold))
3940n/a return NULL;
3941n/a tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo);
3942n/a if (tuple == NULL)
3943n/a return NULL;
3944n/a clone = time_new(Py_TYPE(self), tuple, NULL);
3945n/a if (clone != NULL) {
3946n/a if (fold != 0 && fold != 1) {
3947n/a PyErr_SetString(PyExc_ValueError,
3948n/a "fold must be either 0 or 1");
3949n/a return NULL;
3950n/a }
3951n/a TIME_SET_FOLD(clone, fold);
3952n/a }
3953n/a Py_DECREF(tuple);
3954n/a return clone;
3955n/a}
3956n/a
3957n/a/* Pickle support, a simple use of __reduce__. */
3958n/a
3959n/a/* Let basestate be the non-tzinfo data string.
3960n/a * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
3961n/a * So it's a tuple in any (non-error) case.
3962n/a * __getstate__ isn't exposed.
3963n/a */
3964n/astatic PyObject *
3965n/atime_getstate(PyDateTime_Time *self, int proto)
3966n/a{
3967n/a PyObject *basestate;
3968n/a PyObject *result = NULL;
3969n/a
3970n/a basestate = PyBytes_FromStringAndSize((char *)self->data,
3971n/a _PyDateTime_TIME_DATASIZE);
3972n/a if (basestate != NULL) {
3973n/a if (proto > 3 && TIME_GET_FOLD(self))
3974n/a /* Set the first bit of the first byte */
3975n/a PyBytes_AS_STRING(basestate)[0] |= (1 << 7);
3976n/a if (! HASTZINFO(self) || self->tzinfo == Py_None)
3977n/a result = PyTuple_Pack(1, basestate);
3978n/a else
3979n/a result = PyTuple_Pack(2, basestate, self->tzinfo);
3980n/a Py_DECREF(basestate);
3981n/a }
3982n/a return result;
3983n/a}
3984n/a
3985n/astatic PyObject *
3986n/atime_reduce_ex(PyDateTime_Time *self, PyObject *args)
3987n/a{
3988n/a int proto;
3989n/a if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
3990n/a return NULL;
3991n/a
3992n/a return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto));
3993n/a}
3994n/a
3995n/astatic PyObject *
3996n/atime_reduce(PyDateTime_Time *self, PyObject *arg)
3997n/a{
3998n/a return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2));
3999n/a}
4000n/a
4001n/astatic PyMethodDef time_methods[] = {
4002n/a
4003n/a {"isoformat", (PyCFunction)time_isoformat, METH_VARARGS | METH_KEYWORDS,
4004n/a PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]"
4005n/a "[+HH:MM].\n\n"
4006n/a "timespec specifies what components of the time to include.\n")},
4007n/a
4008n/a {"strftime", (PyCFunction)time_strftime, METH_VARARGS | METH_KEYWORDS,
4009n/a PyDoc_STR("format -> strftime() style string.")},
4010n/a
4011n/a {"__format__", (PyCFunction)date_format, METH_VARARGS,
4012n/a PyDoc_STR("Formats self with strftime.")},
4013n/a
4014n/a {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS,
4015n/a PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
4016n/a
4017n/a {"tzname", (PyCFunction)time_tzname, METH_NOARGS,
4018n/a PyDoc_STR("Return self.tzinfo.tzname(self).")},
4019n/a
4020n/a {"dst", (PyCFunction)time_dst, METH_NOARGS,
4021n/a PyDoc_STR("Return self.tzinfo.dst(self).")},
4022n/a
4023n/a {"replace", (PyCFunction)time_replace, METH_VARARGS | METH_KEYWORDS,
4024n/a PyDoc_STR("Return time with new specified fields.")},
4025n/a
4026n/a {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS,
4027n/a PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
4028n/a
4029n/a {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS,
4030n/a PyDoc_STR("__reduce__() -> (cls, state)")},
4031n/a
4032n/a {NULL, NULL}
4033n/a};
4034n/a
4035n/astatic const char time_doc[] =
4036n/aPyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\
4037n/a\n\
4038n/aAll arguments are optional. tzinfo may be None, or an instance of\n\
4039n/aa tzinfo subclass. The remaining arguments may be ints.\n");
4040n/a
4041n/astatic PyTypeObject PyDateTime_TimeType = {
4042n/a PyVarObject_HEAD_INIT(NULL, 0)
4043n/a "datetime.time", /* tp_name */
4044n/a sizeof(PyDateTime_Time), /* tp_basicsize */
4045n/a 0, /* tp_itemsize */
4046n/a (destructor)time_dealloc, /* tp_dealloc */
4047n/a 0, /* tp_print */
4048n/a 0, /* tp_getattr */
4049n/a 0, /* tp_setattr */
4050n/a 0, /* tp_reserved */
4051n/a (reprfunc)time_repr, /* tp_repr */
4052n/a 0, /* tp_as_number */
4053n/a 0, /* tp_as_sequence */
4054n/a 0, /* tp_as_mapping */
4055n/a (hashfunc)time_hash, /* tp_hash */
4056n/a 0, /* tp_call */
4057n/a (reprfunc)time_str, /* tp_str */
4058n/a PyObject_GenericGetAttr, /* tp_getattro */
4059n/a 0, /* tp_setattro */
4060n/a 0, /* tp_as_buffer */
4061n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4062n/a time_doc, /* tp_doc */
4063n/a 0, /* tp_traverse */
4064n/a 0, /* tp_clear */
4065n/a time_richcompare, /* tp_richcompare */
4066n/a 0, /* tp_weaklistoffset */
4067n/a 0, /* tp_iter */
4068n/a 0, /* tp_iternext */
4069n/a time_methods, /* tp_methods */
4070n/a 0, /* tp_members */
4071n/a time_getset, /* tp_getset */
4072n/a 0, /* tp_base */
4073n/a 0, /* tp_dict */
4074n/a 0, /* tp_descr_get */
4075n/a 0, /* tp_descr_set */
4076n/a 0, /* tp_dictoffset */
4077n/a 0, /* tp_init */
4078n/a time_alloc, /* tp_alloc */
4079n/a time_new, /* tp_new */
4080n/a 0, /* tp_free */
4081n/a};
4082n/a
4083n/a/*
4084n/a * PyDateTime_DateTime implementation.
4085n/a */
4086n/a
4087n/a/* Accessor properties. Properties for day, month, and year are inherited
4088n/a * from date.
4089n/a */
4090n/a
4091n/astatic PyObject *
4092n/adatetime_hour(PyDateTime_DateTime *self, void *unused)
4093n/a{
4094n/a return PyLong_FromLong(DATE_GET_HOUR(self));
4095n/a}
4096n/a
4097n/astatic PyObject *
4098n/adatetime_minute(PyDateTime_DateTime *self, void *unused)
4099n/a{
4100n/a return PyLong_FromLong(DATE_GET_MINUTE(self));
4101n/a}
4102n/a
4103n/astatic PyObject *
4104n/adatetime_second(PyDateTime_DateTime *self, void *unused)
4105n/a{
4106n/a return PyLong_FromLong(DATE_GET_SECOND(self));
4107n/a}
4108n/a
4109n/astatic PyObject *
4110n/adatetime_microsecond(PyDateTime_DateTime *self, void *unused)
4111n/a{
4112n/a return PyLong_FromLong(DATE_GET_MICROSECOND(self));
4113n/a}
4114n/a
4115n/astatic PyObject *
4116n/adatetime_tzinfo(PyDateTime_DateTime *self, void *unused)
4117n/a{
4118n/a PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None;
4119n/a Py_INCREF(result);
4120n/a return result;
4121n/a}
4122n/a
4123n/astatic PyObject *
4124n/adatetime_fold(PyDateTime_DateTime *self, void *unused)
4125n/a{
4126n/a return PyLong_FromLong(DATE_GET_FOLD(self));
4127n/a}
4128n/a
4129n/astatic PyGetSetDef datetime_getset[] = {
4130n/a {"hour", (getter)datetime_hour},
4131n/a {"minute", (getter)datetime_minute},
4132n/a {"second", (getter)datetime_second},
4133n/a {"microsecond", (getter)datetime_microsecond},
4134n/a {"tzinfo", (getter)datetime_tzinfo},
4135n/a {"fold", (getter)datetime_fold},
4136n/a {NULL}
4137n/a};
4138n/a
4139n/a/*
4140n/a * Constructors.
4141n/a */
4142n/a
4143n/astatic char *datetime_kws[] = {
4144n/a "year", "month", "day", "hour", "minute", "second",
4145n/a "microsecond", "tzinfo", "fold", NULL
4146n/a};
4147n/a
4148n/astatic PyObject *
4149n/adatetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4150n/a{
4151n/a PyObject *self = NULL;
4152n/a PyObject *state;
4153n/a int year;
4154n/a int month;
4155n/a int day;
4156n/a int hour = 0;
4157n/a int minute = 0;
4158n/a int second = 0;
4159n/a int usecond = 0;
4160n/a int fold = 0;
4161n/a PyObject *tzinfo = Py_None;
4162n/a
4163n/a /* Check for invocation from pickle with __getstate__ state */
4164n/a if (PyTuple_GET_SIZE(args) >= 1 &&
4165n/a PyTuple_GET_SIZE(args) <= 2 &&
4166n/a PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) &&
4167n/a PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE &&
4168n/a MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))
4169n/a {
4170n/a PyDateTime_DateTime *me;
4171n/a char aware;
4172n/a
4173n/a if (PyTuple_GET_SIZE(args) == 2) {
4174n/a tzinfo = PyTuple_GET_ITEM(args, 1);
4175n/a if (check_tzinfo_subclass(tzinfo) < 0) {
4176n/a PyErr_SetString(PyExc_TypeError, "bad "
4177n/a "tzinfo state arg");
4178n/a return NULL;
4179n/a }
4180n/a }
4181n/a aware = (char)(tzinfo != Py_None);
4182n/a me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware));
4183n/a if (me != NULL) {
4184n/a char *pdata = PyBytes_AS_STRING(state);
4185n/a
4186n/a memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
4187n/a me->hashcode = -1;
4188n/a me->hastzinfo = aware;
4189n/a if (aware) {
4190n/a Py_INCREF(tzinfo);
4191n/a me->tzinfo = tzinfo;
4192n/a }
4193n/a if (pdata[2] & (1 << 7)) {
4194n/a me->data[2] -= 128;
4195n/a me->fold = 1;
4196n/a }
4197n/a else {
4198n/a me->fold = 0;
4199n/a }
4200n/a }
4201n/a return (PyObject *)me;
4202n/a }
4203n/a
4204n/a if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws,
4205n/a &year, &month, &day, &hour, &minute,
4206n/a &second, &usecond, &tzinfo, &fold)) {
4207n/a self = new_datetime_ex2(year, month, day,
4208n/a hour, minute, second, usecond,
4209n/a tzinfo, fold, type);
4210n/a }
4211n/a return self;
4212n/a}
4213n/a
4214n/a/* TM_FUNC is the shared type of _PyTime_localtime() and
4215n/a * _PyTime_gmtime(). */
4216n/atypedef int (*TM_FUNC)(time_t timer, struct tm*);
4217n/a
4218n/a/* As of version 2015f max fold in IANA database is
4219n/a * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */
4220n/astatic long long max_fold_seconds = 24 * 3600;
4221n/a/* NB: date(1970,1,1).toordinal() == 719163 */
4222n/astatic long long epoch = 719163LL * 24 * 60 * 60;
4223n/a
4224n/astatic long long
4225n/autc_to_seconds(int year, int month, int day,
4226n/a int hour, int minute, int second)
4227n/a{
4228n/a long long ordinal;
4229n/a
4230n/a /* ymd_to_ord() doesn't support year <= 0 */
4231n/a if (year < MINYEAR || year > MAXYEAR) {
4232n/a PyErr_Format(PyExc_ValueError, "year %i is out of range", year);
4233n/a return -1;
4234n/a }
4235n/a
4236n/a ordinal = ymd_to_ord(year, month, day);
4237n/a return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
4238n/a}
4239n/a
4240n/astatic long long
4241n/alocal(long long u)
4242n/a{
4243n/a struct tm local_time;
4244n/a time_t t;
4245n/a u -= epoch;
4246n/a t = u;
4247n/a if (t != u) {
4248n/a PyErr_SetString(PyExc_OverflowError,
4249n/a "timestamp out of range for platform time_t");
4250n/a return -1;
4251n/a }
4252n/a if (_PyTime_localtime(t, &local_time) != 0)
4253n/a return -1;
4254n/a return utc_to_seconds(local_time.tm_year + 1900,
4255n/a local_time.tm_mon + 1,
4256n/a local_time.tm_mday,
4257n/a local_time.tm_hour,
4258n/a local_time.tm_min,
4259n/a local_time.tm_sec);
4260n/a}
4261n/a
4262n/a/* Internal helper.
4263n/a * Build datetime from a time_t and a distinct count of microseconds.
4264n/a * Pass localtime or gmtime for f, to control the interpretation of timet.
4265n/a */
4266n/astatic PyObject *
4267n/adatetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
4268n/a PyObject *tzinfo)
4269n/a{
4270n/a struct tm tm;
4271n/a int year, month, day, hour, minute, second, fold = 0;
4272n/a
4273n/a if (f(timet, &tm) != 0)
4274n/a return NULL;
4275n/a
4276n/a year = tm.tm_year + 1900;
4277n/a month = tm.tm_mon + 1;
4278n/a day = tm.tm_mday;
4279n/a hour = tm.tm_hour;
4280n/a minute = tm.tm_min;
4281n/a /* The platform localtime/gmtime may insert leap seconds,
4282n/a * indicated by tm.tm_sec > 59. We don't care about them,
4283n/a * except to the extent that passing them on to the datetime
4284n/a * constructor would raise ValueError for a reason that
4285n/a * made no sense to the user.
4286n/a */
4287n/a second = Py_MIN(59, tm.tm_sec);
4288n/a
4289n/a /* local timezone requires to compute fold */
4290n/a if (tzinfo == Py_None && f == _PyTime_localtime) {
4291n/a long long probe_seconds, result_seconds, transition;
4292n/a
4293n/a result_seconds = utc_to_seconds(year, month, day,
4294n/a hour, minute, second);
4295n/a /* Probe max_fold_seconds to detect a fold. */
4296n/a probe_seconds = local(epoch + timet - max_fold_seconds);
4297n/a if (probe_seconds == -1)
4298n/a return NULL;
4299n/a transition = result_seconds - probe_seconds - max_fold_seconds;
4300n/a if (transition < 0) {
4301n/a probe_seconds = local(epoch + timet + transition);
4302n/a if (probe_seconds == -1)
4303n/a return NULL;
4304n/a if (probe_seconds == result_seconds)
4305n/a fold = 1;
4306n/a }
4307n/a }
4308n/a return new_datetime_ex2(year, month, day, hour,
4309n/a minute, second, us, tzinfo, fold,
4310n/a (PyTypeObject *)cls);
4311n/a}
4312n/a
4313n/a/* Internal helper.
4314n/a * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
4315n/a * to control the interpretation of the timestamp. Since a double doesn't
4316n/a * have enough bits to cover a datetime's full range of precision, it's
4317n/a * better to call datetime_from_timet_and_us provided you have a way
4318n/a * to get that much precision (e.g., C time() isn't good enough).
4319n/a */
4320n/astatic PyObject *
4321n/adatetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
4322n/a PyObject *tzinfo)
4323n/a{
4324n/a time_t timet;
4325n/a long us;
4326n/a
4327n/a if (_PyTime_ObjectToTimeval(timestamp,
4328n/a &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1)
4329n/a return NULL;
4330n/a
4331n/a return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
4332n/a}
4333n/a
4334n/a/* Internal helper.
4335n/a * Build most accurate possible datetime for current time. Pass localtime or
4336n/a * gmtime for f as appropriate.
4337n/a */
4338n/astatic PyObject *
4339n/adatetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
4340n/a{
4341n/a _PyTime_t ts = _PyTime_GetSystemClock();
4342n/a time_t secs;
4343n/a int us;
4344n/a
4345n/a if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
4346n/a return NULL;
4347n/a assert(0 <= us && us <= 999999);
4348n/a
4349n/a return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
4350n/a}
4351n/a
4352n/a/*[clinic input]
4353n/a
4354n/a@classmethod
4355n/adatetime.datetime.now
4356n/a
4357n/a tz: object = None
4358n/a Timezone object.
4359n/a
4360n/aReturns new datetime object representing current time local to tz.
4361n/a
4362n/aIf no tz is specified, uses local timezone.
4363n/a[clinic start generated code]*/
4364n/a
4365n/astatic PyObject *
4366n/adatetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
4367n/a/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/
4368n/a{
4369n/a PyObject *self;
4370n/a
4371n/a /* Return best possible local time -- this isn't constrained by the
4372n/a * precision of a timestamp.
4373n/a */
4374n/a if (check_tzinfo_subclass(tz) < 0)
4375n/a return NULL;
4376n/a
4377n/a self = datetime_best_possible((PyObject *)type,
4378n/a tz == Py_None ? _PyTime_localtime :
4379n/a _PyTime_gmtime,
4380n/a tz);
4381n/a if (self != NULL && tz != Py_None) {
4382n/a /* Convert UTC to tzinfo's zone. */
4383n/a self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self);
4384n/a }
4385n/a return self;
4386n/a}
4387n/a
4388n/a/* Return best possible UTC time -- this isn't constrained by the
4389n/a * precision of a timestamp.
4390n/a */
4391n/astatic PyObject *
4392n/adatetime_utcnow(PyObject *cls, PyObject *dummy)
4393n/a{
4394n/a return datetime_best_possible(cls, _PyTime_gmtime, Py_None);
4395n/a}
4396n/a
4397n/a/* Return new local datetime from timestamp (Python timestamp -- a double). */
4398n/astatic PyObject *
4399n/adatetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
4400n/a{
4401n/a PyObject *self;
4402n/a PyObject *timestamp;
4403n/a PyObject *tzinfo = Py_None;
4404n/a static char *keywords[] = {"timestamp", "tz", NULL};
4405n/a
4406n/a if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp",
4407n/a keywords, &timestamp, &tzinfo))
4408n/a return NULL;
4409n/a if (check_tzinfo_subclass(tzinfo) < 0)
4410n/a return NULL;
4411n/a
4412n/a self = datetime_from_timestamp(cls,
4413n/a tzinfo == Py_None ? _PyTime_localtime :
4414n/a _PyTime_gmtime,
4415n/a timestamp,
4416n/a tzinfo);
4417n/a if (self != NULL && tzinfo != Py_None) {
4418n/a /* Convert UTC to tzinfo's zone. */
4419n/a self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self);
4420n/a }
4421n/a return self;
4422n/a}
4423n/a
4424n/a/* Return new UTC datetime from timestamp (Python timestamp -- a double). */
4425n/astatic PyObject *
4426n/adatetime_utcfromtimestamp(PyObject *cls, PyObject *args)
4427n/a{
4428n/a PyObject *timestamp;
4429n/a PyObject *result = NULL;
4430n/a
4431n/a if (PyArg_ParseTuple(args, "O:utcfromtimestamp", &timestamp))
4432n/a result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp,
4433n/a Py_None);
4434n/a return result;
4435n/a}
4436n/a
4437n/a/* Return new datetime from _strptime.strptime_datetime(). */
4438n/astatic PyObject *
4439n/adatetime_strptime(PyObject *cls, PyObject *args)
4440n/a{
4441n/a static PyObject *module = NULL;
4442n/a PyObject *string, *format;
4443n/a _Py_IDENTIFIER(_strptime_datetime);
4444n/a
4445n/a if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
4446n/a return NULL;
4447n/a
4448n/a if (module == NULL) {
4449n/a module = PyImport_ImportModuleNoBlock("_strptime");
4450n/a if (module == NULL)
4451n/a return NULL;
4452n/a }
4453n/a return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime,
4454n/a cls, string, format, NULL);
4455n/a}
4456n/a
4457n/a/* Return new datetime from date/datetime and time arguments. */
4458n/astatic PyObject *
4459n/adatetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
4460n/a{
4461n/a static char *keywords[] = {"date", "time", "tzinfo", NULL};
4462n/a PyObject *date;
4463n/a PyObject *time;
4464n/a PyObject *tzinfo = NULL;
4465n/a PyObject *result = NULL;
4466n/a
4467n/a if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords,
4468n/a &PyDateTime_DateType, &date,
4469n/a &PyDateTime_TimeType, &time, &tzinfo)) {
4470n/a if (tzinfo == NULL) {
4471n/a if (HASTZINFO(time))
4472n/a tzinfo = ((PyDateTime_Time *)time)->tzinfo;
4473n/a else
4474n/a tzinfo = Py_None;
4475n/a }
4476n/a result = PyObject_CallFunction(cls, "iiiiiiiO",
4477n/a GET_YEAR(date),
4478n/a GET_MONTH(date),
4479n/a GET_DAY(date),
4480n/a TIME_GET_HOUR(time),
4481n/a TIME_GET_MINUTE(time),
4482n/a TIME_GET_SECOND(time),
4483n/a TIME_GET_MICROSECOND(time),
4484n/a tzinfo);
4485n/a if (result)
4486n/a DATE_SET_FOLD(result, TIME_GET_FOLD(time));
4487n/a }
4488n/a return result;
4489n/a}
4490n/a
4491n/a/*
4492n/a * Destructor.
4493n/a */
4494n/a
4495n/astatic void
4496n/adatetime_dealloc(PyDateTime_DateTime *self)
4497n/a{
4498n/a if (HASTZINFO(self)) {
4499n/a Py_XDECREF(self->tzinfo);
4500n/a }
4501n/a Py_TYPE(self)->tp_free((PyObject *)self);
4502n/a}
4503n/a
4504n/a/*
4505n/a * Indirect access to tzinfo methods.
4506n/a */
4507n/a
4508n/a/* These are all METH_NOARGS, so don't need to check the arglist. */
4509n/astatic PyObject *
4510n/adatetime_utcoffset(PyObject *self, PyObject *unused) {
4511n/a return call_utcoffset(GET_DT_TZINFO(self), self);
4512n/a}
4513n/a
4514n/astatic PyObject *
4515n/adatetime_dst(PyObject *self, PyObject *unused) {
4516n/a return call_dst(GET_DT_TZINFO(self), self);
4517n/a}
4518n/a
4519n/astatic PyObject *
4520n/adatetime_tzname(PyObject *self, PyObject *unused) {
4521n/a return call_tzname(GET_DT_TZINFO(self), self);
4522n/a}
4523n/a
4524n/a/*
4525n/a * datetime arithmetic.
4526n/a */
4527n/a
4528n/a/* factor must be 1 (to add) or -1 (to subtract). The result inherits
4529n/a * the tzinfo state of date.
4530n/a */
4531n/astatic PyObject *
4532n/aadd_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta,
4533n/a int factor)
4534n/a{
4535n/a /* Note that the C-level additions can't overflow, because of
4536n/a * invariant bounds on the member values.
4537n/a */
4538n/a int year = GET_YEAR(date);
4539n/a int month = GET_MONTH(date);
4540n/a int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor;
4541n/a int hour = DATE_GET_HOUR(date);
4542n/a int minute = DATE_GET_MINUTE(date);
4543n/a int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor;
4544n/a int microsecond = DATE_GET_MICROSECOND(date) +
4545n/a GET_TD_MICROSECONDS(delta) * factor;
4546n/a
4547n/a assert(factor == 1 || factor == -1);
4548n/a if (normalize_datetime(&year, &month, &day,
4549n/a &hour, &minute, &second, &microsecond) < 0) {
4550n/a return NULL;
4551n/a }
4552n/a
4553n/a return new_datetime(year, month, day,
4554n/a hour, minute, second, microsecond,
4555n/a HASTZINFO(date) ? date->tzinfo : Py_None, 0);
4556n/a}
4557n/a
4558n/astatic PyObject *
4559n/adatetime_add(PyObject *left, PyObject *right)
4560n/a{
4561n/a if (PyDateTime_Check(left)) {
4562n/a /* datetime + ??? */
4563n/a if (PyDelta_Check(right))
4564n/a /* datetime + delta */
4565n/a return add_datetime_timedelta(
4566n/a (PyDateTime_DateTime *)left,
4567n/a (PyDateTime_Delta *)right,
4568n/a 1);
4569n/a }
4570n/a else if (PyDelta_Check(left)) {
4571n/a /* delta + datetime */
4572n/a return add_datetime_timedelta((PyDateTime_DateTime *) right,
4573n/a (PyDateTime_Delta *) left,
4574n/a 1);
4575n/a }
4576n/a Py_RETURN_NOTIMPLEMENTED;
4577n/a}
4578n/a
4579n/astatic PyObject *
4580n/adatetime_subtract(PyObject *left, PyObject *right)
4581n/a{
4582n/a PyObject *result = Py_NotImplemented;
4583n/a
4584n/a if (PyDateTime_Check(left)) {
4585n/a /* datetime - ??? */
4586n/a if (PyDateTime_Check(right)) {
4587n/a /* datetime - datetime */
4588n/a PyObject *offset1, *offset2, *offdiff = NULL;
4589n/a int delta_d, delta_s, delta_us;
4590n/a
4591n/a if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) {
4592n/a offset2 = offset1 = Py_None;
4593n/a Py_INCREF(offset1);
4594n/a Py_INCREF(offset2);
4595n/a }
4596n/a else {
4597n/a offset1 = datetime_utcoffset(left, NULL);
4598n/a if (offset1 == NULL)
4599n/a return NULL;
4600n/a offset2 = datetime_utcoffset(right, NULL);
4601n/a if (offset2 == NULL) {
4602n/a Py_DECREF(offset1);
4603n/a return NULL;
4604n/a }
4605n/a if ((offset1 != Py_None) != (offset2 != Py_None)) {
4606n/a PyErr_SetString(PyExc_TypeError,
4607n/a "can't subtract offset-naive and "
4608n/a "offset-aware datetimes");
4609n/a Py_DECREF(offset1);
4610n/a Py_DECREF(offset2);
4611n/a return NULL;
4612n/a }
4613n/a }
4614n/a if ((offset1 != offset2) &&
4615n/a delta_cmp(offset1, offset2) != 0) {
4616n/a offdiff = delta_subtract(offset1, offset2);
4617n/a if (offdiff == NULL) {
4618n/a Py_DECREF(offset1);
4619n/a Py_DECREF(offset2);
4620n/a return NULL;
4621n/a }
4622n/a }
4623n/a Py_DECREF(offset1);
4624n/a Py_DECREF(offset2);
4625n/a delta_d = ymd_to_ord(GET_YEAR(left),
4626n/a GET_MONTH(left),
4627n/a GET_DAY(left)) -
4628n/a ymd_to_ord(GET_YEAR(right),
4629n/a GET_MONTH(right),
4630n/a GET_DAY(right));
4631n/a /* These can't overflow, since the values are
4632n/a * normalized. At most this gives the number of
4633n/a * seconds in one day.
4634n/a */
4635n/a delta_s = (DATE_GET_HOUR(left) -
4636n/a DATE_GET_HOUR(right)) * 3600 +
4637n/a (DATE_GET_MINUTE(left) -
4638n/a DATE_GET_MINUTE(right)) * 60 +
4639n/a (DATE_GET_SECOND(left) -
4640n/a DATE_GET_SECOND(right));
4641n/a delta_us = DATE_GET_MICROSECOND(left) -
4642n/a DATE_GET_MICROSECOND(right);
4643n/a result = new_delta(delta_d, delta_s, delta_us, 1);
4644n/a if (result == NULL)
4645n/a return NULL;
4646n/a
4647n/a if (offdiff != NULL) {
4648n/a Py_SETREF(result, delta_subtract(result, offdiff));
4649n/a Py_DECREF(offdiff);
4650n/a }
4651n/a }
4652n/a else if (PyDelta_Check(right)) {
4653n/a /* datetime - delta */
4654n/a result = add_datetime_timedelta(
4655n/a (PyDateTime_DateTime *)left,
4656n/a (PyDateTime_Delta *)right,
4657n/a -1);
4658n/a }
4659n/a }
4660n/a
4661n/a if (result == Py_NotImplemented)
4662n/a Py_INCREF(result);
4663n/a return result;
4664n/a}
4665n/a
4666n/a/* Various ways to turn a datetime into a string. */
4667n/a
4668n/astatic PyObject *
4669n/adatetime_repr(PyDateTime_DateTime *self)
4670n/a{
4671n/a const char *type_name = Py_TYPE(self)->tp_name;
4672n/a PyObject *baserepr;
4673n/a
4674n/a if (DATE_GET_MICROSECOND(self)) {
4675n/a baserepr = PyUnicode_FromFormat(
4676n/a "%s(%d, %d, %d, %d, %d, %d, %d)",
4677n/a type_name,
4678n/a GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4679n/a DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4680n/a DATE_GET_SECOND(self),
4681n/a DATE_GET_MICROSECOND(self));
4682n/a }
4683n/a else if (DATE_GET_SECOND(self)) {
4684n/a baserepr = PyUnicode_FromFormat(
4685n/a "%s(%d, %d, %d, %d, %d, %d)",
4686n/a type_name,
4687n/a GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4688n/a DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4689n/a DATE_GET_SECOND(self));
4690n/a }
4691n/a else {
4692n/a baserepr = PyUnicode_FromFormat(
4693n/a "%s(%d, %d, %d, %d, %d)",
4694n/a type_name,
4695n/a GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
4696n/a DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
4697n/a }
4698n/a if (baserepr != NULL && DATE_GET_FOLD(self) != 0)
4699n/a baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self));
4700n/a if (baserepr == NULL || ! HASTZINFO(self))
4701n/a return baserepr;
4702n/a return append_keyword_tzinfo(baserepr, self->tzinfo);
4703n/a}
4704n/a
4705n/astatic PyObject *
4706n/adatetime_str(PyDateTime_DateTime *self)
4707n/a{
4708n/a return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " ");
4709n/a}
4710n/a
4711n/astatic PyObject *
4712n/adatetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
4713n/a{
4714n/a int sep = 'T';
4715n/a char *timespec = NULL;
4716n/a static char *keywords[] = {"sep", "timespec", NULL};
4717n/a char buffer[100];
4718n/a PyObject *result = NULL;
4719n/a int us = DATE_GET_MICROSECOND(self);
4720n/a static char *specs[][2] = {
4721n/a {"hours", "%04d-%02d-%02d%c%02d"},
4722n/a {"minutes", "%04d-%02d-%02d%c%02d:%02d"},
4723n/a {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"},
4724n/a {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"},
4725n/a {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"},
4726n/a };
4727n/a size_t given_spec;
4728n/a
4729n/a if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, &timespec))
4730n/a return NULL;
4731n/a
4732n/a if (timespec == NULL || strcmp(timespec, "auto") == 0) {
4733n/a if (us == 0) {
4734n/a /* seconds */
4735n/a given_spec = 2;
4736n/a }
4737n/a else {
4738n/a /* microseconds */
4739n/a given_spec = 4;
4740n/a }
4741n/a }
4742n/a else {
4743n/a for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) {
4744n/a if (strcmp(timespec, specs[given_spec][0]) == 0) {
4745n/a if (given_spec == 3) {
4746n/a us = us / 1000;
4747n/a }
4748n/a break;
4749n/a }
4750n/a }
4751n/a }
4752n/a
4753n/a if (given_spec == Py_ARRAY_LENGTH(specs)) {
4754n/a PyErr_Format(PyExc_ValueError, "Unknown timespec value");
4755n/a return NULL;
4756n/a }
4757n/a else {
4758n/a result = PyUnicode_FromFormat(specs[given_spec][1],
4759n/a GET_YEAR(self), GET_MONTH(self),
4760n/a GET_DAY(self), (int)sep,
4761n/a DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
4762n/a DATE_GET_SECOND(self), us);
4763n/a }
4764n/a
4765n/a if (!result || !HASTZINFO(self))
4766n/a return result;
4767n/a
4768n/a /* We need to append the UTC offset. */
4769n/a if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo,
4770n/a (PyObject *)self) < 0) {
4771n/a Py_DECREF(result);
4772n/a return NULL;
4773n/a }
4774n/a PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer));
4775n/a return result;
4776n/a}
4777n/a
4778n/astatic PyObject *
4779n/adatetime_ctime(PyDateTime_DateTime *self)
4780n/a{
4781n/a return format_ctime((PyDateTime_Date *)self,
4782n/a DATE_GET_HOUR(self),
4783n/a DATE_GET_MINUTE(self),
4784n/a DATE_GET_SECOND(self));
4785n/a}
4786n/a
4787n/a/* Miscellaneous methods. */
4788n/a
4789n/astatic PyObject *
4790n/aflip_fold(PyObject *dt)
4791n/a{
4792n/a return new_datetime_ex2(GET_YEAR(dt),
4793n/a GET_MONTH(dt),
4794n/a GET_DAY(dt),
4795n/a DATE_GET_HOUR(dt),
4796n/a DATE_GET_MINUTE(dt),
4797n/a DATE_GET_SECOND(dt),
4798n/a DATE_GET_MICROSECOND(dt),
4799n/a HASTZINFO(dt) ?
4800n/a ((PyDateTime_DateTime *)dt)->tzinfo : Py_None,
4801n/a !DATE_GET_FOLD(dt),
4802n/a Py_TYPE(dt));
4803n/a}
4804n/a
4805n/astatic PyObject *
4806n/aget_flip_fold_offset(PyObject *dt)
4807n/a{
4808n/a PyObject *result, *flip_dt;
4809n/a
4810n/a flip_dt = flip_fold(dt);
4811n/a if (flip_dt == NULL)
4812n/a return NULL;
4813n/a result = datetime_utcoffset(flip_dt, NULL);
4814n/a Py_DECREF(flip_dt);
4815n/a return result;
4816n/a}
4817n/a
4818n/a/* PEP 495 exception: Whenever one or both of the operands in
4819n/a * inter-zone comparison is such that its utcoffset() depends
4820n/a * on the value of its fold fold attribute, the result is False.
4821n/a *
4822n/a * Return 1 if exception applies, 0 if not, and -1 on error.
4823n/a */
4824n/astatic int
4825n/apep495_eq_exception(PyObject *self, PyObject *other,
4826n/a PyObject *offset_self, PyObject *offset_other)
4827n/a{
4828n/a int result = 0;
4829n/a PyObject *flip_offset;
4830n/a
4831n/a flip_offset = get_flip_fold_offset(self);
4832n/a if (flip_offset == NULL)
4833n/a return -1;
4834n/a if (flip_offset != offset_self &&
4835n/a delta_cmp(flip_offset, offset_self))
4836n/a {
4837n/a result = 1;
4838n/a goto done;
4839n/a }
4840n/a Py_DECREF(flip_offset);
4841n/a
4842n/a flip_offset = get_flip_fold_offset(other);
4843n/a if (flip_offset == NULL)
4844n/a return -1;
4845n/a if (flip_offset != offset_other &&
4846n/a delta_cmp(flip_offset, offset_other))
4847n/a result = 1;
4848n/a done:
4849n/a Py_DECREF(flip_offset);
4850n/a return result;
4851n/a}
4852n/a
4853n/astatic PyObject *
4854n/adatetime_richcompare(PyObject *self, PyObject *other, int op)
4855n/a{
4856n/a PyObject *result = NULL;
4857n/a PyObject *offset1, *offset2;
4858n/a int diff;
4859n/a
4860n/a if (! PyDateTime_Check(other)) {
4861n/a if (PyDate_Check(other)) {
4862n/a /* Prevent invocation of date_richcompare. We want to
4863n/a return NotImplemented here to give the other object
4864n/a a chance. But since DateTime is a subclass of
4865n/a Date, if the other object is a Date, it would
4866n/a compute an ordering based on the date part alone,
4867n/a and we don't want that. So force unequal or
4868n/a uncomparable here in that case. */
4869n/a if (op == Py_EQ)
4870n/a Py_RETURN_FALSE;
4871n/a if (op == Py_NE)
4872n/a Py_RETURN_TRUE;
4873n/a return cmperror(self, other);
4874n/a }
4875n/a Py_RETURN_NOTIMPLEMENTED;
4876n/a }
4877n/a
4878n/a if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) {
4879n/a diff = memcmp(((PyDateTime_DateTime *)self)->data,
4880n/a ((PyDateTime_DateTime *)other)->data,
4881n/a _PyDateTime_DATETIME_DATASIZE);
4882n/a return diff_to_bool(diff, op);
4883n/a }
4884n/a offset1 = datetime_utcoffset(self, NULL);
4885n/a if (offset1 == NULL)
4886n/a return NULL;
4887n/a offset2 = datetime_utcoffset(other, NULL);
4888n/a if (offset2 == NULL)
4889n/a goto done;
4890n/a /* If they're both naive, or both aware and have the same offsets,
4891n/a * we get off cheap. Note that if they're both naive, offset1 ==
4892n/a * offset2 == Py_None at this point.
4893n/a */
4894n/a if ((offset1 == offset2) ||
4895n/a (PyDelta_Check(offset1) && PyDelta_Check(offset2) &&
4896n/a delta_cmp(offset1, offset2) == 0)) {
4897n/a diff = memcmp(((PyDateTime_DateTime *)self)->data,
4898n/a ((PyDateTime_DateTime *)other)->data,
4899n/a _PyDateTime_DATETIME_DATASIZE);
4900n/a if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4901n/a int ex = pep495_eq_exception(self, other, offset1, offset2);
4902n/a if (ex == -1)
4903n/a goto done;
4904n/a if (ex)
4905n/a diff = 1;
4906n/a }
4907n/a result = diff_to_bool(diff, op);
4908n/a }
4909n/a else if (offset1 != Py_None && offset2 != Py_None) {
4910n/a PyDateTime_Delta *delta;
4911n/a
4912n/a assert(offset1 != offset2); /* else last "if" handled it */
4913n/a delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self,
4914n/a other);
4915n/a if (delta == NULL)
4916n/a goto done;
4917n/a diff = GET_TD_DAYS(delta);
4918n/a if (diff == 0)
4919n/a diff = GET_TD_SECONDS(delta) |
4920n/a GET_TD_MICROSECONDS(delta);
4921n/a Py_DECREF(delta);
4922n/a if ((op == Py_EQ || op == Py_NE) && diff == 0) {
4923n/a int ex = pep495_eq_exception(self, other, offset1, offset2);
4924n/a if (ex == -1)
4925n/a goto done;
4926n/a if (ex)
4927n/a diff = 1;
4928n/a }
4929n/a result = diff_to_bool(diff, op);
4930n/a }
4931n/a else if (op == Py_EQ) {
4932n/a result = Py_False;
4933n/a Py_INCREF(result);
4934n/a }
4935n/a else if (op == Py_NE) {
4936n/a result = Py_True;
4937n/a Py_INCREF(result);
4938n/a }
4939n/a else {
4940n/a PyErr_SetString(PyExc_TypeError,
4941n/a "can't compare offset-naive and "
4942n/a "offset-aware datetimes");
4943n/a }
4944n/a done:
4945n/a Py_DECREF(offset1);
4946n/a Py_XDECREF(offset2);
4947n/a return result;
4948n/a}
4949n/a
4950n/astatic Py_hash_t
4951n/adatetime_hash(PyDateTime_DateTime *self)
4952n/a{
4953n/a if (self->hashcode == -1) {
4954n/a PyObject *offset, *self0;
4955n/a if (DATE_GET_FOLD(self)) {
4956n/a self0 = new_datetime_ex2(GET_YEAR(self),
4957n/a GET_MONTH(self),
4958n/a GET_DAY(self),
4959n/a DATE_GET_HOUR(self),
4960n/a DATE_GET_MINUTE(self),
4961n/a DATE_GET_SECOND(self),
4962n/a DATE_GET_MICROSECOND(self),
4963n/a HASTZINFO(self) ? self->tzinfo : Py_None,
4964n/a 0, Py_TYPE(self));
4965n/a if (self0 == NULL)
4966n/a return -1;
4967n/a }
4968n/a else {
4969n/a self0 = (PyObject *)self;
4970n/a Py_INCREF(self0);
4971n/a }
4972n/a offset = datetime_utcoffset(self0, NULL);
4973n/a Py_DECREF(self0);
4974n/a
4975n/a if (offset == NULL)
4976n/a return -1;
4977n/a
4978n/a /* Reduce this to a hash of another object. */
4979n/a if (offset == Py_None)
4980n/a self->hashcode = generic_hash(
4981n/a (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
4982n/a else {
4983n/a PyObject *temp1, *temp2;
4984n/a int days, seconds;
4985n/a
4986n/a assert(HASTZINFO(self));
4987n/a days = ymd_to_ord(GET_YEAR(self),
4988n/a GET_MONTH(self),
4989n/a GET_DAY(self));
4990n/a seconds = DATE_GET_HOUR(self) * 3600 +
4991n/a DATE_GET_MINUTE(self) * 60 +
4992n/a DATE_GET_SECOND(self);
4993n/a temp1 = new_delta(days, seconds,
4994n/a DATE_GET_MICROSECOND(self),
4995n/a 1);
4996n/a if (temp1 == NULL) {
4997n/a Py_DECREF(offset);
4998n/a return -1;
4999n/a }
5000n/a temp2 = delta_subtract(temp1, offset);
5001n/a Py_DECREF(temp1);
5002n/a if (temp2 == NULL) {
5003n/a Py_DECREF(offset);
5004n/a return -1;
5005n/a }
5006n/a self->hashcode = PyObject_Hash(temp2);
5007n/a Py_DECREF(temp2);
5008n/a }
5009n/a Py_DECREF(offset);
5010n/a }
5011n/a return self->hashcode;
5012n/a}
5013n/a
5014n/astatic PyObject *
5015n/adatetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
5016n/a{
5017n/a PyObject *clone;
5018n/a PyObject *tuple;
5019n/a int y = GET_YEAR(self);
5020n/a int m = GET_MONTH(self);
5021n/a int d = GET_DAY(self);
5022n/a int hh = DATE_GET_HOUR(self);
5023n/a int mm = DATE_GET_MINUTE(self);
5024n/a int ss = DATE_GET_SECOND(self);
5025n/a int us = DATE_GET_MICROSECOND(self);
5026n/a PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None;
5027n/a int fold = DATE_GET_FOLD(self);
5028n/a
5029n/a if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace",
5030n/a datetime_kws,
5031n/a &y, &m, &d, &hh, &mm, &ss, &us,
5032n/a &tzinfo, &fold))
5033n/a return NULL;
5034n/a tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo);
5035n/a if (tuple == NULL)
5036n/a return NULL;
5037n/a clone = datetime_new(Py_TYPE(self), tuple, NULL);
5038n/a
5039n/a if (clone != NULL) {
5040n/a if (fold != 0 && fold != 1) {
5041n/a PyErr_SetString(PyExc_ValueError,
5042n/a "fold must be either 0 or 1");
5043n/a return NULL;
5044n/a }
5045n/a DATE_SET_FOLD(clone, fold);
5046n/a }
5047n/a Py_DECREF(tuple);
5048n/a return clone;
5049n/a}
5050n/a
5051n/astatic PyObject *
5052n/alocal_timezone_from_timestamp(time_t timestamp)
5053n/a{
5054n/a PyObject *result = NULL;
5055n/a PyObject *delta;
5056n/a struct tm local_time_tm;
5057n/a PyObject *nameo = NULL;
5058n/a const char *zone = NULL;
5059n/a
5060n/a if (_PyTime_localtime(timestamp, &local_time_tm) != 0)
5061n/a return NULL;
5062n/a#ifdef HAVE_STRUCT_TM_TM_ZONE
5063n/a zone = local_time_tm.tm_zone;
5064n/a delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1);
5065n/a#else /* HAVE_STRUCT_TM_TM_ZONE */
5066n/a {
5067n/a PyObject *local_time, *utc_time;
5068n/a struct tm utc_time_tm;
5069n/a char buf[100];
5070n/a strftime(buf, sizeof(buf), "%Z", &local_time_tm);
5071n/a zone = buf;
5072n/a local_time = new_datetime(local_time_tm.tm_year + 1900,
5073n/a local_time_tm.tm_mon + 1,
5074n/a local_time_tm.tm_mday,
5075n/a local_time_tm.tm_hour,
5076n/a local_time_tm.tm_min,
5077n/a local_time_tm.tm_sec, 0, Py_None, 0);
5078n/a if (local_time == NULL) {
5079n/a return NULL;
5080n/a }
5081n/a if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0)
5082n/a return NULL;
5083n/a utc_time = new_datetime(utc_time_tm.tm_year + 1900,
5084n/a utc_time_tm.tm_mon + 1,
5085n/a utc_time_tm.tm_mday,
5086n/a utc_time_tm.tm_hour,
5087n/a utc_time_tm.tm_min,
5088n/a utc_time_tm.tm_sec, 0, Py_None, 0);
5089n/a if (utc_time == NULL) {
5090n/a Py_DECREF(local_time);
5091n/a return NULL;
5092n/a }
5093n/a delta = datetime_subtract(local_time, utc_time);
5094n/a Py_DECREF(local_time);
5095n/a Py_DECREF(utc_time);
5096n/a }
5097n/a#endif /* HAVE_STRUCT_TM_TM_ZONE */
5098n/a if (delta == NULL) {
5099n/a return NULL;
5100n/a }
5101n/a if (zone != NULL) {
5102n/a nameo = PyUnicode_DecodeLocale(zone, "surrogateescape");
5103n/a if (nameo == NULL)
5104n/a goto error;
5105n/a }
5106n/a result = new_timezone(delta, nameo);
5107n/a Py_XDECREF(nameo);
5108n/a error:
5109n/a Py_DECREF(delta);
5110n/a return result;
5111n/a}
5112n/a
5113n/astatic PyObject *
5114n/alocal_timezone(PyDateTime_DateTime *utc_time)
5115n/a{
5116n/a time_t timestamp;
5117n/a PyObject *delta;
5118n/a PyObject *one_second;
5119n/a PyObject *seconds;
5120n/a
5121n/a delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch);
5122n/a if (delta == NULL)
5123n/a return NULL;
5124n/a one_second = new_delta(0, 1, 0, 0);
5125n/a if (one_second == NULL) {
5126n/a Py_DECREF(delta);
5127n/a return NULL;
5128n/a }
5129n/a seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta,
5130n/a (PyDateTime_Delta *)one_second);
5131n/a Py_DECREF(one_second);
5132n/a Py_DECREF(delta);
5133n/a if (seconds == NULL)
5134n/a return NULL;
5135n/a timestamp = _PyLong_AsTime_t(seconds);
5136n/a Py_DECREF(seconds);
5137n/a if (timestamp == -1 && PyErr_Occurred())
5138n/a return NULL;
5139n/a return local_timezone_from_timestamp(timestamp);
5140n/a}
5141n/a
5142n/astatic long long
5143n/alocal_to_seconds(int year, int month, int day,
5144n/a int hour, int minute, int second, int fold);
5145n/a
5146n/astatic PyObject *
5147n/alocal_timezone_from_local(PyDateTime_DateTime *local_dt)
5148n/a{
5149n/a long long seconds;
5150n/a time_t timestamp;
5151n/a seconds = local_to_seconds(GET_YEAR(local_dt),
5152n/a GET_MONTH(local_dt),
5153n/a GET_DAY(local_dt),
5154n/a DATE_GET_HOUR(local_dt),
5155n/a DATE_GET_MINUTE(local_dt),
5156n/a DATE_GET_SECOND(local_dt),
5157n/a DATE_GET_FOLD(local_dt));
5158n/a if (seconds == -1)
5159n/a return NULL;
5160n/a /* XXX: add bounds check */
5161n/a timestamp = seconds - epoch;
5162n/a return local_timezone_from_timestamp(timestamp);
5163n/a}
5164n/a
5165n/astatic PyDateTime_DateTime *
5166n/adatetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
5167n/a{
5168n/a PyDateTime_DateTime *result;
5169n/a PyObject *offset;
5170n/a PyObject *temp;
5171n/a PyObject *self_tzinfo;
5172n/a PyObject *tzinfo = Py_None;
5173n/a static char *keywords[] = {"tz", NULL};
5174n/a
5175n/a if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords,
5176n/a &tzinfo))
5177n/a return NULL;
5178n/a
5179n/a if (check_tzinfo_subclass(tzinfo) == -1)
5180n/a return NULL;
5181n/a
5182n/a if (!HASTZINFO(self) || self->tzinfo == Py_None) {
5183n/a self_tzinfo = local_timezone_from_local(self);
5184n/a if (self_tzinfo == NULL)
5185n/a return NULL;
5186n/a } else {
5187n/a self_tzinfo = self->tzinfo;
5188n/a Py_INCREF(self_tzinfo);
5189n/a }
5190n/a
5191n/a /* Conversion to self's own time zone is a NOP. */
5192n/a if (self_tzinfo == tzinfo) {
5193n/a Py_DECREF(self_tzinfo);
5194n/a Py_INCREF(self);
5195n/a return self;
5196n/a }
5197n/a
5198n/a /* Convert self to UTC. */
5199n/a offset = call_utcoffset(self_tzinfo, (PyObject *)self);
5200n/a Py_DECREF(self_tzinfo);
5201n/a if (offset == NULL)
5202n/a return NULL;
5203n/a /* result = self - offset */
5204n/a result = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5205n/a (PyDateTime_Delta *)offset, -1);
5206n/a Py_DECREF(offset);
5207n/a if (result == NULL)
5208n/a return NULL;
5209n/a
5210n/a /* Make sure result is aware and UTC. */
5211n/a if (!HASTZINFO(result)) {
5212n/a temp = (PyObject *)result;
5213n/a result = (PyDateTime_DateTime *)
5214n/a new_datetime_ex2(GET_YEAR(result),
5215n/a GET_MONTH(result),
5216n/a GET_DAY(result),
5217n/a DATE_GET_HOUR(result),
5218n/a DATE_GET_MINUTE(result),
5219n/a DATE_GET_SECOND(result),
5220n/a DATE_GET_MICROSECOND(result),
5221n/a PyDateTime_TimeZone_UTC,
5222n/a DATE_GET_FOLD(result),
5223n/a Py_TYPE(result));
5224n/a Py_DECREF(temp);
5225n/a if (result == NULL)
5226n/a return NULL;
5227n/a }
5228n/a else {
5229n/a /* Result is already aware - just replace tzinfo. */
5230n/a temp = result->tzinfo;
5231n/a result->tzinfo = PyDateTime_TimeZone_UTC;
5232n/a Py_INCREF(result->tzinfo);
5233n/a Py_DECREF(temp);
5234n/a }
5235n/a
5236n/a /* Attach new tzinfo and let fromutc() do the rest. */
5237n/a temp = result->tzinfo;
5238n/a if (tzinfo == Py_None) {
5239n/a tzinfo = local_timezone(result);
5240n/a if (tzinfo == NULL) {
5241n/a Py_DECREF(result);
5242n/a return NULL;
5243n/a }
5244n/a }
5245n/a else
5246n/a Py_INCREF(tzinfo);
5247n/a result->tzinfo = tzinfo;
5248n/a Py_DECREF(temp);
5249n/a
5250n/a temp = (PyObject *)result;
5251n/a result = (PyDateTime_DateTime *)
5252n/a _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL);
5253n/a Py_DECREF(temp);
5254n/a
5255n/a return result;
5256n/a}
5257n/a
5258n/astatic PyObject *
5259n/adatetime_timetuple(PyDateTime_DateTime *self)
5260n/a{
5261n/a int dstflag = -1;
5262n/a
5263n/a if (HASTZINFO(self) && self->tzinfo != Py_None) {
5264n/a PyObject * dst;
5265n/a
5266n/a dst = call_dst(self->tzinfo, (PyObject *)self);
5267n/a if (dst == NULL)
5268n/a return NULL;
5269n/a
5270n/a if (dst != Py_None)
5271n/a dstflag = delta_bool((PyDateTime_Delta *)dst);
5272n/a Py_DECREF(dst);
5273n/a }
5274n/a return build_struct_time(GET_YEAR(self),
5275n/a GET_MONTH(self),
5276n/a GET_DAY(self),
5277n/a DATE_GET_HOUR(self),
5278n/a DATE_GET_MINUTE(self),
5279n/a DATE_GET_SECOND(self),
5280n/a dstflag);
5281n/a}
5282n/a
5283n/astatic long long
5284n/alocal_to_seconds(int year, int month, int day,
5285n/a int hour, int minute, int second, int fold)
5286n/a{
5287n/a long long t, a, b, u1, u2, t1, t2, lt;
5288n/a t = utc_to_seconds(year, month, day, hour, minute, second);
5289n/a /* Our goal is to solve t = local(u) for u. */
5290n/a lt = local(t);
5291n/a if (lt == -1)
5292n/a return -1;
5293n/a a = lt - t;
5294n/a u1 = t - a;
5295n/a t1 = local(u1);
5296n/a if (t1 == -1)
5297n/a return -1;
5298n/a if (t1 == t) {
5299n/a /* We found one solution, but it may not be the one we need.
5300n/a * Look for an earlier solution (if `fold` is 0), or a
5301n/a * later one (if `fold` is 1). */
5302n/a if (fold)
5303n/a u2 = u1 + max_fold_seconds;
5304n/a else
5305n/a u2 = u1 - max_fold_seconds;
5306n/a lt = local(u2);
5307n/a if (lt == -1)
5308n/a return -1;
5309n/a b = lt - u2;
5310n/a if (a == b)
5311n/a return u1;
5312n/a }
5313n/a else {
5314n/a b = t1 - u1;
5315n/a assert(a != b);
5316n/a }
5317n/a u2 = t - b;
5318n/a t2 = local(u2);
5319n/a if (t2 == -1)
5320n/a return -1;
5321n/a if (t2 == t)
5322n/a return u2;
5323n/a if (t1 == t)
5324n/a return u1;
5325n/a /* We have found both offsets a and b, but neither t - a nor t - b is
5326n/a * a solution. This means t is in the gap. */
5327n/a return fold?Py_MIN(u1, u2):Py_MAX(u1, u2);
5328n/a}
5329n/a
5330n/a/* date(1970,1,1).toordinal() == 719163 */
5331n/a#define EPOCH_SECONDS (719163LL * 24 * 60 * 60)
5332n/a
5333n/astatic PyObject *
5334n/adatetime_timestamp(PyDateTime_DateTime *self)
5335n/a{
5336n/a PyObject *result;
5337n/a
5338n/a if (HASTZINFO(self) && self->tzinfo != Py_None) {
5339n/a PyObject *delta;
5340n/a delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch);
5341n/a if (delta == NULL)
5342n/a return NULL;
5343n/a result = delta_total_seconds(delta);
5344n/a Py_DECREF(delta);
5345n/a }
5346n/a else {
5347n/a long long seconds;
5348n/a seconds = local_to_seconds(GET_YEAR(self),
5349n/a GET_MONTH(self),
5350n/a GET_DAY(self),
5351n/a DATE_GET_HOUR(self),
5352n/a DATE_GET_MINUTE(self),
5353n/a DATE_GET_SECOND(self),
5354n/a DATE_GET_FOLD(self));
5355n/a if (seconds == -1)
5356n/a return NULL;
5357n/a result = PyFloat_FromDouble(seconds - EPOCH_SECONDS +
5358n/a DATE_GET_MICROSECOND(self) / 1e6);
5359n/a }
5360n/a return result;
5361n/a}
5362n/a
5363n/astatic PyObject *
5364n/adatetime_getdate(PyDateTime_DateTime *self)
5365n/a{
5366n/a return new_date(GET_YEAR(self),
5367n/a GET_MONTH(self),
5368n/a GET_DAY(self));
5369n/a}
5370n/a
5371n/astatic PyObject *
5372n/adatetime_gettime(PyDateTime_DateTime *self)
5373n/a{
5374n/a return new_time(DATE_GET_HOUR(self),
5375n/a DATE_GET_MINUTE(self),
5376n/a DATE_GET_SECOND(self),
5377n/a DATE_GET_MICROSECOND(self),
5378n/a Py_None,
5379n/a DATE_GET_FOLD(self));
5380n/a}
5381n/a
5382n/astatic PyObject *
5383n/adatetime_gettimetz(PyDateTime_DateTime *self)
5384n/a{
5385n/a return new_time(DATE_GET_HOUR(self),
5386n/a DATE_GET_MINUTE(self),
5387n/a DATE_GET_SECOND(self),
5388n/a DATE_GET_MICROSECOND(self),
5389n/a GET_DT_TZINFO(self),
5390n/a DATE_GET_FOLD(self));
5391n/a}
5392n/a
5393n/astatic PyObject *
5394n/adatetime_utctimetuple(PyDateTime_DateTime *self)
5395n/a{
5396n/a int y, m, d, hh, mm, ss;
5397n/a PyObject *tzinfo;
5398n/a PyDateTime_DateTime *utcself;
5399n/a
5400n/a tzinfo = GET_DT_TZINFO(self);
5401n/a if (tzinfo == Py_None) {
5402n/a utcself = self;
5403n/a Py_INCREF(utcself);
5404n/a }
5405n/a else {
5406n/a PyObject *offset;
5407n/a offset = call_utcoffset(tzinfo, (PyObject *)self);
5408n/a if (offset == NULL)
5409n/a return NULL;
5410n/a if (offset == Py_None) {
5411n/a Py_DECREF(offset);
5412n/a utcself = self;
5413n/a Py_INCREF(utcself);
5414n/a }
5415n/a else {
5416n/a utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self,
5417n/a (PyDateTime_Delta *)offset, -1);
5418n/a Py_DECREF(offset);
5419n/a if (utcself == NULL)
5420n/a return NULL;
5421n/a }
5422n/a }
5423n/a y = GET_YEAR(utcself);
5424n/a m = GET_MONTH(utcself);
5425n/a d = GET_DAY(utcself);
5426n/a hh = DATE_GET_HOUR(utcself);
5427n/a mm = DATE_GET_MINUTE(utcself);
5428n/a ss = DATE_GET_SECOND(utcself);
5429n/a
5430n/a Py_DECREF(utcself);
5431n/a return build_struct_time(y, m, d, hh, mm, ss, 0);
5432n/a}
5433n/a
5434n/a/* Pickle support, a simple use of __reduce__. */
5435n/a
5436n/a/* Let basestate be the non-tzinfo data string.
5437n/a * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo).
5438n/a * So it's a tuple in any (non-error) case.
5439n/a * __getstate__ isn't exposed.
5440n/a */
5441n/astatic PyObject *
5442n/adatetime_getstate(PyDateTime_DateTime *self, int proto)
5443n/a{
5444n/a PyObject *basestate;
5445n/a PyObject *result = NULL;
5446n/a
5447n/a basestate = PyBytes_FromStringAndSize((char *)self->data,
5448n/a _PyDateTime_DATETIME_DATASIZE);
5449n/a if (basestate != NULL) {
5450n/a if (proto > 3 && DATE_GET_FOLD(self))
5451n/a /* Set the first bit of the third byte */
5452n/a PyBytes_AS_STRING(basestate)[2] |= (1 << 7);
5453n/a if (! HASTZINFO(self) || self->tzinfo == Py_None)
5454n/a result = PyTuple_Pack(1, basestate);
5455n/a else
5456n/a result = PyTuple_Pack(2, basestate, self->tzinfo);
5457n/a Py_DECREF(basestate);
5458n/a }
5459n/a return result;
5460n/a}
5461n/a
5462n/astatic PyObject *
5463n/adatetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args)
5464n/a{
5465n/a int proto;
5466n/a if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto))
5467n/a return NULL;
5468n/a
5469n/a return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto));
5470n/a}
5471n/a
5472n/astatic PyObject *
5473n/adatetime_reduce(PyDateTime_DateTime *self, PyObject *arg)
5474n/a{
5475n/a return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2));
5476n/a}
5477n/a
5478n/astatic PyMethodDef datetime_methods[] = {
5479n/a
5480n/a /* Class methods: */
5481n/a
5482n/a DATETIME_DATETIME_NOW_METHODDEF
5483n/a
5484n/a {"utcnow", (PyCFunction)datetime_utcnow,
5485n/a METH_NOARGS | METH_CLASS,
5486n/a PyDoc_STR("Return a new datetime representing UTC day and time.")},
5487n/a
5488n/a {"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
5489n/a METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5490n/a PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
5491n/a
5492n/a {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
5493n/a METH_VARARGS | METH_CLASS,
5494n/a PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")},
5495n/a
5496n/a {"strptime", (PyCFunction)datetime_strptime,
5497n/a METH_VARARGS | METH_CLASS,
5498n/a PyDoc_STR("string, format -> new datetime parsed from a string "
5499n/a "(like time.strptime()).")},
5500n/a
5501n/a {"combine", (PyCFunction)datetime_combine,
5502n/a METH_VARARGS | METH_KEYWORDS | METH_CLASS,
5503n/a PyDoc_STR("date, time -> datetime with same date and time fields")},
5504n/a
5505n/a /* Instance methods: */
5506n/a
5507n/a {"date", (PyCFunction)datetime_getdate, METH_NOARGS,
5508n/a PyDoc_STR("Return date object with same year, month and day.")},
5509n/a
5510n/a {"time", (PyCFunction)datetime_gettime, METH_NOARGS,
5511n/a PyDoc_STR("Return time object with same time but with tzinfo=None.")},
5512n/a
5513n/a {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS,
5514n/a PyDoc_STR("Return time object with same time and tzinfo.")},
5515n/a
5516n/a {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS,
5517n/a PyDoc_STR("Return ctime() style string.")},
5518n/a
5519n/a {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS,
5520n/a PyDoc_STR("Return time tuple, compatible with time.localtime().")},
5521n/a
5522n/a {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS,
5523n/a PyDoc_STR("Return POSIX timestamp as float.")},
5524n/a
5525n/a {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS,
5526n/a PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")},
5527n/a
5528n/a {"isoformat", (PyCFunction)datetime_isoformat, METH_VARARGS | METH_KEYWORDS,
5529n/a PyDoc_STR("[sep] -> string in ISO 8601 format, "
5530n/a "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n"
5531n/a "sep is used to separate the year from the time, and "
5532n/a "defaults to 'T'.\n"
5533n/a "timespec specifies what components of the time to include"
5534n/a " (allowed values are 'auto', 'hours', 'minutes', 'seconds',"
5535n/a " 'milliseconds', and 'microseconds').\n")},
5536n/a
5537n/a {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS,
5538n/a PyDoc_STR("Return self.tzinfo.utcoffset(self).")},
5539n/a
5540n/a {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS,
5541n/a PyDoc_STR("Return self.tzinfo.tzname(self).")},
5542n/a
5543n/a {"dst", (PyCFunction)datetime_dst, METH_NOARGS,
5544n/a PyDoc_STR("Return self.tzinfo.dst(self).")},
5545n/a
5546n/a {"replace", (PyCFunction)datetime_replace, METH_VARARGS | METH_KEYWORDS,
5547n/a PyDoc_STR("Return datetime with new specified fields.")},
5548n/a
5549n/a {"astimezone", (PyCFunction)datetime_astimezone, METH_VARARGS | METH_KEYWORDS,
5550n/a PyDoc_STR("tz -> convert to local time in new timezone tz\n")},
5551n/a
5552n/a {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS,
5553n/a PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")},
5554n/a
5555n/a {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS,
5556n/a PyDoc_STR("__reduce__() -> (cls, state)")},
5557n/a
5558n/a {NULL, NULL}
5559n/a};
5560n/a
5561n/astatic const char datetime_doc[] =
5562n/aPyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\
5563n/a\n\
5564n/aThe year, month and day arguments are required. tzinfo may be None, or an\n\
5565n/ainstance of a tzinfo subclass. The remaining arguments may be ints.\n");
5566n/a
5567n/astatic PyNumberMethods datetime_as_number = {
5568n/a datetime_add, /* nb_add */
5569n/a datetime_subtract, /* nb_subtract */
5570n/a 0, /* nb_multiply */
5571n/a 0, /* nb_remainder */
5572n/a 0, /* nb_divmod */
5573n/a 0, /* nb_power */
5574n/a 0, /* nb_negative */
5575n/a 0, /* nb_positive */
5576n/a 0, /* nb_absolute */
5577n/a 0, /* nb_bool */
5578n/a};
5579n/a
5580n/astatic PyTypeObject PyDateTime_DateTimeType = {
5581n/a PyVarObject_HEAD_INIT(NULL, 0)
5582n/a "datetime.datetime", /* tp_name */
5583n/a sizeof(PyDateTime_DateTime), /* tp_basicsize */
5584n/a 0, /* tp_itemsize */
5585n/a (destructor)datetime_dealloc, /* tp_dealloc */
5586n/a 0, /* tp_print */
5587n/a 0, /* tp_getattr */
5588n/a 0, /* tp_setattr */
5589n/a 0, /* tp_reserved */
5590n/a (reprfunc)datetime_repr, /* tp_repr */
5591n/a &datetime_as_number, /* tp_as_number */
5592n/a 0, /* tp_as_sequence */
5593n/a 0, /* tp_as_mapping */
5594n/a (hashfunc)datetime_hash, /* tp_hash */
5595n/a 0, /* tp_call */
5596n/a (reprfunc)datetime_str, /* tp_str */
5597n/a PyObject_GenericGetAttr, /* tp_getattro */
5598n/a 0, /* tp_setattro */
5599n/a 0, /* tp_as_buffer */
5600n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5601n/a datetime_doc, /* tp_doc */
5602n/a 0, /* tp_traverse */
5603n/a 0, /* tp_clear */
5604n/a datetime_richcompare, /* tp_richcompare */
5605n/a 0, /* tp_weaklistoffset */
5606n/a 0, /* tp_iter */
5607n/a 0, /* tp_iternext */
5608n/a datetime_methods, /* tp_methods */
5609n/a 0, /* tp_members */
5610n/a datetime_getset, /* tp_getset */
5611n/a &PyDateTime_DateType, /* tp_base */
5612n/a 0, /* tp_dict */
5613n/a 0, /* tp_descr_get */
5614n/a 0, /* tp_descr_set */
5615n/a 0, /* tp_dictoffset */
5616n/a 0, /* tp_init */
5617n/a datetime_alloc, /* tp_alloc */
5618n/a datetime_new, /* tp_new */
5619n/a 0, /* tp_free */
5620n/a};
5621n/a
5622n/a/* ---------------------------------------------------------------------------
5623n/a * Module methods and initialization.
5624n/a */
5625n/a
5626n/astatic PyMethodDef module_methods[] = {
5627n/a {NULL, NULL}
5628n/a};
5629n/a
5630n/a/* C API. Clients get at this via PyDateTime_IMPORT, defined in
5631n/a * datetime.h.
5632n/a */
5633n/astatic PyDateTime_CAPI CAPI = {
5634n/a &PyDateTime_DateType,
5635n/a &PyDateTime_DateTimeType,
5636n/a &PyDateTime_TimeType,
5637n/a &PyDateTime_DeltaType,
5638n/a &PyDateTime_TZInfoType,
5639n/a new_date_ex,
5640n/a new_datetime_ex,
5641n/a new_time_ex,
5642n/a new_delta_ex,
5643n/a datetime_fromtimestamp,
5644n/a date_fromtimestamp,
5645n/a new_datetime_ex2,
5646n/a new_time_ex2
5647n/a};
5648n/a
5649n/a
5650n/a
5651n/astatic struct PyModuleDef datetimemodule = {
5652n/a PyModuleDef_HEAD_INIT,
5653n/a "_datetime",
5654n/a "Fast implementation of the datetime type.",
5655n/a -1,
5656n/a module_methods,
5657n/a NULL,
5658n/a NULL,
5659n/a NULL,
5660n/a NULL
5661n/a};
5662n/a
5663n/aPyMODINIT_FUNC
5664n/aPyInit__datetime(void)
5665n/a{
5666n/a PyObject *m; /* a module object */
5667n/a PyObject *d; /* its dict */
5668n/a PyObject *x;
5669n/a PyObject *delta;
5670n/a
5671n/a m = PyModule_Create(&datetimemodule);
5672n/a if (m == NULL)
5673n/a return NULL;
5674n/a
5675n/a if (PyType_Ready(&PyDateTime_DateType) < 0)
5676n/a return NULL;
5677n/a if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
5678n/a return NULL;
5679n/a if (PyType_Ready(&PyDateTime_DeltaType) < 0)
5680n/a return NULL;
5681n/a if (PyType_Ready(&PyDateTime_TimeType) < 0)
5682n/a return NULL;
5683n/a if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
5684n/a return NULL;
5685n/a if (PyType_Ready(&PyDateTime_TimeZoneType) < 0)
5686n/a return NULL;
5687n/a
5688n/a /* timedelta values */
5689n/a d = PyDateTime_DeltaType.tp_dict;
5690n/a
5691n/a x = new_delta(0, 0, 1, 0);
5692n/a if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5693n/a return NULL;
5694n/a Py_DECREF(x);
5695n/a
5696n/a x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
5697n/a if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5698n/a return NULL;
5699n/a Py_DECREF(x);
5700n/a
5701n/a x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
5702n/a if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5703n/a return NULL;
5704n/a Py_DECREF(x);
5705n/a
5706n/a /* date values */
5707n/a d = PyDateTime_DateType.tp_dict;
5708n/a
5709n/a x = new_date(1, 1, 1);
5710n/a if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5711n/a return NULL;
5712n/a Py_DECREF(x);
5713n/a
5714n/a x = new_date(MAXYEAR, 12, 31);
5715n/a if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5716n/a return NULL;
5717n/a Py_DECREF(x);
5718n/a
5719n/a x = new_delta(1, 0, 0, 0);
5720n/a if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5721n/a return NULL;
5722n/a Py_DECREF(x);
5723n/a
5724n/a /* time values */
5725n/a d = PyDateTime_TimeType.tp_dict;
5726n/a
5727n/a x = new_time(0, 0, 0, 0, Py_None, 0);
5728n/a if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5729n/a return NULL;
5730n/a Py_DECREF(x);
5731n/a
5732n/a x = new_time(23, 59, 59, 999999, Py_None, 0);
5733n/a if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5734n/a return NULL;
5735n/a Py_DECREF(x);
5736n/a
5737n/a x = new_delta(0, 0, 1, 0);
5738n/a if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5739n/a return NULL;
5740n/a Py_DECREF(x);
5741n/a
5742n/a /* datetime values */
5743n/a d = PyDateTime_DateTimeType.tp_dict;
5744n/a
5745n/a x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0);
5746n/a if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5747n/a return NULL;
5748n/a Py_DECREF(x);
5749n/a
5750n/a x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0);
5751n/a if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5752n/a return NULL;
5753n/a Py_DECREF(x);
5754n/a
5755n/a x = new_delta(0, 0, 1, 0);
5756n/a if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
5757n/a return NULL;
5758n/a Py_DECREF(x);
5759n/a
5760n/a /* timezone values */
5761n/a d = PyDateTime_TimeZoneType.tp_dict;
5762n/a
5763n/a delta = new_delta(0, 0, 0, 0);
5764n/a if (delta == NULL)
5765n/a return NULL;
5766n/a x = create_timezone(delta, NULL);
5767n/a Py_DECREF(delta);
5768n/a if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0)
5769n/a return NULL;
5770n/a PyDateTime_TimeZone_UTC = x;
5771n/a
5772n/a delta = new_delta(-1, 60, 0, 1); /* -23:59 */
5773n/a if (delta == NULL)
5774n/a return NULL;
5775n/a x = create_timezone(delta, NULL);
5776n/a Py_DECREF(delta);
5777n/a if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
5778n/a return NULL;
5779n/a Py_DECREF(x);
5780n/a
5781n/a delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */
5782n/a if (delta == NULL)
5783n/a return NULL;
5784n/a x = create_timezone(delta, NULL);
5785n/a Py_DECREF(delta);
5786n/a if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
5787n/a return NULL;
5788n/a Py_DECREF(x);
5789n/a
5790n/a /* Epoch */
5791n/a PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0,
5792n/a PyDateTime_TimeZone_UTC, 0);
5793n/a if (PyDateTime_Epoch == NULL)
5794n/a return NULL;
5795n/a
5796n/a /* module initialization */
5797n/a PyModule_AddIntMacro(m, MINYEAR);
5798n/a PyModule_AddIntMacro(m, MAXYEAR);
5799n/a
5800n/a Py_INCREF(&PyDateTime_DateType);
5801n/a PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType);
5802n/a
5803n/a Py_INCREF(&PyDateTime_DateTimeType);
5804n/a PyModule_AddObject(m, "datetime",
5805n/a (PyObject *)&PyDateTime_DateTimeType);
5806n/a
5807n/a Py_INCREF(&PyDateTime_TimeType);
5808n/a PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType);
5809n/a
5810n/a Py_INCREF(&PyDateTime_DeltaType);
5811n/a PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType);
5812n/a
5813n/a Py_INCREF(&PyDateTime_TZInfoType);
5814n/a PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
5815n/a
5816n/a Py_INCREF(&PyDateTime_TimeZoneType);
5817n/a PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType);
5818n/a
5819n/a x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL);
5820n/a if (x == NULL)
5821n/a return NULL;
5822n/a PyModule_AddObject(m, "datetime_CAPI", x);
5823n/a
5824n/a /* A 4-year cycle has an extra leap day over what we'd get from
5825n/a * pasting together 4 single years.
5826n/a */
5827n/a Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1);
5828n/a assert(DI4Y == days_before_year(4+1));
5829n/a
5830n/a /* Similarly, a 400-year cycle has an extra leap day over what we'd
5831n/a * get from pasting together 4 100-year cycles.
5832n/a */
5833n/a Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1);
5834n/a assert(DI400Y == days_before_year(400+1));
5835n/a
5836n/a /* OTOH, a 100-year cycle has one fewer leap day than we'd get from
5837n/a * pasting together 25 4-year cycles.
5838n/a */
5839n/a Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1);
5840n/a assert(DI100Y == days_before_year(100+1));
5841n/a
5842n/a one = PyLong_FromLong(1);
5843n/a us_per_ms = PyLong_FromLong(1000);
5844n/a us_per_second = PyLong_FromLong(1000000);
5845n/a us_per_minute = PyLong_FromLong(60000000);
5846n/a seconds_per_day = PyLong_FromLong(24 * 3600);
5847n/a if (one == NULL || us_per_ms == NULL || us_per_second == NULL ||
5848n/a us_per_minute == NULL || seconds_per_day == NULL)
5849n/a return NULL;
5850n/a
5851n/a /* The rest are too big for 32-bit ints, but even
5852n/a * us_per_week fits in 40 bits, so doubles should be exact.
5853n/a */
5854n/a us_per_hour = PyLong_FromDouble(3600000000.0);
5855n/a us_per_day = PyLong_FromDouble(86400000000.0);
5856n/a us_per_week = PyLong_FromDouble(604800000000.0);
5857n/a if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
5858n/a return NULL;
5859n/a return m;
5860n/a}
5861n/a
5862n/a/* ---------------------------------------------------------------------------
5863n/aSome time zone algebra. For a datetime x, let
5864n/a x.n = x stripped of its timezone -- its naive time.
5865n/a x.o = x.utcoffset(), and assuming that doesn't raise an exception or
5866n/a return None
5867n/a x.d = x.dst(), and assuming that doesn't raise an exception or
5868n/a return None
5869n/a x.s = x's standard offset, x.o - x.d
5870n/a
5871n/aNow some derived rules, where k is a duration (timedelta).
5872n/a
5873n/a1. x.o = x.s + x.d
5874n/a This follows from the definition of x.s.
5875n/a
5876n/a2. If x and y have the same tzinfo member, x.s = y.s.
5877n/a This is actually a requirement, an assumption we need to make about
5878n/a sane tzinfo classes.
5879n/a
5880n/a3. The naive UTC time corresponding to x is x.n - x.o.
5881n/a This is again a requirement for a sane tzinfo class.
5882n/a
5883n/a4. (x+k).s = x.s
5884n/a This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
5885n/a
5886n/a5. (x+k).n = x.n + k
5887n/a Again follows from how arithmetic is defined.
5888n/a
5889n/aNow we can explain tz.fromutc(x). Let's assume it's an interesting case
5890n/a(meaning that the various tzinfo methods exist, and don't blow up or return
5891n/aNone when called).
5892n/a
5893n/aThe function wants to return a datetime y with timezone tz, equivalent to x.
5894n/ax is already in UTC.
5895n/a
5896n/aBy #3, we want
5897n/a
5898n/a y.n - y.o = x.n [1]
5899n/a
5900n/aThe algorithm starts by attaching tz to x.n, and calling that y. So
5901n/ax.n = y.n at the start. Then it wants to add a duration k to y, so that [1]
5902n/abecomes true; in effect, we want to solve [2] for k:
5903n/a
5904n/a (y+k).n - (y+k).o = x.n [2]
5905n/a
5906n/aBy #1, this is the same as
5907n/a
5908n/a (y+k).n - ((y+k).s + (y+k).d) = x.n [3]
5909n/a
5910n/aBy #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
5911n/aSubstituting that into [3],
5912n/a
5913n/a x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
5914n/a k - (y+k).s - (y+k).d = 0; rearranging,
5915n/a k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
5916n/a k = y.s - (y+k).d
5917n/a
5918n/aOn the RHS, (y+k).d can't be computed directly, but y.s can be, and we
5919n/aapproximate k by ignoring the (y+k).d term at first. Note that k can't be
5920n/avery large, since all offset-returning methods return a duration of magnitude
5921n/aless than 24 hours. For that reason, if y is firmly in std time, (y+k).d must
5922n/abe 0, so ignoring it has no consequence then.
5923n/a
5924n/aIn any case, the new value is
5925n/a
5926n/a z = y + y.s [4]
5927n/a
5928n/aIt's helpful to step back at look at [4] from a higher level: it's simply
5929n/amapping from UTC to tz's standard time.
5930n/a
5931n/aAt this point, if
5932n/a
5933n/a z.n - z.o = x.n [5]
5934n/a
5935n/awe have an equivalent time, and are almost done. The insecurity here is
5936n/aat the start of daylight time. Picture US Eastern for concreteness. The wall
5937n/atime jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
5938n/asense then. The docs ask that an Eastern tzinfo class consider such a time to
5939n/abe EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
5940n/aon the day DST starts. We want to return the 1:MM EST spelling because that's
5941n/athe only spelling that makes sense on the local wall clock.
5942n/a
5943n/aIn fact, if [5] holds at this point, we do have the standard-time spelling,
5944n/abut that takes a bit of proof. We first prove a stronger result. What's the
5945n/adifference between the LHS and RHS of [5]? Let
5946n/a
5947n/a diff = x.n - (z.n - z.o) [6]
5948n/a
5949n/aNow
5950n/a z.n = by [4]
5951n/a (y + y.s).n = by #5
5952n/a y.n + y.s = since y.n = x.n
5953n/a x.n + y.s = since z and y are have the same tzinfo member,
5954n/a y.s = z.s by #2
5955n/a x.n + z.s
5956n/a
5957n/aPlugging that back into [6] gives
5958n/a
5959n/a diff =
5960n/a x.n - ((x.n + z.s) - z.o) = expanding
5961n/a x.n - x.n - z.s + z.o = cancelling
5962n/a - z.s + z.o = by #2
5963n/a z.d
5964n/a
5965n/aSo diff = z.d.
5966n/a
5967n/aIf [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
5968n/aspelling we wanted in the endcase described above. We're done. Contrarily,
5969n/aif z.d = 0, then we have a UTC equivalent, and are also done.
5970n/a
5971n/aIf [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
5972n/aadd to z (in effect, z is in tz's standard time, and we need to shift the
5973n/alocal clock into tz's daylight time).
5974n/a
5975n/aLet
5976n/a
5977n/a z' = z + z.d = z + diff [7]
5978n/a
5979n/aand we can again ask whether
5980n/a
5981n/a z'.n - z'.o = x.n [8]
5982n/a
5983n/aIf so, we're done. If not, the tzinfo class is insane, according to the
5984n/aassumptions we've made. This also requires a bit of proof. As before, let's
5985n/acompute the difference between the LHS and RHS of [8] (and skipping some of
5986n/athe justifications for the kinds of substitutions we've done several times
5987n/aalready):
5988n/a
5989n/a diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7]
5990n/a x.n - (z.n + diff - z'.o) = replacing diff via [6]
5991n/a x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
5992n/a x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n
5993n/a - z.n + z.n - z.o + z'.o = cancel z.n
5994n/a - z.o + z'.o = #1 twice
5995n/a -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo
5996n/a z'.d - z.d
5997n/a
5998n/aSo z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal,
5999n/awe've found the UTC-equivalent so are done. In fact, we stop with [7] and
6000n/areturn z', not bothering to compute z'.d.
6001n/a
6002n/aHow could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by
6003n/aa dst() offset, and starting *from* a time already in DST (we know z.d != 0),
6004n/awould have to change the result dst() returns: we start in DST, and moving
6005n/aa little further into it takes us out of DST.
6006n/a
6007n/aThere isn't a sane case where this can happen. The closest it gets is at
6008n/athe end of DST, where there's an hour in UTC with no spelling in a hybrid
6009n/atzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During
6010n/athat hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
6011n/aUTC) because the docs insist on that, but 0:MM is taken as being in daylight
6012n/atime (4:MM UTC). There is no local time mapping to 5:MM UTC. The local
6013n/aclock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
6014n/astandard time. Since that's what the local clock *does*, we want to map both
6015n/aUTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous
6016n/ain local time, but so it goes -- it's the way the local clock works.
6017n/a
6018n/aWhen x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
6019n/aso z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
6020n/az' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
6021n/a(correctly) concludes that z' is not UTC-equivalent to x.
6022n/a
6023n/aBecause we know z.d said z was in daylight time (else [5] would have held and
6024n/awe would have stopped then), and we know z.d != z'.d (else [8] would have held
6025n/aand we would have stopped then), and there are only 2 possible values dst() can
6026n/areturn in Eastern, it follows that z'.d must be 0 (which it is in the example,
6027n/abut the reasoning doesn't depend on the example -- it depends on there being
6028n/atwo possible dst() outcomes, one zero and the other non-zero). Therefore
6029n/az' must be in standard time, and is the spelling we want in this case.
6030n/a
6031n/aNote again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
6032n/aconcerned (because it takes z' as being in standard time rather than the
6033n/adaylight time we intend here), but returning it gives the real-life "local
6034n/aclock repeats an hour" behavior when mapping the "unspellable" UTC hour into
6035n/atz.
6036n/a
6037n/aWhen the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
6038n/athe 1:MM standard time spelling we want.
6039n/a
6040n/aSo how can this break? One of the assumptions must be violated. Two
6041n/apossibilities:
6042n/a
6043n/a1) [2] effectively says that y.s is invariant across all y belong to a given
6044n/a time zone. This isn't true if, for political reasons or continental drift,
6045n/a a region decides to change its base offset from UTC.
6046n/a
6047n/a2) There may be versions of "double daylight" time where the tail end of
6048n/a the analysis gives up a step too early. I haven't thought about that
6049n/a enough to say.
6050n/a
6051n/aIn any case, it's clear that the default fromutc() is strong enough to handle
6052n/a"almost all" time zones: so long as the standard offset is invariant, it
6053n/adoesn't matter if daylight time transition points change from year to year, or
6054n/aif daylight time is skipped in some years; it doesn't matter how large or
6055n/asmall dst() may get within its bounds; and it doesn't even matter if some
6056n/aperverse time zone returns a negative dst()). So a breaking case must be
6057n/apretty bizarre, and a tzinfo subclass can override fromutc() if it is.
6058n/a--------------------------------------------------------------------------- */